From godot-ai-builder
Scene creation and node hierarchy architecture for Godot 4. Use when building scenes, choosing between programmatic vs .tscn, designing node trees, or connecting scripts to scenes. CRITICAL: prefer programmatic scene building for generated code.
npx claudepluginhub hubdev-ai/godot-ai-builderThis skill uses the workspace's default tool permissions.
For AI-generated games, **build scenes in code** (via `_ready()`), not as .tscn text.
Designs Godot 4.x scenes (.tscn files), node hierarchies, and level layouts. Provides patterns for 2D/3D players, enemies, UI, HUD, inventories, and worlds.
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.
Share bugs, ideas, or general feedback.
For AI-generated games, build scenes in code (via _ready()), not as .tscn text.
Why:
Scene file (5 lines):
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://scripts/main.gd" id="1"]
[node name="Main" type="Node2D"]
script = ExtResource("1")
Script (builds everything):
extends Node2D
func _ready():
_build_player()
_build_enemies()
_build_ui()
_build_spawner()
func _build_player() -> CharacterBody2D:
var player = CharacterBody2D.new()
player.name = "Player"
player.position = Vector2(512, 300)
player.collision_layer = 1 # Layer 1 = player
player.collision_mask = 4 | 6 # Detect enemies + walls
player.add_to_group("player")
# Collision shape
var shape = CollisionShape2D.new()
var rect = RectangleShape2D.new()
rect.size = Vector2(32, 32)
shape.shape = rect
player.add_child(shape)
# Visual (ColorRect for prototyping)
var visual = ColorRect.new()
visual.name = "Visual"
visual.size = Vector2(32, 32)
visual.position = Vector2(-16, -16)
visual.color = Color(0.2, 0.6, 1.0)
player.add_child(visual)
# Attach script
player.set_script(load("res://scripts/player.gd"))
add_child(player)
return player
func _build_bullet(pos: Vector2, dir: Vector2) -> Area2D:
var bullet = Area2D.new()
bullet.position = pos
bullet.collision_layer = 2 # Layer 2 = player bullets
bullet.collision_mask = 4 # Detect enemies
var shape = CollisionShape2D.new()
var circle = CircleShape2D.new()
circle.radius = 5.0
shape.shape = circle
bullet.add_child(shape)
var visual = ColorRect.new()
visual.size = Vector2(8, 8)
visual.position = Vector2(-4, -4)
visual.color = Color.YELLOW
bullet.add_child(visual)
bullet.set_script(load("res://scripts/bullet.gd"))
bullet.set("direction", dir) # Set exported var
return bullet
func _build_ui():
var canvas = CanvasLayer.new()
canvas.name = "UI"
# Score label
var score = Label.new()
score.name = "ScoreLabel"
score.text = "Score: 0"
score.position = Vector2(20, 20)
score.add_theme_font_size_override("font_size", 24)
canvas.add_child(score)
# Health bar
var hp_bar = ProgressBar.new()
hp_bar.name = "HealthBar"
hp_bar.position = Vector2(20, 50)
hp_bar.size = Vector2(200, 20)
hp_bar.max_value = 100
hp_bar.value = 100
canvas.add_child(hp_bar)
add_child(canvas)
func _build_spawner():
var timer = Timer.new()
timer.name = "SpawnTimer"
timer.wait_time = 2.0
timer.autostart = true
timer.timeout.connect(_on_spawn_timer)
add_child(timer)
func _build_camera(target: Node2D):
var cam = Camera2D.new()
cam.name = "Camera"
cam.position_smoothing_enabled = true
cam.position_smoothing_speed = 5.0
cam.zoom = Vector2(1.5, 1.5)
target.add_child(cam) # Attach to player for follow
Only use .tscn text for:
[gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://scripts/enemy.gd" id="1"]
[sub_resource type="RectangleShape2D" id="SubResource_1"]
size = Vector2(24, 24)
[node name="Enemy" type="CharacterBody2D"]
collision_layer = 4
collision_mask = 1
script = ExtResource("1")
[node name="Collision" type="CollisionShape2D" parent="."]
shape = SubResource("SubResource_1")
[node name="Visual" type="ColorRect" parent="."]
offset_left = -12.0
offset_top = -12.0
offset_right = 12.0
offset_bottom = 12.0
color = Color(0.9, 0.15, 0.15, 1.0)
load_steps = ext_resources + sub_resources + 1parent attributeparent="."parent="Child/Grandchild"format=3 for Godot 4Color(r, g, b, a) with floats 0.0-1.0Vector2(x, y)Main (Node2D)
├── Background (ColorRect or TileMapLayer)
├── Player (CharacterBody2D)
├── EnemyContainer (Node2D)
├── BulletContainer (Node2D)
├── SpawnTimer (Timer)
├── Camera2D
└── UI (CanvasLayer)
├── ScoreLabel (Label)
└── HealthBar (ProgressBar)
Main (Node2D)
├── TileMapLayer (level geometry)
├── Player (CharacterBody2D + Camera2D child)
├── Enemies (Node2D)
├── Collectibles (Node2D)
└── UI (CanvasLayer)
Menu (Control)
├── PanelContainer
│ └── VBoxContainer
│ ├── Title (Label)
│ ├── PlayBtn (Button)
│ ├── SettingsBtn (Button)
│ └── QuitBtn (Button)
└── AnimationPlayer (for transitions)