=====================================
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
