/phantom-camera
Use when using the Phantom Camera addon — PhantomCamera2D/3D with priority-based switching, follow and look-at modes, and tween transitions
$ npx -y skills add jame581/GodotPrompter --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.
Use when using the Phantom Camera addon — PhantomCamera2D/3D with priority-based switching, follow and look-at modes, and tween transitions
SKILL.md
phantom-camera.SKILL.mdname: phantom-camera
description: Use when using the Phantom Camera addon — PhantomCamera2D/3D with priority-based switching, follow and look-at modes, and tween transitions
Phantom Camera
> **Related skills:** **camera-system** for hand-rolled camera patterns, **tween-animation** for the easing concepts the transitions build on.
> **Addon:** Phantom Camera · version `v0.11.0.2` · Godot 4.4+ · MIT · source: https://github.com/ramokz/phantom-camera · nodes are GDScript, plus an official C# wrapper API (`namespace PhantomCamera`) shipped as source `.cs` files in the addon. **Pre-1.0:** minor versions may break API.
---
1. When to use Phantom Camera vs. `camera-system`
| Approach | Best for | |---|---| | Hand-rolled (`camera-system` skill) | One camera, simple follow/shake, no addon dependency | | **Phantom Camera** | Multiple camera "shots" that need priority-based switching, dead-zone/group/path/third-person follow logic, and smooth resource-driven tweens between them — Cinemachine-style workflow |
Reach for Phantom Camera when a scene needs several distinct camera behaviors (gameplay follow, a cutscene framing, a boss-fight group shot) that swap automatically based on priority, rather than one script juggling every case. It replaces the `Camera2D`/`Camera3D` positioning logic itself — you still keep exactly one real `Camera2D`/`Camera3D` per viewport; Phantom Camera nodes never render anything on their own.
---
2. Install & setup
**Asset Library (recommended):** Godot AssetLib → search "Phantom Camera" → Download (select only the `phantom_camera` directory) → **Project → Project Settings → Plugins** → enable it.
**GitHub zip:** extract `addons/phantom_camera/` into the project root, then enable the plugin the same way.
Enabling the plugin auto-registers a `PhantomCameraManager` autoload singleton and **restarts the editor every time `_enable_plugin()` runs** (not just the first time) — expected behavior, not a bug. No manual autoload setup is needed. Six custom node types become available in the "Create New Node" dialog: `PhantomCamera2D`, `PhantomCamera3D`, `PhantomCameraHost`, `PhantomCameraNoiseEmitter2D`, `PhantomCameraNoiseEmitter3D`, and `PhantomCameraTweenDirector`.
**C# projects:** the addon ships its official wrapper as plain `.cs` source files under `addons/phantom_camera/scripts/**` (`namespace PhantomCamera`) — no NuGet package to add. A C#-enabled Godot project (one with its own generated `.csproj`, `Godot.NET.Sdk`) picks these up automatically once the addon folder is present; `using PhantomCamera;` is then enough (§3–§7).
---
3. Host + camera model
Two node kinds work together:
- **`PhantomCameraHost`** — add it **as a child of your real `Camera2D`/`Camera3D`** (not the other way
around). It reads the highest-priority `PhantomCamera2D`/`3D` in the scene and drives the real camera's transform every frame. Only the first `PhantomCameraHost` child of a given camera is used.
- **`PhantomCamera2D`** / **`PhantomCamera3D`** — placed anywhere else in the scene tree (siblings of
the player, inside trigger areas, cutscene rigs). Any number can exist; each one describes a candidate "shot" via `priority`, a follow mode, and (3D only) a look-at mode. They render nothing themselves.
# Scene tree:
# Camera2D (or Camera3D)
# └─ PhantomCameraHost
# Player (CharacterBody2D)
# └─ PhantomCamera2D (priority 0, follow_mode = SIMPLE, follow_target = Player)
# BossArena
# └─ PhantomCamera2D (priority 10, follow_mode = GROUP, follow_targets = [Player, Boss])
# CameraRig.gd — on the Camera2D/Camera3D
extends Camera2D
@onready var host: PhantomCameraHost = $PhantomCameraHost
func _ready() -> void:
# host.camera_2d / host.camera_3d are populated automatically from get_parent()
var active := host.get_active_pcam()
print("Active PCam: ", active.name if active else "none")// CameraRig.cs — on the Camera2D/Camera3D
using PhantomCamera;
public partial class CameraRig : Camera2D
{
private PhantomCameraHost _host;
public override void _Ready()
{
// Host.Camera2D / Host.Camera3D are populated automatically from GetParent()
_host = GetNode<Node>("PhantomCameraHost").AsPhantomCameraHost();
var active = _host.GetActivePhantomCamera();
GD.Print("Active PCam: ", active is PhantomCamera2D p ? p.Node2D.Name.ToString() : "none");
}
}`PhantomCameraHost.interpolation_mode` (C#: `InterpolationMode`, enum `Auto`/`Idle`/`Physics`/`Manual`) controls when the Host updates the real camera: `AUTO` (default — picks physics or idle based on the active PCam's target), `IDLE`, `PHYSICS`, or `MANUAL` (call `host.process(delta)` yourself each tick).
`host_layers` (`@export_flags_2d_render` / `_3d_render`) on both the Host and each PCam gate which PCams a given Host will consider — a PCam is only eligible if its `host_layers` bitmask overlaps the Host's.
---
4. Priority-based switching
Every `PhantomCamera2D`/`3D` has `priority: int = 0`. The `PhantomCameraHost` attached to the scene's real camera always follows the highest-priority PCam that shares a `host_layers` bit with it. Change `priority` at runtime with `set_priority(value)` / read with `get_priority()` — values are clamped to `>= 0`.
# TriggerArea.gd — raise priority while the player is inside, restore on exit
extends Area2D
@export var area_pcam: PhantomCamera2D
func _ready() -> void:
area_entered.connect(_on_entered)
area_exited.connect(_on_exited)
func _on_entered(area: Area2D) -> void:
if area.get_parent() is CharacterBody2D:
area_pcam.set_priority(20)
func _on_exited(area: Area2D) -> void:
if area.get_parent() is CharacterBody2D:
area_pcam.set_priority(0)using PhantomCamera;
public partial class TriggerArea : Area2D
{
[Export] private Node2D _areaPCamNode;
private PhantomCamera2D _areaPCam;
public override void _ReaRead more
name: phantom-camera description: Use when using the Phantom Camera addon — PhantomCamera2D/3D with priority-based switching, follow and look-at modes, and tween transitions
Phantom Camera
> **Related skills:** **camera-system** for hand-rolled camera patterns, **tween-animation** for the easing concepts the transitions build on.
> **Addon:** Phantom Camera · version `v0.11.0.2` · Godot 4.4+ · MIT · source: https://github.com/ramokz/phantom-camera · nodes are GDScript, plus an official C# wrapper API (`namespace PhantomCamera`) shipped as source `.cs` files in the addon. **Pre-1.0:** minor versions may break API.
---
1. When to use Phantom Camera vs. `camera-system`
| Approach | Best for | |---|---| | Hand-rolled (`camera-system` skill) | One camera, simple follow/shake, no addon dependency | | **Phantom Camera** | Multiple camera "shots" that need priority-based switching, dead-zone/group/path/third-person follow logic, and smooth resource-driven tweens between them — Cinemachine-style workflow |
Reach for Phantom Camera when a scene needs several distinct camera behaviors (gameplay follow, a cutscene framing, a boss-fight group shot) that swap automatically based on priority, rather than one script juggling every case. It replaces the `Camera2D`/`Camera3D` positioning logic itself — you still keep exactly one real `Camera2D`/`Camera3D` per viewport; Phantom Camera nodes never render anything on their own.
---
2. Install & setup
**Asset Library (recommended):** Godot AssetLib → search "Phantom Camera" → Download (select only the `phantom_camera` directory) → **Project → Project Settings → Plugins** → enable it.
**GitHub zip:** extract `addons/phantom_camera/` into the project root, then enable the plugin the same way.
Enabling the plugin auto-registers a `PhantomCameraManager` autoload singleton and **restarts the editor every time `_enable_plugin()` runs** (not just the first time) — expected behavior, not a bug. No manual autoload setup is needed. Six custom node types become available in the "Create New Node" dialog: `PhantomCamera2D`, `PhantomCamera3D`, `PhantomCameraHost`, `PhantomCameraNoiseEmitter2D`, `PhantomCameraNoiseEmitter3D`, and `PhantomCameraTweenDirector`.
**C# projects:** the addon ships its official wrapper as plain `.cs` source files under `addons/phantom_camera/scripts/**` (`namespace PhantomCamera`) — no NuGet package to add. A C#-enabled Godot project (one with its own generated `.csproj`, `Godot.NET.Sdk`) picks these up automatically once the addon folder is present; `using PhantomCamera;` is then enough (§3–§7).
---
3. Host + camera model
Two node kinds work together:
- **`PhantomCameraHost`** — add it **as a child of your real `Camera2D`/`Camera3D`** (not the other way
around). It reads the highest-priority `PhantomCamera2D`/`3D` in the scene and drives the real camera's transform every frame. Only the first `PhantomCameraHost` child of a given camera is used.
- **`PhantomCamera2D`** / **`PhantomCamera3D`** — placed anywhere else in the scene tree (siblings of
the player, inside trigger areas, cutscene rigs). Any number can exist; each one describes a candidate "shot" via `priority`, a follow mode, and (3D only) a look-at mode. They render nothing themselves.
# Scene tree: # Camera2D (or Camera3D) # └─ PhantomCameraHost # Player (CharacterBody2D) # └─ PhantomCamera2D (priority 0, follow_mode = SIMPLE, follow_target = Player) # BossArena # └─ PhantomCamera2D (priority 10, follow_mode = GROUP, follow_targets = [Player, Boss])
# CameraRig.gd — on the Camera2D/Camera3D
extends Camera2D
@onready var host: PhantomCameraHost = $PhantomCameraHost
func _ready() -> void:
# host.camera_2d / host.camera_3d are populated automatically from get_parent()
var active := host.get_active_pcam()
print("Active PCam: ", active.name if active else "none")// CameraRig.cs — on the Camera2D/Camera3D
using PhantomCamera;
public partial class CameraRig : Camera2D
{
private PhantomCameraHost _host;
public override void _Ready()
{
// Host.Camera2D / Host.Camera3D are populated automatically from GetParent()
_host = GetNode<Node>("PhantomCameraHost").AsPhantomCameraHost();
var active = _host.GetActivePhantomCamera();
GD.Print("Active PCam: ", active is PhantomCamera2D p ? p.Node2D.Name.ToString() : "none");
}
}`PhantomCameraHost.interpolation_mode` (C#: `InterpolationMode`, enum `Auto`/`Idle`/`Physics`/`Manual`) controls when the Host updates the real camera: `AUTO` (default — picks physics or idle based on the active PCam's target), `IDLE`, `PHYSICS`, or `MANUAL` (call `host.process(delta)` yourself each tick).
`host_layers` (`@export_flags_2d_render` / `_3d_render`) on both the Host and each PCam gate which PCams a given Host will consider — a PCam is only eligible if its `host_layers` bitmask overlaps the Host's.
---
4. Priority-based switching
Every `PhantomCamera2D`/`3D` has `priority: int = 0`. The `PhantomCameraHost` attached to the scene's real camera always follows the highest-priority PCam that shares a `host_layers` bit with it. Change `priority` at runtime with `set_priority(value)` / read with `get_priority()` — values are clamped to `>= 0`.
# TriggerArea.gd — raise priority while the player is inside, restore on exit
extends Area2D
@export var area_pcam: PhantomCamera2D
func _ready() -> void:
area_entered.connect(_on_entered)
area_exited.connect(_on_exited)
func _on_entered(area: Area2D) -> void:
if area.get_parent() is CharacterBody2D:
area_pcam.set_priority(20)
func _on_exited(area: Area2D) -> void:
if area.get_parent() is CharacterBody2D:
area_pcam.set_priority(0)using PhantomCamera;
public partial class TriggerArea : Area2D
{
[Export] private Node2D _areaPCamNode;
private PhantomCamera2D _areaPCam;
public override void _ReaAgentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.
Other skills on godot-prompter.
- /authoring-godot-prompter-skills
Use when writing or editing a SKILL.md or an agent definition in this repo — required frontmatter, section ordering, and the GDScript-then-C# example convention.
Open skill - /releasing-godot-prompter
Use when cutting a GodotPrompter release or bumping its version — the version-bump sequence, tag-triggered workflow, and the marketplace manifests that must follow.
Open skill - /2d-essentials
Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+
Open skill - /3d-essentials
Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion culling, and decals in Godot 4.3+
Open skill - /ability-system
Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay tags, and HUD binding
Open skill - /addon-development
Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels
Open skill

