Collision detection in Fraxel is automatic — you declareDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/sanchedev/fraxel/llms.txt
Use this file to discover all available pages before exploring further.
<collider> nodes with shapes and groups in JSX, then subscribe to events via useEvent(). The engine runs a two-phase pipeline every frame: a spatial-hash broadphase narrows down candidate pairs, then a narrowphase performs exact shape overlap tests. For physics simulation with gravity and forces, add a <rigid-body> node alongside the collider. See the Physics guide for a full walkthrough.
shapes factory
Theshapes factory creates typed collision shape descriptors. Pass the result directly to the shape prop of a <collider> node.
shapes.rectangle(width, height)
Width of the rectangle in pixels.
Height of the rectangle in pixels.
RectangleShape:
| Property | Type | Description |
|---|---|---|
type | 'rectangle' | Discriminant — always 'rectangle' |
size | Vector2 | Width (size.x) and height (size.y) of the rectangle |
shapes.circle(radius)
Radius of the circle in pixels.
CircleShape:
| Property | Type | Description |
|---|---|---|
type | 'circle' | Discriminant — always 'circle' |
radius | number | Radius of the circle in pixels |
Shape union type
shape.type to discriminate:
Collider Groups
Every<collider> node has two group arrays that control which colliders interact:
| Prop | Type | Description |
|---|---|---|
group | string[] | The groups this collider belongs to |
collidesWith | string[] | The groups this collider reacts to |
collidesWith list matches a group in collider B’s group list. Both colliders receive the collision events — you don’t need symmetric declarations.
Collision Events
Three events are emitted on aCollider node during each frame’s collision pass. Subscribe with useEvent():
| Event | Callback signature | When it fires |
|---|---|---|
colliderEntered | (otherCollider: Collider) => void | Once — first frame two colliders begin overlapping |
collided | (otherCollider: Collider) => void | Every frame — while two colliders remain overlapping |
colliderExited | (otherCollider: Collider) => void | Once — first frame two colliders stop overlapping |
Events are dispatched on both colliders in a pair. If A enters B, both
A.colliderEntered(B) and B.colliderEntered(A) fire, provided the group filters allow it.RayCast
A<ray-cast> node projects a ray from its global position in a given direction and detects the nearest collider it intersects.
RayCast props
The ray’s direction and length as a
Vector2. The ray extends from the node’s global position to globalPosition + direction. A direction of new Vector2(0, 64) casts 64 pixels downward.Groups the ray tests against. Only colliders whose
group intersects this list are considered.RayCast methods
| Method | Returns | Description |
|---|---|---|
getCollider() | Collider | null | Returns the currently detected nearest collider, or null if nothing is hit |
RayCast events
| Event | Callback signature | When it fires |
|---|---|---|
colliderEntered | (collider: Collider) => void | First frame a new collider is hit (or the hit target changes) |
colliderExited | (collider: Collider) => void | First frame the previously hit collider is no longer detected |
Raycasts query collider groups directly (bypassing the spatial hash broadphase). This ensures raycasts work correctly even when the spatial hash hasn’t been rebuilt for a given frame. Only collider-vs-collider detection uses the spatial hash.
Narrowphase
TheNarrowphase class performs precise shape-vs-shape intersection tests. It is used internally by CollisionSystem, but is also available for manual queries.
Narrowphase.detect(a, b)
The first collider.
The second collider.
boolean — true if the two shapes overlap.
The method dispatches across all four shape combinations:
| Pair | Algorithm |
|---|---|
rectangle ↔ rectangle | AABB overlap (four boundary comparisons) |
circle ↔ circle | Sum-of-radii distance test |
rectangle ↔ circle | Closest point on AABB to circle centre |
circle ↔ rectangle | Same as above, arguments swapped |
PhysicsSystem
PhysicsSystem is a singleton that applies gravity, integrates velocity into position, and resolves physics collisions each frame. It runs automatically after CollisionSystem.update() in the game loop.
PhysicsSystem.gravity
| Property | Type | Default | Description |
|---|---|---|---|
PhysicsSystem.gravity | Vector2 | new Vector2(0, 980) | Global gravity vector applied to every non-static body that has useGravity enabled |
980 is pixels/second² — tuned to feel realistic at typical game scales. Adjust it freely to match your scene’s pixel density.
PhysicsBody
PhysicsBody is the kinematic state container attached to a <rigid-body> node. Access it via body.node.physicsBody:
Methods
applyForce(force)
Force vector in pixels/second². Accumulated into the body’s internal acceleration buffer and applied during the next physics integration step. Resets to zero after each frame — call it every frame for continuous effects like thrust or wind.
applyImpulse(impulse)
Impulse vector in pixels/second. Added directly to velocity — instant effect, no accumulation. Ideal for one-shot events like jumps, explosions, or knockback. Has no effect on static bodies (
isStatic === true).setVelocity(v)
Sets the body’s velocity directly, overriding any accumulated velocity. Use for teleport-style resets or scripted movement.
PhysicsBody properties
| Property | Type | Default | Description |
|---|---|---|---|
velocity | Vector2 | (0, 0) | Current velocity in pixels/second |
mass | number | 1 | Body mass — higher values resist forces and impulses more |
friction | number | 0.1 | Friction coefficient (0–1) applied on collision contact |
bounce | number | 0 | Restitution coefficient (0 = no bounce, 1 = perfect elastic) |
isStatic | boolean | false | If true, the body does not move and has infinite effective mass |
useGravity | boolean | true | If false, global gravity is not applied to this body |
isGrounded | boolean | false | Set by the resolver — true when the body is resting on a surface |
rigid-body JSX props
ConfigurePhysicsBody properties directly as JSX attributes on <rigid-body>:
Spatial Hash (broadphase)
TheSpatialHash divides the world into a fixed-size grid and tracks which colliders occupy each cell. It is used internally by CollisionSystem for broadphase candidate culling — you do not interact with it directly in normal game code.
The spatial hash only handles collider-vs-collider broadphase. Raycasts query
#colliderGroups directly, bypassing the hash entirely.CollisionSystem.setDirty()) and is rebuilt at the start of each frame’s collision pass.
Related guides
- Physics guide — rigid bodies, gravity, forces, and collision response
- Nodes 2D API —
<collider>,<rigid-body>, and<ray-cast>node props - Math API —
Vector2used fordirectionandapplyForce