From godot-claude-skills
Designs Godot 4.x scenes (.tscn files), node hierarchies, and level layouts. Provides patterns for 2D/3D players, enemies, UI, HUD, inventories, and worlds.
npx claudepluginhub alexmeckes/godot-claude-skills --plugin godot-claude-skillsThis skill uses the workspace's default tool permissions.
You are an expert at designing and creating Godot 4.x scenes (.tscn files), node hierarchies, and level layouts.
Constructs Godot scenes from patterns like platformer characters, top-down chars, UI screens, projectiles, pickups, tilemaps with required companion nodes (e.g., CollisionShape2D).
Assists Godot Engine game development with scene creation, node management, GDScript scripting, project structure. Uses MCP tools to edit scenes, add nodes, run projects, debug.
Guides Godot 4.3+ scene tree organization: composition over inheritance, when to split scenes, node hierarchies, and communication patterns.
Share bugs, ideas, or general feedback.
You are an expert at designing and creating Godot 4.x scenes (.tscn files), node hierarchies, and level layouts.
Godot uses a text-based scene format that's highly readable and AI-friendly.
[gd_scene load_steps=3 format=3 uid="uid://abc123"]
[ext_resource type="Script" path="res://scripts/player.gd" id="1_abc"]
[ext_resource type="Texture2D" path="res://sprites/player.png" id="2_def"]
[sub_resource type="CircleShape2D" id="CircleShape2D_xyz"]
radius = 16.0
[node name="Player" type="CharacterBody2D"]
script = ExtResource("1_abc")
speed = 200.0
[node name="Sprite2D" type="Sprite2D" parent="."]
texture = ExtResource("2_def")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_xyz")
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
[gd_scene load_steps=N format=3] - N is total resources + 1Player (CharacterBody2D)
├── Sprite2D
├── CollisionShape2D
├── AnimationPlayer
├── Camera2D
│ └── (smooth follow settings)
├── Hitbox (Area2D)
│ └── CollisionShape2D
└── RayCast2D (ground detection)
Player (CharacterBody3D)
├── CollisionShape3D
├── MeshInstance3D (or imported model)
├── AnimationTree
├── Camera3D
│ └── SpringArm3D (for collision)
└── Marker3D (weapon attachment points)
Enemy (CharacterBody2D)
├── Sprite2D
├── CollisionShape2D
├── AnimationPlayer
├── DetectionArea (Area2D)
│ └── CollisionShape2D
├── Hitbox (Area2D)
│ └── CollisionShape2D
├── NavigationAgent2D
└── Timer (attack cooldown)
UIScreen (Control)
├── Background (TextureRect/ColorRect)
├── VBoxContainer
│ ├── Title (Label)
│ ├── HSeparator
│ └── ButtonContainer (VBoxContainer)
│ ├── StartButton (Button)
│ ├── OptionsButton (Button)
│ └── QuitButton (Button)
└── AnimationPlayer (transitions)
HUD (CanvasLayer)
└── Control
├── MarginContainer
│ └── HBoxContainer
│ ├── HealthBar (ProgressBar/TextureProgressBar)
│ └── ScoreLabel (Label)
├── Minimap (SubViewportContainer)
│ └── SubViewport
│ └── Camera2D
└── DialogBox (PanelContainer)
└── VBoxContainer
├── SpeakerLabel
└── DialogText (RichTextLabel)
Item (Area2D)
├── Sprite2D
├── CollisionShape2D (pickup area)
├── AnimationPlayer (bob/glow)
└── AudioStreamPlayer2D (pickup sound)
Level (Node2D)
├── TileMapLayer (or TileMap for older)
├── Entities (Node2D)
│ ├── Player
│ ├── Enemies (Node2D)
│ │ ├── Enemy1
│ │ └── Enemy2
│ └── Items (Node2D)
├── NavigationRegion2D
│ └── (navigation polygon)
├── ParallaxBackground
│ └── ParallaxLayer
│ └── Sprite2D
└── Camera2D (level bounds)
DialogueManager (Node)
├── CanvasLayer
│ └── DialogueBox (Control)
│ ├── Portrait (TextureRect)
│ ├── NameLabel (Label)
│ ├── TextLabel (RichTextLabel)
│ └── ChoicesContainer (VBoxContainer)
├── Timer (text reveal)
└── AudioStreamPlayer (voice/sfx)
| Node | Use Case |
|---|---|
CharacterBody2D/3D | Player, enemies, NPCs with custom movement |
RigidBody2D/3D | Physics-driven objects (crates, balls) |
StaticBody2D/3D | Immovable collision (walls, floors) |
Area2D/3D | Triggers, detection zones, pickups |
| Node | Use Case |
|---|---|
Sprite2D | Static images |
AnimatedSprite2D | Frame-based animations |
TileMapLayer | Level geometry, backgrounds |
Line2D | Trails, lasers, drawing |
Polygon2D | Custom shapes |
CPUParticles2D | Effects (compatible) |
GPUParticles2D | Effects (performant) |
| Node | Use Case |
|---|---|
MeshInstance3D | 3D models |
CSGBox3D/Sphere3D/etc | Prototyping geometry |
MultiMeshInstance3D | Many identical objects |
GPUParticles3D | 3D particle effects |
Decal | Projected textures |
| Node | Use Case |
|---|---|
Control | Base container |
Label/RichTextLabel | Text display |
Button/TextureButton | Clickable elements |
ProgressBar/TextureProgressBar | Health bars, loading |
HBoxContainer/VBoxContainer | Auto-layout |
MarginContainer | Padding |
PanelContainer | Styled backgrounds |
ScrollContainer | Scrollable content |
TabContainer | Tabbed interfaces |
| Node | Use Case |
|---|---|
AudioStreamPlayer | Global audio (music, UI) |
AudioStreamPlayer2D | Positional 2D audio |
AudioStreamPlayer3D | Positional 3D audio |
| Node | Use Case |
|---|---|
Timer | Delayed actions, cooldowns |
AnimationPlayer | Property animations |
AnimationTree | Complex animation state machines |
Tween | Programmatic animations |
RayCast2D/3D | Line-of-sight, ground detection |
ShapeCast2D/3D | Swept collision detection |
Layer 1: World (static geometry)
Layer 2: Player
Layer 3: Enemies
Layer 4: Player projectiles
Layer 5: Enemy projectiles
Layer 6: Pickups
Layer 7: Triggers/areas
Layer 8: Interactables
Set in scene:
[node name="Player" type="CharacterBody2D"]
collision_layer = 2
collision_mask = 1 | 3 | 6 # Collides with world, enemies, pickups
Use groups to organize and find nodes:
[node name="Enemy" type="CharacterBody2D" groups=["enemies", "damageable"]]
Common groups:
enemies - All enemy nodesdamageable - Anything that can take damageinteractable - Objects player can interact withpersistent - Nodes that persist between scenespausable - Nodes affected by pauseReference external scenes:
[ext_resource type="PackedScene" path="res://scenes/enemy.tscn" id="enemy_scene"]
[node name="Enemy1" parent="Enemies" instance=ExtResource("enemy_scene")]
position = Vector2(100, 200)
[node name="Enemy2" parent="Enemies" instance=ExtResource("enemy_scene")]
position = Vector2(300, 200)
Override instanced scene properties:
[node name="Enemy1" parent="Enemies" instance=ExtResource("enemy_scene")]
position = Vector2(100, 200)
speed = 150.0 # Override exported property
[sub_resource type="Animation" id="Animation_idle"]
length = 1.0
loop_mode = 1
tracks/0/type = "value"
tracks/0/path = NodePath("Sprite2D:frame")
tracks/0/interp = 1
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.25, 0.5, 0.75),
"values": [0, 1, 2, 3]
}
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": SubResource("AnimationLibrary_abc")
}
Start with the root node type - Choose based on the scene's purpose (CharacterBody2D for characters, Control for UI, Node2D for levels)
Build hierarchy logically - Visual nodes as children of physics bodies, UI elements in containers
Use appropriate collision shapes - RectangleShape2D for boxes, CapsuleShape2D for characters, circles for projectiles
Set up layers correctly - Avoid "everything collides with everything"
Name nodes descriptively - "PlayerSprite" not "Sprite2D", "HealthBar" not "ProgressBar"
Use groups for runtime queries - get_tree().get_nodes_in_group("enemies")
Instance reusable scenes - Don't duplicate complex node trees
Consider processing order - Parent nodes process before children
Z-index for 2D layering - Background < World < Entities < Effects < UI
Use CanvasLayer for HUD - Keeps UI separate from game camera