Colliders
Shape determines collision
Every physics body needs a collider — the invisible shape that defines what collides with what. Formo generates colliders automatically from your node type, choosing the best strategy based on shape and body type.
Auto colliders
| Node type | Dynamic body | Static body |
|---|---|---|
| Rectangle | Box | Box |
| Frame | Box | Box |
| Ellipse | Circle or 8-vertex polygon | Circle or 8-vertex polygon |
| Polygon | Convex hull (max 8 verts) | Chain shape (exact boundary) |
| Star (≥7 points or small) | Convex hull (max 8 verts) | Chain shape (exact boundary) |
| Star (3-6 points, big) | Concave decomposition | Chain shape (exact boundary) |
| Vector | Convex hull (max 8 verts) | Chain shape (exact boundary) |
The PIXELS_PER_METER constant (50) converts between canvas pixels and physics meters. A 100px wide rectangle becomes a 2-meter wide box in the simulation.
Concave star colliders
Stars with 3-6 points and large enough spikes get concave decomposition on dynamic bodies. The star is split into a center polygon plus one triangle per spike — a 5-point star becomes 6 convex fixtures on one body. Objects can physically rest between the star's spikes.
Stars with 7+ points or very small spikes (arc length < 16px) use a simple convex hull instead — the gaps between spikes are too narrow for anything to fit through.
Static chain colliders
Static bodies with concave shapes (Vector, Polygon, Star) automatically use a chain shape — an exact edge loop that follows every concavity. This means a static pen-drawn wall works as a perfect collision boundary without any approximation.
Multi-collider bodies
A single node can have multiple colliders. Each collider has:
| Property | Description |
|---|---|
name | Identifier (used in collision events) |
type | Auto, Circle, Box, Capsule |
scale | Size multiplier relative to node |
offsetX | Horizontal offset from node center |
offsetY | Vertical offset from node center |
Why multiple colliders?
A character might need:
- A body collider (box) for wall collisions
- A feet collider (small box at bottom) for ground detection
- A sensor collider (larger circle) for enemy detection range
Each collider reports its name in collision events, so you can distinguish event.collider === "feet" from event.collider === "body".
title: "Multi-collider character"
description: "A node with body and feet colliders"
nodes:
- type: RECT, name: "Character", x: 200, y: 200, w: 40, h: 80, fill: "#3498DB"
- type: RECT, name: "Ground", x: 200, y: 400, w: 400, h: 30, fill: "#2C3E50"
modules:
- node: "Character", module: "physics", config: { bodyType: "dynamic", colliders: [{ name: "body", type: "Box", scale: 1 }, { name: "feet", type: "Box", scale: 0.3, offsetY: 35 }] }
- node: "Ground", module: "physics", config: { bodyType: "static" }
tools_visible: [select, play]
ui_visible: [properties, modules]Collider editor
In the properties panel, the Physics module shows a Collider Group section:
- Add/remove colliders with buttons
- Edit name inline
- Toggle type: Auto / Circle / Box / Capsule
- Adjust scale with slider
- Set offset with dial widget
- Hover a collider entry to highlight it on canvas
Scale awareness
Colliders account for node scale. If you scale a rectangle to 2x width, the box collider grows proportionally. The entryToConfig converter handles the math.
Fixture properties
Each collider becomes a Box2D fixture on the body. Fixtures carry:
- density — mass per area (shared across all fixtures)
- friction — surface roughness (0-1)
- restitution — bounciness (0-1)
Changing density/friction/restitution iterates all fixtures on the body.