aboutsummaryrefslogtreecommitdiff
path: root/AGENTS.md
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-24 22:55:35 -0400
committerhistoria <[not public]>2026-06-24 22:55:35 -0400
commit15b7e221b799ef107dec44ecdb294026dfd3d059 (patch)
tree3748e464a77f0f082bea1567e9d6990052054961 /AGENTS.md
parent9d4b799db4868bcab291b83599ff088763cd4ed6 (diff)
downloadthehouseoficarus-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.md34
1 files changed, 24 insertions, 10 deletions
diff --git a/AGENTS.md b/AGENTS.md
index c2d420f..99cac55 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -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