===================================== things and verbs: how objects interact ===================================== the thing/verb system lets world objects respond to player actions. instead of hardcoding behavior in commands, objects carry their own verb handlers. two ways to register verbs: decorator-based (python classes) or toml-based (content files). both converge to the same dispatch mechanism. object base class ================= ``Object`` (object.py) is the foundation for all world entities. it has: - ``name`` - what the object is called - ``location`` - another Object or None (the entire containment system) - ``x``, ``y`` - coordinates in the world - ``_contents`` - list of objects inside this one - ``_verbs`` - dict mapping verb names to handlers ``__post_init__`` scans the instance for methods decorated with ``@verb`` and auto-registers them in ``_verbs``. thing and container =================== ``Thing`` (thing.py) extends Object for portable items:: name: str description: str portable: bool = True aliases: list[str] = [] readable_text: str | None = None tags: set[str] = field(default_factory=set) ``Container`` (container.py) extends Thing with containment rules:: capacity: int closed: bool = False locked: bool = False ``can_accept()`` checks object type, open state, and capacity before allowing insertions. verb registration: decorator path ================================== the ``@verb`` decorator (verbs.py) marks methods as verb handlers. it sets ``_verb_name`` on the function. ``Object.__post_init__`` discovers these and calls ``register_verb()``:: class Fountain(Thing): @verb("drink") async def drink(self, player, args): await player.send("You drink from the fountain.\r\n") when you instantiate the fountain, the drink handler automatically registers in ``_verbs["drink"]``. verb registration: toml path ============================= ``ThingTemplate`` (things.py) defines objects in toml:: name = "chest" description = "a sturdy wooden chest with iron bindings" portable = false capacity = 5 closed = true locked = false aliases = ["box"] [verbs] unlock = "verb_handlers:unlock_handler" ``spawn_thing()`` (things.py) creates a Thing or Container from the template. if ``capacity`` is set, you get a Container. if ``verbs`` dict is present, it resolves "module:function" strings via importlib and binds them with functools.partial. ``verb_handlers.py`` contains standalone functions referenced by toml. example:: async def unlock_handler(obj, player, args): if not isinstance(obj, Container): await player.send("That's not lockable.\r\n") return if not obj.locked: await player.send("It's already unlocked.\r\n") return # check for key in inventory... obj.locked = False await player.send(f"You unlock the {obj.name}.\r\n") two paths, one dispatch ======================= decorator-based and toml-based verbs both populate ``Object._verbs``. the command dispatcher doesn't care which path was used. finding objects =============== ``find_object()`` (verbs.py) searches for targets: 1. player inventory first 2. ground at player position second 3. matches by name or aliases (case-insensitive) returns the object or None. command dispatch fallback ========================= the command dispatcher (commands/__init__.py) tries registered commands first. if no match, it tries verb dispatch: 1. parse input as "verb target" (e.g., "drink fountain") 2. call ``find_object()`` for target 3. check ``obj.has_verb(verb)`` 4. call ``obj.call_verb(verb, player, args)`` this lets content authors add new interactions without modifying command code. use command =========== ``use`` (commands/use.py) provides explicit verb access:: use fountain # calls fountain's "use" verb use key on chest # calls chest's "use" verb with args="key on chest" parses input, finds object, checks for "use" verb, calls handler. code ==== relevant files:: src/mudlib/object.py # Object base class, verb registration src/mudlib/thing.py # Thing class src/mudlib/container.py # Container class src/mudlib/verbs.py # @verb decorator, find_object() src/mudlib/things.py # ThingTemplate, spawn_thing() src/mudlib/verb_handlers.py # standalone verb functions for toml src/mudlib/commands/__init__.py # command dispatcher with verb fallback src/mudlib/commands/use.py # explicit verb command content/things/ # toml thing definitions