Physics Layers
Configure collision layers, masks, and layer names for your project.
Godot's physics layer system uses bitmasks with 32 layers. Each layer has a number (1-32) and can have a human-readable name. Getting these right is critical for correct collision detection — wrong layers are one of the most common sources of "why doesn't this collide?" bugs.
Understanding the layer system
Godot physics bodies have two bitmask properties:
collision_layer: "I am on these layers" — which layers this body occupiescollision_mask: "I detect these layers" — which layers this body can interact with
Two bodies interact if body A's mask includes body B's layer (or vice versa for mutual detection). This is an AND relationship: the bits must overlap.
Example:
Player: layer=0b0001 (layer 1), mask=0b0110 (layers 2+3)
Enemy: layer=0b0010 (layer 2), mask=0b0001 (layer 1)
Wall: layer=0b0100 (layer 3), mask=0b0000 (no detection)Player detects Enemies (player mask has layer 2 set) and Walls (player mask has layer 3 set). Enemies detect Players. Walls detect nothing. Enemies do not detect Walls (enemy mask=1, wall layer=4, no overlap).
Operations
physics_set_layer_names
Get or set the display names for collision layers. Names appear in the Godot editor's layer picker.
Get all names:
{
"op": "physics_set_layer_names",
"project_path": "/home/user/my-game"
}| Parameter | Type | Required | Description |
|---|---|---|---|
layer_type | string | required | Which layer category to configure. Valid values: "2d_physics", "3d_physics", "2d_render", "3d_render", "2d_navigation", "3d_navigation", "avoidance". |
layers | object | required | Map of layer number (1-32) to human-readable name. Example: {"1": "player", "2": "enemies", "5": "projectiles"}. Layers not included are left unchanged. |
project_path | string | required | Absolute path to the Godot project directory. |
Response:
{
"layer_names": {
"1": "Player",
"2": "Enemies",
"3": "World",
"4": "Pickups",
"5": "Projectiles",
"6": "Triggers"
}
}physics_set_layers
Set collision layer and mask configuration on nodes.
{
"op": "physics_set_layers",
"project_path": "/home/user/my-game",
"scene": "scenes/player.tscn",
"node": "Player",
"layers": [1]
}| Parameter | Type | Required | Description |
|---|---|---|---|
collision_layer | number | optional default: null | Collision layer bitmask (32-bit unsigned integer). Determines which physics layers this object occupies. Omit to leave unchanged. |
collision_mask | number | optional default: null | Collision mask bitmask (32-bit unsigned integer). Determines which physics layers this object scans/detects. Omit to leave unchanged. |
node_path | string | required | Path to the node within the scene tree (e.g. "Player/CollisionShape2D"). |
project_path | string | required | Absolute path to the Godot project directory. |
scene_path | string | required | Scene file to modify (relative to project, e.g. "scenes/player.tscn"). |
Response:
{
"op": "physics_set_layers",
"node": "Enemy",
"collision_layer": 2,
"result": "ok"
}Layer number to bitmask conversion
| Layers active | Bitmask |
|---|---|
| Layer 1 | 1 |
| Layer 2 | 2 |
| Layers 1+2 | 3 |
| Layer 3 | 4 |
| Layers 1+3 | 5 |
| Layers 2+3 | 6 |
| Layers 1+2+3 | 7 |
| Layer 4 | 8 |
The formula: bitmask = sum of (2^(layer_number - 1)) for each active layer.
Director accepts both bitmask integers and layer number arrays — use whichever is clearer.
Example conversation: Fixing a detection problem
Tips
Name your layers before assigning them. Use physics_set_layer_names to set up a consistent naming scheme (Player, Enemies, World, Projectiles, Triggers). This makes layer assignments readable — "layer 2" means nothing; "Enemies" is clear.
Use the layer list format for readability. "masks": [1, 3] is clearer than "collision_mask": 5. Both work; use whichever is less error-prone.
Layers are 1-indexed in Director, but 0-indexed internally in Godot. When reading collision_layer bitmasks in Godot's GDScript, bit 0 = layer 1. Director uses 1-indexed layer numbers to avoid off-by-one confusion.
Area3D requires monitoring: true. An Area3D with correct collision layers but monitoring=false will never emit body_entered/area_entered. Check this with spatial_inspect if detection is still failing after fixing layers.