Welcome to RemyMan
Relevant source files
The following files were used as context for generating this wiki page:
RemyMan (also referred to as "Kilo Man" in the source code) is a high-performance 2D side-scrolling platformer built using Next.js 15/16, React 19, and HTML5 Canvas. The project emphasizes a "pretty, 3D-seeming" aesthetic achieved through advanced canvas rendering techniques, including parallax backgrounds and depth-simulated platforms, without relying on external 3D assets.
Sources: architecture_plan.md:1-10, app/layout.tsx:11-15
System Architecture
The application follows a modular React component structure where high-level state management is decoupled from the intensive game loop and rendering logic. The main entry point resides in app/page.tsx, which renders the GameContainer.
Component Hierarchy
The following diagram illustrates the relationship between the core components:
The GameContainer acts as the orchestrator, managing the high-level game status and performance metrics, while GameCanvas handles the physics engine and rendering.
Sources: architecture_plan.md:14-25, app/components/Game/GameContainer.tsx:49-65
Core Game Engine
The engine is encapsulated within the GameCanvas component and utilizes the requestAnimationFrame API for a smooth game loop. It handles three primary responsibilities: Input processing, Physics simulation, and Rendering.
The Game Loop Flow
The sequence below describes the internal processing for every frame:
Camera & Viewport System
The system employs a dynamic camera that tracks the player across a world significantly larger than the screen (level width of 7000 units). It includes:
- Horizontal Clamping: Prevents the camera from showing out-of-bounds areas.
- Vertical Deadzones: The camera only tracks vertical movement if the player exceeds specific height thresholds or falls into pits.
- Interpolation (Lerp): Smooths camera transitions using a 0.1 factor for X and 0.05 for Y to avoid jitter.
Sources: app/components/Game/GameCanvas.tsx:43-46, app/components/Game/GameCanvas.tsx:327-367, architecture_plan.md:28-36
Physics and Entity System
The game uses a constant-based physics engine to define the "weight" and feel of the character movement.
Physics Constants
| Constant | Value | Description |
|---|---|---|
GRAVITY | 0.6 | Downward force applied every frame |
FRICTION | 0.85 | Horizontal velocity decay |
MOVE_SPEED | 0.8 | Acceleration rate for horizontal movement |
MAX_SPEED | 8.0 | Maximum allowed horizontal velocity |
JUMP_FORCE | -14 | Base upward force applied on jump |
Sources: app/components/Game/GameCanvas.tsx:40-47, architecture_plan.md:89-94
Entity Types
Entities are defined in types.ts and placed within levelData.ts. Each entity possesses unique collision behaviors:
- Platform: Solid objects with top-face depth rendering.
- Hazard: Triggers a "lost" state on collision (rendered as red spikes).
- Monster: Moving entities with patrol logic (start/end points).
- Goal: Triggers the "won" state.
Sources: app/components/Game/types.ts:1-15, app/components/Game/GameCanvas.tsx:294-325
Visuals and Rendering
The "3D-seeming" aesthetic is implemented via layered rendering in the drawBackground and drawPlatform helpers.
Parallax Layers
The background consists of four distinct layers moving at different speeds relative to the camera.x position:
- Sky Gradient: Static linear gradient (#0f172a to #3b0764).
- Logo: Centered with a subtle 0.05 parallax factor.
- Distant Mountains: Dark indigo peaks with a 0.2 parallax factor.
- Near Hills: Indigo slopes with a 0.5 parallax factor.
Sources: app/components/Game/GameCanvas.tsx:106-159, architecture_plan.md:43-48
Procedural Character Rendering
The player character is a humanoid shape composed of geometric primitives.
// Animation logic for the player character
const bob = Math.sin(frameCountRef.current * 0.2) * (Math.abs(p.vx) > 0.1 ? 3 : 1);
const legOffset = Math.sin(frameCountRef.current * 0.4) * 10 * (Math.abs(p.vx) > 0.1 ? 1 : 0);
This logic creates a walking animation and head bobbing effect without using sprite sheets.
Sources: app/components/Game/GameCanvas.tsx:189-218
Game State and UI
The GameStatus type tracks the lifecycle of the application: start, playing, won, and lost.
State Transitions
Point System
Completion data is calculated in GameContainer.tsx when the state transitions to won.
- Base Points: 10,000
- Deduction: 100 points per second elapsed.
- Minimum: 1,000 points.
Sources: app/components/Game/GameContainer.tsx:14-35, app/components/Game/types.ts:46-50
Summary
RemyMan provides a robust foundation for a 2D platformer by combining React's state management with a raw HTML5 Canvas physics engine. Its architecture supports expansive levels through a specialized camera system and creates visual depth using procedural rendering and parallax techniques.
Sources: architecture_Plan.md:1-12, app/components/Game/GameCanvas.tsx:370-410