880abe5888d67c3a60bf95c6869890cad2adf541
Finding 1 (critical): atBootIntro was derived from tree.length === 0 in
StoryView.tsx, but buildStoryTree always returns all topology-root nodes,
so tree.length is always > 0 and the Continue button never rendered.
Fix: add atBootIntro: boolean to StoryView (viewModel), computed by
finding the boot-trigger node id without hardcoding the literal string,
then comparing to the current node. StoryView.tsx reads it from the store.
Also add a viewModel test covering both true and false cases.
Finding 2: onSelect in StoryView.tsx called useGameStore.getState()
directly, bypassing the runtime command layer. Fix: add
GameRuntime.selectStoryNode(id) and wire onSelect through gameRuntime.
Finding 3: aria-pressed on story tree nodes wrongly signals toggle-button
semantics. Fix: replace with aria-current={isSelected ? 'true' : undefined}.
Optional: hoist h-[calc(100dvh-6rem)] to SHELL_HEIGHT const in StoryView.tsx.
Idlegame
Idle/incremental text-fantasy RPG, built as a responsive web app and PWA.
Stack
- TypeScript strict
- Vite + React 19
- Zustand for view state
- Pure TypeScript engine under
src/engine - Zod-validated content and saves
- Biome, Vitest, Tailwind v4, vite-plugin-pwa
Development
pnpm install
pnpm dev
Before pushing a branch:
pnpm typecheck
pnpm lint
pnpm test:coverage
pnpm build
Current Scope
M0 is a walking skeleton: one resource, one timed action, fixed-timestep engine, versioned saves, offline credit, persistence, and a minimal React shell. M1 adds the first playable vertical slice.
Documentation
- Architecture:
docs/architecture.md - Tech stack ADR:
docs/adr/0001-tech-stack.md - M0 plan:
docs/plans/2026-06-11-m0-bootstrap.md
Design, story, decisions, credentials, and durable session memory live in the
Obsidian vault under Idlegame/, not in this repository.
Languages
TypeScript
99.5%
CSS
0.3%
HTML
0.2%