reikhelm/combat/combat-web/README.md
Parley Hatch 902a233229 feat(combat): playable browser front-end + AI monster portraits
A real-time consumer of combat-core (the front-end the spec designs for, §14):
pick a foe, manage your single Vigor pool, try not to spend your survival.

- combat-core: a HumanController (input-driven, spec §5) behind a shared intent
  cell, plus Encounter::tick_once / drain_events so a wall-clock front-end can
  drive the engine a tick at a time (§10). Trivial abilities (difficulty 0, e.g.
  auto-attack) no longer fizzle. Engine unchanged otherwise; 48 tests still green.
- combat-wasm: a wasm-bindgen Game bridge — tick-stepping, JSON world state, the
  player's ability list, and a flavorful MonsterAI that uses each monster's
  signature kit (the wraith curses your ceiling) on a coin-flip so big hits space
  into a readable duel. Own workspace member, kept out of the default host build.
- combat-web: an atmospheric battler. The signature dual Vigor bar shows fill,
  the regen-headroom ceiling, the ceiling marker, and the dark cracked fatigue
  zone in one bar — the squeeze made legible. Floating damage, cast telegraphs,
  combat log, result overlay. Verified end-to-end in a real browser.
- tools/portraits.py: stdlib text-to-image client reusing the proven LAN Z-Image
  stack (minus the depth ControlNet) to render the bestiary. 7 portraits committed.
- Added skeleton / troll / wraith monster stat blocks; bumped the duelist's
  durability so fights are readable (even-con ~30s) and active play beats every
  monster while passive auto-attacking loses the hard ones. Re-validated the sim:
  the skill gradient and anti-turtle guardrail still hold (auto ~1% → skill100 34%
  at even con). README findings updated to match.

Verified live: roster screen, win/lose, the dual bars, telegraphed casts, and a
3s active-play victory over the Skeleton Knight.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 12:46:47 -06:00

2.2 KiB
Raw Permalink Blame History

Vigor — playable combat front-end

A browser battler that drives combat-core (via combat-wasm) in real time: pick a foe, manage your single Vigor pool, and try not to spend your survival. The engine is authoritative and unchanged — this is just a presentation layer and a [HumanController] pushing your intent between ticks.

What's here

  • index.html / style.css / game.js — the UI (torch-lit dark fantasy).
  • portraits/ — AI-generated monster art (Z-Image on the LAN workstation; see ../tools/portraits.py). Committed so the game runs offline.
  • pkg/ — the wasm-bindgen output (gitignored; rebuild with the command below).

Build & play

# 1. Build the wasm bridge into ./pkg  (cargo on PATH; from combat/)
export PATH="$HOME/.cargo/bin:$PATH"
wasm-pack build combat-wasm --dev --target web \
  --out-dir ../combat-web/pkg --out-name combat_wasm

# 2. Serve combat/ as the web root (so the page AND configs/ resolve)
python3 -m http.server 8013 --directory .

# 3. Open the game
open http://127.0.0.1:8013/combat-web/

(Re)generate portraits — needs the LAN ComfyUI / Z-Image server up:

python3 tools/portraits.py --url http://192.168.1.26:8188 --size 768

How to play

  • Click a foe to start. The fight runs in real time (10 ticks/second).
  • Auto-attack is on by default (toggle with the AUTO button or space).
  • Abilities: click a card or press 15. Each shows its fill cost — spending fill lowers your capacity, so a big hit leaves you fragile.
  • Watch the dual bar: bright = current fill, dim = regen headroom, the gold line is your ceiling (cap), and the dark cracked zone on the right is fatigue — ceiling lost for the rest of the fight. When the ceiling collapses to your fill, the next hit overruns you (daze → KO).
  • Second Wind restores ceiling; Guard opens a brief block window. Passive auto-attacking beats the weak foes (Dire Rat, Skeleton); the Golem, Troll, and Wraith want real play — recover, punish when they're spent, don't over-commit.

Difficulty is a table: edit ../configs/default.json (monster stats, ability numbers, the con curve) to taste — the same file the sim tunes against.