Keel separates camera concerns cleanly from the renderer: cameras are plain ECS components on ordinary entities. The 2D and 3D renderers each query for their respective camera component at the start of every frame and build the appropriate transformation matrix from it. No camera object needs to be registered or injected — spawning the entity is all that is required.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/VKSFY/keel/llms.txt
Use this file to discover all available pages before exploring further.
Camera2D — Orthographic
Camera2D drives the sprite renderer’s orthographic projection. It maps world coordinates into normalised device coordinates with an optional zoom factor and rotation. The renderer reads the first Camera2D entity it finds in the world.
Component fields
Spawning a Camera2D
When no
Camera2D entity exists, the renderer falls back to a default orthographic camera centred on the framebuffer, so spawning in pixel coordinates “just works.” Spawn an explicit Camera2D whenever you need to pan, zoom, or rotate the view.Default camera behaviour
Without an explicitCamera2D, the renderer centres the view at (width / 2, height / 2). World coordinates map directly to screen pixels — an entity at (400, 300) on an 800×600 window appears at the centre of the screen.
Moving the camera in a system
Write to theCamera2D component through world.set for one-off moves, or iterate world.query(keel.Camera2D) for in-place bulk mutation:
Zooming and rotation
Camera3D — Perspective
Camera3D drives the 3D renderer’s perspective projection. Position is stored as x, y, z; orientation is expressed as Euler angles (yaw, pitch, roll) applied in Y → X → Z order. The renderer reads the first Camera3D entity in the world.
Component fields
Spawning a Camera3D
Pointing the camera at a target
To aimCamera3D at a world-space target — for example, always looking at the origin — compute yaw and pitch with atan2:
Moving the camera in a system
Field of view
fov is in radians. Use math.radians(deg) to convert from degrees. Values must be in the range (0, π). A common starting point is math.radians(60) (≈ 1.047 rad).
One Camera Per Scene
Standard pattern
Spawn exactly one
Camera2D (for 2D scenes) or one Camera3D (for 3D scenes) per app. The renderer reads the first one it finds.What happens with multiple cameras
If multiple
Camera2D (or Camera3D) entities exist, only the first one encountered during world.query is used. The rest are silently ignored.Using both renderers at once
When bothsetup_renderer_2d and setup_renderer_3d are active, spawn one Camera2D and one Camera3D. The two renderers query independently — Camera2D is invisible to the 3D pass and vice versa. This is the intended pattern for games with a 3D world and a 2D HUD.
