- Add keyboard handler for character input in useGame
- Character validation and typing now handled at module level
- platformHook focuses only on lifecycle: Space (start/restart), Escape (quit)
- Game module self-contained for core typing logic
- Add calculateLineCount() to determine optimal lines based on text length (2-6 lines)
- Add getPerspectiveFactors() for appropriate perspective scaling per line count
- Replace hardcoded 6-line paragraphs with dynamic line calculation in both rendering and game logic
- Fix line break detection in useGameStatus to match rendering calculations exactly
- Extend keybindings to support all special characters: apostrophe, hyphen, colon, semicolon, quotes, parentheses, slash, ampersand, and digits
- Integrate greatFallsParagraphs content as wordList in paragraph mode
- Fix vertical centering to scale properly for variable line counts
- Add GameOptions with gameMode, downwardSpeed, boardDimensions, and wordList
- Platform now controls ALL game behavior through options
- changeGameMode now accepts full GameOptions instead of just mode
- downwardSpeed as single px/s value applies to any mode
- wordList is mode-agnostic, platform provides what they need
- All options are fully optional with sensible defaults
- Update example app to use new options API
- Reduce font size from 32px to 20px for sentences/paragraphs mode
- Add breakTextIntoLines helper to split sentences naturally at spaces
- Render sentences across two lines with proper color progression
- Add space character to allowed input regex
- Set sentence fall speed to 25 pixels/second
- Replace sentences with longer, realistic ones including commas and punctuation
- Sentences always render centered on screen (80% max width constraint)
- Ship stays centered during sentence mode (no horizontal movement)
- Add punctuation support (. , ! ?) to keyboard input
- Disable auto-tracking for sentence/paragraph modes
- Remove quitGame() call from changeGameMode to allow continuous play
- Game now transitions between modes without stopping
- Add test case in example App to auto-switch from letters to words at score 10
- Add blur() to mode buttons to remove focus after clicking
- Add preventDefault() to space/escape handlers to stop button activation
- Fix stale closures in useKeyBindings by accessing gameManager directly
- Remove all useCallback hooks per React 19 best practices
- Remove function dependencies from useEffect hooks
- Add GameMode type: 'letters' | 'words' | 'sentences' | 'paragraphs'
- Add gameMode option to GameOptions (defaults to 'letters')
- Create wordLists.ts with curated word lists for each mode
- Update FallingLetter type to track:
- fullText: complete word/sentence/paragraph
- charIndex: current character progress in word
- Modify word spawning to pick from mode-specific word list
- Update handleTypedLetter to support multi-character typed sequences:
- Track progress through word (charIndex)
- Advance to next character when correct
- Show complete word only when fully typed
- Enhanced canvas rendering with color-coded progress:
- Green: completed characters
- Yellow: current character being typed
- White: remaining characters
- Add mode selector buttons to example app
- Default to 'words' mode in example for testing
- Full TypeScript support for all modes
- Track score (starts at 0)
- +1 score and +1 correct for each correct character typed
- -1 score and +1 missed for each wrong character typed
- +1 deaths for each collision with ship
- Score resets when game starts
- All metrics exposed through ScoreManager
- Updated example app UI with colorful scoreboard showing:
- Time (gray)
- Score (neutral)
- Correct (green)
- Missed (yellow)
- Deaths (red)
- Keystrokes (neutral)
- Uses grid layout for organized metric display
- Score cannot go below 0 (clamped to minimum)
Implement core typing game mechanics with keyboard input handling. Correct
letters trigger explosion animation with radiating particles and spawn new
letter. Wrong letters flash red for immediate feedback. Add 50px margins on
both edges to prevent spaceship and letters from appearing at screen borders.
- Add MAX_ACTIVE_LETTERS constant set to 1
- Only spawn new letter if no letters are currently active
- Prepare for future game modes (word, sentence, paragraph)
- Change keybindings to use Escape instead of Q
- Remove useMounted and manual renderBoard call from example App
- Call renderBoard from useGame useEffect on initialization
- Follow vim-maze pattern for cleaner example app
- Create 10x20 game board grid with retro styling
- Render spaceship emoji at player position (bottom center)
- Implement cursor movement with hjkl (left/right only)
- Add moveToStart (0) and moveToEnd ($) anchor motions
- Re-render board when cursor position changes
- Board displays dark grid with highlighted player row
- Copy vim-snake structure stripped of game-specific logic
- Remove finalScore calculation (raw data only)
- Setup example app with keybinding state management
- Empty board renders and waits for game logic