fire_truck_plan.md (11058B)
1 # Fire Truck Implementation Plan 2 3 ## Goal 4 5 Implement a new `fire-truck` game from a clean slate as a simple top-down Phaser game for young kids. 6 7 The first shipped version should support: 8 9 1. Loading from the portal as a live game. 10 2. Rendering a top-down city with roads and placeholder buildings. 11 3. Automatically driving a fire truck along streets. 12 4. Prompting the player at intersections to press the correct arrow key: 13 - left arrow = turn left 14 - up arrow = go straight 15 - right arrow = turn right 16 5. Stopping the truck on wrong or late input. 17 6. Playing a fail sound and showing a clear visual warning on failure. 18 7. Resuming once the correct arrow is pressed. 19 8. Continuing indefinitely through newly generated turns and intersections. 20 21 Out of scope for this phase: 22 23 - Fires, destinations, scoring, timers, lives 24 - Traffic, pedestrians, collisions 25 - Detailed art assets 26 - Complex audio/music systems 27 - Multiple levels or difficulty settings 28 29 ## Repo Constraints 30 31 Follow existing project conventions: 32 33 1. Static HTML, CSS, and JavaScript only. 34 2. No build tooling. 35 3. Phaser loaded from CDN. 36 4. Optional audio via Web Audio API or Tone.js loaded from CDN. 37 5. No external image assets. Use Phaser graphics / generated textures only. 38 6. Browser tests expect `preserveDrawingBuffer: true`. 39 7. No `console.log` in production code. 40 8. Expose `window.__FT_SCENE__ = this` in `create()` for browser test inspection. 41 42 ## Current State 43 44 The repository currently has stale fire-truck tests referencing an older pseudo-3D implementation: 45 46 - `tests/unit/route.test.js` 47 - `tests/unit/projection.test.js` 48 - fire-truck-specific cases in `tests/browser/runner.js` 49 50 The `games/fire-truck/` directory does not currently exist. 51 52 The portal already has a placeholder tile for `fire-truck` in `js/main.js`, but it is marked `coming-soon`. 53 54 This implementation should treat the game as a fresh top-down design and replace all outdated fire-truck assumptions. 55 56 ## Deliverables 57 58 Create or update these files: 59 60 1. `games/fire-truck/index.html` 61 2. `games/fire-truck/lib.js` 62 3. `games/fire-truck/game.js` 63 4. `js/main.js` 64 5. `tests/unit/route.test.js` 65 6. `tests/unit/projection.test.js` 66 7. `tests/browser/runner.js` 67 68 ## High-Level Architecture 69 70 Split the implementation into two layers: 71 72 1. Pure logic in `lib.js` 73 2. Phaser scene and rendering in `game.js` 74 75 ### `lib.js` responsibilities 76 77 `lib.js` should contain all pure, deterministic logic that can be unit tested in Node without Phaser. 78 79 Keep it small and focused on: 80 81 1. Road network generation 82 2. Intersection classification 83 3. Move legality 84 4. Heading transitions 85 5. Prompt selection 86 6. Path extension for infinite driving 87 88 ### `game.js` responsibilities 89 90 `game.js` should contain: 91 92 1. Phaser scene setup 93 2. World generation bootstrapping 94 3. Rendering of roads, buildings, and truck 95 4. Camera follow behavior 96 5. Automatic movement 97 6. Intersection detection 98 7. Prompt UI 99 8. Input handling 100 9. Failure/recovery behavior 101 10. Minimal SFX 102 11. Debug state exposure for browser tests 103 104 ## Core Design Decisions 105 106 ### 1. World representation 107 108 Use a grid-based city. 109 110 Each cell should be one of: 111 112 1. road cell 113 2. building cell 114 115 Road cells should store exits in cardinal directions: 116 117 - `N` 118 - `E` 119 - `S` 120 - `W` 121 122 A road cell can therefore represent: 123 124 1. straight 125 2. corner 126 3. T intersection 127 4. four-way intersection 128 129 This keeps generation and movement simple and testable. 130 131 ### 2. Truck movement model 132 133 The truck should move automatically from cell center to cell center along the road network. 134 135 Use a heading enum: 136 137 - `north` 138 - `east` 139 - `south` 140 - `west` 141 142 The truck should always be aligned to one heading and centered in its lane/path. 143 144 Movement loop: 145 146 1. truck moves along current road segment 147 2. when nearing next intersection, prompt appears 148 3. player must press correct arrow before reaching the center 149 4. if correct, truck commits the move and continues 150 5. if wrong or late, truck stops 151 6. while stopped, only the correct key resumes movement 152 153 ### 3. Prompt timing 154 155 The correct key must be pressed before the truck reaches the center of the intersection. 156 157 ### 4. Infinite play model 158 159 Do not generate an infinite full map up front. 160 161 Instead: 162 163 1. generate an initial connected city chunk around the start 164 2. track the route ahead 165 3. extend the network / route ahead as needed 166 167 The simplest reliable version is route-first generation with local filler roads/buildings around it. 168 169 ## Recommended Implementation Strategy 170 171 Implement in this order: 172 173 1. Create the HTML shell. 174 2. Implement pure logic functions in `lib.js`. 175 3. Replace the old unit tests with tests for the new logic. 176 4. Implement the Phaser scene in `game.js`. 177 5. Update `js/main.js` so the portal tile is live. 178 6. Replace old browser tests with new top-down gameplay tests. 179 7. Run `npm test` and fix issues. 180 181 ## Acceptance Criteria 182 183 The feature is complete when all of the following are true: 184 185 1. The `Fire Truck` tile on the portal is live and opens the game. 186 2. The game loads without console or runtime errors. 187 3. A top-down road/building city renders clearly. 188 4. The truck starts driving automatically after load. 189 5. A prompt appears before intersections. 190 6. Left/right/up arrows correspond to left/right/straight. 191 7. Wrong input stops the truck and shows fail feedback. 192 8. Missing the prompt before the intersection center also stops the truck. 193 9. Pressing the correct arrow while stopped resumes movement. 194 10. The route continues indefinitely without obvious dead ends. 195 11. The fire-truck unit tests reflect the new design, not the old pseudo-3D one. 196 12. Browser smoke tests reflect the new top-down gameplay. 197 13. `npm test` passes. 198 199 ## Next Steps 200 201 The first version is now implemented and passing tests. The next development pass should focus on feel and city quality rather than adding unrelated features. 202 203 ### 1. Raise runtime frame rate and remove the low-FPS workaround path 204 205 Current issue: 206 207 - The scene currently includes extra wall-clock stepping to keep Playwright stable under headless throttling. 208 - That keeps tests reliable, but it is a workaround rather than the ideal runtime architecture. 209 - The visual update rate and motion smoothness should be improved in normal play. 210 211 Goals: 212 213 1. Keep gameplay smooth at interactive frame rates in the browser. 214 2. Reduce dependence on duplicate movement stepping paths. 215 3. Preserve browser test reliability without degrading real gameplay. 216 217 Recommended work: 218 219 1. Profile the current render/update path and simplify anything done every frame that can be precomputed. 220 2. Keep static city drawing on cached graphics or render textures rather than redrawing dynamic content unnecessarily. 221 3. Ensure only the truck, prompt UI, and transient effects are changing each frame. 222 4. Revisit the Playwright compatibility path so test stability does not force a slower-feeling runtime. 223 5. Prefer one canonical movement/update pipeline if possible, with test timing adapted around it rather than maintaining two divergent timing behaviors long-term. 224 225 Acceptance criteria for this step: 226 227 1. Motion looks smoother during normal play. 228 2. Prompt timing remains correct. 229 3. Browser tests still pass. 230 4. No new console warnings or errors are introduced. 231 232 ### 2. Make street grid generation much more connected and realistic 233 234 Current issue: 235 236 - The current generation is route-first with local side branches. 237 - It is good enough for v1 gameplay, but it does not yet feel like a believable dense city. 238 - Connectivity is limited and the road network is too obviously centered around the active route. 239 240 Goals: 241 242 1. Produce a city grid that feels more like real urban blocks. 243 2. Increase cross-connectivity between nearby streets. 244 3. Include many more plausible T intersections and 4-ways. 245 4. Reduce the feeling of isolated decorative branches. 246 247 Recommended generation direction: 248 249 1. Start from a coarse block plan instead of only the truck route. 250 2. Build a connected backbone of horizontal and vertical streets across a rectangular neighborhood. 251 3. Add secondary streets that connect existing roads rather than ending as stubs. 252 4. Use sparse omissions to create T intersections intentionally, instead of relying on ad hoc branch placement. 253 5. Maintain short-to-medium block lengths so intersections occur often enough for the teaching loop. 254 255 Recommended concrete algorithm changes: 256 257 1. Generate several north-south avenues spanning the neighborhood. 258 2. Generate several east-west streets spanning the neighborhood. 259 3. Use probabilistic gaps at selected crossings to convert some full crossings into T intersections. 260 4. Add short connector streets only when they join two existing streets or complete a block edge. 261 5. Run a connectivity pass to ensure the playable component is highly connected. 262 6. Keep the truck route embedded inside this broader street graph rather than serving as the primary source of roads. 263 264 Recommended test additions for this step: 265 266 1. Verify the generated road graph has a large connected component. 267 2. Verify the graph contains both T intersections and 4-ways in realistic proportions. 268 3. Verify the average road-cell degree is above a minimum threshold. 269 4. Verify there are multiple alternate neighboring connections around the active route. 270 271 Acceptance criteria for this step: 272 273 1. The visible city looks denser and more grid-like. 274 2. Roads feel mutually connected rather than decorative. 275 3. The active route still supports infinite driving. 276 4. Prompt opportunities remain frequent and readable. 277 278 ### 3. Smooth turn animation instead of heading snap 279 280 Current issue: 281 282 - Heading changes are mechanically correct but visually abrupt. 283 284 Goals: 285 286 1. Make turns feel more natural. 287 2. Preserve the simple teaching gameplay. 288 289 Recommended work: 290 291 1. Interpolate truck rotation during the intersection-to-exit transition. 292 2. Optionally move along a short corner arc rather than a strict two-segment snap. 293 3. Keep the implementation small; do not add full path spline complexity unless required. 294 295 Acceptance criteria for this step: 296 297 1. Left and right turns read clearly. 298 2. Straight movement remains centered and stable. 299 3. Prompt timing and fail timing do not regress. 300 301 ### 4. Add positive feedback for correct input 302 303 Current issue: 304 305 - Failure is communicated clearly. 306 - Success currently lacks an equally clear but gentle reward cue. 307 308 Goals: 309 310 1. Reinforce correct arrow input for young kids. 311 2. Keep audio short and non-intrusive. 312 313 Recommended work: 314 315 1. Add a brief success chirp or two-note chime on correct input. 316 2. Optionally add a small visual confirmation such as a soft flash or badge. 317 3. Keep success feedback lighter than failure feedback so the screen stays calm. 318 319 Acceptance criteria for this step: 320 321 1. Correct input is immediately rewarding. 322 2. Feedback does not obscure the next prompt. 323 3. Audio still respects browser autoplay constraints. 324 325 ### Recommended implementation order for the next pass 326 327 1. Improve the street graph generator first. 328 2. Rework runtime update/render flow for smoother frame rate. 329 3. Add turn smoothing. 330 4. Add success feedback. 331 5. Update tests where necessary and rerun `npm test`.