diff --git a/docs/index.rst b/docs/index.rst index ee7ee36..0886427 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -70,5 +70,6 @@ lessons plans ----- +- ``docs/plans/roadmap.rst`` — master plan: 12 phases from object model through DSL (start here) - ``docs/plans/if-terminal.txt`` — level 1 IF architecture design (predates implementation) - ``docs/plans/zmachine-game-compatibility.rst`` — game test plan for interpreter diff --git a/docs/plans/roadmap.rst b/docs/plans/roadmap.rst new file mode 100644 index 0000000..071a2be --- /dev/null +++ b/docs/plans/roadmap.rst @@ -0,0 +1,400 @@ +roadmap — order of operations +============================= + +the master plan. what to build and in what order. + +current state: the engine works. command system, game loop, mode stack, +combat (state machine + TOML moves), persistence (SQLite), editor mode, +IF/z-machine (dfrotz + embedded interpreter), terrain generation, content +loading — all built. what's unbuilt is the object model and everything it +enables: zones, things, inventory, containers, portals, verbs, multi-zone +worlds, rich NPCs, player building, and eventually the DSL. + +the architecture-plan.txt priority list (items 1-8) is essentially done. +this plan picks up from there. + +each phase builds on the one before it. the MUD stays functional +throughout — no phase leaves things broken. + + +phase 1: object foundation +-------------------------- + +the base class everything inherits from. pure additive — nothing breaks, +existing tests keep passing. + +build: + +- Object base class: name, location (Object | None), x (int | None), + y (int | None) +- contents property — reverse lookup: everything whose location is self +- can_accept(obj) method — default: False +- Entity inherits from Object instead of being a standalone dataclass +- Player, Mob unchanged externally — they still work exactly as now + +the location field exists but isn't wired up yet. Entity still has x, y +from before, they just come through Object now. no behavioral change. + +depends on: nothing +enables: everything below +refs: object-model.rst (hierarchy, containment mechanics) + + +phase 2: zones + overworld migration +------------------------------------- + +the big migration. the overworld becomes a Zone object. players live +inside it. movement, rendering, persistence, mob spawning all update. + +build: + +- Zone class: width, height, toroidal flag, terrain data, generator +- Zone.can_accept() returns True (zones accept everything) +- Zone.contents_at(x, y) for spatial queries +- convert current World terrain generator into Zone initialization — the + procedural overworld becomes a Zone instance loaded at startup +- Entity.location = zone (players and mobs live in the overworld zone) +- movement system goes through zone: wrapping, passability checks come + from player.location (the zone), not a global world reference +- viewport rendering reads terrain from player.location +- persistence adds zone name to save/load schema +- mob spawning sets location=zone +- remove world injection into command modules — commands access + player.location instead of module-level globals +- send_nearby_message uses zone.contents_at() instead of iterating the + global players dict + +the global ``_world`` singleton goes away. ``players`` dict can stay for +session management but spatial queries go through zones. + +migration strategy: + +- keep World class temporarily as Zone's terrain generator +- migrate one system at a time (movement → rendering → persistence → + broadcasting) with tests green at every step +- object-model.rst "how existing code maps in" section traces each path + +depends on: phase 1 +enables: multi-zone, portals, interior spaces +refs: object-model.rst (Zone section, migration paths), + zones-and-building.rst (zone properties, wrapping, generators) + + +phase 3: things + inventory +--------------------------- + +items exist. you can carry them. the world has stuff in it. + +build: + +- Thing class: description, portable flag (from Object) +- Entity.can_accept() allows portable Things (inventory) +- pick up / drop commands +- inventory command (list Things whose location is the player) +- items on the ground: Thing at location=zone, x=5, y=10 +- look shows nearby items at your coordinates +- thing templates in TOML (content/things/) loaded at startup +- thing spawning: template → instance with location=zone +- viewport shows ground items (new symbol or marker) +- persistence: player inventory persists to SQLite; ground items respawn + from templates on restart + +depends on: phase 2 (things need zones to exist in) +enables: equipment, crafting ingredients, quest items, loot +refs: object-model.rst (Thing section), things-and-building.rst (decorator + pattern, content format) + + +phase 4: containers + portals +----------------------------- + +nesting and zone transitions. both depend on Thing existing. + +containers: + +- Container class: capacity, closed (bool), locked (bool) +- Container.can_accept() checks capacity + open state +- put / get commands (move Thing into/out of Container) +- open / close commands +- lock / unlock (requires key item — first real item interaction) +- nested inventory display (backpack contains: ...) + +portals: + +- Portal class: target_zone, target_x, target_y, portable=False +- zone transition: step on portal → location changes to target zone, + position changes to target coords +- enter / go command for explicit portal use +- build at least one interior zone (tavern or test room) with hand-built + tile data from TOML +- two-way portals (portal in each zone pointing at the other) +- look shows portal presence, portal descriptions + +depends on: phase 3 (portals and containers are Things) +enables: multi-zone world, interior spaces, locked doors, bags, keys +refs: object-model.rst (Container, Portal sections), + zones-and-building.rst (zone data format, hand-built zones) + + +phase 5: verbs + interaction +---------------------------- + +the layer that makes the world feel alive. drink from a fountain, pet a +mob, read a sign. anything can have verbs. + +build: + +- @verb decorator on Object — any object in the world can have verbs +- @thing decorator for spawnable templates with verbs pre-attached +- verb resolution: "drink fountain" → find fountain at player's + coordinates → call its drink verb handler +- verb dispatch integrates with command system — verbs checked as + fallback after global commands fail to match +- content format: verbs defined in TOML alongside thing definitions, + or in python via the decorator +- default verbs: look at / examine (work on everything with a + description) + +depends on: phase 4 (need objects with verbs to interact with) +enables: rich interaction, builder content, puzzle creation +refs: things-and-building.rst (@thing/@verb decorator system, full + PepsiCan example) + + +phase 6: multi-zone content + building +-------------------------------------- + +the world has places. builders can create more. + +build: + +- zone loading from TOML files (hand-built zones with tile grids) +- hub / phone-switch zone with portals to different areas +- tutorial zone for new players +- tavern / social zone (interior, bounded, not toroidal) +- paint mode: admin tool for editing zone terrain tile-by-tile +- zone TOML export (runtime state → version-controlled files) +- spawn points per zone (where you appear on entry) +- zone-specific ambient messages +- per-zone mob spawning rules (what mobs live here, density, respawn) + +depends on: phase 4 (portals connect zones) +enables: a world with actual geography, builder workflow +refs: zones-and-building.rst (zone format, paint mode, building tools, + portal network design) + + +phase 7: GMCP + rich client support +------------------------------------ + +structured data for graphical MUD clients (Mudlet, Blightmud, etc.). +independent of the object model — can be done earlier if desired. + +build: + +- GMCP option negotiation in telnet handshake (telnetlib3 supports this) +- Char.Vitals package: pl, stamina, max_stamina +- Char.Status package: flying, resting, mode, combat state +- Room.Info package: zone name, x, y, terrain type +- MSDP for real-time variable updates (client-side HP bars, gauges) +- map data for clients that support structured map rendering + +telnetlib3 already handles the protocol layer. this phase is defining the +data packages and wiring them to game state changes. + +depends on: nothing (can start anytime) +enables: rich MUD client experience alongside raw telnet +refs: DREAMBOOK.md (things to explore: GMCP, MSDP) + + +phase 8: NPC evolution +---------------------- + +mobs become characters, not just combat targets. + +build: + +- dialogue trees: TOML-defined, triggered by "talk to" or "ask" commands +- non-combat behaviors: patrol, wander, idle, shopkeeper, guard +- behavior trees or state machines defined in TOML +- mob reactions to verbs ("pet" the cat, "ask" the bartender about X) +- spawn/respawn system using location=None as template state (die → + location=None, timer → respawn at zone with fresh stats) +- mob schedules (bartender appears in tavern during the day, gone at + night) +- shopkeeper mobs (buy/sell interface using inventory system) + +depends on: phase 5 (verbs for interaction), phase 6 (zones for mobs + to inhabit) +enables: living world, quests, commerce +refs: architecture-plan.txt (entity model section), + object-model.rst (location=None for templates/despawned) + + +phase 9: world systems +---------------------- + +time, weather, seasons. the world breathes. + +build: + +- game time cycle: ticks → hours → days → seasons +- time of day affects descriptions ("the tavern is dim in the evening + light" vs "sunlight streams through the windows") +- weather system: rain, wind, storms (per zone or global) +- weather affects gameplay: rain slows movement, storms block flying, + cold water is worse in winter +- seasonal terrain variation: snow in winter, flowers in spring, color + palette shifts +- ambient messages tied to time/weather ("a cold wind picks up") + +depends on: phase 6 (zones with descriptions to vary) +enables: atmosphere, seasonal events, weather-dependent gameplay +refs: DREAMBOOK.md (seasons, weather, time of day) + + +phase 10: player creation + housing +------------------------------------ + +players shape the world. the MOO dream. + +build: + +- player-owned zones (personal rooms, houses, pocket dimensions) +- building commands: create zone, set dimensions, paint terrain, place + things +- in-world editing via editor mode (descriptions, verb scripts) +- player-created content stored in SQLite +- admin review + export to files (sqlite → TOML for version control) +- permissions: who can build, who can edit what, visitor access controls +- crafting system: combine things → new thing, recipes in TOML +- IF creation tools: use the IF primitives to build small adventures + from inside the MUD + +depends on: phase 6 (zones), phase 5 (verbs), persistence +enables: the MOO vision — player-built, player-programmed world +refs: DREAMBOOK.md (user-created content, presence and community), + architecture-plan.txt (player-created content in sqlite, + engine/content boundary) + + +phase 11: the DSL +----------------- + +replace python callables with a scripting language writable from inside +the MUD. this is the hardest design challenge in the project. + +build: + +- language design: informed by what phases 1-10 needed to express +- interpreter/runtime: sandboxed, no file/network access +- content definitions gain ``body: dsl:script_name`` option alongside + ``body: python:module.function`` +- DSL scripts editable in-world via editor mode +- help system teaches the DSL from inside the MUD +- standard library: common verbs, triggers, conditions +- migration path: existing python handlers get DSL equivalents over time + +defer specifics until phases 1-10 reveal exactly what the DSL needs to +express. the ecosystem research (dsls.md) catalogs prior art: MOO's +language, LPC, MUSH softcode. + +depends on: everything above being stable +enables: non-programmers creating game content from a telnet session +refs: architecture-plan.txt (DSL section, content definition format), + docs/research/dsls.md (prior art) + + +phase 12: horizons +------------------ + +things from the dreambook's "explore later" list. order is flexible — +tackle based on interest and what the world needs. + +- web client: xterm.js terminal emulator pointed at telnet port. honor + the protocol even in the browser +- MCCP compression for bandwidth-heavy sessions +- inter-MUD communication (IMC2, I3) +- AI-driven NPCs: LLM-backed conversation, personality, memory +- alternate screen buffer: split views (map panel + text panel) +- sound via MSP or links +- procedural dungeon generation: zones with random layout per visit +- quest system: objectives, tracking, rewards, quest-giver NPCs + + +dependency graph +---------------- + +:: + + phase 1: object foundation + │ + ▼ + phase 2: zones + migration + │ + ▼ + phase 3: things + inventory + │ + ▼ + phase 4: containers + portals + │ + ▼ + phase 5: verbs + interaction + │ phase 7: GMCP (independent) + ▼ + phase 6: multi-zone content + │ + ├────────────────┐ + ▼ ▼ + phase 8: NPCs phase 9: world systems + │ │ + └───────┬────────┘ + ▼ + phase 10: player creation + │ + ▼ + phase 11: DSL + │ + ▼ + phase 12: horizons + + +notes +----- + +**the phase 2 migration is the riskiest step.** it touches movement, +rendering, persistence, mob spawning, and message broadcasting. the +strategy is incremental: migrate one subsystem at a time, keep tests +green, keep the MUD playable. the object-model.rst doc has a detailed +"how existing code maps in" section for this. + +**phase 7 (GMCP) floats.** it doesn't depend on the object model and +can be done whenever energy or interest is there. it's slotted at 7 +because the data it reports (zone name, position, combat state) gets +richer as the object model matures, but basic vitals work anytime. + +**phases 8-10 have some flexibility.** world systems (weather, time) +could come before NPC evolution. player creation could come before +either. the dependency shown is the tightest path — if housing needs +NPCs (shopkeepers, guards), then 8 before 10. if not, reorder freely. + +**the DSL (phase 11) is intentionally last.** the architecture-plan.txt +says "defer it until we know exactly what it needs to express." phases +1-10 discover that organically. + + +related docs +------------- + +- ``DREAMBOOK.md`` — vision, philosophy, wild ideas +- ``docs/how/architecture-plan.txt`` — engine/content boundary, original + priority list (items 1-8 now complete) +- ``docs/how/object-model.rst`` — class hierarchy, containment, verbs, + migration paths +- ``docs/how/zones-and-building.rst`` — zone format, building tools, + paint mode, portal network +- ``docs/how/things-and-building.rst`` — @thing/@verb decorator system +- ``docs/how/combat.rst`` — combat system (built, referenced by phase 8) +- ``docs/how/commands.txt`` — command system (built, extended by new + phases) +- ``docs/research/dsls.md`` — scripting language catalog (phase 11)