Add content loading pipeline documentation
This commit is contained in:
parent
19d0836e2b
commit
1a91b384b5
1 changed files with 151 additions and 0 deletions
151
docs/how/content-loading.rst
Normal file
151
docs/how/content-loading.rst
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
=============================
|
||||
content loading pipeline
|
||||
=============================
|
||||
|
||||
the content pipeline converts static TOML definitions into runtime Python objects
|
||||
at startup. all loading happens once before accepting player connections — no hot-reload.
|
||||
|
||||
startup sequence
|
||||
================
|
||||
|
||||
from ``server.py run_server()``, in order::
|
||||
|
||||
1. init_db() → database
|
||||
2. init_game_time() → game clock
|
||||
3. World() + terrain → procedural terrain
|
||||
4. Zone (overworld) → overworld from terrain
|
||||
5. load_zones() → content zones (hub, tavern, etc) from content/zones/
|
||||
6. load_commands() → TOML commands from content/commands/
|
||||
7. load_help_topics() → help topics from content/help/
|
||||
8. register_combat_commands() → combat moves from content/combat/
|
||||
9. load_mob_templates() → mob definitions from content/mobs/
|
||||
10. load_thing_templates() → thing/container definitions from content/things/
|
||||
11. load_recipes() → crafting recipes from content/recipes/
|
||||
12. load_all_dialogues() → NPC dialogue trees from content/dialogue/
|
||||
|
||||
common loader pattern
|
||||
=====================
|
||||
|
||||
every content type follows the same pattern::
|
||||
|
||||
1. load_X(path) → parse single TOML file into dataclass
|
||||
2. load_Xs(directory) → iterate .toml files, call load_X each, return dict
|
||||
3. At startup: global_registry.update(load_Xs(dir))
|
||||
|
||||
the loader functions are synchronous. they read files, parse TOML, validate data,
|
||||
and populate module-level registries. errors during load are logged but don't
|
||||
crash the server (graceful degradation).
|
||||
|
||||
content directory structure
|
||||
===========================
|
||||
|
||||
all content lives under ``content/``::
|
||||
|
||||
content/commands/ → command definitions (name, aliases, handler or message)
|
||||
content/combat/ → combat moves (attacks, defenses, variants)
|
||||
content/things/ → thing/container templates
|
||||
content/mobs/ → mob templates with loot and schedules
|
||||
content/zones/ → zone definitions (terrain grids, portals, spawns, ambient)
|
||||
content/recipes/ → crafting recipes
|
||||
content/dialogue/ → NPC dialogue trees
|
||||
content/help/ → help topic files
|
||||
content/stories/ → z-machine game files (not TOML, loaded separately)
|
||||
|
||||
each subdirectory contains multiple ``.toml`` files. the loader iterates them
|
||||
all and merges results into a single registry.
|
||||
|
||||
global registries
|
||||
=================
|
||||
|
||||
module-level dicts, populated at startup, read-only during play::
|
||||
|
||||
commands/__init__.py: _registry dict
|
||||
combat/commands.py: combat_moves dict
|
||||
things.py: thing_templates dict
|
||||
mobs.py: mob_templates dict, mobs list
|
||||
zones.py: zone_registry dict
|
||||
crafting.py: recipes dict
|
||||
commands/help.py: _help_topics dict
|
||||
commands/talk.py: dialogue_trees dict
|
||||
|
||||
these dicts are never mutated after startup. new content requires a server restart.
|
||||
|
||||
handler resolution
|
||||
==================
|
||||
|
||||
commands and thing verbs can reference Python functions via ``"module:function"``
|
||||
strings. at load time, the loader uses ``importlib`` to resolve the string into
|
||||
a callable.
|
||||
|
||||
commands can also have inline message text instead of a handler. in that case,
|
||||
the loader wraps the message in a simple async handler that sends the text.
|
||||
|
||||
if handler resolution fails, the loader logs a warning and continues. the command
|
||||
is registered but won't work (graceful degradation).
|
||||
|
||||
template vs instance
|
||||
====================
|
||||
|
||||
templates are immutable definitions stored as dataclasses. spawning creates mutable
|
||||
runtime objects (``Thing``, ``Mob``, etc).
|
||||
|
||||
templates stay in the registry forever. instances are created and destroyed during
|
||||
play. when a mob dies, the template remains — you can spawn another.
|
||||
|
||||
this separation keeps content definitions clean and allows multiple instances of
|
||||
the same template (ten wolves from one ``wolf`` template).
|
||||
|
||||
validation
|
||||
==========
|
||||
|
||||
different content types validate at different levels:
|
||||
|
||||
dialogue trees
|
||||
--------------
|
||||
|
||||
validate all node references at load time. if a choice points to a nonexistent node,
|
||||
``load_dialogue()`` raises ``ValueError`` and the server won't start.
|
||||
|
||||
combat moves
|
||||
------------
|
||||
|
||||
validate ``countered_by`` references. if a move references a nonexistent counter,
|
||||
the loader logs a warning but continues. the move is still usable, just without
|
||||
that counter.
|
||||
|
||||
zone portals
|
||||
------------
|
||||
|
||||
parse ``"zone_name:x,y"`` target format at load time. if the format is invalid,
|
||||
the portal won't work. if the zone doesn't exist yet (load order), it's fine —
|
||||
the portal stores the string and runtime lookup happens when someone uses it.
|
||||
|
||||
code
|
||||
====
|
||||
|
||||
startup sequence::
|
||||
|
||||
src/mudlib/server.py (run_server function)
|
||||
|
||||
loaders::
|
||||
|
||||
src/mudlib/commands/__init__.py (load_command, load_commands)
|
||||
src/mudlib/combat/commands.py (load_combat_move, register_combat_commands)
|
||||
src/mudlib/things.py (load_thing_templates)
|
||||
src/mudlib/mobs.py (load_mob_template, load_mob_templates)
|
||||
src/mudlib/zones.py (load_zone, load_zones)
|
||||
src/mudlib/crafting.py (load_recipes)
|
||||
src/mudlib/commands/help.py (load_help_topic, load_help_topics)
|
||||
src/mudlib/commands/talk.py (load_dialogue, load_all_dialogues)
|
||||
|
||||
content directories::
|
||||
|
||||
content/commands/
|
||||
content/combat/
|
||||
content/things/
|
||||
content/mobs/
|
||||
content/zones/
|
||||
content/recipes/
|
||||
content/dialogue/
|
||||
content/help/
|
||||
content/stories/
|
||||
Loading…
Reference in a new issue