Game

Game is the entry point for every CarverJS application. It wraps React Three Fiber's <Canvas />, sets up the WebGL renderer, lighting, environment, input system, and game loop — so you can focus on building your scene.

A single Game can contain multiple World components (levels/scenes). Only one World is active at a time.

tsx
import { Game } from "@carverjs/core/components";

Quick Start #

Minimal 3D game #

tsx
import { Game, World, Actor } from "@carverjs/core/components";

function App() {
  return (
    <Game>
      <World>
        <Actor type="primitive" shape="box" color="red" position={[0, 1, 0]} castShadow />
        <Actor type="primitive" shape="plane" color="#eee" size={20} rotation={[-Math.PI / 2, 0, 0]} receiveShadow />
      </World>
    </Game>
  );
}

Minimal 2D game #

tsx
import { Game, World, Actor } from "@carverjs/core/components";

function App() {
  return (
    <Game mode="2d">
      <World>
        <Actor type="sprite" src="/player.png" position={[0, 0, 0]} />
      </World>
    </Game>
  );
}

What Game Sets Up #

Feature3D Mode (default)2D Mode
CanvasShadows enabledShadows disabled
Ambient Lightintensity 0.4intensity 1
Directional Lightposition [10,15,10], castShadow, 1024x1024 shadow mapNot rendered
SkysunPosition [100,20,100]Not rendered
Environmentpreset "sunset", backgroundNot rendered
Game LoopActive (GameLoopTick at priority -5)Active
Audio SystemActive (AudioFlush at priority -48)Active
Collision SystemActive (CollisionFlush at priority -25)Active
Input SystemActive (InputFlush at priority -50)Active

Props Reference #

Game extends all R3F CanvasProps (except camera) plus the following:

PropTypeDefaultDescription
mode"2d" | "3d""3d"Controls lighting, shadows, and default features
ambientLightPropsAmbientLightPropsOverrides for the ambient light
directionalLightPropsDirectionalLightPropsOverrides for the directional light (3D only)
skyPropsSkyPropsOverrides for <Sky /> (3D only)
environmentPropsEnvironmentPropsOverrides for <Environment /> (3D only)
childrenReactNodeOne or more <World> components and other scene content

Any extra props (e.g., style, dpr, gl) are passed to the underlying <Canvas />.


Customizing the Environment #

Override lighting #

tsx
<Game
  ambientLightProps={{ intensity: 0.8 }}
  directionalLightProps={{ position: [5, 5, 5], intensity: 2 }}
>
  <World>{/* ... */}</World>
</Game>

Override sky and environment #

tsx
<Game
  skyProps={{ sunPosition: [0, 1, 0] }}
  environmentProps={{ preset: "dawn" }}
>
  <World>{/* ... */}</World>
</Game>

Pass Canvas props #

tsx
<Game style={{ background: "#1a1a2e" }} dpr={[1, 2]}>
  <World>{/* ... */}</World>
</Game>

Game Loop & Input #

Game automatically mounts four internal systems:

  1. GameLoopTick (priority -5) — increments the global game store's elapsed and frameCount each frame while phase is "playing".

  2. CollisionFlush (priority -25) — runs built-in CollisionManager overlap detection each frame. Runs after fixedUpdate, before update.

  3. AudioFlush (priority -48) — initializes the AudioManager, syncs the audio listener to the active camera, updates spatial sound positions, and auto-pauses audio with the game phase.

  4. InputFlush (priority -50) — attaches the InputManager to the canvas and flushes input state before all game logic stages.

Any component inside <Game> can use useGameLoop, useInput, useCollision, and useAudio without additional setup.


Multiple Worlds #

A Game can contain multiple World components. Use the active prop to control which one is rendered:

tsx
function App() {
  const [level, setLevel] = useState("forest");

  return (
    <Game>
      <World active={level === "forest"}>
        <ForestScene onComplete={() => setLevel("dungeon")} />
      </World>
      <World active={level === "dungeon"}>
        <DungeonScene />
      </World>
    </Game>
  );
}

Since the Canvas is owned by Game, switching worlds doesn't destroy the WebGL context — transitions are fast.


Architecture #

text
Game (Canvas + WebGL context)
  ├── GameLoopTick        — master clock
  ├── AudioFlush          — audio system
  ├── CollisionFlush      — built-in collision detection
  ├── InputFlush          — input system
  ├── Lighting            — ambient + directional (3D)
  ├── Sky + Environment   — scene backdrop (3D)
  └── World(s)            — level containers
        ├── PhysicsGate   — optional Rapier physics wrapper
        ├── Camera        — default or custom
        └── Actors        — scene content

Type Definitions #

See Types for WorldMode, SkyProps, EnvironmentProps, AmbientLightProps, and DirectionalLightProps.