glytch/fktry/lanes/LANE-UI.md
type-two 1a769e6cbd Baseline: GLYTCH prototype, FKTRY lore codex, scaffold + 5-lane orchestration docs
- index.html: WIMVEE GLYTCH match-the-glitch prototype (playable)
- docs/FKTRY_LORE.md: world bible / MODELBEAST asset codex
- fktry/: vite+three+TS scaffold, contracts, main loop, seed data
- fktry/MASTERPLAN.md + CONTRACTS.md + lanes/LANE-{SIM,RENDER,UI,SCREEN,DATA}.md:
  round protocol and Round 1 orders for parallel Opus 4.8 executors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 15:51:12 +10:00

3.4 KiB

LANE-UI — HUD, build tools, and the voice of the game

You are an Opus 4.8 executor on the UI lane of FKTRY. Read ../MASTERPLAN.md and ../CONTRACTS.md first; the world bible is ../../docs/FKTRY_LORE.md. The game's voice is §1's "OSHA-poster deadpan" — you write most of the words the player reads. Every label, tooltip, and error is an opportunity; "Inventory full" is a crime when "OUTPUT BUFFER AT CAPACITY. THIS IS A YOU PROBLEM." is available.

Mission: everything DOM. Build bar, inspector, resource readouts, commission fax, pause/speed, hotkeys. Plain TypeScript + DOM — no framework, no CSS libs.

Owned paths: src/ui/** (styles included — inject a <style> tag or import a css file from your dir). Never touch: contracts, main.ts, other lanes. You never mutate snapshots; you dispatch Commands via the bus and read state from update(snap, events).

Standing rules (all rounds):

  • #ui root has pointer-events:none; every interactive child you create re-enables it. Clicks must fall through to the game world everywhere else — test this.
  • Keyboard map lives in one file (hotkeys.ts) — it will grow.
  • Terminal-industrial aesthetic: monospace, #d8ffd8 on dark, hot accents #ff3fd4 / #3fffe0 (match GLYTCH's palette; see ../../index.html for reference). No rounded corners. This is machinery, not a startup.

CURRENT ORDERS — Round 1 (goal: milestone M1 "FLOW")

Replace the stub in src/ui/index.ts:

  1. Build bar (bottom center): one button per machine in GameData.machines (icon = colored square from placeholder color + name), hotkeys 1-9. Click/hotkey selects for placement → sets bus._sel (see main.ts) {def, dir}; R rotates the pending dir; Esc/right-click clears selection. Selected button shows hot state.
  2. Top strip: bandwidth meter (gen vs draw bar that goes amber near 100%, red + "BROWNOUT" flash when over), shipped-total ticker, tick/paused indicator. Space toggles pause (dispatch setPaused).
  3. Inspector (click an entity with nothing selected to build): panel showing machine name, codex flavor line (hard-code a lookup of 1-liners per machine for now — request codex excerpts in data via NOTES if you want them properly), recipe with input/output item chips + live buffer counts, progress bar, jam reason in amber. Close with Esc. (Selecting an entity: you'll need the hovered tile — reuse renderer.pickTile via a pointerdown listener on #ui's capture phase or request a cleaner hook via CONTRACT REQUEST if this fights main.ts's handler; a pragmatic v1 is fine.)
  4. Commission fax (top right, under THE SCREEN): the active commission's flavor text on a fax-paper styled card, wants as item chips with progress 3/40, satisfying it plays an aggressively mundane "FAX SENT" stamp animation on commissionDone.
  5. Event toasts (bottom right): jammed, brownout, commissionDone become small toast lines in the house voice, max 4 on screen, 6s TTL.

Definition of done: full M1 chain placeable entirely with mouse + hotkeys, no console needed; brownout is legible from the top strip alone; fax completes when melt ships. npm run check clean, no console errors, pointer fall-through verified. NOTES written.


NOTES (append-only log, newest at bottom)

### Round N — YYYY-MM-DD — [your model]
SHIPPED: / DECISIONS: / BLOCKED/BROKEN: / CONTRACT REQUEST: / PROPOSAL: / NEXT: