> ## Documentation Index
> Fetch the complete documentation index at: https://docs.summerengine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Camera rigs skill for AI agents

> Camera rigs: Camera2D follow with limits, first-person head, SpringArm3D third-person, top-down, FOV. A Summer Engine skill for AI agents.

`camera-rigs` is a skill from the [Summer skill library](/mcp/skills): a guide your AI agent reads when the task matches, so it builds the good version on the first try. Camera rigs: Camera2D follow with limits, first-person head, SpringArm3D third-person, top-down, FOV.

| | |
| - | - |
| Status | Preview: not yet exercised in-engine by the Summer team |
| Domains | Scenes and project, 3D models, 2D art |
| Version | `1.0.0` |
| Engine version | `>=4.6` |
| Recommended set | No, installed by `--all` or by name |

## When your agent uses it

* Black screen on play, or the camera shows past the level edge
* Jerky camera follow, wrong FOV, or the third-person camera clips into walls
* Need a top-down, isometric, orthographic, orbit, or spring-arm camera

## Install

`summer setup` installs every skill for your agent. To add only this one:

```bash theme={null}
npx -y summer-engine@latest skills install camera-rigs --agent claude-code
```

Swap `claude-code` for your agent, such as `codex` or `cursor`. See [Skills](/mcp/skills#quick-start) for every option.

## The skill

One rule above all: exactly ONE camera is active. In 3D that is the single
`Camera3D` with `current = true`; two current cameras = flicker or the wrong
view, and a scene with no current camera renders nothing in the game. In 2D a
`Camera2D` is active when `enabled = true` (the default) and it is in the tree;
with several enabled cameras, call `make_current()` on the one you want.

Trigger phrases: "black screen on play", "camera shows past the level edge",
"jerky follow", "wrong FOV", "I need a top-down / isometric / orbit camera".

Ops use engine variant strings (`"Vector3(0, 5, 10)"`), never JSON objects
(`{x: 0, y: 5, z: 10}` fails). Every mutation names its scene: pass the exact
`scenePath` (e.g. `res://main.tscn`). One `summer_batch` per rig saves the scene
once; the examples below use it.

## 2D follow camera

Add the `Camera2D` as a CHILD of the player so it follows for free, then smooth
it and clamp it to the level.

```
summer_batch(scenePath="res://main.tscn", ops=[
  {"op": "AddNode", "parent": "./Player", "type": "Camera2D", "name": "Camera"},
  {"op": "SetProp", "path": "./Player/Camera", "key": "position_smoothing_enabled", "value": true},
  {"op": "SetProp", "path": "./Player/Camera", "key": "position_smoothing_speed", "value": 6.0},
  {"op": "SetProp", "path": "./Player/Camera", "key": "limit_left", "value": 0},
  {"op": "SetProp", "path": "./Player/Camera", "key": "limit_right", "value": 1920},
  {"op": "SetProp", "path": "./Player/Camera", "key": "limit_top", "value": 0},
  {"op": "SetProp", "path": "./Player/Camera", "key": "limit_bottom", "value": 1080}
])
```

* Smoothing speed 5-8 feels responsive; higher = tighter, lower = drifty.
* Set limits to the actual level bounds (the numbers above are placeholders).
  `limit_smoothing_enabled = true` avoids a hard stop at the edge.
* Zoom `Vector2(2, 2)` zooms IN (bigger), `Vector2(0.5, 0.5)` zooms OUT (top-down).

## 2D top-down camera

Same as above minus the platformer edge-lock urgency. Zoom out to show the field
(`Vector2(0.5, 0.5)`). Keep it centered on the player; no vertical bias.

## 3D first-person camera

Camera is a child of a `Head` node on the player. Body yaws, Head pitches. See
the `character-movement` skill (its 3D movement reference: `summer_docs_read` id `skill/character-movement/references/movement-3d.md`) or
`fps-controller` for the look script. FOV 70-75, near 0.05.

```
summer_batch(scenePath="res://main.tscn", ops=[
  {"op": "AddNode", "parent": "./Player/Head", "type": "Camera3D", "name": "Camera"},
  {"op": "SetProp", "path": "./Player/Head/Camera", "key": "fov", "value": 72.0},
  {"op": "SetProp", "path": "./Player/Head/Camera", "key": "near", "value": 0.05},
  {"op": "SetProp", "path": "./Player/Head/Camera", "key": "current", "value": true}
])
```

## 3D third-person camera (spring arm)

The `SpringArm3D` pushes the camera in when a wall is behind the player, so it
never clips through geometry. This is the correct third-person rig - do not just
park a Camera3D behind the player.

```
summer_batch(scenePath="res://main.tscn", ops=[
  {"op": "AddNode", "parent": "./Player", "type": "SpringArm3D", "name": "SpringArm"},
  {"op": "SetProp", "path": "./Player/SpringArm", "key": "position", "value": "Vector3(0, 2, 0)"},
  {"op": "SetProp", "path": "./Player/SpringArm", "key": "spring_length", "value": 4.5},
  {"op": "SetProp", "path": "./Player/SpringArm", "key": "collision_mask", "value": 2},
  {"op": "AddNode", "parent": "./Player/SpringArm", "type": "Camera3D", "name": "Camera"},
  {"op": "SetProp", "path": "./Player/SpringArm/Camera", "key": "current", "value": true}
])
```

Set `collision_mask` to the LEVEL layer only. If it includes the player layer the
arm collapses to length 0 and you see inside the character (a controller script
can also call `add_excluded_object(get_rid())` on the arm).

## Orthographic top-down 3D (twin-stick, strategy, isometric)

```
summer_batch(scenePath="res://main.tscn", ops=[
  {"op": "SetProp", "path": "./Camera", "key": "projection", "value": 1},
  {"op": "SetProp", "path": "./Camera", "key": "size", "value": 20.0},
  {"op": "SetProp", "path": "./Camera", "key": "position", "value": "Vector3(0, 20, 0)"},
  {"op": "SetProp", "path": "./Camera", "key": "rotation_degrees", "value": "Vector3(-90, 0, 0)"}
])
```

`projection = 1` is orthogonal. `size` is the vertical world units shown - bigger
\= more zoomed out. For isometric, rotate \~(-30, 45, 0) instead of straight down.

## FOV guidance

* 60-75: most 3D games. 90+: fast FPS (feels faster, more peripheral).
* Under 40 or over 110 distorts. Never animate FOV wildly; a small kick (+8 on
  sprint, tweened back) reads as speed.

## Verify

A camera is only proven by a frame. After the rig is in, `summer_play`, then
`summer_screenshot` with `target: "game"`, then `summer_stop`; or save frames
from a `RunVerification` probe while the player moves (see
`playtesting-a-feature`). An editor `viewport` screenshot shows the editor's
camera, not the game's.

## Troubleshooting

| Symptom | Cause | Fix |
| - | - | - |
| Black screen | No current/enabled camera | 3D: `current = true` on exactly one; 2D: one enabled Camera2D in the tree |
| Camera inside geometry | Spawned inside a wall/player | Move it out; spring arm for 3P |
| Jerky follow | Smoothing off/too slow | Enable smoothing, speed 6-10 |
| Shows past level edge | No 2D limits | Set `limit_*` to level bounds |
| Wrong facing (3D) | rotation.y off | y: 0 = forward, 180 = backward |
| Everything tiny/huge (ortho) | `size` wrong | Tune `size`, not `position.y` |

## From a shell

No Summer MCP tools in this session? Run each one as a command; when `summer --version` is missing or below 4.0, use `npx -y summer-engine@latest` in place of `summer`. Fields are flags in kebab-case (`--scene-path res://main.tscn`) or one `--input '<json>'`, and `summer ops describe <op>` prints the exact input. The `summer-cli` skill has the rest.

| In this skill | Command |
| - | - |
| `summer_docs_read` | `summer docs read` |
| `summer_add_node` | `summer engine add-node` |
| `summer_batch` | `summer engine batch` |
| `summer_get_diagnostics` | `summer engine get-diagnostics` |
| `summer_get_scene_tree` | `summer engine get-scene-tree` |
| `summer_inspect_node` | `summer engine inspect-node` |
| `summer_play` | `summer engine play` |
| `summer_save_scene` | `summer engine save-scene` |
| `summer_screenshot` | `summer engine screenshot` |
| `summer_set_prop` | `summer engine set-prop` |
| `summer_stop` | `summer engine stop` |

## Related skills

* [`make-game`](/skills/make-game): Orchestrate 'make me a game': brainstorm, plan, scaffold, mechanics, art, audio, polish, verify, ship.
* [`character-movement`](/skills/character-movement): Player controllers for 2D and 3D, plus the standard third-person controller for Summer humanoids.
* [`fps-controller`](/skills/fps-controller): First-person controller: WASD, mouse look, jump, coyote time, jump buffering, air control.

***

Source: [`library/skills/camera-rigs/SKILL.md`](https://github.com/SummerEngine/summer/blob/main/library/skills/camera-rigs/SKILL.md), rendered from `summer-engine@4.3.0` on npm.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.