8e2cff5032
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
3.4 KiB
3.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
A standalone, dependency-light Python prototype for a turn-based text RPG dungeon-crawler: generate rooms populated with random mobs, fight through them, quit or die. No relationship to the other Godot projects in eliron-worlds (eliron-world-dungeons, POC/elirons_knights) is documented — despite the mob roster below sharing race names with the eliron-world-dungeons GDD, treat that as coincidental/unverified, not an established asset or code link.
Commands
- Run the game:
python app.py(must run from this directory — save/load uses relative paths like<name>.jsonin the CWD) - Run tests:
python -m unittest test_character_builder.py(orpython test_character_builder.py) — onlycharacter_builder.pyhas tests - No
requirements.txt/pyproject.toml. Only external dependency ispydantic, and it's optional — see below.
Architecture
base_mob.py—BaseMob, the single entity class for both players and enemies (mob_type:FRIEND/NEUTRAL/ENEMY).change_pv()appliesprotectionas damage reduction on negative deltas;perform_attack()loopsspeedtimes per attack call.mobs_utils.py— a fixed roster of 3 hardcodedBaseMobinstances (Yanaar,Ulnarain,Skroll),generate_random_mob_list()(picks a random subset), andgenerate_random_rooms()(distributes mobs into rooms — mutates the input list viapop(0), so it consumesmobs_in_levelas a side effect rather than just reading it).level_one.py—Level: ownsplayer, generatesmobs_in_level/roomsat construction, trackscurrent_room_index, and exposescombat()(turn order decided byspeed). Its ownif __name__ == "__main__":block duplicates a second, slightly different interactive game loop fromapp.py(this one skips the flee/combat submenu and always fights) — don't assume one is canonical over the other; check both if you change the room/combat flow.app.py— the actual entrypoint, with its ownaction_menu()/game loop (separate fromlevel_one.py's), plus a submenu per mob (2= fight,3= flee).menu.py— entirely commented-out dead code, not imported anywhere. Bothapp.pyandlevel_one.pydefine their own localaction_menu()instead.character_builder.py—CharacterBuilderis a thin dispatcher:save_character_impl/load_character_implclass attributes are wired at import time to either the module-levelsave_character/load_character(plain JSON) or, ifELIRON_BUILDER=pydanticis set andpydanticis actually importable (soft-detected viaimportlib.util.find_spec, no hard dependency), topydantic_character_builder.py's equivalents. Adding a third backend means implementing matchingsave_character(character) -> str/load_character(name) -> BaseMob | Nonefunctions and adding a branch to this wiring block.pydantic_character_builder.py— same persistence contract as above, implemented with a pydanticCharacterModelinstead of manualjson.dump/json.load.Hector.json/Jamin.json— pre-made saved characters checked into the repo root (loaded by name viaCharacterBuilder.load_character);test_character_builder.pycreates/removes its ownArthur.jsonfixture and doesn't touch these.