/phantom-camera
Guidance for using the optional Phantom Camera Godot addon in generated projects. Use when a Godot 4 game explicitly opts into Phantom Camera, already has the addon installed, or needs camera behavior that is cleaner with multiple virtual cameras than with a hand-written
$ npx -y skills add RandallLiuXin/GodotMaker --skill phantom-camera --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/phantom-camera
Context preview
The summary Claude sees to decide when to auto-load this skill.
Guidance for using the optional Phantom Camera Godot addon in generated projects. Use when a Godot 4 game explicitly opts into Phantom Camera, already has the addon installed, or needs camera behavior that is cleaner with multiple virtual cameras than with a hand-written
SKILL.md
phantom-camera.SKILL.mdname: phantom-camera
description: |
Guidance for using the optional Phantom Camera Godot addon in generated projects.
Use when a Godot 4 game explicitly opts into Phantom Camera, already has the
addon installed, or needs camera behavior that is cleaner with multiple virtual
cameras than with a hand-written Camera2D script. Do not require this addon for
ordinary projects that can be served by Godot's built-in Camera2D/Camera3D.
Phantom Camera
$ARGUMENTS
Phantom Camera is an optional Godot 4 addon for advanced camera behavior inspired by Cinemachine. Prefer it when the game needs several camera rigs, smooth transitions, framed/dead-zone following, group/path following, camera shake, or cutscene-style camera moves. Keep using plain `Camera2D` / `Camera3D` when the request is a simple static camera, a one-off follow script, or when the generated project has not opted into optional addons.
Opt-in Rules
Use Phantom Camera only when one of these is true:
1. The user asks for Phantom Camera by name. 2. `addons/phantom_camera/plugin.cfg` exists and the plugin is enabled in `project.godot`. 3. The GDD or task explicitly calls for advanced camera behavior and the user or project config allows adding optional addons.
Do not silently add the addon to every scaffolded project. If the addon is not present, document the dependency and either ask for approval before installing it or implement a built-in camera fallback.
Compatibility note: before installing, check the selected Phantom Camera release or `addons/phantom_camera/plugin.cfg` for its supported Godot version. If the project is pinned below the addon's minimum, use built-in camera code instead.
Scene Pattern
For 2D, use this baseline scene shape:
World
|-- Player
|-- Camera2D
| `-- PhantomCameraHost
|-- PhantomCamera2DFollow
`-- PhantomCamera2DZone
For 3D, mirror the same structure with `Camera3D`, `PhantomCameraHost`, and `PhantomCamera3D`.
The `PhantomCameraHost` should be a child of the real `Camera2D` / `Camera3D`. Each `PhantomCamera2D` or `PhantomCamera3D` stores a camera behavior. The active camera is selected by priority: raise one PCam's priority to activate it and lower it when leaving that context.
2D Follow Camera
Use a follow PCam for a player or other primary target. Glued follow is the lightest mode. Framed follow is better for platformers and arena games because the dead zone prevents the camera from drifting on every small movement.
extends Node2D
@onready var player: Node2D = $Player
@onready var follow_pcam: PhantomCamera2D = $PhantomCamera2DFollow
func _ready() -> void:
follow_pcam.set_follow_target(player)
follow_pcam.set_follow_damping(true)
follow_pcam.set_follow_damping_value(Vector2(0.2, 0.2))
follow_pcam.set_tween_duration(0.35)
follow_pcam.set_priority(20)When the follow target is a physics body and the project runs on Godot 4.4 or newer, enable Physics Interpolation in Project Settings to reduce jitter. On older projects, follow a visual child that updates in `_process` instead of the physics body itself.
Camera Zones
Use camera zones when an area of the map needs different zoom, framing, or camera limits.
CameraZone2D
|-- CollisionShape2D
`-- PhantomCamera2DZone
extends Area2D
@export var active_priority := 40
@export var inactive_priority := 0
@onready var zone_pcam: PhantomCamera2D = $PhantomCamera2DZone
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("player"):
zone_pcam.set_priority(active_priority)
func _on_body_exited(body: Node2D) -> void:
if body.is_in_group("player"):
zone_pcam.set_priority(inactive_priority)Keep the default follow PCam at a lower priority, such as `20`, so entering a zone cleanly takes over and exiting returns control to the normal camera.
Transitions
Set per-PCam tween settings instead of writing custom interpolation between cameras. Use short durations for gameplay contexts and longer durations for cinematic reveals.
func focus_boss_intro() -> void:
$PhantomCamera2DPlayer.set_priority(10)
$PhantomCamera2DBoss.set_tween_duration(1.0)
$PhantomCamera2DBoss.set_priority(50)
func return_to_player() -> void:
$PhantomCamera2DBoss.set_priority(0)
$PhantomCamera2DPlayer.set_priority(20)If several PCams should share the same curve and duration, create one `PhantomCameraTween` resource and assign it to each PCam with `set_tween_resource()`.
Camera Shake
Use Phantom Camera noise for sustained shake tied to a PCam, such as a storm, rumbling machinery, or low-health effect. Use a noise emitter for one-shot events such as explosions or heavy impacts when the addon is present.
@onready var follow_pcam: PhantomCamera2D = $PhantomCamera2DFollow
func start_danger_shake(noise: PhantomCameraNoise2D) -> void:
follow_pcam.set_noise(noise)
func stop_danger_shake() -> void:
follow_pcam.set_noise(null)Do not stack several continuous noise sources on the same PCam unless the design really needs it. Keep gameplay readability ahead of spectacle.
Cutscene Camera Moves
For cutscenes, create dedicated PCams at named positions and switch priority as the sequence advances. This keeps camera logic visible in the scene tree and avoids mixing story timing into the player controller.
extends Node
@onready var player_pcam: PhantomCamera2D = %PhantomCamera2DPlayer
@onready var gate_pcam: PhantomCamera2D = %PhantomCamera2DGateReveal
func play_gate_reveal() -> void:
player_pcam.set_priority(10)
gate_pcam.set_tween_duration(1.25)
gate_pcam.set_priority(60)
await gate_pcam.tween_completed
await get_tree().create_timer(0.8).timeout
gate_pcam.set_priority(0)
player_pcam.set_priority(20)For longer authored sequences, drive PCam priority, target positions, and zoom from `AnimationPlayer` or Phantom Camera's tween director
Read more
name: phantom-camera description: | Guidance for using the optional Phantom Camera Godot addon in generated projects. Use when a Godot 4 game explicitly opts into Phantom Camera, already has the addon installed, or needs camera behavior that is cleaner with multiple virtual cameras than with a hand-written Camera2D script. Do not require this addon for ordinary projects that can be served by Godot's built-in Camera2D/Camera3D.
Phantom Camera
$ARGUMENTS
Phantom Camera is an optional Godot 4 addon for advanced camera behavior inspired by Cinemachine. Prefer it when the game needs several camera rigs, smooth transitions, framed/dead-zone following, group/path following, camera shake, or cutscene-style camera moves. Keep using plain `Camera2D` / `Camera3D` when the request is a simple static camera, a one-off follow script, or when the generated project has not opted into optional addons.
Opt-in Rules
Use Phantom Camera only when one of these is true:
1. The user asks for Phantom Camera by name. 2. `addons/phantom_camera/plugin.cfg` exists and the plugin is enabled in `project.godot`. 3. The GDD or task explicitly calls for advanced camera behavior and the user or project config allows adding optional addons.
Do not silently add the addon to every scaffolded project. If the addon is not present, document the dependency and either ask for approval before installing it or implement a built-in camera fallback.
Compatibility note: before installing, check the selected Phantom Camera release or `addons/phantom_camera/plugin.cfg` for its supported Godot version. If the project is pinned below the addon's minimum, use built-in camera code instead.
Scene Pattern
For 2D, use this baseline scene shape:
World |-- Player |-- Camera2D | `-- PhantomCameraHost |-- PhantomCamera2DFollow `-- PhantomCamera2DZone
For 3D, mirror the same structure with `Camera3D`, `PhantomCameraHost`, and `PhantomCamera3D`.
The `PhantomCameraHost` should be a child of the real `Camera2D` / `Camera3D`. Each `PhantomCamera2D` or `PhantomCamera3D` stores a camera behavior. The active camera is selected by priority: raise one PCam's priority to activate it and lower it when leaving that context.
2D Follow Camera
Use a follow PCam for a player or other primary target. Glued follow is the lightest mode. Framed follow is better for platformers and arena games because the dead zone prevents the camera from drifting on every small movement.
extends Node2D
@onready var player: Node2D = $Player
@onready var follow_pcam: PhantomCamera2D = $PhantomCamera2DFollow
func _ready() -> void:
follow_pcam.set_follow_target(player)
follow_pcam.set_follow_damping(true)
follow_pcam.set_follow_damping_value(Vector2(0.2, 0.2))
follow_pcam.set_tween_duration(0.35)
follow_pcam.set_priority(20)When the follow target is a physics body and the project runs on Godot 4.4 or newer, enable Physics Interpolation in Project Settings to reduce jitter. On older projects, follow a visual child that updates in `_process` instead of the physics body itself.
Camera Zones
Use camera zones when an area of the map needs different zoom, framing, or camera limits.
CameraZone2D |-- CollisionShape2D `-- PhantomCamera2DZone
extends Area2D
@export var active_priority := 40
@export var inactive_priority := 0
@onready var zone_pcam: PhantomCamera2D = $PhantomCamera2DZone
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("player"):
zone_pcam.set_priority(active_priority)
func _on_body_exited(body: Node2D) -> void:
if body.is_in_group("player"):
zone_pcam.set_priority(inactive_priority)Keep the default follow PCam at a lower priority, such as `20`, so entering a zone cleanly takes over and exiting returns control to the normal camera.
Transitions
Set per-PCam tween settings instead of writing custom interpolation between cameras. Use short durations for gameplay contexts and longer durations for cinematic reveals.
func focus_boss_intro() -> void:
$PhantomCamera2DPlayer.set_priority(10)
$PhantomCamera2DBoss.set_tween_duration(1.0)
$PhantomCamera2DBoss.set_priority(50)
func return_to_player() -> void:
$PhantomCamera2DBoss.set_priority(0)
$PhantomCamera2DPlayer.set_priority(20)If several PCams should share the same curve and duration, create one `PhantomCameraTween` resource and assign it to each PCam with `set_tween_resource()`.
Camera Shake
Use Phantom Camera noise for sustained shake tied to a PCam, such as a storm, rumbling machinery, or low-health effect. Use a noise emitter for one-shot events such as explosions or heavy impacts when the addon is present.
@onready var follow_pcam: PhantomCamera2D = $PhantomCamera2DFollow
func start_danger_shake(noise: PhantomCameraNoise2D) -> void:
follow_pcam.set_noise(noise)
func stop_danger_shake() -> void:
follow_pcam.set_noise(null)Do not stack several continuous noise sources on the same PCam unless the design really needs it. Keep gameplay readability ahead of spectacle.
Cutscene Camera Moves
For cutscenes, create dedicated PCams at named positions and switch priority as the sequence advances. This keeps camera logic visible in the scene tree and avoids mixing story timing into the player controller.
extends Node
@onready var player_pcam: PhantomCamera2D = %PhantomCamera2DPlayer
@onready var gate_pcam: PhantomCamera2D = %PhantomCamera2DGateReveal
func play_gate_reveal() -> void:
player_pcam.set_priority(10)
gate_pcam.set_tween_duration(1.25)
gate_pcam.set_priority(60)
await gate_pcam.tween_completed
await get_tree().create_timer(0.8).timeout
gate_pcam.set_priority(0)
player_pcam.set_priority(20)For longer authored sequences, drive PCam priority, target positions, and zoom from `AnimationPlayer` or Phantom Camera's tween director
Autonomous text-to-game pipeline for Godot, powered by Claude Code,Codex,Opencode
Repo: RandallLiuXin/GodotMaker
Other skills on godotmaker.
- /background-map
Generate and validate a fixed-viewport background, map base, or parallax plate as a ready-to-load Texture2D.
Open skill - /card-kit
Produce reusable card art sources and native Godot card UI resources.
Open skill - /character-bundle
Produce one illustrated character SpriteFrames resource from high-level body-action intent, optional character and style references, and a resolved animation plan.
Open skill - /compact-prop-pack
Produce a reusable compact-prop atlas from one provider source sheet, with independently loadable AtlasTexture resources for every declared prop.
Open skill - /fx-bundle
Produce a standalone static Texture2D effect or one explicitly timed animated SpriteFrames effect.
Open skill - /platform-strip
Generate non-pixel-art, horizontally repeatable platform strips from real image sources as fixed Texture2D cells or AtlasTexture regions.
Open skill

