# 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 steps - `just run` - start the server (`python -m mudlib`) - `just debug` - start with debug logging - `just render` - generate full world map HTML in `build/` ## Project Layout - `src/mudlib/` - the engine (commands, world, combat, render, store) - `tests/` - pytest tests - `content/` - content definitions (commands, combat moves) loaded at runtime - `worlds/` - world definition files (yaml/toml, version controlled) - `docs/` - project knowledge (see below) - `DREAMBOOK.md` - the vision, philosophy, wild ideas. not a spec - `scripts/` - 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 Consult `docs/index.rst` when starting unfamiliar work to find relevant 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 - 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