Collision System
The RODENT arena uses Godot 3D physics collision geometry to represent physical boundaries such as walls, outer enclosure boundaries, and doors.
The collision system is generated from the same arena configuration that controls the visible 3D geometry.
Collision Architecture
The primary collision structure is:
Arena configuration
│
▼
Arena3D
│
├── Visual mesh
│
└── StaticBody3D
│
└── CollisionShape3D
│
└── BoxShape3D
This keeps visible geometry and collision geometry aligned.
Static Collision Bodies
Wall-like objects use Godot StaticBody3D nodes.
A typical collision object contains:
StaticBody3D
└── CollisionShape3D
└── BoxShape3D
Static bodies are appropriate for fixed arena geometry because walls and enclosure boundaries do not move during normal simulation.
Inner Wall Collision
Enabled inner walls receive collision geometry.
A wall is defined by:
{
"id": "divider",
"rect": [48, 20, 4, 60],
"height": 20,
"material_id": "painted_steel",
"enabled": true
}
The renderer converts the wall dimensions into a box mesh and matching box collision shape.
The collision body's:
- position
- dimensions
- rotation
are derived from the same wall definition as the visual mesh.
This prevents the common problem where an object looks solid but has no corresponding physical boundary.
Disabled Walls
Walls with:
"enabled": false
are not rendered as active wall geometry and do not provide an active physical boundary.
This allows arena configurations to enable or disable structural boundaries through data rather than source-code changes.
Outer Wall Collision
Outer walls are generated when:
"use_outer_walls": true
is enabled.
The renderer creates four enclosure boundaries:
North
South
West
East
and four corner posts.
The outer wall geometry is collidable and prevents movement outside the configured arena enclosure.
Door Collision
Doors use their own StaticBody3D and BoxShape3D.
A door's collision state depends on its current state.
Door state
│
├── open
│ └── collision disabled
│
├── closed
│ └── collision enabled
│
├── locked
│ └── collision enabled
│
└── transitioning
└── collision enabled
This allows a door to act as a dynamic passage boundary while retaining the same underlying arena geometry.
Open Doors
When a door becomes open, the renderer:
- Disables the door collision shape.
- Sets the collision layer to zero.
- Sets the collision mask to zero.
- Changes the visual appearance.
- Rotates the visual door panel into its open position.
The important distinction is that the door's visual representation and physical state are changed together.
Closed Doors
A closed door keeps its collision active.
The door therefore behaves as a physical barrier between the regions connected by the wall opening.
Locked Doors
A locked door remains physically closed.
The renderer also changes the visual appearance to indicate the locked state.
The collision system therefore treats locked as physically blocking, even though it is visually distinguished from an ordinary closed door.
Transitioning Doors
A transitioning door remains collidable while its visual state indicates that it is in the process of changing.
This prevents the physical barrier from disappearing before the door reaches the open state.
Door-to-Wall Relationship
Each door references a wall through its:
"wall": "wall_id"
The referenced wall must exist.
The renderer uses this relationship when creating the wall opening.
Conceptually:
Inner wall
████████████████████████████
Door
↓
██████████ ████████████
The wall is segmented around the door instead of remaining a solid collision object through the opening.
Rotated Walls
Wall rotation requires collision geometry and door-gap calculations to use the same coordinate system.
For a rotated wall, the renderer:
- Reads the wall rotation.
- Builds the wall geometry using that rotation.
- Converts door positions into the wall's local coordinate system.
- Calculates the door opening in local coordinates.
- Generates wall segments around the opening.
- Applies the same rotation to the resulting collision bodies.
This means a wall rotated by:
"rotation_y": 45
retains a correctly aligned opening and collision boundary.
Collision and Visual Alignment
The renderer uses the same source values for the visible mesh and collision body.
For a wall:
Wall JSON
│
├── position ─────► Mesh position
│ ► Collision position
│
├── dimensions ───► Mesh size
│ ► Collision size
│
└── rotation ────► Mesh rotation
► Collision rotation
This makes the collision representation predictable from the arena definition.
Collision Regeneration
The arena renderer rebuilds generated objects when a new experiment snapshot is applied.
Generated collision objects are removed together with their corresponding visual objects.
This prevents collision shapes from an earlier arena configuration from remaining after the arena has changed.
Live Door Changes
Doors can change state during an experiment.
The renderer exposes door state updates through the arena system.
A state change updates both:
Visual door state
Physical collision state
For example:
closed
│
▼
open
│
├── visual door opens
└── collision disabled
This makes door intervention visible and physically meaningful in the arena.
Camera Collision
The camera has a separate collision mechanism.
Camera collision does not use the arena's rat-movement collision bodies as a replacement for camera logic.
Instead, the camera raycasts from its target towards its desired position.
If geometry is detected, the camera is moved towards the collision point and offset slightly from the surface.
Camera target
│
│ raycast
▼
obstacle
│
▼
collision point
│
▼
camera position
This prevents the camera from clipping through walls or other generated geometry.
Structures and Collision Scope
The renderer supports bridge and ramp structures.
These structures are primarily generated as visual geometry.
The current Arena3D bridge implementation does not create generic StaticBody3D collision geometry for the bridge base and ramps.
Therefore, documentation should distinguish:
Wall / door / enclosure collision
from:
Bridge / ramp visual geometry
The renderer should not be interpreted as providing universal collision for every visible structure.
Collision Responsibilities
The collision system is responsible for:
- creating static wall collision
- creating outer enclosure collision
- creating door collision
- disabling collision for open doors
- preserving collision for closed doors
- preserving collision for locked doors
- preserving collision during door transitions
- aligning rotated collision geometry
- aligning wall openings with door positions
- removing stale collision objects during arena rebuilds
- supporting camera obstacle detection
Related Implementation
The primary implementation is in:
src/app/arena_3d.gd
The arena panel and application layer provide the surrounding controls for displaying and updating the renderer.
The collision system is therefore integrated into the arena renderer rather than implemented as a separate physics-only subsystem.