diff options
| author | historia <[not public]> | 2026-06-24 22:55:35 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-24 22:55:35 -0400 |
| commit | 15b7e221b799ef107dec44ecdb294026dfd3d059 (patch) | |
| tree | 3748e464a77f0f082bea1567e9d6990052054961 /AGENTS.md | |
| parent | 9d4b799db4868bcab291b83599ff088763cd4ed6 (diff) | |
| download | thehouseoficarus-15b7e221b799ef107dec44ecdb294026dfd3d059.tar.gz | |
refactor: pulled techs out to yaml files, unified numerous combat functions, broke up game object
Diffstat (limited to 'AGENTS.md')
| -rw-r--r-- | AGENTS.md | 34 |
1 files changed, 24 insertions, 10 deletions
@@ -1,6 +1,6 @@ # AGENTS.md -The House of Icarus — a Runescape-like sci-fi MUD written in Go. Data-driven via YAML files. No database, no ORM. +The House of Icarus — a sci-fi MUD inspired by classic retro MMOs, written in Go. Data-driven via YAML files. No database, no ORM. Set on a terraformed asteroid where technology has regressed. "Technology" replaces Prayer, "Science" replaces Magic, Scavenging replaces Runecrafting. @@ -29,7 +29,7 @@ internal/ action/ Behavior structs (GatherConfig, TalkConfig, UseConfig), SuccessChance player/ Player struct, skills, inventory, bank, equipment, accounts, XP, validation world/ World, RoomDef, MobDef, MobInstance, ObjState, ground items, wandering - combat/ Combat state tracking, OSRS-style formulas (HitChance, MaxHit, AttackRoll) + combat/ Combat state tracking, classic formulas (HitChance, MaxHit, AttackRoll) object/ ItemDef, ObjectDef, ItemStore, ObjectStore, EquipSlot, WeaponType, ItemStats engine/ Tick scheduler — configurable ms interval, subscriber pattern, ToTicks() color/ xterm-256 color system with auto ANSI downgrade, gradients, inline tags @@ -43,8 +43,9 @@ internal/ | `core_*.go` | Infrastructure — types, utils, login, production engine, skill XP, flags, courses, equipment, stations, messages, startup validation | 13 | | `action_*.go` | Tick-based action lifecycles — gather, firemaking, talk, use, search, thieving, farming, agility, scavenging, assassin, fletching, cleaning, room scripts, targeting | 16 | | `cmd_*.go` | Command handlers — one file per command or command group | 49 | -| `sys_*.go` | Game subsystems — technology, science, combat (death + aggro), assassin tasks, buffs, construction, hazards, labor (task mobs) | 8 | -| `ui_*.go` | Display/output — color, prompt, table, map, help | 5 | +| `sys_*.go` | Game subsystems — technology, science, combat (death + aggro), assassin tasks, buffs, construction, hazards, labor (task mobs), safespots | 8 | +| `ui_*.go` | Display/output — color, prompt, table, map, help, hit-line formatting, XP drops | 6 | +| `flagstore.go`, `safespot_manager.go`, `command_queue.go` | Extracted state managers with their own mutexes | 3 | | `hacking/` | Hacking sub-package — Minigame interface, TerminalDef, CalcXP, WumpusGame, MastermindGame, LiarsDiceGame | 4 | **To add a new command:** create `cmd_<name>.go` with the handler, add one line to `cmd_registry.go`. @@ -71,7 +72,12 @@ internal/ - `world.MobStore` — defs, instances - `action.Store` — cache - `engine.Engine` — subscribers -- `Game` — charsMu (loggedInChars map) +- `Game` — charsMu (loggedInChars map), enterMu (enterSeqs map) +- `net.Hub` — sessions, rooms maps (protects `Add`/`Remove`/`EnterRoom`/`LeaveRoom`/`AllSessions`/`PlayersInRoom` from concurrent access across accept/session/tick goroutines) +- `net.Session` — per-session writeMu serializes writes to the Conn (protects against interleaved bytes from cross-session broadcasts and tick-driven writes) +- `FlagStore` — world flags (shared by all players) +- `SafespotManager` — per-player safespot states (value-copy API avoids lock-copy-pointer anti-pattern) +- `CommandQueue` — free/active/consume command queues (written from session goroutines, drained by tick goroutine) - `combat` — combatants, mobTargets The pattern is: lock, snapshot/unmarshal, unlock, then process. The engine creates a subscriber snapshot each tick. @@ -99,6 +105,7 @@ data/drops/<id>.yaml Shared drop tables (weighted item lists, sub-table ref data/hazards/<id>.yaml Shared room hazard definitions (attack_type, attack, max_hit, speed, messages, required_item) data/help/<id>.yaml Help topics data/modules/<id>.yaml Science module definitions (id, level, max_hit, base_xp, junk_cost, category) +data/techs/<id>.yaml Technology definitions (id, name, level, drain_rate, category, group, effects) data/courses/<id>.yaml Agility course definitions (name, required_level, start_room, obstacles) data/players/accounts/ Account YAML (gitignored) data/players/characters/ Character YAML (gitignored) @@ -110,7 +117,7 @@ See `building_guide/` for full YAML format reference with examples. ## Startup Validation -At startup, the server runs comprehensive integrity checks on all data files. Errors cause the server to exit; warnings are informational. +At startup, the server runs comprehensive integrity checks on all data files. Errors and warnings are logged to stderr; the server continues starting regardless (a "may behave unexpectedly" banner is printed if errors are found). **Duplicate ID checks** across all data directories (items, rooms, mobs, objects, drops, courses, modules, help). Detects collision from two files with the same ID in different subdirectories. @@ -325,7 +332,7 @@ Used by exits, talk options, on-enter scripts, and use_interactions checks. A ba **Attack types.** Weapons have an `attack_type` field (stab/slash/crush/ranged/science). The attack type determines which player attack bonus and which mob defense bonus to use. -**OSRS accuracy formula.** `HitChance(a, d)`: if `a > d` → `1 - (d+2)/(2*(a+1))`, else `a/(2*(d+1))`. Equal rolls ≈ 50%. +**Accuracy formula.** `HitChance(a, d)`: if `a > d` → `1 - (d+2)/(2*(a+1))`, else `a/(2*(d+1))`. Equal rolls ≈ 50%. **Ranged combat.** Weapon type "ranged" uses Ranged level for attack rolls, consumes 1 ammo per attack. If ammo runs out, combat ends. XP: 75% Ranged, 25% Hitpoints. @@ -360,13 +367,19 @@ A **non-violent reuse** of the entire combat engine for worksites — building s ## Technology System (tech.go) -25 hardcoded techs in 4 categories, unlocked by Technology level: +Tech definitions loaded from `data/techs/` via `LoadTechs()`. Techs in 4 categories, unlocked by Technology level: - **Attack/Strength/Defense/Ranged/Science tiers:** I/II/III at 5%/10%/15% level boost - **Protection techs:** Kinetic Barrier (melee), Projectile Screen (ranged), Neural Firewall (science) — 40% damage reduction each - **Utility:** Nano Repair (2x HP regen), Rapid Repair (4x), Power Saver (20% drain reduction), Dead Man's Switch (25% max HP retribution on death) - **Combo:** Overclock (15% atk+str), Fortify (15% def + 2x regen) -Battery = Technology level (float64). Each tech has a drain rate (0.05–0.25 per tick). Equipment TechnologyBonus reduces drain (capped at 50%). Active techs deactivate when battery hits 0. 1-tick "flicking" grace period supported. +Reserved tech IDs whose semantics are coupled to code logic: +- `protect_melee` / `protect_ranged` / `protect_science` — mapped by attack type in `damageAfterTechProtection`. Must exist in YAML; startup validation enforces this. +- `retribution` — checked by name in `killPlayer` (cmd_attack.go) for the death retribution mechanic. Must exist in YAML. + +The Science tier techs (Neural Focus I/II/III) boost Science accuracy via `techLevelBonus(p, "science")`, which is included in the attack roll of both the melee/ranged `calculatePlayerAttackRoll` and the deck `scienceAttack` path. + +Battery = Technology level (float64). Each tech has a drain rate (0.05–0.25 per tick). Equipment TechnologyBonus reduces drain (capped at 50%). Active techs deactivate when battery hits 0. 1-tick "flicking" grace period supported. ActiveTechs is not persisted (resets on reconnect). ## Science System (science.go) @@ -394,7 +407,7 @@ Three minigames at 3 terminal levels (1, 20, 40): XP scales with Hacking level. -## Skills (23 total, 1-99, RSC XP table) +## Skills (23 total, 1-99, classic XP table) | Category | Skills | |---|---| @@ -523,6 +536,7 @@ Prompt variables: `%h` (HP), `%H` (max HP), `%b` (battery), `%B` (max battery), - Hazard damage uses its own `applyHazardHit` path that deliberately omits the flee-abort (`MoveTicks`) logic, so hazards never interrupt walking. Mob hits still do. - A safespot blocks ALL hazard damage regardless of type (`safespotBlocksHazard`), but a melee work/attack step still forces you out of cover (so only ranged/science work keeps you sheltered). - `killPlayer` is the shared death path (extracted from `endCombat`); both combat death and lethal hazard hits go through it. `mob` may be nil for a hazard kill. +- Science (deck) attacks go through `scienceAttack` which calls `combat.EffectiveRoll` for both attack and defense rolls — consistent with melee/ranged. The `techLevelBonus(p, "science")` is included in the attack roll (Neural Focus techs boost science accuracy). The `hpBar`/`progressBar` share a common `renderBar` helper; XP-drop suffixes use `formatXpDrop`/`formatXpDropSingle`. ## Adding a New Skill |
