Collision
Part of Nodes — overlap checks for map-placed instances and node types.
Helpers test whether colliders overlap this frame (not a one-frame “contact began” event). Method form (self:hasCollided(...), …) passes the calling node as the first argument. Signatures and examples for each function are under Functions below. Map loading and checkpoints: Maps.
What you can pass
Arguments are not interchangeable even when names look similar:
| Kind | Example | Means |
|---|---|---|
| Instance | redDoor from spawn(Door, …) | One specific node in the world |
| Type path | "entities/Spike.lua" | Any active instance of that type |
| Tag | tag.wall (Game Settings → Tags) | Any type that carries that tag |
Prefer tags for roles (solid, hazard, edge). Use a type path for one exact class. Use an instance when you already hold that object. Legacy "#tag" strings are migrated on import; use tag.<name>.
Named colliders
Types can define several shapes in the spatial editor, each with an id (body, feet, proximity, …). Pass that id to scope a check (e.g. self:hasCollided("feet", tag.wall)). Unscoped calls use any of your colliders.
Visibility and collision flags
These are the same flags you set on map placements (and can change at runtime):
visible— drawing only; the node can still collide when enabled.enabled— when off, the node does not update and does not take part in collision.enableCollisions— default on; when off, skipped by collision checks (and the collider overlay) even if the node is enabled and visible. At runtime:self:collidersEnabled(false).
Which helper to use
hasCollided— “Am I overlapping X right now?” (true or false)getCollidedEntities— “Who am I overlapping?” (a list to loop over or react to)getCollidedPairs— “Which of my colliders hit what?” (named shapes such as feet vs body)
Signatures and examples for each are under Functions below.
hasCollided
Test overlap this frame between instances, types, or tags. Optional collider ids scope the check to named shapes from the spatial editor.
- hasCollided(a, b) -> bool
- hasCollided(self, selfColliderId, other) -> bool
- hasCollided(self, selfColliderId, other, otherColliderId) -> bool
- hasCollided(self, other, otherColliderId) -> bool
Parameters
- a — First thing to check (instance, type, or tag).
- b — Second thing to check (instance, type, or tag).
- self — This node instance.
- otherColliderId — Optional collider id on the other instance (e.g. `"hitbox"`). Omit to match any of theirs.
- selfColliderId — Collider id on `self` (e.g. `"feet"` or `"hurtbox"`).
Returns
- bool
Examples
-- Tag: true when the player overlaps anything tagged wall.
local hitWall = hasCollided(player, tag.wall)
-- Instance: one specific door (Door is the class; redDoor is the live object).
local redDoor = spawn(Door, 64, 32)
if player:hasCollided(redDoor) then end
-- Type path: player vs any Spike of that type.
if hasCollided(player, "entities/Spike.lua") then end
-- Only the feet sensor vs walls.
if player:hasCollided("feet", tag.wall) then
player.onGround = true
end
-- Named hurtbox vs one enemy instance's hitbox.
local enemy = spawn(Enemy, 80, 40)
if player:hasCollided("hurtbox", enemy, "hitbox") then
player:takeDamage()
endgetCollidedEntities
List who overlaps this instance this frame. Pass a collider id to only count overlaps from that shape.
- getCollidedEntities(self) -> table
- getCollidedEntities(self, colliderId) -> table
Parameters
- self — This node instance.
- colliderId — Collider id from the node spatial editor (e.g. `"feet"`).
Returns
- table
Examples
-- Every map node currently touching the player.
local hits = getCollidedEntities(player)
-- Only overlaps with the proximity collider on the player.
local nearby = player:getCollidedEntities("proximity")
-- Works for scripted nodes and no-script map handles (isType / destroy on both).
for _, other in ipairs(hits) do
if other:isType("entities/Coin.lua") then
other:destroy()
end
endgetCollidedPairs
List which of your colliders hit which other nodes (and which of their colliders). Optional id scopes to one of your shapes.
- getCollidedPairs(self) -> table
- getCollidedPairs(self, colliderId) -> table
Parameters
- self — This node instance.
- colliderId — Collider id from the node spatial editor (e.g. `"feet"`).
Returns
- table
Examples
-- Which of my colliders hit what this frame.
for _, hit in ipairs(player:getCollidedPairs()) do
if hit.selfCollider == "feet" then
player.onGround = true
elseif hit.selfCollider == "proximity" then
player:alert(hit.other)
end
endcollidersEnabled
Enable or disable this instance’s colliders for `hasCollided*` and the collider debug overlay, without changing `enable` or `visible`. Prefer `self:collidersEnabled(false)`. Returns true when the change was applied (the instance must be map- or script-spawned and have colliders).
- collidersEnabled(self, enabled) -> bool
Parameters
- self — This node instance.
- enableCollisions — If false, collisions ignore this node.
Returns
- bool
Examples
-- Stop this node colliding, without hiding it.
collidersEnabled(self, false)