State Management
Relevant source files
The following files were used as context for generating this wiki page:
State management in the Kilo Man project is handled through a hybrid architecture that separates high-level application state from high-frequency game engine state. React's useState and useRef hooks are the primary mechanisms for managing data, ensuring that the UI remains responsive while the game loop maintains high performance without unnecessary re-renders.
The system is structured to propagate state from the GameContainer down to specialized components like GameCanvas and UIOverlay. This separation allows for clean management of game transitions (e.g., start, playing, won, lost), physics calculations, and user interface updates.
Sources: app/components/Game/GameContainer.tsx:1-10, architecture_plan.md:12-21
High-Level Application State
The GameContainer acts as the orchestrator for the overall game status and global modifiers. It utilizes React state to manage the progression of the game and calculates session-specific data such as completion times and scores.
Key State Variables
| Variable | Type | Description | Source |
|---|---|---|---|
gameState | GameStatus | Tracks if the game is in 'start', 'playing', 'won', or 'lost' state. | app/components/Game/types.ts:50 |
jumpModifier | number | A multiplier for player jump force, adjustable via UI. | app/components/Game/GameContainer.tsx:10 |
completionData | CompletionData | Stores final time and points upon reaching the goal. | app/components/Game/types.ts:52-55 |
Point Calculation Logic
Points are calculated based on the duration of a successful "playing" session. The system starts with a base of 10,000 points and deducts 100 points for every second elapsed, with a minimum floor of 1,000 points.
Sources: app/components/Game/GameContainer.tsx:14-21, app/components/Game/GameContainer.tsx:34-43
Game Engine & Physics State
Inside the GameCanvas component, state is managed primarily through useRef to facilitate the high-frequency updates required by the requestAnimationFrame loop. This avoids the overhead of React's reconciliation process for physics and movement.
Mutable References (Refs)
The game loop relies on several mutable references to track the instantaneous position and velocity of entities:
- playerRef: Maintains
PlayerStateincluding coordinates (x, y), velocity (vx, vy), and orientation. - monstersRef: An array of
MonsterStateobjects tracking patrol positions and velocities. - cameraRef: Tracks the viewport's x and y offsets to handle scrolling and parallax.
- keysRef: A dictionary of active keyboard inputs used to determine movement.
Sources: app/components/Game/GameCanvas.tsx:44-55, app/components/Game/types.ts:20-48
Lifecycle and Reset Flow
When the gameState changes to 'playing', the engine performs a full state reset. It fetches the 'start' position from levelData.ts and initializes monsters based on level definitions.
The diagram shows the initialization sequence triggered when the game transitions from the start screen or a game-over state into active gameplay.
Sources: app/components/Game/GameCanvas.tsx:75-103, app/components/Game/levelData.ts:98
Data Flow Architecture
The data flow is unidirectional from the container to the children, with callbacks used to signal state changes back to the parent.
This sequence illustrates how user interactions in the UI and collision events in the Canvas update the shared state in the Container.
Sources: app/components/Game/GameContainer.tsx:50-65, app/components/Game/GameCanvas.tsx:232-245
Entity and Configuration Models
The system defines specific interfaces to ensure type safety across the state management layers.
Entity Types
Entities are defined in levelData.ts and mapped to the LevelEntity interface.
- platform: Static objects used for collision and footing.
- hazard: Objects that trigger the 'lost' state upon contact.
- monster: Dynamic entities with
patrolRangeandspeedthat trigger the 'lost' state. - goal: Triggers the 'won' state.
Sources: app/components/Game/types.ts:1-18, architecture_plan.md:33-40
Physics Configuration
Constants governing movement state are centralized in a GameConfig object:
gravity: 0.6friction: 0.85moveSpeed: 0.8maxSpeed: 8.0baseJumpForce: -14
Sources: app/components/Game/GameCanvas.tsx:35-42, architecture_plan.md:104-109
Summary
State management in Kilo Man is designed for performance and clarity. By lifting game status and UI-driven modifiers to the GameContainer, the application maintains a single source of truth for the game lifecycle. Simultaneously, the use of React refs within GameCanvas ensures that the 60fps game loop can update physics and camera states with minimal latency, resulting in a smooth platforming experience.
Sources: architecture_plan.md:5-10, app/components/Game/GameCanvas.tsx:334-350