Add object model design doc
This commit is contained in:
parent
94a01186c8
commit
400ebe4275
2 changed files with 251 additions and 0 deletions
250
docs/how/object-model.rst
Normal file
250
docs/how/object-model.rst
Normal file
|
|
@ -0,0 +1,250 @@
|
||||||
|
object model — containment, verbs, and the location tree
|
||||||
|
========================================================
|
||||||
|
|
||||||
|
a design doc for the object hierarchy that powers containment, inventory,
|
||||||
|
zones, and verb-driven interaction. captures the core rule, the class
|
||||||
|
structure, and how everything connects.
|
||||||
|
|
||||||
|
see also: ``things-and-building.rst`` (@thing/@verb decorator system),
|
||||||
|
``zones-and-building.rst`` (zone data format), ``architecture-plan.txt``
|
||||||
|
(engine/content boundary), ``combat.rst`` (combat on Entity subgraph).
|
||||||
|
|
||||||
|
|
||||||
|
the core rule
|
||||||
|
-------------
|
||||||
|
|
||||||
|
every object has a ``location`` attribute that points to another object, or
|
||||||
|
None. that's the entire containment system.
|
||||||
|
|
||||||
|
where something is = what its location points to. None means it's a top-level
|
||||||
|
thing — a zone, a template that hasn't spawned yet, or something removed from
|
||||||
|
the world.
|
||||||
|
|
||||||
|
here's what the tree looks like::
|
||||||
|
|
||||||
|
overworld zone (location=None)
|
||||||
|
├── player "jared" (location=overworld, x=50, y=30)
|
||||||
|
│ ├── sword (location=jared) ← inventory
|
||||||
|
│ └── backpack (location=jared) ← inventory
|
||||||
|
│ ├── gem (location=backpack) ← nested
|
||||||
|
│ └── potion (location=backpack)
|
||||||
|
├── oak tree (location=overworld, x=50, y=31) ← fixture
|
||||||
|
└── portal (location=overworld, x=52, y=30) ← leads to tavern zone
|
||||||
|
|
||||||
|
tavern zone (location=None)
|
||||||
|
├── bartender mob (location=tavern, x=3, y=2)
|
||||||
|
├── chair (location=tavern, x=1, y=1) ← fixture
|
||||||
|
└── mug (location=tavern, x=3, y=3) ← item on the floor
|
||||||
|
|
||||||
|
``contents`` is the reverse query — "give me everything whose location is me."
|
||||||
|
|
||||||
|
spatial position (x, y) is optional. objects in zones have coordinates. items
|
||||||
|
in inventory don't. a sword in your backpack has location=backpack, x=None,
|
||||||
|
y=None.
|
||||||
|
|
||||||
|
|
||||||
|
the hierarchy
|
||||||
|
-------------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Object (name, location, x, y) ← @verb targets this
|
||||||
|
├── Zone (width, height, toroidal, terrain)
|
||||||
|
├── Entity (combat stats)
|
||||||
|
│ ├── Player (session stuff)
|
||||||
|
│ └── Mob (ai stuff)
|
||||||
|
├── Thing (description, portable)
|
||||||
|
│ ├── Container (capacity, closed, locked)
|
||||||
|
│ └── Portal (target_zone, target_x, target_y)
|
||||||
|
└── (Exit — maybe, if portals don't cover it)
|
||||||
|
|
||||||
|
**Object**
|
||||||
|
base class for everything in the world. has name, location (Object or
|
||||||
|
None), optional x/y for spatial position within location. the @verb
|
||||||
|
decorator targets this — anything can have verbs. defines ``can_accept(obj)``
|
||||||
|
method (default: False) for controlling what can be placed inside.
|
||||||
|
|
||||||
|
**Zone**
|
||||||
|
a spatial area with a grid. the overworld, a tavern interior, a pocket
|
||||||
|
dimension. location=None (top-level). has terrain, dimensions, toroidal
|
||||||
|
flag. ``can_accept`` returns True (zones accept everything). defines
|
||||||
|
``contents_at(x, y)`` for spatial queries.
|
||||||
|
|
||||||
|
**Entity**
|
||||||
|
something that fights. adds combat stats (PL, stamina, defense timing).
|
||||||
|
``can_accept`` allows portable Things (inventory).
|
||||||
|
|
||||||
|
**Player**
|
||||||
|
a connected human. adds writer, mode_stack, caps, editor, if_session.
|
||||||
|
subclass of Entity.
|
||||||
|
|
||||||
|
**Mob**
|
||||||
|
AI-controlled entity. adds moves list, behavior. subclass of Entity.
|
||||||
|
|
||||||
|
**Thing**
|
||||||
|
an interactive object. adds description, portable flag. the @thing
|
||||||
|
decorator targets this for spawnable templates.
|
||||||
|
|
||||||
|
**Container**
|
||||||
|
a Thing that explicitly accepts contents. adds capacity, closed, locked
|
||||||
|
state. game-facing behaviors (open/close, lock/unlock, put/get).
|
||||||
|
|
||||||
|
**Portal**
|
||||||
|
a Thing that connects zones. adds target_zone, target_x, target_y.
|
||||||
|
portable=False.
|
||||||
|
|
||||||
|
**Exit**
|
||||||
|
not needed yet. portals + zone grids might cover all transitions. parked
|
||||||
|
until we discover it's necessary.
|
||||||
|
|
||||||
|
note: Fixture was considered as a class but we just use
|
||||||
|
``Thing(portable=False)`` instead. no shared behavior that warrants a class.
|
||||||
|
|
||||||
|
|
||||||
|
containment mechanics
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
the containment MECHANISM is on Object (any object can technically be a
|
||||||
|
location via the location pointer). but the GAME restricts it via
|
||||||
|
``can_accept()``:
|
||||||
|
|
||||||
|
- Zone: accepts everything
|
||||||
|
- Entity: accepts portable Things (inventory)
|
||||||
|
- Container: accepts items up to capacity, if not closed
|
||||||
|
- Thing: rejects by default (can't put a sword inside another sword)
|
||||||
|
- Object base: rejects by default
|
||||||
|
|
||||||
|
this means containment is a capability, not a class. follows the Evennia/LPC
|
||||||
|
pattern. the Container class just bundles the common container game behaviors
|
||||||
|
— it's not special from a tree perspective.
|
||||||
|
|
||||||
|
|
||||||
|
location=None
|
||||||
|
-------------
|
||||||
|
|
||||||
|
three things have location=None:
|
||||||
|
|
||||||
|
1. **zones** — they're top-level containers. the overworld, tavern zone, etc.
|
||||||
|
|
||||||
|
2. **templates/prototypes** — things that exist but aren't placed anywhere yet.
|
||||||
|
a mob template, an item blueprint. they're in code or data files but not
|
||||||
|
spawned into the world.
|
||||||
|
|
||||||
|
3. **despawned objects** — removed from the world but not deleted. a mob dies
|
||||||
|
and goes back to location=None until respawn.
|
||||||
|
|
||||||
|
this is first-class. a mob template at location=None is the prototype. spawn
|
||||||
|
it = clone with location=zone. dies = back to location=None until respawn.
|
||||||
|
no special flags needed, just the natural state.
|
||||||
|
|
||||||
|
|
||||||
|
verbs on everything
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
@verb targets Object, not Thing. everything in the world can have verbs:
|
||||||
|
|
||||||
|
- "pet" a mob (verb on Entity)
|
||||||
|
- "open" a chest (verb on Container)
|
||||||
|
- "drink from" a fountain (verb on Thing with portable=False)
|
||||||
|
- "dig" in a zone (verb on Zone)
|
||||||
|
- "high-five" a player (verb on Entity)
|
||||||
|
|
||||||
|
the verb system doesn't care about the class hierarchy. if it's an Object and
|
||||||
|
has a verb registered, players can use it.
|
||||||
|
|
||||||
|
|
||||||
|
how existing code maps in
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Entity(name, x, y) → Entity(name, location=zone, x=5, y=10)
|
||||||
|
entities gain a location field. x/y stay but become relative to location.
|
||||||
|
|
||||||
|
Player/Mob → same, just gains location field from Object parent
|
||||||
|
existing code largely unchanged. location replaces implicit zone references.
|
||||||
|
|
||||||
|
overworld terrain grid → becomes a Zone object
|
||||||
|
the procedural perlin overworld becomes a Zone instance. toroidal, with
|
||||||
|
generator=perlin.
|
||||||
|
|
||||||
|
planned zones (tavern, tutorial) → each a Zone object
|
||||||
|
hand-built zones like the treehouse. bounded or toroidal, tile data from
|
||||||
|
TOML files.
|
||||||
|
|
||||||
|
planned portals → Portal things inside zones
|
||||||
|
portals are objects with target_zone, target_x, target_y. live inside zones
|
||||||
|
like any other Thing.
|
||||||
|
|
||||||
|
@thing PepsiCan from things-and-building doc → Thing subclass
|
||||||
|
same as planned. @thing decorator creates Thing templates. spawn them into
|
||||||
|
zones or player inventory.
|
||||||
|
|
||||||
|
combat encounters → still between Entities, unchanged
|
||||||
|
combat operates on the Entity subgraph. location doesn't matter for combat
|
||||||
|
resolution, only proximity (same zone, nearby x/y).
|
||||||
|
|
||||||
|
IF sessions → still on Player, unchanged
|
||||||
|
if_session lives on Player. the IF subprocess doesn't care about location.
|
||||||
|
|
||||||
|
mode stack → still on Player, unchanged
|
||||||
|
mode_stack is a Player concern. doesn't interact with the object tree.
|
||||||
|
|
||||||
|
the migration is gentle. Entity gains a location field and x/y become
|
||||||
|
optional (None when inside a non-spatial container like a backpack).
|
||||||
|
|
||||||
|
|
||||||
|
what this enables
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
- **inventory** — put sword in backpack, backpack in player. nested
|
||||||
|
containment via location pointers.
|
||||||
|
|
||||||
|
- **items on the ground** — sword at location=zone, x=5, y=10. visible to
|
||||||
|
anyone at those coordinates.
|
||||||
|
|
||||||
|
- **furniture and fixtures** — Thing with portable=False. a fountain, a tree,
|
||||||
|
a statue. stays put, but can have verbs.
|
||||||
|
|
||||||
|
- **containers** — chests, bags, locked doors. Container subclass handles
|
||||||
|
capacity, closed, locked state.
|
||||||
|
|
||||||
|
- **zone transitions** — portals as objects. step on portal tile, location
|
||||||
|
changes to target zone.
|
||||||
|
|
||||||
|
- **mob templates and spawning** — location=None is the template. spawn =
|
||||||
|
clone with location=zone. dies = back to None.
|
||||||
|
|
||||||
|
- **verb-driven interaction on anything** — pet the cat, read the sign, dig
|
||||||
|
the ground. @verb on Object means no restrictions.
|
||||||
|
|
||||||
|
- **the "phone switch" navigation zone** — a zone full of portals. walk to
|
||||||
|
a portal, step through, appear in that world. the hub.
|
||||||
|
|
||||||
|
|
||||||
|
open questions (parked)
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
- **equipment slots** (wield, wear) — additive later when combat needs it. do
|
||||||
|
we track worn/wielded separately from inventory, or is it just metadata on
|
||||||
|
the Thing? defer until combat design demands it.
|
||||||
|
|
||||||
|
- **Exit class** — may not be needed. portals might cover it. if we discover
|
||||||
|
a need for one-way passages with different behavior than portals, revisit.
|
||||||
|
|
||||||
|
- **persistence** — which objects persist to SQLite, which are runtime-only?
|
||||||
|
player inventory persists. zone state (tile changes from paint mode)
|
||||||
|
persists to TOML. mob instances probably don't persist (respawn from
|
||||||
|
templates). decide per-class as we implement.
|
||||||
|
|
||||||
|
- **object registry implementation** — global dict? spatial index? contents
|
||||||
|
cache? probably: zones maintain contents_at(x, y) lookups, global registry
|
||||||
|
maps object IDs to instances for verb resolution.
|
||||||
|
|
||||||
|
|
||||||
|
related docs
|
||||||
|
------------
|
||||||
|
|
||||||
|
- ``things-and-building.rst`` — @thing/@verb decorator system, content layer
|
||||||
|
on top of this model
|
||||||
|
- ``zones-and-building.rst`` — zone data format, building tools, paint mode
|
||||||
|
- ``architecture-plan.txt`` — overall engine/content boundary
|
||||||
|
- ``combat.rst`` — combat system (operates on Entity subgraph)
|
||||||
|
|
@ -19,6 +19,7 @@ engine
|
||||||
- ``docs/how/terrain-generation.txt`` — perlin noise, elevation thresholds, river tracing
|
- ``docs/how/terrain-generation.txt`` — perlin noise, elevation thresholds, river tracing
|
||||||
- ``docs/how/things-and-building.rst`` — interactive objects, python class decorators
|
- ``docs/how/things-and-building.rst`` — interactive objects, python class decorators
|
||||||
- ``docs/how/zones-and-building.rst`` — zones as spatial unit, procedural overworld, player homes
|
- ``docs/how/zones-and-building.rst`` — zones as spatial unit, procedural overworld, player homes
|
||||||
|
- ``docs/how/object-model.rst`` — object hierarchy, containment, verbs, location system
|
||||||
- ``docs/how/prompt-system.txt`` — modal prompts, color markup, per-player customization
|
- ``docs/how/prompt-system.txt`` — modal prompts, color markup, per-player customization
|
||||||
|
|
||||||
combat
|
combat
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue