From 2af6053ccfdbf0bf422c11141d3de566420d4f64 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Tue, 10 Mar 2026 23:54:29 +0700 Subject: [PATCH] docs(01-02): complete core infrastructure plan - SUMMARY.md created with full execution details - STATE.md updated: plan 2 of 3, 11% progress - ROADMAP.md updated: 01-02 marked complete - All 79 tests passing, TypeScript compiles clean Co-Authored-By: Claude Opus 4.6 --- .planning/ROADMAP.md | 6 +- .planning/STATE.md | 36 +++-- .../01-core-foundation/01-02-SUMMARY.md | 145 ++++++++++++++++++ 3 files changed, 167 insertions(+), 20 deletions(-) create mode 100644 .planning/phases/01-core-foundation/01-02-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 97b72ab..4ea17fd 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -34,7 +34,7 @@ Decimal phases appear between their surrounding integers in numeric order. Plans: - [x] 01-01-PLAN.md — Project scaffolding with Vite + TypeScript + Canvas, config constants, and shared types -- [ ] 01-02-PLAN.md — Game loop with delta time, typed event emitter, and Tile model class +- [x] 01-02-PLAN.md — Game loop with delta time, typed event emitter, and Tile model class - [ ] 01-03-PLAN.md — Game orchestrator class, main entry point, and human verification ### Phase 2: Grid and Input @@ -126,7 +126,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| -| 1. Core Foundation | 1/3 | In progress | 01-01 | +| 1. Core Foundation | 2/3 | In progress | 01-01, 01-02 | | 2. Grid and Input | 0/3 | Not started | - | | 3. Core Matching Mechanics | 0/3 | Not started | - | | 4. Game State Management | 0/3 | Not started | - | @@ -136,4 +136,4 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 --- *Roadmap created: 2026-03-10* *Granularity: standard* -*Last updated: 2026-03-10 after 01-01-PLAN completion* +*Last updated: 2026-03-10 after 01-02-PLAN completion* diff --git a/.planning/STATE.md b/.planning/STATE.md index 2cbc3c6..5c305cf 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,15 +3,15 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: planning -stopped_at: Completed 01-01-PLAN.md -last_updated: "2026-03-10T16:41:12Z" -last_activity: 2026-03-10 — Completed 01-01-PLAN.md (Project Scaffolding) +stopped_at: Completed 01-02-PLAN.md +last_updated: "2026-03-10T16:51:31Z" +last_activity: 2026-03-10 — Completed 01-02-PLAN.md (Core Infrastructure) progress: total_phases: 6 completed_phases: 0 total_plans: 18 - completed_plans: 1 - percent: 5 + completed_plans: 2 + percent: 11 --- # Project State @@ -26,28 +26,28 @@ See: .planning/PROJECT.md (updated 2026-03-10) ## Current Position Phase: 1 of 6 (Core Foundation) -Plan: 1 of 3 in current phase +Plan: 2 of 3 in current phase Status: In progress -Last activity: 2026-03-10 — Completed 01-01-PLAN.md (Project Scaffolding) +Last activity: 2026-03-10 — Completed 01-02-PLAN.md (Core Infrastructure) -Progress: [█░░░░░░░░░] 5% +Progress: [█░░░░░░░░░] 11% ## Performance Metrics **Velocity:** -- Total plans completed: 1 -- Average duration: 6 min -- Total execution time: 0.1 hours +- Total plans completed: 2 +- Average duration: 6.5 min +- Total execution time: 0.2 hours **By Phase:** | Phase | Plans | Total | Avg/Plan | |-------|-------|-------|----------| -| 01-core-foundation | 1 | 3 | 6 min | +| 01-core-foundation | 2 | 3 | 6.5 min | **Recent Trend:** -- Last 5 plans: 01-01 (6 min) -- Trend: First plan completed +- Last 5 plans: 01-01 (6 min), 01-02 (7 min) +- Trend: Consistent execution time *Updated after each plan completion* @@ -62,6 +62,8 @@ Recent decisions affecting current work: - [01-01]: Manual file creation instead of `npm create vite` due to interactive prompt issues - [01-01]: Vitest configured with node environment for unit tests - [01-01]: Used `as const` assertion for CONFIG to enable type inference +- [01-02]: Used `object` constraint for TypedEventEmitter generic to support interface types +- [01-02]: Added helper methods (getTickLength, getRafId, isRunning) to GameLoop for testability ### Pending Todos @@ -77,6 +79,6 @@ None yet. ## Session Continuity -Last session: 2026-03-10T16:41:12Z -Stopped at: Completed 01-01-PLAN.md -Resume file: .planning/phases/01-core-foundation/01-01-SUMMARY.md +Last session: 2026-03-10T16:51:31Z +Stopped at: Completed 01-02-PLAN.md +Resume file: .planning/phases/01-core-foundation/01-02-SUMMARY.md diff --git a/.planning/phases/01-core-foundation/01-02-SUMMARY.md b/.planning/phases/01-core-foundation/01-02-SUMMARY.md new file mode 100644 index 0000000..8fb9448 --- /dev/null +++ b/.planning/phases/01-core-foundation/01-02-SUMMARY.md @@ -0,0 +1,145 @@ +--- +phase: 01-core-foundation +plan: 02 +subsystem: core +tags: [game-loop, event-emitter, tile-model, tdd, requestAnimationFrame] + +# Dependency graph +requires: + - phase: 01-01 + provides: Project scaffolding, TypeScript config, Vitest setup, types/index.ts, config.ts +provides: + - GameLoop class with requestAnimationFrame-based 60fps loop + - TypedEventEmitter class wrapping Node's EventEmitter + - Tile model class with position, type, emoji getter, and adjacency check +affects: [game-logic, renderer, input-handling] + +# Tech tracking +tech-stack: + added: [] + patterns: + - TDD (test-driven development) with Vitest + - requestAnimationFrame game loop with fixed timestep + - Typed event emitter pattern + - Immutable data models with readonly properties + +key-files: + created: + - src/game/GameLoop.ts + - src/game/EventEmitter.ts + - src/models/Tile.ts + - src/__tests__/GameLoop.test.ts + - src/__tests__/EventEmitter.test.ts + - src/__tests__/Tile.test.ts + modified: [] + +key-decisions: + - "Used `object` constraint for TypedEventEmitter generic to support interface types without index signatures" + - "Added getTickLength() and getRafId() helper methods for testability" + - "Added once() and removeAllListeners() methods to TypedEventEmitter for flexibility" + +patterns-established: + - "TDD pattern: commit failing test first, then implementation" + - "Game loop: fixed timestep (1000/60ms) with delta time accumulation" + - "Event emitter: type-safe wrapper around Node's EventEmitter" + +requirements-completed: [CORE-01] + +# Metrics +duration: 7min +completed: 2026-03-10 +--- + +# Phase 1 Plan 2: Core Infrastructure Summary + +**GameLoop, TypedEventEmitter, and Tile model implemented with TDD - 47 new unit tests all passing** + +## Performance + +- **Duration:** 7 min +- **Started:** 2026-03-10T16:44:32Z +- **Completed:** 2026-03-10T16:51:31Z +- **Tasks:** 3 +- **Files modified:** 6 + +## Accomplishments + +- GameLoop class with requestAnimationFrame-based 60fps loop, delta time tracking, and start/stop lifecycle +- TypedEventEmitter class providing type-safe event handling with on/emit/off/once/removeAllListeners +- Tile model class implementing Tile interface with emoji getter and isAdjacent() method +- All 47 new unit tests pass (12 GameLoop + 18 EventEmitter + 17 Tile) + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: GameLoop class** - `ca2f540` (test), `99a0b56` (refactor - type fixes) +2. **Task 2: TypedEventEmitter class** - `2c2d422` (test), `86e0d2e` (feat), `99a0b56` (refactor - type fixes) +3. **Task 3: Tile model class** - `21fe45c` (test), `f74eb98` (feat) + +**Plan metadata:** pending (docs: complete plan) + +_Note: TDD tasks have multiple commits (test -> feat -> refactor)_ + +## Files Created/Modified + +- `src/game/GameLoop.ts` - requestAnimationFrame-based game loop with start/stop, delta time tracking +- `src/game/EventEmitter.ts` - Type-safe event emitter wrapping Node's EventEmitter +- `src/models/Tile.ts` - Tile model with id, type, position, cleared, emoji getter, isAdjacent() +- `src/__tests__/GameLoop.test.ts` - 12 unit tests for GameLoop +- `src/__tests__/EventEmitter.test.ts` - 18 unit tests for TypedEventEmitter +- `src/__tests__/Tile.test.ts` - 17 unit tests for Tile + +## Decisions Made + +- **EventEmitter generic constraint:** Changed from `Record` to `object` to support TypeScript interfaces without index signatures (like GameEvents) +- **Test infrastructure:** Used global mocks for requestAnimationFrame/cancelAnimationFrame since tests run in node environment +- **Added helper methods:** Added `getTickLength()`, `getRafId()`, `isRunning()` to GameLoop for testability + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Fixed TypeScript type inference in tests** +- **Found during:** Task 1 verification (tsc --noEmit) +- **Issue:** `vi.fn()` without generic type argument returns incompatible type for GameLoop callback; closure variable narrowing issue +- **Fix:** Added explicit generic types `vi.fn<(deltaTime: number) => void>()` and used array instead of nullable variable for captured callbacks +- **Files modified:** src/__tests__/GameLoop.test.ts +- **Verification:** `npx tsc --noEmit` passes +- **Committed in:** `99a0b56` (refactor commit) + +**2. [Rule 1 - Bug] Fixed EventEmitter generic constraint** +- **Found during:** Task 2 verification (tsc --noEmit) +- **Issue:** `Record` constraint requires index signature, but interfaces don't have them +- **Fix:** Changed constraint from `Record` to `object` +- **Files modified:** src/game/EventEmitter.ts +- **Verification:** `npx tsc --noEmit` passes +- **Committed in:** `99a0b56` (refactor commit) + +--- + +**Total deviations:** 2 auto-fixed (both Rule 1 - Bug) +**Impact on plan:** Type safety fixes essential for correct TypeScript compilation. No scope creep. + +## Issues Encountered + +None - all tasks completed as planned with minor type fixes. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +- Core game infrastructure complete: GameLoop, TypedEventEmitter, Tile model +- Ready for Grid implementation (plan 01-03) which will use Tile class and event system +- All 79 tests passing (including 32 from plan 01-01) + +## Self-Check: PASSED + +- All 6 created files verified present +- All 6 commits verified in git history + +--- +*Phase: 01-core-foundation* +*Completed: 2026-03-10*