Commit graph

218 commits

Author SHA1 Message Date
1c22530be7
Add character creation flow with description prompt 2026-02-14 17:17:36 -05:00
0f3ae87f33
Add description and home_zone fields to player and database 2026-02-14 17:17:36 -05:00
97d5173522
Fix command registry leaking between tests 2026-02-14 16:22:45 -05:00
25339edbf5
Add weather-driven ambient messages
Rain, storm, snow, and fog now have atmospheric ambient messages.
Clear and cloudy conditions return empty list. Messages are evocative
and lowercase, ready to be mixed with zone-specific ambience.
2026-02-14 16:20:00 -05:00
4c4d947ce2
Add visibility system for time and weather effects
Night, fog, and storms now reduce viewport size. Night reduces by 6
width and 2 height (21x11 -> 15x9). Thick fog reduces by 8 width and 4
height. Storm reduces by 4 width and 2 height. Effects stack but clamp
to minimum 7x5. Dawn and dusk subtly dim by 2 width.
2026-02-14 16:20:00 -05:00
9594e23011
Add atmosphere rendering function 2026-02-14 16:20:00 -05:00
d91b180824
Add game day tracking to game time system 2026-02-14 16:18:03 -05:00
15d141b53e
Add season system with tests 2026-02-14 16:18:03 -05:00
4b0a7315c1
Add weather system with tests
Implements procedural weather transitions with:
- WeatherCondition enum (clear, cloudy, rain, storm, snow, fog)
- WeatherState dataclass (condition + intensity 0-1)
- get_weather_description() for atmospheric text varying by intensity
- advance_weather() with probabilistic transitions based on season/climate
- Climate profiles: temperate (balanced), arid (clear/rare rain),
  arctic (snow/fog/cloudy)
2026-02-14 16:18:03 -05:00
32f52ef704
Add time-of-day system with tests 2026-02-14 16:18:03 -05:00
4d44c4aadd
Add librarian NPC with integration tests
Create librarian mob template as a non-combatant NPC with:
- dialogue tree linking (npc_name field)
- time-based schedule (working 7-21, idle otherwise)
- empty moves list (cannot fight)

Wire dialogue tree loading into server startup to load from content/dialogue/.

Add npc_name field to MobTemplate and spawn_mob to preserve dialogue tree links.

Integration tests verify:
- spawning from template preserves npc_name and schedule
- full conversation flow (start, advance, end)
- converse state blocks movement
- schedule transitions change behavior state
- working state blocks movement
- patrol behavior follows waypoints
2026-02-14 14:31:39 -05:00
f0238d9e49
Integrate behavior states into mob movement
Mob movement now respects NPC behavior states:
- converse and working states block movement (NPCs stay put)
- patrol state uses waypoint navigation instead of home region
- flee state moves away from threat coordinates
- idle state uses original home region wander logic

Tests verify each behavior state influences movement correctly.
2026-02-14 14:31:39 -05:00
52f49104eb
Add NPC schedule system with game time
Implements time-based behavior transitions for NPCs:
- GameTime converts real time to game time (1 real min = 1 game hour)
- ScheduleEntry defines hour/state/location/data transitions
- NpcSchedule manages multiple entries with midnight wrapping
- process_schedules() applies transitions when game hour changes
- TOML support for schedule data in mob templates
- Integrated into game loop with hourly checks

Tests cover schedule transitions, game time calculation, TOML loading, and preventing duplicate processing.
2026-02-14 14:31:39 -05:00
67a0290ede
Add talk and reply commands with conversation system
Implements player-NPC dialogue using the dialogue tree data model.
Conversation state tracking manages active conversations and transitions
NPCs to "converse" behavior state during dialogue. Commands support
terminal node cleanup and display formatting with numbered choices.
2026-02-14 14:31:39 -05:00
5d61008dc1
Add dialogue tree data model with tests
Implements a TOML-based dialogue tree system for NPCs with:
- DialogueChoice: player response options with optional conditions
- DialogueNode: NPC text with choices and optional actions
- DialogueTree: complete tree with root node and node graph
- Validation for root_node and next_node references
- load_dialogue() for single files, load_all_dialogues() for directories

Includes librarian dialogue example with nested conversation flow.
2026-02-14 14:31:39 -05:00
369bc5efcb
Add NPC behavior state machine with tests
Adds behavior state tracking to Mob entity with five states: idle, patrol,
converse, flee, and working. Each state has specific processing logic:
- idle: no-op (existing wander logic handles movement)
- patrol: cycles through waypoints with toroidal wrapping support
- converse: stationary during player-driven dialogue
- flee: moves away from threat coordinates
- working: stationary NPC at their post

The behavior module is self-contained and testable, ready for integration
with mob_ai.py in a later step.
2026-02-14 14:31:39 -05:00
355795a991
Add bulk book import script 2026-02-14 12:39:48 -05:00
b5c5542792
Add boundary region data model with TOML parsing and export
Boundaries are rectangular regions within zones that can trigger effects
when players enter or exit. Added BoundaryRegion dataclass with contains()
method, TOML parsing in load_zone(), and export support. Tests verify
parsing, export, and round-trip behavior.
2026-02-14 12:39:48 -05:00
da76b6004e
Add YAML map import script with tests
Implements import_map.py script that converts YAML zone definitions to
TOML format used by the engine. YAML format supports all zone features
including terrain, portals, spawns, ambient messages, and boundaries.
2026-02-14 12:39:48 -05:00
75da6871ba
Add mob pathfinding back to home region
Mobs with home regions now pathfind back when they've strayed. Each tick,
process_mob_movement() checks all mobs and moves them one tile toward their
home region center using Manhattan distance. Movement is throttled to 3
seconds, respects impassable terrain, skips mobs in combat, and broadcasts
to nearby players.
2026-02-14 12:39:48 -05:00
e6ca4dc6b1
Fix code review issues for phase 14 2026-02-14 12:12:23 -05:00
71f4ae4ec4
Add builder commands @goto, @dig, @save, and @place
These commands enable runtime world editing:
- @goto teleports to a named zone's spawn point
- @dig creates a new blank zone with specified dimensions
- @save exports the current zone to TOML
- @place spawns a thing from templates at player position
2026-02-14 11:57:26 -05:00
dd5286097b
Export safe flag and home_region in zone TOML 2026-02-14 11:54:47 -05:00
68c18572d6
Add readable objects with read command
Implements TDD feature for readable text on Things:
- Added readable_text field to Thing dataclass
- Extended ThingTemplate to parse readable_text from TOML
- Created read command that finds objects by name/alias in inventory or on ground
- Handles edge cases: no target, not found, not readable
2026-02-14 11:51:52 -05:00
5e0ec120c6
Add mob home regions to spawn rules and entity 2026-02-14 11:51:39 -05:00
755d23aa13
Add safe zone flag to prevent combat in peaceful areas 2026-02-14 11:50:49 -05:00
14dc2424ef
Show unlock requirements in help for locked moves
help <move> displays lock status and what's needed to unlock
when the move has an unlock_condition the player hasn't met.
2026-02-14 11:40:46 -05:00
8e9e6f8245
Add unlock conditions to roundhouse and sweep moves
Roundhouse requires 5 total kills, sweep requires defeating
3 goblins. Basic moves (punch, dodge, duck, parry, jump)
remain available from the start.
2026-02-14 11:40:46 -05:00
a2efd16390
Add skill unlock system with TOML conditions and gating
UnlockCondition on CombatMove, parsed from [unlock] TOML section.
check_unlocks evaluates kill_count and mob_kills thresholds.
Locked moves rejected with "You haven't learned that yet." in
do_attack/do_defend. New unlocks announced after kills.
2026-02-14 11:40:46 -05:00
085a19a564
Add score command with stats display
Shows PL, stamina, K/D ratio, time played, and unlocked moves.
Registered as score/stats/profile, available in all modes.
2026-02-14 11:40:45 -05:00
e31af53577
Wire kill/death tracking into combat engine
Increment player.kills and player.mob_kills on mob defeat,
player.deaths on player defeat. Session time accumulation
via accumulate_play_time helper.
2026-02-14 11:40:45 -05:00
a398227814
Add player stats model and persistence
kills, deaths, mob_kills dict, play_time_seconds, unlocked_moves set
on Player. New player_stats SQLite table with save/load functions.
2026-02-14 11:40:45 -05:00
21caa099c8
Fix prompt template to show PL as gauge with max value 2026-02-14 10:45:39 -05:00
189f8ac273
Add decomposition timer with broadcast and game loop integration 2026-02-14 10:20:22 -05:00
0fbd63a1f7
Add loot table system with LootEntry and roll_loot
LootEntry defines probabilistic item drops with min/max counts.
roll_loot takes a loot table and returns Thing instances.
MobTemplate now has loot field, parsed from TOML [[loot]] sections.
2026-02-14 10:02:38 -05:00
56169a5ed6
Add corpse decomposition system with active_corpses registry
process_decomposing removes expired corpses and broadcasts messages
to entities at the same tile. Registered in game loop.
2026-02-14 10:02:33 -05:00
68f8c64cf3
Show corpses distinctly in look command 2026-02-14 09:59:44 -05:00
487e316629
Wire corpse spawning into combat death handling
When a mob dies in combat, create_corpse is called to spawn a corpse
at the mob's position with the mob's inventory transferred. This
replaces the direct despawn_mob call, making combat deaths leave
lootable corpses behind.

The fallback to despawn_mob is kept if the mob somehow has no zone.
2026-02-14 09:56:37 -05:00
4f487d5178
Add Corpse class and create_corpse factory
Corpse is a non-portable Container subclass that holds a deceased mob's
inventory. The create_corpse factory transfers items from the mob to the
corpse, sets a decompose_at timestamp for eventual cleanup, and calls
despawn_mob to remove the mob from the world.
2026-02-14 09:54:20 -05:00
4878f39124
Add container grammar with get-all and targeting support
- Update _find_container to use targeting module (prefix + ordinal)
- Update cmd_put to use find_in_inventory directly
- Add 'get all from <container>' support with portable item filtering
- Add comprehensive tests for all container grammar features
2026-02-14 01:39:45 -05:00
aca9864881
Wire target resolution into thing commands
Replace local exact-match helpers with targeting module calls for
prefix matching and ordinal disambiguation. Works in get, drop, and
container extraction (get X from Y).
2026-02-14 01:39:45 -05:00
a98f340e5a
Wire target resolution into look command 2026-02-14 01:39:45 -05:00
86797c3a82
Wire target resolution into combat commands 2026-02-14 01:39:45 -05:00
3f042de360
Add player alias system with persistence and dispatch
Implements a complete alias system allowing players to create command shortcuts.
Aliases are expanded during dispatch with a recursion guard (max 10 levels).

Changes:
- Add aliases field to Player dataclass (dict[str, str])
- Add player_aliases table to database schema
- Add save_aliases() and load_aliases() persistence functions
- Add alias/unalias commands with built-in command protection
- Integrate alias expansion into dispatch() before command resolution
- Add comprehensive test coverage for all features
2026-02-14 01:39:45 -05:00
4c969d2987
Add target resolution module with ordinal and prefix matching 2026-02-14 01:39:45 -05:00
be63a1cbde
Extract shared test fixtures to conftest.py
Moved common test fixtures (mock_writer, mock_reader, test_zone, player,
nearby_player, clear_state) from individual test files into a shared
conftest.py. This eliminates duplication across test_power.py, test_sleep.py,
test_combat_zaxis.py, test_quit.py, test_stamina_cues.py, and
test_stamina_cue_wiring.py.

Some test files override specific fixtures where they need custom behavior
(e.g., test_quit.py adds a close method to mock_writer, stamina tests use
smaller zones and custom player positions).
2026-02-14 01:00:37 -05:00
8bb87965d7
Wire stamina cues into combat and power loops 2026-02-14 01:00:37 -05:00
894a0b7396
Fix flying dodge template grammar 2026-02-14 01:00:37 -05:00
b4dea1d349
Add unconscious state with automatic recovery
Players become unconscious when PL or stamina drops to 0. While unconscious, both stats slowly recover at 0.1 per tick (1.0 per second). When both reach above 0, player regains consciousness with a message. Recovery runs in the main game loop via process_unconscious.
2026-02-14 01:00:37 -05:00
4da8d41b45
Add z-axis altitude check for starting combat
Players must be at same altitude (both flying or both grounded) to initiate combat. Attack fails with 'You can't reach them from here!' if altitude differs.
2026-02-14 01:00:37 -05:00