| Header | Link |
|---|---|
| Purpose | Purpose |
| Use Cases | Use Cases |
| Practical Example | Practical Example |
| Reference | Reference |
Copy-and-paste field reference for every 2D node you place in a .scn scene: sprites, cameras, lights, physics bodies, tilemaps, water, skeletons, and 2D audio geometry. Each template shows the exact block layout and field names so you can drop a node in and tune values without guessing. For node trees a script builds at runtime, use Node Collections.
- Build the look of a 2D level:
Node2D,Sprite2D,AnimatedSprite2D,Label2D,NineSlice2D,TileMap2D. - Add a camera and lighting:
Camera2D,PointLight2D,SpotLight2D,RayLight2D,AmbientLight2D. - Give things collision and physics:
StaticBody2D,RigidBody2D,CharacterBody2D, andArea2Dwith a childCollisionShape2D. - Rig and animate characters:
Skeleton2D,BoneAttachment2D,BoneCollider2D,PhysicsBoneChain2D,IKTarget2D. - Add water and audio geometry:
WaterBody2D,AudioMask2D,AudioEffectZone2D,AudioPortal2D.
Choose a template by engine behavior first: transform, render, physics, camera, or tile map. Compose child nodes when one object needs several behaviors. Put gameplay configuration in the attached script state and inject fixed node/asset references from the scene instead of rediscovering them at runtime.
A minimal playable 2D scene: a scripted player sprite plus an active camera.
[player]
parent = $root
script = "res://scripts/player.rs"
[Sprite2D]
texture = "res://textures/player.png"
[Node2D]
position = (0, 0)
[/Node2D]
[/Sprite2D]
[/player]
[camera]
parent = $root
[Camera2D]
active = true
[Node2D/]
[/Camera2D]
[/camera]
[node2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/node2d]
[skeleton2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[Skeleton2D]
skeleton = "res://path/to/rig.pskel2d"
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/Skeleton2D]
[/skeleton2d]
[boneattachment2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[BoneAttachment2D]
skeleton = @SkeletonNodeName
bone = 0
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/BoneAttachment2D]
[/boneattachment2d]
[iktarget2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[IKTarget2D]
skeleton = @SkeletonNodeName
bone = 0
chain_length = 2
iterations = 8
tolerance = 0.01
weight = 1.0
match_rotation = true
[/IKTarget2D]
[/iktarget2d]
[physicsbonechain2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[PhysicsBoneChain2D]
skeleton = @SkeletonNodeName
bone = 0
chain_length = 4
enabled = true
gravity = (0, -9.81)
damping = 0.08
stiffness = 0.35
radius = 0.05
collisions = true
iterations = 3
[/PhysicsBoneChain2D]
[/physicsbonechain2d]
[bonecollider2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[BoneCollider2D]
enabled = true
[/BoneCollider2D]
[/bonecollider2d]
[sprite2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[Sprite2D]
texture = "res://path/to/texture.png"
texture_region = (0, 0, 32, 32)
flip_x = false
flip_y = false
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/Sprite2D]
[/sprite2d]
[label2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[Label2D]
text = "World label"
# alt: text = %loc: "ui.world_label"
size = (128, 32)
color = (1, 1, 1, 1)
font_size = 20
h_align = center
v_align = center
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/Label2D]
[/label2d]
[button2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[Button2D]
size = (128, 48)
fill = "#263238"
hover_fill = "#37474F"
pressed_fill = "#102027"
input_enabled = true
# Default is "pointer"; override with any supported cursor icon.
cursor_icon = "pointer"
# Extra signals only. Default button2d_clicked still emits.
clicked_signals = ["world_button_clicked"]
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/Button2D]
[/button2d]
[image_button2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[ImageButton2D]
texture = "res://path/to/button.png"
texture_region = (0, 0, 64, 32)
size = (128, 64)
tint = (1, 1, 1, 1)
hover_tint = (1, 1, 1, 1)
pressed_tint = (0.8, 0.8, 0.8, 1)
input_enabled = true
# Default is "pointer"; override with any supported cursor icon.
cursor_icon = "pointer"
# Extra signals only. Default image_button2d_clicked still emits.
clicked_signals = ["world_image_button_clicked"]
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/ImageButton2D]
[/image_button2d]
[nine_slice2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[NineSlice2D]
texture = "res://path/to/panel.png"
texture_region = (0, 0, 64, 64)
size = (128, 48)
tint = (1, 1, 1, 1)
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/NineSlice2D]
[/nine_slice2d]
[animated_sprite2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[AnimatedSprite2D]
texture = "res://path/to/texture.png"
flip_x = false
flip_y = false
current_animation = "idle"
current_frame = 0
fps_scale = 1.0
playing = true
looping = true
animations = [
{ name = "idle", start = (0, 0), frame_size = (32, 32), frame_count = 4, fps = 8 },
{ name = "run", start = (0, 32), frame_size = (32, 32), frame_count = 6, fps = 12 },
{ name = "hurt_grid", start = (0, 64), frame_size = (32, 32), frame_count = 8, columns = 4, fps = 10 }
]
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/AnimatedSprite2D]
[/animated_sprite2d]
[camera_stream_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[CameraStream2D]
camera = @CameraNode
resolution = (512, 512)
aspect_ratio = 0.0
aspect_mode = "fit"
enabled = true
tint = (1, 1, 1, 1)
post_processing = []
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/CameraStream2D]
[/camera_stream_2d]
[sub_view_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[SubView2D]
size = (1, 1)
resolution = (512, 512)
aspect_ratio = 0.0
aspect_mode = "fit"
view_position = (0, 0, 5)
view_rotation = (0, 0, 0, 1)
projection = "perspective"
perspective_fov_y_degrees = 60
view_2d_position = (0, 0)
view_2d_rotation = 0.0
view_2d_zoom = 1.0
background = "#00000000"
tint = (1, 1, 1, 1)
enabled = true
suspend_when_hidden = true
post_processing = []
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/SubView2D]
[/sub_view_2d]
[water_body_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[WaterBody2D]
shape = { type="quad", width=32, height=32 }
quality = "low"
depth = 4.0
flow = (0, 0)
wind = (1, 0)
idle_mode = "calm"
wave_speed = 1.0
wave_scale = 1.0
damping = 0.985
buoyancy = 1.0
drag = 0.35
wake_strength = 1.35
foam_strength = 0.9
sample_readback_rate = 30
lod_near = 128
lod_mid = 384
lod_far = 896
min_resolution = 32
collision_layers = [1]
collision_mask = []
coastline = { foam_color=(0.9, 0.97, 1.0, 1.0) foam_strength=0.75 foam_width=1.5 cutoff_softness=0.25 wave_reflection=0.45 wave_damping=0.35 edge_noise=0.2 }
debug = false
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/WaterBody2D]
[/water_body_2d]
[camera2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[Camera2D]
zoom = 0.0
post_processing = []
audio_options = { audio_mask=[], effects=[] }
active = false
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/Camera2D]
[/camera2d]
[ambient_light_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[AmbientLight2D]
color = (1, 1, 1)
intensity = 0.0
cast_shadows = false
active = true
[/AmbientLight2D]
[/ambient_light_2d]
[ray_light_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[RayLight2D]
color = (1, 1, 1)
intensity = 1.0
cast_shadows = false
shadow_softness = 0.0
shadow_samples = 8
active = true
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/RayLight2D]
[/ray_light_2d]
[point_light_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[PointLight2D]
color = (1, 1, 1)
intensity = 1.0
range = 256.0
cast_shadows = false
shadow_softness = 0.0
shadow_samples = 8
active = true
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/PointLight2D]
[/point_light_2d]
[spot_light_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[SpotLight2D]
color = (1, 1, 1)
intensity = 1.0
range = 256.0
inner_angle_radians = 0.349066
outer_angle_radians = 0.523599
cast_shadows = false
shadow_softness = 0.0
shadow_samples = 8
active = true
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/SpotLight2D]
[/spot_light_2d]
[collision_shape_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[CollisionShape2D]
shape = { type = quad width = 1.0 height = 1.0 }
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/CollisionShape2D]
[/collision_shape_2d]
[static_body_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[StaticBody2D]
enabled = true
friction = 0.7
restitution = 0.0
density = 1.0
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/StaticBody2D]
[/static_body_2d]
[rigid_body_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[RigidBody2D]
enabled = true
continuous_collision_detection = true
linear_velocity = (0, 0)
angular_velocity = 0.0
gravity_scale = 1.0
linear_damping = 0.0
angular_damping = 0.0
can_sleep = true
lock_rotation = false
friction = 0.7
restitution = 0.0
density = 1.0
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/RigidBody2D]
[/rigid_body_2d]
[character_body_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[CharacterBody2D]
enabled = true
friction = 0.7
restitution = 0.0
density = 1.0
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/CharacterBody2D]
[/character_body_2d]
[area2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[Area2D]
enabled = true
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/Area2D]
[/area2d]
[audio_mask_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[AudioMask2D]
active = true
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/AudioMask2D]
[/audio_mask_2d]
[audio_effect_zone_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[AudioEffectZone2D]
active = true
audio_mask = []
effects = [
{ reverb_send = 0.35 echo = 0.0 dampening = 0.0 }
]
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/AudioEffectZone2D]
[/audio_effect_zone_2d]
[audio_portal_2d]
parent = @PARENTKEY
script = "res://path/to/script.rs"
[AudioPortal2D]
active = true
strength = 1.0
targets = [@OtherPortal]
[Node2D]
position = (0, 0)
rotation = 0.0
scale = (1, 1)
z_index = 0
visible = true
[/Node2D]
[/AudioPortal2D]
[/audio_portal_2d]
[level]
[TileMap2D]
tileset = "res://tiles/world.ptileset"
width = 8
height = 4
empty_tile = -1
tiles = [
1, 1, 1, 1, 1, 1, 1, 1,
1, -1, -1, -1, -1, -1, -1, 1,
1, -1, -1, -1, -1, -1, -1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
]
collision_enabled = true
collision_layers = [1]
collision_mask = []
[/TileMap2D]
[/level]