Skip to content

Physics (2D) ​

This page is the physics lookup: body types, collider shapes, joints, soft body, and authoring tools. For a how-to, start with Physics and collisions. Native classes are RigidBody2D, Collider2D, Joint2D, and SoftBody2D.

Opal uses Rapier 2D for rigid-body simulation and an integrated particle-and-spring model for deformable bodies. Physics runs during Play (and editor preview when enabled), driven by built-in components:

ComponentIDRole
Rigid Body 2DrigidBody2dMass, velocity, gravity, body type
Collider 2Dcollider2dCollision shape, friction, bounce, sensors
Joint 2Djoint2dHinge / weld / distance between two bodies
Soft Body 2DsoftBody2dDeformable jelly / cloth with particle collisions and a textured mesh
Fluid 2Dfluid2dExperimental particle liquid, material, budget, and surface rendering
Fluid Emitter 2DfluidEmitter2dPour or burst particles into a shared fluid domain
Fluid Drain 2DfluidDrain2dRemove a domain's particles crossing a rectangle
Fluid Probe 2DfluidProbe2dObserve point occupancy and flow; emit water contact events

Quick setup ​

Dynamic object (ball, crate, character) ​

  1. Attach Rigid Body 2D — set Body Type to Dynamic.
  2. Attach Collider 2D — shape matches the sprite (Use Object Size is usually on).
  3. Hit Play. Gravity pulls the object down; collisions fire flow events.

A rigid body without a collider simulates motion but never collides. The inspector shows a warning when this pairing is missing.

Static floor / wall ​

  1. Attach Collider 2D only.
  2. Opal creates an implicit fixed rigid body automatically.

No Rigid Body 2D is required for immovable geometry.

Deformable jelly or cloth ​

  1. Select a sprite or shape and add Physics → Soft Body 2D.
  2. Choose Jelly, Cushion, Flag, or Curtain in its inspector. Each preset is one undoable edit.
  3. Resize the object to set its rest mesh dimensions. The selected mesh shows spring edges and pinned particles.
  4. Place a floor with Collider 2D, then press Play. Sprite pixels deform with the mesh; untextured objects use Fill Color.
  5. Tune Stretch Resistance, Bend Resistance, Spring Damping, and Area Preservation. Watch Deformation, Speed, and Contacts to distinguish overall motion from shape change.

Soft Body 2D supplies its own simulated particles and colliders. While it is enabled, a Rigid Body 2D or Collider 2D on the same object is unused. Skeletons, character controllers, and tile maps require separate objects. Joint 2D does not attach directly to soft-body particles; use the pinning presets or custom mesh pins. Moving or rotating the object or its parent moves its mesh and anchors while retaining deformation.

Jelly uses stretch, shear, bend, and signed-area resistance. Cloth uses a rectangular lattice or a conformed sprite mesh with stretch/bend resistance and no area restoration. Pins hold selected particles in the authored anchor frame. Without pins, the object's transform follows its particle centroid. A box and an ellipse are available for jelly; ellipse UVs naturally clip a rectangular sprite to the ellipse rather than squeeze its corners.

Auto Conform traces the current sprite frame into a concave rest mesh. Preview Detail (3–12, up to 144 particles), Padding (px), and Alpha threshold, then Apply Fit. Detail sets the starting particle budget; Auto Conform increases it when the outline needs more particles and reserves room for interior particles. It fills the body with a regular quad grid, sized in object-local pixels, and uses triangles around irregular contours. At the 144-particle limit it simplifies small contour details and reports the adjustment in the preview. Rounded contours use evenly spaced boundary particles, with clearance to interior samples to avoid needle triangles. Sharp authored features are retained when resampling would cut them off. Each quad has balanced shear constraints across both diagonals; rendering splits it into two triangles, while the mesh guides show the cell perimeter. Existing saved meshes retain their vertices: choose Refit from Sprite to regenerate their layout. This automatic simplification applies only to tracing artwork; manual mesh edits retain their exact outline. Cancel leaves the object untouched. Cropped frames and sprite flips are respected. One connected silhouette is supported; holes and disconnected pieces produce an explanation instead of a filled hull. Tracing samples the frame at up to 96 pixels on its longest side, so preview fine details before applying.

Edit Mesh opens an isolated draft. Drag outline points, select them for numeric X/Y edits, or use arrow keys (Shift moves ten pixels). Switch to Pins to click particles or select a particle and toggle its anchor. Existing preset anchors are shown. Reshaping rebuilds triangles and clears custom pins; finish shaping before pinning. Apply Mesh records one undo step. Changing the Pinning preset replaces custom pins; Refit from Sprite replaces all outline edits and custom pins. The rest mesh saves with the scene and exports with the game; it does not retrace artwork during playback.

Rows and columns count particles, from 3 through 12 per axis (up to 144 per object). More detail adds solver work. The defaults use 49 particles. Collision Radius is in local pixels; zero chooses a radius from particle spacing. Collisions are sampled by particles, so small objects can pass through mesh gaps. Internal particle self-collision, tearing, and normal-map sprite lighting are not supported. Use the separate Fluid 2D component for liquid; soft bodies do not participate in fluid pressure coupling. Distinct soft bodies collide with one another and with rigid bodies. Start with modest resolution and the automatic radius, and test fast/thin obstacles in your own scene.

Conformed jelly adds local compression and boundary-bend guards so preserving total area does not allow individual cells to fold into sharp pinches. Area Preservation controls the cell-collapse guard; Bend Resistance controls changes in boundary curvature. Cloth remains free to fold. While conformed jelly is active, each fixed tick uses four internal collision steps; ordinary scenes keep the usual single solve. Interpolation and authored kinematic motion still span the full fixed tick. Refit an existing mesh to gain the improved contour spacing.

Spring Damping is a damping ratio; 1 critically damps an isolated spring. Air Resistance damps overall velocity. Total Mass is shared across movable particles. Material edits retain current particle poses and velocities; changing resolution, rest shape, pinning, size, or collision radius rebuilds the rest mesh. Reset Shape restores the session's creation pose and initial velocities. Runtime poses and live outputs are never serialized into the component's authored settings.

In Object Flow, use Apply Impulse, Set Velocity, Reset Shape, or Set Enabled on Soft Body 2D. An impulse is distributed over movable particles, so the same impulse produces a smaller velocity change on a heavier body. Collision Start/End count a transition once per other object, even when several particle pairs overlap; Contacts counts objects, not particles. Show Mesh in Play also exports, making it useful for debugging a standalone build.

The soft-body solver runs once per fixed physics tick and renders interpolated particle positions. This keeps a fixed input-free experiment consistent at different render cadences; it does not establish deterministic replay for all Flow/scripts/input in an entire game.


Experimental liquid ​

Open Help → Fluid Playground… to import a new example scene into the current project. It includes a tank, floating crate, sinking weight, nozzle, and moving gate. The scene's Play controls open the gate, add a burst, and reset the tank. Importing preserves the original scene; normal scene naming and saving apply.

Authoring a tank ​

  1. Build walls from solid Collider 2D objects or solid Shape 2D objects.
  2. Choose Water Fill from the hierarchy create menu, or add Fluid 2D to an object inside the tank. Its rectangle defines the starting fill, including rotation and scale. It does not contain the water.
  3. Add Fluid Emitter 2D to a nozzle and choose the Fluid 2D object in Fluid Domain. Emitters feeding the same domain share one simulation. Disable Fill on Start for an initially empty tank.
  4. Add Rigid Body 2D and Collider 2D to loose props. With fluid density 1, start a floating crate at collider density 0.35; a weight at 1.6 sinks. Shape, added mass, and constraints also affect the result.
  5. Optionally add Fluid Drain 2D, select the same domain, and size its rectangle over an outlet. A sensor is unnecessary.

The hierarchy create menu also offers Empty Fluid Domain, Fluid Emitter, Fluid Drain, and Fluid Probe. New emitters, drains and probes link to the selected fluid domain, or to the only domain in the scene. With multiple domains and none selected, choose Fluid Domain explicitly.

Flow exposes Emit Burst, Set Emitting, Set Draining, Clear Liquid, and Reset Liquid through the components. Reset Liquid refills the domain; it does not reset separate props or mechanisms. The bundled example explicitly resets those objects too.

Controls and diagnostics ​

ControlMeaning
Particle SpacingInitial sample separation in world pixels; smaller spacing increases work. Changing it resets the live domain.
Particle BudgetMaximum live samples, from 32 to 8,000; emission pauses when full. This is a limit, not a performance guarantee. Changing the budget preserves existing samples up to the new limit.
DensityMass per square pixel, matching collider density; particle mass is density × spacing².
Maximum IterationsUpper limit on compression correction passes per microstep.
Compression TargetEarly-exit target for positive density error; default 0.000001 preserves strict coupling. Raising it permits more compression and can destabilize light props. The iteration ceiling can be reached before this target.
Velocity SmoothingNumerical damping of relative velocity, from 0 to 0.2; not calibrated viscosity or surface tension.
Swirl PreservationOptional 0–1 restoration of a share of rotational energy lost to smoothing. Default 0. Requires nonzero Velocity Smoothing; not surface tension.
Smooth SurfaceReconstructs a shaded, translucent surface from live particles. Color and opacity are presentation only.
Foam IntensityWhitens exposed water where neighboring particles move differently (impacts, shear, breakup); water translating together stays clear however fast it moves. 0 disables this visual detail. It does not create physical bubbles or additional particles.
Highlight IntensityAdjusts the soft rim light on the surface; 0 removes that highlight without changing the liquid.
Debug Particles / Show VelocityInspect discrete samples and their current velocity directions.
Compression ErrorMean positive relative density error; excludes free-surface deficits. It does not measure geometric area drift.
Peak Compression / Iterations UsedMaximum positive density error and correction count from the latest microstep.
Fluid CPU (ms)Fluid work across the latest fixed tick, including emit/solve/coupling/drain. Excludes Rapier's own solve, sync, publication and rendering.
Emitted / Drained per SecondActual accepted/removed counts divided by the latest fixed tick duration; these tick rates may fluctuate.
Blocked This Tick / Budget RejectionsBirths rejected by occupied liquid/solid geometry or by capacity. No rejected-birth backlog.
Surface CPU (ms)CPU surface work including Canvas reconstruction/draw or WebGL command submission; excludes asynchronous GPU completion.

Emitter Particles / Second schedules births within each microstep, including fractional carry. A newborn moves only for the time since its birth and its launch path is checked against solids. Its pressure coupling begins on the following microstep (at most 1/240s later at the normal clock). Nozzles moving with a rotating parent follow the parent's center-of-mass trajectory. Drains sweep relative particle/drain motion after every committed microstep, including rotation; they do not rely on end-point overlap alone.

The initial fill is capped by the budget and skips solid interiors. Blocked or occupied nozzle slots are refused; missed emission is not accumulated into a later burst. Different fluid domains do not interact.

Gameplay water queries ​

Add Fluid Probe 2D to a character, prop, or marker and choose its domain. Its center plus the local offset samples the latest committed simulation. In Water, Point Coverage, Water X/Y Speed, and Relative Speed are read-only outputs for Flow and scripts. This is a point observation, not an exact submerged volume, depth, force, or swept contact detector. Use multiple probes for separated points on a large object.

Entered Water and Exited Water fire once per transition. The default enter/exit thresholds (0.4/0.25) reduce flicker at the surface. Splash additionally fires on an observed entry above the configured relative speed; a probe initially inside water does not splash. These are gameplay events, not automatic sound or foam effects. They carry a FluidContact snapshot with domain ID, world point, occupancy, flow and relative speed. Removal, disabling and Play/Stop clear live state.

The typed scripting API uses the same runtime. Assign the water object to the script's public water field in the Inspector:

csharp
class WaterReader : Component {
    public Entity water;
    void FixedUpdate(float dt) {
        if (water == null) return;
        Fluid2D domain = water.GetComponent<Fluid2D>();
        if (domain == null) return;
        Vector2 samplePosition = Transform.WorldPosition;
        RigidBody2D body = GetComponent<RigidBody2D>();
        if (body != null) samplePosition = body.SimulationPosition;
        FluidSample sample = domain.SamplePoint(samplePosition);
        if (sample.Present) Debug.Log(sample.VelocityY);
    }
}

SamplePoint expects a world position. Transform.WorldPosition follows the visual pose; RigidBody2D.SimulationPosition reads the latest committed physics pose for a body, which is useful in FixedUpdate. SamplePoint returns a detached FluidSample. A valid component with no live liquid, or a point outside its water, returns zero coverage and velocity. Normal scripting reference rules still apply: check missing objects/components, and reacquire references after their owning scene or session ends; stale handles are rejected before the query runs. Present uses coverage ≥0.4; probe hysteresis has separately editable thresholds. Positive Y velocity points down. See Fluid2D, FluidProbe2D, and FluidContact for complete methods, properties and event signatures. Fluid2D.Clear/Reset, FluidEmitter2D.EmitBurst/SetEmitting and FluidDrain2D.SetDraining use the same commands as Flow.

Surface rendering ​

The surface is reconstructed from the particles with bounded anisotropic kernels (after Yu & Turk): each particle's contribution is an area-preserving ellipse fitted to its neighbors, so streams and flat surfaces join into continuous shapes instead of rows of round beads, while interior water and isolated droplets stay round. Render positions are lightly smoothed (at most 0.35 spacing) without moving the simulated particles, and stretching is capped at 3:1 so genuine gaps stay open. Shading uses local density and gradient in stable, sparse tiles; a disconnected droplet cannot change an unchanged pool's color or sample spacing. Whitewater appears only on exposed surface where neighboring velocities disagree, fades as the water settles, and can be tuned or disabled with Foam Intensity. The reconstruction does not know about solid walls: water on both sides of a wall thinner than about two particle spacings can visually join through it. Highlight Intensity controls the existing soft rim light. Both controls change appearance without adding simulation particles or forces. WebGL2 uses a native scalar-field atlas when floating-point render targets and blending are available; allocation or capability failures use Canvas reconstruction. Both paths preserve clips, opacity and render-target ordering. GPU support is not a speed guarantee: small pools can be cheaper as CPU bitmaps, and total cost includes physics. This visual whitewater is not persistent physical foam; there is no refraction or simulated surface tension in this release.

Runtime contract and limits ​

The reference solver is Position Based Fluids (PBF) with a normalized 2D cubic kernel reaching 2.5 particle spacings, spatial hashing, sampled solid boundary volumes, contact projection, and velocity smoothing. Rapier remains the sole rigid-body world. Fluid pressure and contact corrections produce reaction impulses at boundary points, including torque; no extra generic buoyancy force is layered on top.

Fluid and rigid bodies share four microsteps per fixed tick while liquid is active. Boundaries come from committed Rapier poses, with moving-wall prediction and velocity at each sample. Reaction impulses are applied before the corresponding Rapier microstep. This is explicit staggered coupling, not a joint implicit solve. Neighbor candidates use a conservative displacement bound and are rebuilt when necessary; density kernels and gradients always use current positions. Each pressure iteration limits how far water may move, separately for each connected body of interacting particles, so one crushed splash cannot stall the rest of the pool. Optional Swirl Preservation adapts PBF vorticity confinement with an energy ceiling tied to smoothing loss and zero added net fluid impulse. Rendering interpolates particle positions and never advances simulation.

Contact correction shares movement between water and movable props using their inverse mass and rotational inertia, respecting locked axes. A shared predicted body pose lets subsequent contacts see earlier corrections, including on compound colliders. Moving boundary samples invalidate cached neighbors. This avoids treating a light prop as an immovable wall and then launching it with the accumulated reaction. Pressure remains an approximate sampled-boundary solve; this is not a fully implicit fluid–rigid solver.

Supported boundaries include boxes, circles, capsules, convex polygons, solid Shapes, and merged tilemap rectangles. Sensors are pass-through. Deforming soft bodies, skeleton bone boundaries, multiplayer particle replication, physical surface tension/adhesion, and interaction between separate domains are not implemented. Fast obstacles, extreme mass ratios, thin gaps, and large budgets still need scene-specific testing. Use separate convex pieces for concave containers. A sinking body can settle on a trapped particle layer above the floor; particle spacing limits the size of gaps this model resolves.

Live particles and diagnostics are transient. Scene, prefab, project, IndexedDB, server, and folder saves retain authored component settings and domain references. Play/Stop creates and disposes the live system; exported players use the same runtime and rendering path.

Decision — accepted experimental baseline, 22 September 2026: under the user's delegated implementation authority, the product director selected PBF to deliver the first playable authoring/export milestone. IPBF and DFSPH remain unimplemented comparison candidates; no production solver winner has been established. The paper references, Salva integration findings, and reproducible benchmark scope are in tools/physics/README.md. Revisit the solver when equal-quality browser measurements justify a replacement. No persistence migration is needed: these are new built-in component fields.

Body types ​

Authoring tools ​

Select an object with Collider 2D, then click Edit Shape or press C in Arrange. Handles remain a consistent screen size as you zoom, with live local-pixel dimensions below the shape. Solid outlines mark blocking surfaces; dashed outlines mark sensors.

  • Box: drag an edge or corner. The opposite edge stays fixed; Shift resizes around the center (corners also preserve proportions).
  • Circle: drag the radius handle; drag the center crosshair to move the collider independently of the artwork.
  • Capsule: drag either tip to set full height, or the side handle to change radius. Shift moves both tips symmetrically. Rounded caps are included in the displayed height.
  • Polygon: drag square vertices, drag a diamond to insert a vertex on that edge, or Alt-click a vertex to remove it. Polygons must remain convex with at least three vertices. The center crosshair moves all vertices together.

Use the standard Shape dropdown and size fields to configure geometry. Only relevant size controls appear for the selected shape. The optional Tools menu contains Center, which aligns the collider with the object origin, and Match Object, which resets its geometry to the object dimensions.

Tools → Auto Fit… previews a fit to the displayed sprite frame. Choose a shape, adjust Detail for polygons, Padding (px), and Alpha threshold, then apply once. The preview respects frame cropping, flips, and object aspect ratio. Cancel makes no changes. Polygon colliders remain convex, so the preview warns about bridged inward curves, holes, or separate pieces. Missing or unreadable artwork blocks fitting rather than generating an unrelated box.

Each completed drag is one undo step. Escape cancels the current drag and leaves collider editing. Changing selection during a drag restores the original collider. Resizing an object-sized collider switches it to explicit dimensions; changing its offset does not.

Edit friction, bounce, density, and sensor mode through Collider 2D's standard Material fields. The collapsed Motion presets disclosure on Rigid Body 2D offers optional starting configurations. Each preset is one undoable edit; numeric properties remain editable.

Rigid-body labels and velocity guides are off by default. Enable Settings → Editor → Show rigid body details in the viewport to inspect the selected body's type, constraints, continuous-collision setting, launch velocity, and spin. The choice persists as an editor preference. Arrow lengths are bounded guides rather than trajectory predictions; these diagnostics do not appear in Play or exported games.

TypeBehavior
dynamicSimulated by Rapier. Transform is written back each frame.
fixedImmovable. Thing transform drives the physics body (editor drag, motion, etc.).
kinematicPositionMoved by setting the Thing position; pushes dynamic bodies.
kinematicVelocityMoved by velocity; useful for moving platforms.

Coordinates & gravity ​

  • Scene positions use screen-style coordinates: +Y is down, same as the stage.
  • Default gravity is (0, 980) — tuned for pixel-scale scenes with lengthUnit: 100.
  • Collider sizes follow object width/height (and scale) when Use Object Size is enabled.

Collision events ​

Both components expose:

EventWhen
collisionStartContact begins
collisionEndContact ends

Payload: otherId, otherName, started, sensor.

Wire these in Object Flow like any other component event. If both Rigid Body 2D and Collider 2D are attached, each may emit for the same contact — prefer listening on Collider 2D unless you need body-specific logic.

Read-only fields update during play:

  • Rigid Body 2D: vx, vy, speed, sleeping
  • Collider 2D: colliding, contactCount

Common actions ​

Rigid Body 2D

ActionUse
setVelocityLaunch or steer (x, y)
applyImpulseInstant kick
teleportSnap position and sync the physics body
setBodyTypeSwitch dynamic / fixed / kinematic at runtime
pinToWeld to another body (arrow sticking). Params: targetId, atContactPoint, breakForce (max anchor separation in px; 0 = unbreakable). Fires pinBroke when the weld snaps.
wake / sleepControl sleep state

Collider 2D

ActionUse
setSensorPass-through trigger (no physical response)
setEnabledToggle participation in simulation
generateAutoColliderFit collider from sprite alpha (polygon, box, circle, tight)

Joints (Joint 2D) ​

Connect two physics bodies with a hinge, weld, or rope/spring. Attach Joint 2D on one object and set Target to the other. Both objects need Rigid Body 2D (and usually Collider 2D).

TypeBehavior
revoluteHinge. Limits are authored in degrees; motors use rad/s.
fixedWeld (no relative motion). Used by pinTo for arrow sticking.
distanceRope (stiffness 0) or spring (stiffness > 0). Rest Length 0 captures the current anchor separation when the joint is created.

Anchors are body-local pixels (0,0 = center). Drag the cyan handles on the stage when a Joint 2D object is selected. Break Separation (field breakForce) is max anchor separation in px before the joint snaps — not a force (Rapier JS does not expose joint impulses). Authored joints fire joint2d/broke; pinTo welds fire rigidBody2d/pinBroke.

Multi-object ragdoll ​

Place the Ragdoll Humanoid prefab (Library → Prefabs): six sibling parts with revolute joints. Bodies start as kinematicPosition (pose holds). Go limp with setBodyType → dynamic on every part (Tutorials → Ragdoll Switch). See bundled/scenes/demo-joints.json for a pendulum, chain, and arrow→crate pinTo example.

Archery (stick + damage) ​

The Arrow prefab (builtin_prefab_arrow) is a CCD dynamic body with baked launch velocity. Its Object Flow listens for rigidBody2d/collisionStart (target group Ragdolls), then pinTo + health.damage. Spawn with spawnBlueprint from a Fire control. Acceptance scene: bundled/scenes/demo-archery.json (one hit → go limp + death punch). Tutorials → Archery (Stick + Damage). Combat Action stays on characters with Stats/Team — not on the projectile.

Skeleton ragdoll (skinned mesh) ​

Author Physics bone flags per bone in Skeleton Studio (stored as skeleton.ragdoll). Add the Ragdoll component; call Activate (or enable Activate on Death with Health). Bone capsules spawn at the current animated pose, jointed with authored angle limits. The skinned mesh follows via inverse-FK writeback — no renderer changes. Deactivate frees bodies and leaves the limp pose frozen.


Character Controllers + Collider 2D ​

The character-controller family — Platformer Controller, Top-Down Controller, and Side-Scroller Controller — shares one movement engine. Pick the node that matches your game; only the Platformer Controller adds gravity, jumping, and foot probes.

When Collide With World is enabled on any of them, movement uses Rapier shape casts against other Collider 2D objects.

The character's probe shape is derived from its own Collider 2D (box, circle, capsule, or polygon) including offset and auto-collider geometry. Without a collider, object bounds are used as a fallback.

Recommended stack for platformers / top-down characters:

  1. A character controller (e.g. Platformer Controller) — collideWithWorld: true
  2. Collider 2D — edit with the collider tools / auto-collider
  3. Rigid Body 2D (optional) — use kinematicPosition or fixed, not dynamic

World geometry: Collider 2D on floors and walls.

Foot probes (platformer ground feel) ​

When Collide With World is on and mode is Platformer, gold foot probes control when the character is considered grounded:

FieldPurpose
Show Foot ProbesDraw probes and draggable handles on canvas
Foot SpreadHalf-width from collider center to each foot (0 = collider width)
Foot InsetPull probes inward from spread edge (0 = auto)
Left / Right Foot XExplicit offsets from collider center (set by dragging handles)
Probe DepthDownward ground-check distance
Probe LiftStart probes above the foot row
Foot Row YMove the whole foot row up/down
Ground Check ModeBoth Feet, Leading Foot When Moving, or Either Foot
Leading Foot SpeedHorizontal speed before leading-foot mode kicks in

Drag the gold handles on the selected character in Arrange to tune ledge hang, foot placement, and probe depth. During preview, active probes brighten based on movement direction.


Collider editing (Arrange workspace) ​

When an object has Collider 2D attached:

  1. A teal overlay shows the collision shape on the stage (amber dashed when Sensor is on).
  2. Use Edit Shape in the inspector (or press C) to enter collider edit mode.
  3. Drag handles to resize primitives, move the offset, or edit polygon vertices. Edge and corner drags anchor the opposite side by default; hold Shift to resize symmetrically from the collider center.
  4. Auto Collider generates a fit from sprite alpha: polygon trace, box fit, circle fit, or tight bounds.

Polygon colliders are convex only (Rapier limitation). Concave silhouettes are approximated via convex hull or box/circle fit.

Toggle Show all colliders in the Collider 2D inspector to faintly draw overlays on every physics object.


Parented objects ​

Physics uses world pose (position + rotation in scene space). Child objects with physics components simulate at their world transform.

v1 guidance: Avoid putting a dynamic rigid body on a child whose parent moves every frame (e.g. a dragged group). The sim may fight manual parent motion. Prefer:

  • Physics on root objects, or
  • Kinematic/fixed parents with dynamic children that are not parented to moving transforms.

Lifecycle ​

PhaseWhat happens
Play startpreparePhysics() loads Rapier WASM and builds bodies from scene objects
Each framestepPhysics() syncs transforms → simulates → writes dynamic bodies back
Play end / editorshutdownPhysics() disposes the world

Only custom scene objects (getCustomObjects()) participate — not built-in layout template things.


Shapes ​

ShapeNotes
boxDefault; uses width × height
circleRadius from smaller object dimension or Radius field
capsulePill shape; Capsule Height + radius
polygonConvex polygon; edit vertices in collider edit mode

Use Offset X/Y to shift the shape relative to the object pivot.


Troubleshooting ​

SymptomCheck
Object falls through floorFloor needs Collider 2D; dynamic object needs Collider 2D too
No collision eventsSensor colliders don't block; verify enabled on both components
Object doesn't moveBody type must be dynamic; check gravityScale (0 disables gravity)
Jitter when parent movesSee Parented objects above

PathRole
src/game/physics/runtime.jsSimulation loop, sync, events
src/game/physics/backends/rapier.jsRapier world wrapper
src/game/components/built-in/rigid-body-2d.jsRigid body component
src/game/components/built-in/collider-2d.jsCollider component
src/game/components/built-in/joint-2d.jsJoint component
src/game/scene-editor/joint-editor.jsAnchor drag handles
src/game/scene-editor/collider-editor.jsCanvas collider edit mode
src/game/physics/auto-collider.jsAuto-collider generation
src/game/physics/collider-overlay.jsStage overlay drawing
src/editor-play-session.jspreparePhysics when Play starts (editor)
src/app/bootstrap-runtime.js / frame loopWires play session + per-frame stepPhysics
src/player.jsStandalone player steps physics each frame

See also ​