Copies the cleaned-up zvm source (ruff-compliant, ty-clean) back into the zmachine module. Adds __init__.py with proper exports and updates .gitignore for debug.log/disasm.log.
3.2 KiB
3.2 KiB
mudlib
Telnet MUD engine built on telnetlib3. Python 3.12+, managed with uv.
Commands
just check- lint (ruff --fix + format), typecheck (ty), test (pytest)just lint/just typecheck/just test- individual stepsjust run- start the server (python -m mudlib)just debug- start with debug loggingjust render- generate full world map HTML inbuild/
Project Layout
src/mudlib/- the engine (commands, world, combat, render, store)tests/- pytest testscontent/- content definitions (commands, combat moves) loaded at runtimeworlds/- world definition files (yaml/toml, version controlled)docs/- project knowledge (see below)DREAMBOOK.md- the vision, philosophy, wild ideas. not a specscripts/- standalone tools (map renderer, etc)build/- generated output (gitignored)repos/- symlinked reference repos, gitignored, not our code. includes:repos/viola/- DFillmore/viola z-machine interpreter (working, global state)repos/zvm/- sussman/zvm z-machine interpreter (clean architecture, half-built)repos/telnetlib3/,repos/miniboa/- telnet libraries
Docs
Three categories in docs/. Plain text or rst, not markdown.
docs/how/- how things work. write one when you build something non-obvious. terrain generation, command system, etc. aimed at someone reading the code who wants the "why did we do it this way" context.docs/why/- design philosophy. telnet-first, text worlds, etc. the reasoning behind big decisions. doesn't change often.docs/lessons/- things we learned the hard way. write one when you hit a real bug or gotcha that cost time. charset-vs-mtts, etc. include the fix so we don't repeat it.
Update docs when:
- you build a new system (add a how/)
- you make a design decision worth explaining (add a why/)
- you debug something painful (add a lessons/)
- existing docs become wrong (update them)
Architecture
- telnetlib3 is a dependency, not vendored. contribute fixes upstream
- telnetlib3 gives us: GMCP, MSDP, NAWS, async server, reader/writer streams
- game loop is tick-based (async task alongside telnet server)
- world is toroidal (wraps in both axes). terrain noise tiles seamlessly
- world definitions live in data files, runtime state lives in memory
- SQLite for persistence (player accounts, progress)
- session mode stack filters what events reach the player (normal/combat/editor)
- combat system: state machine with TOML-defined moves (attacks, defends, counters). see
docs/how/combat.rst- moves with directional variants (punch left/right) use a single TOML with
[variants]sections - commands are always single words; direction is an argument, not part of the command name
- moves with directional variants (punch left/right) use a single TOML with
- content loading: TOML definitions for commands and combat moves, loaded at startup
- entity model: Entity base class, Player and Mob subclasses sharing common interface
- editor mode: in-world text editor with syntax highlighting and search/replace
- IF mode: interactive fiction via dfrotz subprocess, mode stack integration, spectator broadcasting. see
docs/how/if-terminal.txt
Style
- simple > clever
- no mock implementations
- match existing patterns in each file