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/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/object-model.rst`` — object hierarchy, containment, verbs, location system
|
||||
- ``docs/how/prompt-system.txt`` — modal prompts, color markup, per-player customization
|
||||
|
||||
combat
|
||||
|
|
|
|||
Loading…
Reference in a new issue