reikhelm/game-web/README.md
Parley Hatch 5813ee3b5a feat(game): REIKHELM: DESCENT — playable first-person roguelike
The pieces finally meet: procgen dungeons + the baked EoB atlas pipeline +
the Vigor combat engine become one game. Three fixed pre-baked floors
(seeds 7 → 69 → 59, 208 frames), monsters/loot/encounters rerolled per run
and composited over the empty scenes; the Ember Sovereign waits at the
bottom.

- game-wasm: run state machine in Rust (manifest nav graph as dungeon
  truth, seeded spawning by theme/depth, embedded combat-core Encounter,
  vigor/fatigue persistence between fights, rest/potions/relics/flee,
  permadeath + victory). 8 native tests incl. a whole-run bot and a
  ScriptedPlayer boss-winnability probe used for tuning.
- game-web: no-framework front-end — title/death/victory screens, baked
  frames with screen-blend monster portraits, combat overlay (dual vigor
  bars, cast telegraphs, cooldown sweeps, floaters), minimap with fog,
  all SFX synthesized in WebAudio.
- balance: floor-scaled levels with a hero's edge over trash, no packs on
  floor 1, boss tuned by sim sweep (~35%/55% win at skill 50/80).
- campaign atlases now versioned (tools/.gitignore exception); boss
  portrait added to the Z-Image roster.

Verified end-to-end in-browser: an autopilot beat the full game through
the real UI (10 fights, 2 flees, Sovereign down), and died plenty before
that.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:30:50 -06:00

60 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# REIKHELM: DESCENT
A first-person dungeon-crawler roguelike, three floors deep. Eye of the Beholder
presentation over the reikhelm procgen + AI-render pipeline, with the Vigor
combined-pool combat system as the fight engine. Pure Rust→WASM + vanilla JS —
no game engine.
## Play
```bash
wasm-pack build game-wasm --target web --out-dir ../game-web/pkg --no-typescript
python3 tools/serve.py --root game-web --port 8001
# open http://127.0.0.1:8001
```
**Explore** `W/S` step · `A/D` turn · `R` rest (hold) · `G` drink draught ·
`T` drink tonic · `Enter` take the stairs
**Combat** `15` abilities · `Space` toggle auto-attack · `Tab` switch target ·
`F` flee (costs ceiling, the monsters remember)
## The shape of a run
- Three fixed floors (atlas seeds **7 → 69 → 59**), pre-baked to pixel art by
`tools/bake_atlas.py`; monsters, treasure, and loot reroll **per run** from the
fate seed. The baked scenes are empty ruins by design — inhabitants are
composited at runtime.
- Your **vigor pool is health, mana, and stamina at once** (the Vigor system,
see `combat/`). Damage and effort drain the same pool; fatigue lowers its
ceiling and persists **between** fights. Resting restores fill quickly and
fatigue slowly; tonics clear fatigue; relics widen the pool for the run.
- The deepest room of floor III holds **the Ember Sovereign**. Kill him to win.
Death is permanent.
## Architecture
```
game-wasm/ the whole game state machine (Rust, natively tested)
src/manifest.rs parses the baked atlas manifests (nav graph = source of truth)
src/spawn.rs seeded monster/treasure placement + balance constants
src/run.rs explore/combat/dead/victory state machine, persistence
src/views.rs one JSON payload per interaction; combat views match combat-web
src/monster_ai.rs the shared enemy brain
game-web/ thin browser view (no framework)
game.js input → wasm call → render from returned state
audio.js all SFX synthesized in WebAudio, zero assets
config.json the combat table: combat/configs/default.json + the boss
tools/out/atlas/<seed>/ the baked campaign art (committed; _work/ is not)
```
The dungeon geometry is read from the atlas **manifest**, never regenerated —
the graph the game walks is exactly the graph the baked frames depict.
## Balancing notes
- Tuned via `cargo test -p game-wasm -- --nocapture`: a whole-run bot plays the
real campaign headlessly, and a `ScriptedPlayer` probe sweeps boss win rates
(target: ~35% at skill 50, ~55% at skill 80, with potions/flee on top).
- Floor 1 spawns no packs; the wraith debuts on floor 2; player gains a level
per descent so trash stays beneath a hero's edge — depth pressure comes from
kits, packs, and fatigue attrition.