# Third Collapse A low-tech sci-fi MUD set on a terraformed asteroid. Runescape-style combat and skill progression, written in Go. ## Theme Takes place on a terraformed asteroid. Technology has regressed — people scrap and scavenge remnants of the old world. "Science" replaces Prayer, "Technology" replaces Magic. Scavenging replaces Runecrafting. ## Skills (23 total, all go from 1-99) ``` Combat: Attack, Strength, Defense, Hitpoints, Ranged, Science, Technology, Assassin Gathering: Fishing, Woodcutting, Mining, Hacking, Scavenging, Farming, Thieving Production: Cooking, Smithing, Crafting, Fletching, Alchemy, Construction, Firemaking Utility: Agility ``` ## Architecture ``` cmd/mud/ Entry point (--config flag, multi-listener) internal/ config/ YAML config loading (telnet, http, https listeners) action/ Behavior system: gather/talk/use/toggle types, drop tables engine/ Tick scheduler (600ms) world/ Rooms, exits, ground items, mobs, object instance state player/ Character sheet, skills, XP, inventory, equipment, validation combat/ Combat formulas, combat state tracking object/ ItemDef, ObjectDef, item/object stores net/ Telnet + HTTPS/WebSocket server, sessions, Conn interface, echo control game/ Session handler, login flow, command dispatch, action tick, input sanitization data/ behaviors/ Behavior YAML files (gather, talk, use, toggle) drops/ Shared drop table YAML files rooms/ Room YAML files objects/ Object definition YAML files items/ Item definition YAML files mobs/ Mob definition YAML files help/ Help topic YAML files players/ accounts/ Account YAML files (gitignored) characters/ Character YAML files (gitignored) ``` ## Behavior System Objects and mobs in rooms can have behaviors. Four types exist: | Type | Verbs | Use | | -------- | --------------------- | -------------------------------------------------------------------------- | | `gather` | mine, chop, cut, fish | Resource gathering with skill checks, tool requirements, depletion/respawn | | `use` | use | Crafting stations — consume items, produce output, optional skill checks | | `talk` | talk, speak, ask | NPC conversation trees with choices, conditions, actions | | `toggle` | pull, push | Levers, switches, gates — set world flags, conditional on existing values | Behaviors are defined in `data/behaviors/.yaml`. Objects reference them with `behavior: `. Mobs can also carry `behavior: ` — StartAction falls back to mob lookup when no object matches. ### Two Depletion Mechanics **Per-drop depletion** (mining, regular trees): Set `depletes: true` on a drop entry. The resource depletes on first successful gather of that drop. **Shared depletion** (higher-tier trees): Set `deplete_timer: ` on the behavior. A shared timer counts down while anyone is chopping; when it hits 0, the next successful gather depletes the tree for all players. The timer regenerates back to max when no one is chopping. ### Bird's Nests Set `nest_chance: 256` on a gather behavior to give a 1/256 independent chance to find a bird's nest alongside the normal drop. Bird's nests are searched with the `search` command, rolling on the `birds_nest_drop` drop table. ### Condition System Used by exits, talk options, on-enter scripts, and toggle checks: | Field | Scope | Example | | ------------- | ------------------------------ | -------------------------------- | | `flag` | World (shared by all players) | `flag: gate_open` | | `player_flag` | Per-character (quest progress) | `player_flag: finished_tutorial` | | `has_item` | Player inventory check | `has_item: bronze_key` | | `all_of` | All sub-conditions must pass | Nested list of conditions | | `any_of` | Any sub-condition passes | Nested list of conditions | | `not` | Invert the check | `not: true` | ### Node Actions (talk dialog) Set on nodes in talk behaviors: | Field | Effect | | ------------------ | ------------------------------------------------------ | | `set_flags` | Sets world flags (global) | | `set_player_flags` | Sets player-local flags (per-character, saved to YAML) | | `give_item` | Gives an item to inventory | | `take_item` | Removes an item from inventory | | `teleport` | Moves player to a room ID | | `heal` | Restores hitpoints | All fields in a single action are processed together. ### Accounts & Aliases Accounts stored in `data/players/accounts/.yaml`. Each account has: - Password hash (sha256 + salt) - Character list - Alias map (`alias ` — account-wide, shared by all characters) Aliases resolve before built-in commands and support argument passthrough (`alias k kill` → `k man` expands to `kill man`). ### World - Rooms are flat YAML files, read from disk on each access (live editing) - Everything is YAML-driven — no database - Exits support conditions (world flags, player flags, items, compound) - Rooms support `on_enter` scripts with per-step conditions - Objects can be `hidden: true` (interactable but not listed in room) - Mobs wander via legal room exits (unconditioned), not hardcoded room lists - Mob wander config (`wander_rooms`, `wander_interval`) set per-instance in room YAML - Object wander config same format — objects teleport between listed rooms ## Implemented ### Core Systems - [x] Telnet server, account creation, hashed passwords, account/character management - [x] HTTPS/WebSocket server with embedded web terminal client - [x] Multi-listener config (telnet + http + https, any combination) - [x] YAML config file (`config.yaml`) with `--config` flag and runtime defaults - [x] 600ms tick engine driving all world simulation - [x] Room-based player hub with enter/exit/action notifications - [x] Single-login enforcement, disconnect timer - [x] Player YAML persistence on every state change - [x] Transport-agnostic Conn interface (tcpConn + wsConn) - [x] Password echo suppression (telnet IAC ECHO, web OSC sequences) - [x] Input sanitization (control character stripping at HandleSession) - [x] Name validation (alphanumeric+spaces, 3-30 chars) - [x] Max input line length (1024 bytes) - [x] WebSocket origin checking (same-origin + loopback) - [x] Tick-based action queue system (600ms) — commands classified as instant, free, or active - [x] ActionState system for player activity display in room look - [x] Smart conflict resolution (multi-player attack/get timestamp ordering, shared depletion deferral) - [x] Fractional tick system — all YAML timers accept float64, probabilistically rounded - [x] Configurable tick_length and game_speed for server operators - [x] Ground item spawn stacking fix (Tick + SeedGroundItems) ### Commands - [x] `look / l` — room rendering (mobs, objects, ground items, exits, players) - [x] `look ` — examine mobs, objects, items, players, directions - [x] `n/s/e/w/u/d` — movement (conditional exits, interrupts combat/actions) - [x] `get / drop / drop all` — item pickup/drop with stacking, reservations - [x] `say` — room chat (preserves case) - [x] `score / inventory / equipment / exits` — character and world info - [x] `style` — combat style selection (prefix matching) - [x] `attack / kill ` — combat with numbered targeting - [x] `mine / chop / cut / fish ` — gathering with numbered targeting - [x] `use ` — crafting station interaction - [x] `talk / speak / ask ` — NPC conversations (objects or mobs) - [x] `pull / push ` — toggle interactions (levers, gates) - [x] `alias / unalias ` — account-wide command aliases - [x] `option / options [name] [value]` — 15 character settings (bool, string, int types) - [x] `queued` — show pending tick actions - [x] `description / desc / help [topic] / quit` - [x] `search ` — search bird's nests for loot - [x] `burn [item]` — start a fire from logs on ground or in inventory (smart default) - [x] `stoke [item]` — add logs to an existing fire for firemaking XP ### Combat - [x] RSC-based formulas (attack/defense rolls, max hit) - [x] Attack styles with bonuses and XP distribution - [x] Equipment bonuses, HP tracking, death mechanics - [x] Combat lock timer, movement interrupts combat - [x] Mob/player regen (1 HP per 100 ticks) - [x] Mob exit-based wandering, enter/leave/spawn notifications - [x] Drop reservation system (100-tick owner lock on loot) ### Skills & Gathering - [x] Mining (copper rocks, pickaxe, depletion/respawn, gem sub-table) - [x] Fishing (wandering spots, non-depleting, fishing rod) - [x] Woodcutting (9 tree types, axes, shared depletion, bird's nests, exhausted message) - [x] Firemaking (9 log tiers, burn/stoke, fire objects, fire tools: matches/firesteel/lighter) - [x] Tool system (tool_type + tool_speed on items, tool requirement on behaviors) - [x] Shared drop tables (referenced by multiple behaviors) - [x] XP drops for all skill actions (combat, gathering, use) - [x] Level-up messages across all skills ("*** You are now level N ! ***") - [x] 23 skill definitions with RSC XP table (4 implemented: Mining, Fishing, Woodcutting, Firemaking) ### World & Data - [x] Room, item, object, mob, behavior, drop table YAML loaders - [x] Object instance tracking (depletion, wandering, respawn, broadcast) - [x] 21 structured rooms (west gathering wing, east production/utility/combat wing) - [x] Conditional exits (world flags, player flags, items, compound conditions) - [x] Room on_enter scripts with conditions - [x] Hidden objects (interactable but not listed in room output) - [x] Player-local flags vs world flags for multiplayer state separation - [x] Compound conditions: all_of / any_of - [x] Aligned ground item reservation display - [x] Mob wander config per-instance in room YAML (not on MobDef) - [x] Object depletion timer display (depletion toggle) - [x] Bidirectional prefix matching for get/drop/attack/gather commands - [x] Ambiguity detection when multiple object types match a command - [x] Smart default targeting for mine/chop/fish (single type → auto-select) - [x] Smart default targeting for attack/kill (same mob type → auto-target) - [x] Smart default targeting for burn/stoke (single log type → auto-select) - [x] Object inroom_description (replaces generic "A X is here.") - [x] Object removal_item (drops item when object instance is removed) - [x] Ground item independent despawn timers (no stack merging) - [x] Ground item despawn display (option: despawn) - [x] Reserve display format: "reserved for t" ### Documentation - [x] WORLDBUILDING.md — comprehensive guide with examples - [x] AGENTS.md — repo structure for LLM context ## Data Format Reference See WORLDBUILDING.md for full examples of every data type with explanations. ## Action Plan ### Phase 1: ASCII map implemented with BFS - [x] Replaced `toggle` command with `option`/`options` — supports bool (on/off), string (choice lists), and int option types - [x] All old toggles migrated to the option system (tiny_map, xp_drops, exits, mob_enter, mob_leave, mob_spawn, reserve, depletion, description) - [x] Added `color` option (none, ansi, xterm256) - [x] Added `mapwidth` and `mapheight` options for the `map` command viewport size - [x] `map` command — renders a full ASCII map centered on the player using BFS graph traversal with geometric coordinate assignment - [x] Shared BFS graph builder (`buildGraph`) reused by both the tiny map (in `look`) and the `map` command - [x] Added `mappadding` option (none, x, y, xy) — controls blank-row stripping and left-trimming of map output - [x] Tiny map built via BFS viewport rendering (3x3 room window at 2x zoom) — no hardcoded corner/cardinal rules, no room duplication ### Phase 2: Core Skill Chains (breadth over depth) - [x] Woodcutting — tree objects + axes, shared depletion, bird's nests - [x] Firemaking — burn (inventory/ground logs → fire object), stoke (add logs to fire), 3 fire tools - [x] Exhausted message on gather behaviors (custom tree-fall message) - [x] Depleted message on gather behaviors (custom depleted rock/tree message) - [x] Level-up messages across all skills - [x] Smart default targeting for gather/combat/burn/stoke - [x] Ground item despawn display via new `despawn` option - [x] Object `inroom_description` replacing generic "A X is here." - [x] Object `removal_item` for generic cleanup drops (fire → ashes) - [x] Independent despawn timers per ground item entry - [ ] Cooking — fire/range object (`use` type), raw fish/meat → cooked food - [ ] Smithing — furnace + anvil objects (`use` type), ore → bars → weapons/armor - [ ] Fletching — fletching table object (`use` type), logs → arrow shafts/bows - [ ] Equipment: bronze/iron weapons, axes, cooked trout, arrows, bows ### Phase 3: World Depth - [ ] Shop system — talk node action for buy/sell interface with credits - [ ] Bank system — deposit/withdraw items at bank booth objects - [ ] Ranged combat — bows/crossbows/ammo, add Ranged to combat formulas - [ ] Aggressive mobs — initiate combat on room entry - [ ] Flee command - [ ] Equipment skill requirements ### Phase 4: Polish - [ ] Hacking, Thieving, Agility, Alchemy, Construction, Crafting, Scavenging, Farming, Assassin - [ ] Quest system (already supported via talk nodes + world/player flags) - [ ] PvP combat, multi-combat zones - [ ] ANSI color output - [ ] Admin commands - [ ] Persist ground items and mob state across restarts - [ ] More rooms — flesh out the asteroid world