reikhelm/game-web/index.html
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

134 lines
4.6 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>REIKHELM: DESCENT</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- ======================= TITLE ======================= -->
<section id="title" class="screen show">
<div class="title-wrap">
<h1 class="wordmark">REIKHELM</h1>
<div class="subtitle">— D E S C E N T —</div>
<p class="tagline">Three floors down sits the Ember Sovereign.<br>Take the crown, or join the bones.</p>
<div class="archetypes">
<button class="arch-card" data-arch="duelist">
<img src="portraits/duelist.png" alt="">
<span class="arch-name">The Duelist</span>
<span class="arch-blurb">Steel, grit, and a wide pool.<br>Guard the blows. Answer harder.</span>
</button>
<button class="arch-card" data-arch="battlemage">
<img src="portraits/battlemage.png" alt="">
<span class="arch-name">The Sorcerer</span>
<span class="arch-blurb">A thin frame, a deep art.<br>Curse, burn, and never get hit.</span>
</button>
</div>
<div class="seed-row">
<span class="dim">fate</span>
<span id="seed-label" class="seed"></span>
<button id="reroll" title="reroll fate"></button>
</div>
<div class="hint dim">choose your champion to begin</div>
</div>
</section>
<!-- ======================= GAME ======================= -->
<section id="game" class="screen">
<div id="stage">
<img id="frame" alt="" draggable="false">
<div id="frame-fade"></div>
<div id="vignette"></div>
<div id="danger-vignette"></div>
<!-- monsters composited over the empty baked scene -->
<div id="sprites"></div>
<!-- floating combat numbers -->
<div id="floaters"></div>
<!-- encounter banner -->
<div id="banner"></div>
<!-- floor transition card -->
<div id="floorcard">
<div id="floorcard-depth"></div>
<div id="floorcard-name"></div>
</div>
<!-- enemy panels (combat) -->
<div id="enemies"></div>
<!-- top HUD -->
<div id="hud-top">
<div id="floor-label"></div>
<div id="compass"></div>
</div>
<!-- descend prompt -->
<div id="descend-prompt" class="prompt">▼ the stair descends — <b>[enter]</b></div>
<div id="rest-overlay">· resting ·</div>
<!-- bottom HUD -->
<div id="hud">
<div id="log"></div>
<div id="player-panel">
<div id="player-bars">
<div class="vbar" id="player-vbar">
<div class="vbar-cap"></div>
<div class="vbar-fill"></div>
<div class="vbar-ceiling"></div>
<div class="vbar-num"></div>
</div>
<div id="player-cast" class="castbar"><div></div></div>
</div>
<div id="belt">
<span class="belt-item" id="belt-gold" title="gold"><b>0</b></span>
<span class="belt-item key" id="belt-draught" title="vigor draught — restores fill [G]">🜪 <b>0</b><span class="kb">G</span></span>
<span class="belt-item key" id="belt-tonic" title="stamina tonic — clears fatigue [T]">🜍 <b>0</b><span class="kb">T</span></span>
<span class="belt-item" id="belt-relic" title="relics — widen your pool"><b>0</b></span>
</div>
<div id="actionbar"></div>
<div id="combat-controls">
<button id="btn-auto" class="ctl">AUTO <span class="kb">space</span></button>
<button id="btn-flee" class="ctl">FLEE <span class="kb">F</span></button>
</div>
</div>
<canvas id="minimap"></canvas>
</div>
<div id="keys-hint" class="dim">w/s move · a/d turn · r rest · g/t drink · enter stairs · 1-5 abilities</div>
</div>
</section>
<!-- ======================= END SCREENS ======================= -->
<section id="death" class="screen">
<div class="end-wrap">
<h1 class="end-title doom">THE DESCENT CLAIMS YOU</h1>
<div id="death-by" class="end-sub"></div>
<div id="death-stats" class="stats"></div>
<div class="end-buttons">
<button id="btn-retry" class="big-btn">descend again</button>
</div>
</div>
</section>
<section id="victory" class="screen">
<div class="end-wrap">
<img id="victory-boss" src="portraits/boss.png" alt="">
<h1 class="end-title gold">THE EMBER CROWN IS YOURS</h1>
<div class="end-sub">the Sovereign's fire gutters out beneath you</div>
<div id="victory-stats" class="stats"></div>
<div class="end-buttons">
<button id="btn-again" class="big-btn">descend again</button>
</div>
</div>
</section>
<script type="module" src="game.js"></script>
</body>
</html>