# tecs.physics Rapier 2D as part of the world. Install the plugin, spawn an entity with a [`Transform2D`](/modules/ecs/#tecs.ecs.Transform2D), and attach a body: ```teal world:addPlugin(tecs.physics.plugin({gravity = {0.0, 980.0}})) local ground = world:spawn(tecs.Transform2D(320, 460)) tecs.physics.attach( world, ground, {["type"] = "static", halfWidth = 320, halfHeight = 20} ) local crate = world:spawn(tecs.Transform2D(320, 100)) tecs.physics.attach( world, crate, {halfWidth = 16, halfHeight = 16, friction = 0.4} ) tecs.physics.applyImpulse(world, crate, 400.0, 0.0) ``` The solver writes each body's [`Transform2D`](/modules/ecs/#tecs.ecs.Transform2D) back, so nothing else has to move the entity. `detach` takes a body out of the solve without despawning its entity. Public positions, extents, linear velocities, impulses, forces, and gravity use pixels. Angles and angular velocities use radians. Rapier solves in meters through the `pixelsPerMeter` conversion. [`Body`](/modules/physics/#tecs.physics.Body) and [`Collider`](/modules/physics/#tecs.physics.Collider) declare what the game requested. [`Motion`](/modules/physics/#tecs.physics.Motion) preserves simulation state across pauses. Engine-owned [`RigidBody`](/modules/physics/#tecs.physics.RigidBody) keeps the attachment visible to tools; ordinary game code should ignore it. A secondary collider lives on its own entity and relates back through [`ColliderOf`](/modules/physics/#tecs.physics.ColliderOf). `FixedUpdate` steps each ECS world's simulation from `physics.of`. A fixed timestep makes replay and snapshot continuation deterministic, and snapshots preserve the complete Rapier state. ## Module contents ### Types | Type | Kind | Description | | --- | --- | --- | | [`Body`](/modules/physics/#tecs.physics.Body) | record | Body declares a body's simulation behavior. | | [`BodyOptions`](/modules/physics/#tecs.physics.BodyOptions) | record | BodyOptions describes one complete body or secondary collider declaration. | | [`Collider`](/modules/physics/#tecs.physics.Collider) | record | Collider declares a body's geometry, material and collision filtering. | | [`ContactBegin`](/modules/physics/#tecs.physics.ContactBegin) | record | ContactBegin reports the start of contact between two bodies. | | [`ContactEnd`](/modules/physics/#tecs.physics.ContactEnd) | record | ContactEnd reports the end of contact between two bodies. | | [`Motion`](/modules/physics/#tecs.physics.Motion) | record | Motion preserves a body's saved velocity in pixels and radians per second. | | [`PhysicsOptions`](/modules/physics/#tecs.physics.PhysicsOptions) | record | PhysicsOptions configures a Rapier world before plugin installation. | | [`QueryOptions`](/modules/physics/#tecs.physics.QueryOptions) | record | QueryOptions filters the shapes a raycast may hit. | | [`RaycastHit`](/modules/physics/#tecs.physics.RaycastHit) | record | RaycastHit reports where a ray first met a collider. | | [`RigidBody`](/modules/physics/#tecs.physics.RigidBody) | record | A RigidBody identifies one live body in a Rapier simulation. | | [`SensorBegin`](/modules/physics/#tecs.physics.SensorBegin) | record | SensorBegin reports a body entering a sensor. | | [`SensorEnd`](/modules/physics/#tecs.physics.SensorEnd) | record | SensorEnd reports a body leaving a sensor. | ### Functions | Function | Kind | Description | | --- | --- | --- | | [`angularVelocity`](/modules/physics/#tecs.physics.angularVelocity) | Static | Reads angular velocity in radians per second. | | [`applyForce`](/modules/physics/#tecs.physics.applyForce) | Static | Applies a continuous force at the body's center and wakes it. | | [`applyForceAt`](/modules/physics/#tecs.physics.applyForceAt) | Static | Applies a continuous force at a world-space point and wakes the body. | | [`applyImpulse`](/modules/physics/#tecs.physics.applyImpulse) | Static | Pushes a body once, at its center of mass. | | [`applyImpulseAt`](/modules/physics/#tecs.physics.applyImpulseAt) | Static | Applies an impulse at a world-space point, so it spins the body as well as moving it. | | [`applyImpulseTo`](/modules/physics/#tecs.physics.applyImpulseTo) | Static | Applies a center-of-mass impulse to a RigidBody row. | | [`applyTorque`](/modules/physics/#tecs.physics.applyTorque) | Static | Applies torque and wakes the body. | | [`attach`](/modules/physics/#tecs.physics.attach) | Static | Declares a body on entity. | | [`attachCollider`](/modules/physics/#tecs.physics.attachCollider) | Static | Adds another collider to a declared body. | | [`detach`](/modules/physics/#tecs.physics.detach) | Static | Removes a body's declaration. | | [`hasBody`](/modules/physics/#tecs.physics.hasBody) | Static | Returns whether Rapier is still solving a body for entity. | | [`isAwake`](/modules/physics/#tecs.physics.isAwake) | Static | Returns whether Rapier currently considers the body awake. | | [`of`](/modules/physics/#tecs.physics.of) | Static | Returns the Rapier simulation installed in world. | | [`plugin`](/modules/physics/#tecs.physics.plugin) | Static | Installs the simulation and its sync. | | [`raycast`](/modules/physics/#tecs.physics.raycast) | Static | Casts a segment and returns its nearest collider, in pixels. | | [`setAngularVelocity`](/modules/physics/#tecs.physics.setAngularVelocity) | Static | Sets angular velocity in radians per second and wakes the body. | | [`setAwake`](/modules/physics/#tecs.physics.setAwake) | Static | Wakes or sleeps a body. | | [`setVelocity`](/modules/physics/#tecs.physics.setVelocity) | Static | Sets a body's velocity, in pixels per second, and wakes it. | | [`teleport`](/modules/physics/#tecs.physics.teleport) | Static | Teleports a body and immediately updates its Transform2D. | | [`velocity`](/modules/physics/#tecs.physics.velocity) | Static | Reads a body's velocity, live from Rapier, in pixels per second. | ### Values | Value | Type | Description | | --- | --- | --- | | [`ColliderOf`](/modules/physics/#tecs.physics.ColliderOf) | [`Component`](/modules/ecs/#tecs.ecs.Component) | Read-only. ColliderOf relates a secondary collider to its owning body. | | [`pixelsPerMeter`](/modules/physics/#tecs.physics.pixelsPerMeter) | `number` | Read-only. pixelsPerMeter reports the fixed conversion between public pixels and Rapier meters. | ## Types ### tecs.physics.Body record `Body` declares a body's simulation behavior. Read-only. `Body` names the caller-writable body component. ```teal record tecs.physics.Body is Component kind: number fixedRotation: number isBullet: number sleepEnabled: number gravityScale: number linearDamping: number angularDamping: number end ``` #### Interfaces | Interface | | --- | | [`Component`](/modules/ecs/#tecs.ecs.Component) | #### tecs.physics.Body.kind field Caller-writable. The caller sets `kind` to 0 for static, 1 for kinematic or 2 for dynamic through `getMut`. Physics applies the change during the next fixed update. ```teal tecs.physics.Body.kind: number ``` #### tecs.physics.Body.fixedRotation field Caller-writable. The caller sets `fixedRotation` to 1 to lock rotation or 0 to unlock it. Physics applies the change during the next fixed update. ```teal tecs.physics.Body.fixedRotation: number ``` #### tecs.physics.Body.isBullet field Caller-writable. The caller sets `isBullet` to 1 for continuous collision or 0 for discrete collision. Physics applies the change during the next fixed update. ```teal tecs.physics.Body.isBullet: number ``` #### tecs.physics.Body.sleepEnabled field Caller-writable. The caller sets `sleepEnabled` to 1 to permit sleeping or 0 to keep solving. Physics applies the change during the next fixed update. ```teal tecs.physics.Body.sleepEnabled: number ``` #### tecs.physics.Body.gravityScale field Caller-writable. The caller sets `gravityScale` through `getMut`. Physics applies it during the next fixed update. ```teal tecs.physics.Body.gravityScale: number ``` #### tecs.physics.Body.linearDamping field Caller-writable. The caller sets `linearDamping` through `getMut`. Physics applies it during the next fixed update. ```teal tecs.physics.Body.linearDamping: number ``` #### tecs.physics.Body.angularDamping field Caller-writable. The caller sets `angularDamping` through `getMut`. Physics applies it during the next fixed update. ```teal tecs.physics.Body.angularDamping: number ``` ### tecs.physics.BodyOptions record `BodyOptions` describes one complete body or secondary collider declaration. `attachCollider` reads only the shape, material, filter and offset fields. It ignores body-level fields because a secondary collider has no damping or gravity of its own. ```teal global record tecs.physics.BodyOptions type: string halfWidth: number halfHeight: number radius: number density: number friction: number restitution: number fixedRotation: boolean gravityScale: number linearDamping: number angularDamping: number sleepEnabled: boolean isBullet: boolean categoryBits: number maskBits: number isSensor: boolean offsetX: number offsetY: number capsuleLength: number end ``` #### tecs.physics.BodyOptions.type field Caller-writable. The caller sets `type` before `attach` reads it to `"static"`, `"kinematic"` or `"dynamic"`. It defaults to dynamic, and an unrecognized string raises. ```teal tecs.physics.BodyOptions.type: string ``` #### tecs.physics.BodyOptions.halfWidth field Caller-writable. The caller sets `halfWidth` in pixels before `attach` reads it. A 32-pixel square uses 16. It defaults to 8. ```teal tecs.physics.BodyOptions.halfWidth: number ``` #### tecs.physics.BodyOptions.halfHeight field Caller-writable. The caller sets `halfHeight` in pixels with `halfWidth`. It defaults to 8. ```teal tecs.physics.BodyOptions.halfHeight: number ``` #### tecs.physics.BodyOptions.radius field Caller-writable. The caller sets `radius` in pixels before `attach` reads it. Naming it selects a circle over box extents. A capsule requires a positive value. ```teal tecs.physics.BodyOptions.radius: number ``` #### tecs.physics.BodyOptions.density field Caller-writable. The caller sets `density` as mass per unit area before `attach` reads it. It defaults to Rapier's 1.0. Rapier treats zero mass as infinite mass. ```teal tecs.physics.BodyOptions.density: number ``` #### tecs.physics.BodyOptions.friction field Caller-writable. The caller sets `friction` before `attach` reads it. It defaults to Rapier's 0.6. A contact takes the geometric mean of the two shapes', so zero on either one is a frictionless slide however rough the other is. ```teal tecs.physics.BodyOptions.friction: number ``` #### tecs.physics.BodyOptions.restitution field Caller-writable. The caller sets `restitution` before `attach` reads it. It defaults to Rapier's 0.0. One produces a perfectly elastic bounce, and above one a body gains energy on every contact. A contact takes the larger of the two shapes', so the bouncier surface decides and a deadened one cannot damp it. ```teal tecs.physics.BodyOptions.restitution: number ``` #### tecs.physics.BodyOptions.fixedRotation field Caller-writable. The caller sets `fixedRotation` before `attach` reads it. True locks the angle; it defaults to false. ```teal tecs.physics.BodyOptions.fixedRotation: boolean ``` #### tecs.physics.BodyOptions.gravityScale field Caller-writable. The caller sets `gravityScale` before `attach` reads it. It defaults to 1. Zero floats, and negative falls upward. ```teal tecs.physics.BodyOptions.gravityScale: number ``` #### tecs.physics.BodyOptions.linearDamping field Caller-writable. The caller sets `linearDamping` before `attach` reads it. It defaults to 0 and uses Rapier's damping term. ```teal tecs.physics.BodyOptions.linearDamping: number ``` #### tecs.physics.BodyOptions.angularDamping field Caller-writable. The caller sets `angularDamping` before `attach` reads it. It defaults to 0 and uses Rapier's damping term. ```teal tecs.physics.BodyOptions.angularDamping: number ``` #### tecs.physics.BodyOptions.sleepEnabled field Caller-writable. The caller sets `sleepEnabled` before `attach` reads it. It defaults to true, and only an explicit false disables it. Rapier stops solving a sleeping body until contact or an explicit wake. ```teal tecs.physics.BodyOptions.sleepEnabled: boolean ``` #### tecs.physics.BodyOptions.isBullet field Caller-writable. The caller sets `isBullet` before `attach` reads it to enable continuous collision. It defaults to false. ```teal tecs.physics.BodyOptions.isBullet: boolean ``` #### tecs.physics.BodyOptions.categoryBits field Caller-writable. The caller sets `categoryBits` before `attach` reads it. It defaults to 1 and uses the low 32 Rapier collision-group bits. ```teal tecs.physics.BodyOptions.categoryBits: number ``` #### tecs.physics.BodyOptions.maskBits field Caller-writable. The caller sets `maskBits` before `attach` reads it. It defaults to every category. Two shapes touch only when each mask names the other category. ```teal tecs.physics.BodyOptions.maskBits: number ``` #### tecs.physics.BodyOptions.isSensor field Caller-writable. The caller sets `isSensor` before `attach` reads it. True reports overlap events without collision response. It defaults to false. ```teal tecs.physics.BodyOptions.isSensor: boolean ``` #### tecs.physics.BodyOptions.offsetX field Caller-writable. The caller sets `offsetX` in body-frame pixels before `attach` reads it, so it turns with the body. It defaults to 0. ```teal tecs.physics.BodyOptions.offsetX: number ``` #### tecs.physics.BodyOptions.offsetY field Caller-writable. The caller sets `offsetY` with `offsetX` before `attach` reads it. It defaults to 0. ```teal tecs.physics.BodyOptions.offsetY: number ``` #### tecs.physics.BodyOptions.capsuleLength field Caller-writable. The caller sets `capsuleLength` before `attach` reads it. It selects a vertical capsule and gives the distance between end centers, excluding the caps. `radius` supplies the positive cap radius. ```teal tecs.physics.BodyOptions.capsuleLength: number ``` ### tecs.physics.Collider record `Collider` declares a body's geometry, material and collision filtering. Write its fields through `getMut`; physics applies changes during the next fixed update. Read-only. `Collider` names the caller-writable collider component. ```teal record tecs.physics.Collider is Component shape: number halfWidth: number halfHeight: number radius: number length: number offsetX: number offsetY: number density: number friction: number restitution: number categoryBits: number maskBits: number isSensor: number end ``` #### Interfaces | Interface | | --- | | [`Component`](/modules/ecs/#tecs.ecs.Component) | #### tecs.physics.Collider.shape field Caller-writable. The caller sets `shape` to 0 for box, 1 for circle or 2 for capsule through `getMut`. Physics applies the change during the next fixed update. ```teal tecs.physics.Collider.shape: number ``` #### tecs.physics.Collider.halfWidth field Caller-writable. The caller sets `halfWidth` in pixels for a box. ```teal tecs.physics.Collider.halfWidth: number ``` #### tecs.physics.Collider.halfHeight field Caller-writable. The caller sets `halfHeight` in pixels for a box. ```teal tecs.physics.Collider.halfHeight: number ``` #### tecs.physics.Collider.radius field Caller-writable. The caller sets `radius` in pixels for a circle or capsule. ```teal tecs.physics.Collider.radius: number ``` #### tecs.physics.Collider.length field Caller-writable. The caller sets `length` to the pixel distance between capsule end centers. ```teal tecs.physics.Collider.length: number ``` #### tecs.physics.Collider.offsetX field Caller-writable. The caller sets `offsetX` in body-frame pixels. ```teal tecs.physics.Collider.offsetX: number ``` #### tecs.physics.Collider.offsetY field Caller-writable. The caller sets `offsetY` in body-frame pixels. ```teal tecs.physics.Collider.offsetY: number ``` #### tecs.physics.Collider.density field Caller-writable. The caller sets `density` as mass per unit area. ```teal tecs.physics.Collider.density: number ``` #### tecs.physics.Collider.friction field Caller-writable. The caller sets `friction` as Coulomb friction. ```teal tecs.physics.Collider.friction: number ``` #### tecs.physics.Collider.restitution field Caller-writable. The caller sets `restitution` for bounce. ```teal tecs.physics.Collider.restitution: number ``` #### tecs.physics.Collider.categoryBits field Caller-writable. The caller sets `categoryBits` to the shape's collision categories. ```teal tecs.physics.Collider.categoryBits: number ``` #### tecs.physics.Collider.maskBits field Caller-writable. The caller sets `maskBits` to categories this shape may contact. ```teal tecs.physics.Collider.maskBits: number ``` #### tecs.physics.Collider.isSensor field Caller-writable. The caller sets `isSensor` to 1 for overlap events without collision response, or 0 for a solid shape. ```teal tecs.physics.Collider.isSensor: number ``` ### tecs.physics.ContactBegin record `ContactBegin` reports the start of contact between two bodies. Read-only. `ContactBegin` names the contact-start event. ```teal record tecs.physics.ContactBegin is events.Event entityA: integer entityB: integer end ``` #### Interfaces | Interface | | --- | | [`events.Event`](/modules/events/#tecs.events.Event) | #### tecs.physics.ContactBegin.entityA field Read-only. Physics sets `entityA` to one contact body before emitting the event. ```teal tecs.physics.ContactBegin.entityA: integer ``` #### tecs.physics.ContactBegin.entityB field Read-only. Physics sets `entityB` to the other contact body. ```teal tecs.physics.ContactBegin.entityB: integer ``` ### tecs.physics.ContactEnd record `ContactEnd` reports the end of contact between two bodies. Read-only. `ContactEnd` names the contact-end event. ```teal record tecs.physics.ContactEnd is events.Event entityA: integer entityB: integer end ``` #### Interfaces | Interface | | --- | | [`events.Event`](/modules/events/#tecs.events.Event) | #### tecs.physics.ContactEnd.entityA field Read-only. Physics sets `entityA` to one former contact body before emitting the event. ```teal tecs.physics.ContactEnd.entityA: integer ``` #### tecs.physics.ContactEnd.entityB field Read-only. Physics sets `entityB` to the other former contact body. ```teal tecs.physics.ContactEnd.entityB: integer ``` ### tecs.physics.Motion record `Motion` preserves a body's saved velocity in pixels and radians per second. Read-only. `Motion` names the engine-updated pause and snapshot state. ```teal record tecs.physics.Motion is Component vx: number vy: number omega: number end ``` #### Interfaces | Interface | | --- | | [`Component`](/modules/ecs/#tecs.ecs.Component) | #### tecs.physics.Motion.vx field Read-only. Physics stores horizontal velocity in pixels per second during pause, snapshot and restore operations. Use `velocity` for live state. ```teal tecs.physics.Motion.vx: number ``` #### tecs.physics.Motion.vy field Read-only. Physics stores vertical velocity in pixels per second with `vx`. ```teal tecs.physics.Motion.vy: number ``` #### tecs.physics.Motion.omega field Read-only. Physics stores angular velocity in radians per second with `vx`. ```teal tecs.physics.Motion.omega: number ``` ### tecs.physics.PhysicsOptions record `PhysicsOptions` configures a Rapier world before plugin installation. ```teal global record tecs.physics.PhysicsOptions gravity: {number} subStepCount: integer workerCount: integer end ``` #### tecs.physics.PhysicsOptions.gravity field Caller-writable. The caller sets `gravity` before the plugin reads it. It contains x then y in pixels per second squared and defaults to 980 downward. ```teal tecs.physics.PhysicsOptions.gravity: {number} ``` #### tecs.physics.PhysicsOptions.subStepCount field Caller-writable. The caller sets `subStepCount` before plugin installation. It defaults to Rapier's 4. ```teal tecs.physics.PhysicsOptions.subStepCount: integer ``` #### tecs.physics.PhysicsOptions.workerCount field Caller-writable. The caller sets `workerCount` before the first physics world initializes the process-wide Rapier pool. Later worlds must use the same value. ```teal tecs.physics.PhysicsOptions.workerCount: integer ``` ### tecs.physics.QueryOptions record `QueryOptions` filters the shapes a raycast may hit. ```teal global record tecs.physics.QueryOptions categoryBits: number maskBits: number end ``` #### tecs.physics.QueryOptions.categoryBits field Caller-writable. The caller sets `categoryBits` before `raycast` reads it. It defaults to all categories. The ray skips a shape whose mask excludes every ray category. ```teal tecs.physics.QueryOptions.categoryBits: number ``` #### tecs.physics.QueryOptions.maskBits field Caller-writable. The caller sets `maskBits` before `raycast` reads it. It defaults to all categories. ```teal tecs.physics.QueryOptions.maskBits: number ``` ### tecs.physics.RaycastHit record `RaycastHit` reports where a ray first met a collider. ```teal global record tecs.physics.RaycastHit entity: integer x: number y: number normalX: number normalY: number fraction: number end ``` #### tecs.physics.RaycastHit.entity field Read-only. `raycast` sets `entity` to the shape owner. A secondary collider reports its own entity rather than its body's. ```teal tecs.physics.RaycastHit.entity: integer ``` #### tecs.physics.RaycastHit.x field Read-only. `raycast` sets `x` to the contact point in world pixels. ```teal tecs.physics.RaycastHit.x: number ``` #### tecs.physics.RaycastHit.y field Read-only. `raycast` sets `y` with `x`, positive downward. ```teal tecs.physics.RaycastHit.y: number ``` #### tecs.physics.RaycastHit.normalX field Read-only. `raycast` sets `normalX` to the outward unit normal. It does not scale this value to pixels. ```teal tecs.physics.RaycastHit.normalX: number ``` #### tecs.physics.RaycastHit.normalY field Read-only. `raycast` sets `normalY` with `normalX`. ```teal tecs.physics.RaycastHit.normalY: number ``` #### tecs.physics.RaycastHit.fraction field Read-only. `raycast` sets `fraction` from 0 at the segment start to 1 at the segment end. ```teal tecs.physics.RaycastHit.fraction: number ``` ### tecs.physics.RigidBody record A `RigidBody` identifies one live body in a Rapier simulation. Engine-owned and transient. Ordinary game code should use [`Body`](/modules/physics/#tecs.physics.Body), [`Motion`](/modules/physics/#tecs.physics.Motion), and the functions on `tecs.physics`. Engine-owned. `RigidBody` exposes live attachment state for tools. Ordinary game code ignores it. ```teal record tecs.physics.RigidBody is Component index1: number world0: number generation: number end ``` #### Interfaces | Interface | | --- | | [`Component`](/modules/ecs/#tecs.ecs.Component) | #### tecs.physics.RigidBody.index1 field Engine-owned. Identifies the body slot; ordinary game code should ignore it. ```teal tecs.physics.RigidBody.index1: number ``` #### tecs.physics.RigidBody.world0 field Engine-owned. Identifies the simulation; ordinary game code should ignore it. ```teal tecs.physics.RigidBody.world0: number ``` #### tecs.physics.RigidBody.generation field Engine-owned. Rejects stale body slots; ordinary game code should ignore it. ```teal tecs.physics.RigidBody.generation: number ``` ### tecs.physics.SensorBegin record `SensorBegin` reports a body entering a sensor. Read-only. `SensorBegin` names the sensor-enter event. ```teal record tecs.physics.SensorBegin is events.Event sensor: integer visitor: integer end ``` #### Interfaces | Interface | | --- | | [`events.Event`](/modules/events/#tecs.events.Event) | #### tecs.physics.SensorBegin.sensor field Read-only. Physics sets `sensor` to the sensor entity before emitting the event. ```teal tecs.physics.SensorBegin.sensor: integer ``` #### tecs.physics.SensorBegin.visitor field Read-only. Physics sets `visitor` to the entering entity. ```teal tecs.physics.SensorBegin.visitor: integer ``` ### tecs.physics.SensorEnd record `SensorEnd` reports a body leaving a sensor. Read-only. `SensorEnd` names the sensor-exit event. ```teal record tecs.physics.SensorEnd is events.Event sensor: integer visitor: integer end ``` #### Interfaces | Interface | | --- | | [`events.Event`](/modules/events/#tecs.events.Event) | #### tecs.physics.SensorEnd.sensor field Read-only. Physics sets `sensor` to the sensor entity before emitting the event. ```teal tecs.physics.SensorEnd.sensor: integer ``` #### tecs.physics.SensorEnd.visitor field Read-only. Physics sets `visitor` to the leaving entity. ```teal tecs.physics.SensorEnd.visitor: integer ``` ## Functions ### tecs.physics.angularVelocity Static Reads angular velocity in radians per second. Radians need no conversion, so this is the same number Rapier holds, unlike the linear velocity beside it. ```teal function tecs.physics.angularVelocity( world: types.World, entity: integer ): number ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. | #### Returns | Type | Description | | --- | --- | | `number` | Returns live Rapier angular velocity in radians per second, or zero without a live body. | ### tecs.physics.applyForce Static Applies a continuous force at the body's center and wakes it. Cleared by Rapier at the end of every step, so holding a body up against gravity means calling this every fixed step rather than once. ```teal function tecs.physics.applyForce( world: types.World, entity: integer, x: number, y: number ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. A missing live body makes the call a no-op. | | `x` | `number` | The caller supplies pixel-scaled force along x. | | `y` | `number` | The caller supplies pixel-scaled force along y, positive downward. | #### Returns None. ### tecs.physics.applyForceAt Static Applies a continuous force at a world-space point and wakes the body. Cleared at the end of every step, like `applyForce`. ```teal function tecs.physics.applyForceAt( world: types.World, entity: integer, x: number, y: number, pointX: number, pointY: number ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. A missing live body makes the call a no-op. | | `x` | `number` | The caller supplies pixel-scaled force along x. | | `y` | `number` | The caller supplies pixel-scaled force along y, positive downward. | | `pointX` | `number` | The caller supplies the world-pixel application point along x. | | `pointY` | `number` | The caller supplies the world-pixel application point along y. | #### Returns None. ### tecs.physics.applyImpulse Static Pushes a body once, at its center of mass. An impulse rather than a force, so the effect does not depend on how long the step happened to be. Wakes the body: Rapier lets a resting island sleep, and pushing a sleeping body without waking it does nothing. ```teal function tecs.physics.applyImpulse( world: types.World, entity: integer, x: number, y: number ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. A missing live body makes the call a no-op. | | `x` | `number` | The caller supplies pixel-scaled impulse along x. | | `y` | `number` | The caller supplies pixel-scaled impulse along y, positive downward. | #### Returns None. ### tecs.physics.applyImpulseAt Static Applies an impulse at a world-space point, so it spins the body as well as moving it. ```teal function tecs.physics.applyImpulseAt( world: types.World, entity: integer, x: number, y: number, pointX: number, pointY: number ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. A missing live body makes the call a no-op. | | `x` | `number` | The caller supplies pixel-scaled impulse along x. | | `y` | `number` | The caller supplies pixel-scaled impulse along y, positive downward. | | `pointX` | `number` | The caller supplies the world-pixel impact position along x. | | `pointY` | `number` | The caller supplies the world-pixel impact position along y. | #### Returns None. ### tecs.physics.applyImpulseTo Static Applies a center-of-mass impulse to a [`RigidBody`](/modules/physics/#tecs.physics.RigidBody) row. ```teal function tecs.physics.applyImpulseTo( row: RigidBody, x: number, y: number ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `row` | [`RigidBody`](/modules/physics/#tecs.physics.RigidBody) | The caller supplies a row from a [`RigidBody`](/modules/physics/#tecs.physics.RigidBody) column. A stale or null row does nothing. | | `x` | `number` | The caller supplies pixel-scaled impulse along x. | | `y` | `number` | The caller supplies pixel-scaled impulse along y, positive downward. | #### Returns None. ### tecs.physics.applyTorque Static Applies torque and wakes the body. Cleared at the end of every step, like the two forces above. ```teal function tecs.physics.applyTorque( world: types.World, entity: integer, torque: number ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. A missing live body makes the call a no-op. | | `torque` | `number` | The caller supplies Newton-meters in Rapier's native torque units. Positive values raise angular velocity. | #### Returns None. ### tecs.physics.attach Static Declares a body on `entity`. Physics creates the Rapier body during the next fixed update. ```teal function tecs.physics.attach( world: types.World, entity: integer, options: BodyOptions ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies a world with `physics.plugin`; otherwise the call raises. | | `entity` | `integer` | The caller supplies the entity that gains [`Body`](/modules/physics/#tecs.physics.Body), [`Collider`](/modules/physics/#tecs.physics.Collider), [`Transform2D`](/modules/ecs/#tecs.ecs.Transform2D), and [`Motion`](/modules/physics/#tecs.physics.Motion) as needed. | | `options` | [`BodyOptions`](/modules/physics/#tecs.physics.BodyOptions) | The caller supplies the initial body and collider settings. Unknown body types and invalid capsules raise. | #### Returns None. ### tecs.physics.attachCollider Static Adds another collider to a declared body. The collider is its own entity, which makes each shape independently inspectable and mutable. ```teal function tecs.physics.attachCollider( world: types.World, entity: integer, body: integer, options: BodyOptions ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world that owns both entities. | | `entity` | `integer` | The caller supplies the secondary collider entity, which gains [`Collider`](/modules/physics/#tecs.physics.Collider) and [`ColliderOf`](/modules/physics/#tecs.physics.ColliderOf). | | `body` | `integer` | The caller supplies an entity with [`Body`](/modules/physics/#tecs.physics.Body); otherwise the call raises. | | `options` | [`BodyOptions`](/modules/physics/#tecs.physics.BodyOptions) | The caller supplies shape, material, filter and offset settings. Body-level fields have no effect. | #### Returns None. ### tecs.physics.detach Static Removes a body's declaration. Physics destroys its Rapier body during the next fixed update. ```teal function tecs.physics.detach(world: types.World, entity: integer) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the entity that loses [`Body`](/modules/physics/#tecs.physics.Body). Other physics declaration components remain. | #### Returns None. ### tecs.physics.hasBody Static Returns whether Rapier is still solving a body for `entity`. False for an entity whose RigidBody came out of a snapshot. A load restores the row as the null handle rather than a body id this run never issued, so this is how a game tells "was simulating and is not any more" from "never had a body", and the two are worth telling apart: nothing rebuilds a body on load. ```teal function tecs.physics.hasBody( world: types.World, entity: integer ): boolean ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies any entity. | #### Returns | Type | Description | | --- | --- | | `boolean` | Returns true only while Rapier holds a valid live body. It returns false before the first fixed update and after destruction. | ### tecs.physics.isAwake Static Returns whether Rapier currently considers the body awake. ```teal function tecs.physics.isAwake( world: types.World, entity: integer ): boolean ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies any entity. | #### Returns | Type | Description | | --- | --- | | `boolean` | Returns true while Rapier actively solves the body, or false when it sleeps or does not exist. | ### tecs.physics.of Static Returns the Rapier simulation installed in `world`. ```teal function tecs.physics.of(world: types.World): World ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies a world with or without the plugin. | #### Returns | Type | Description | | --- | --- | | `World` | Returns the world's live Rapier simulation, or nil before installation and after shutdown. | ### tecs.physics.plugin Static Installs the simulation and its sync. ```teal function tecs.physics.plugin(options: PhysicsOptions): function( types.World ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `options` | [`PhysicsOptions`](/modules/physics/#tecs.physics.PhysicsOptions) | The caller supplies Rapier settings or nil for Earth-like downward gravity and Rapier's default substep count. | #### Returns | Type | Description | | --- | --- | | `function(`[`types.World`](/modules/ecs/#tecs.World)`)` | Returns a plugin for `world:addPlugin`. Each world receives an independent Rapier simulation; all worlds share one worker pool. | ### tecs.physics.raycast Static Casts a segment and returns its nearest collider, in pixels. The cast tests one segment and ignores everything beyond `x2, y2`, so a miss may indicate insufficient length. ```teal function tecs.physics.raycast( world: types.World, x1: number, y1: number, x2: number, y2: number, options: QueryOptions ): RaycastHit ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies a world. A world without physics returns nil. | | `x1` | `number` | The caller supplies the segment start in world pixels along x. | | `y1` | `number` | The caller supplies the segment start in world pixels along y. | | `x2` | `number` | The caller supplies the segment end in world pixels along x. | | `y2` | `number` | The caller supplies the segment end in world pixels along y. | | `options` | [`QueryOptions`](/modules/physics/#tecs.physics.QueryOptions) | The caller supplies collision filters or nil to test every shape, including sensors. | #### Returns | Type | Description | | --- | --- | | [`RaycastHit`](/modules/physics/#tecs.physics.RaycastHit) | Returns a fresh caller-owned nearest hit, or nil on a miss. | ### tecs.physics.setAngularVelocity Static Sets angular velocity in radians per second and wakes the body. ```teal function tecs.physics.setAngularVelocity( world: types.World, entity: integer, omega: number ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. A missing live body makes the call a no-op. | | `omega` | `number` | The caller supplies angular velocity in radians per second. | #### Returns None. ### tecs.physics.setAwake Static Wakes or sleeps a body. ```teal function tecs.physics.setAwake( world: types.World, entity: integer, awake: boolean ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. A missing live body makes the call a no-op. | | `awake` | `boolean` | The caller passes true to wake the body or false to sleep it immediately. | #### Returns None. ### tecs.physics.setVelocity Static Sets a body's velocity, in pixels per second, and wakes it. Does nothing for an entity with no live body, which matches the zero value returned by `physics.velocity`. ```teal function tecs.physics.setVelocity( world: types.World, entity: integer, vx: number, vy: number ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. A missing live body makes the call a no-op. | | `vx` | `number` | The caller supplies horizontal velocity in pixels per second. | | `vy` | `number` | The caller supplies vertical velocity in pixels per second, positive downward. | #### Returns None. ### tecs.physics.teleport Static Teleports a body and immediately updates its Transform2D. A move rather than a push: velocity is left exactly as it was, so a falling body carries on falling from wherever it lands. Teleportation leaves [`PreviousTransform2D`](/modules/gfx/#tecs.gfx.PreviousTransform2D) unchanged. `FixedFirst` snapshots that column and the renderer interpolates from it, so a teleport in any phase after that is drawn as one frame of travel between the two positions rather than as a jump. Teleporting before `FixedFirst`, or accepting the one frame, are the two ways round it. ```teal function tecs.physics.teleport( world: types.World, entity: integer, x: number, y: number, angle: number ) ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. A missing live body makes the call a no-op, including [`Transform2D`](/modules/ecs/#tecs.ecs.Transform2D). | | `x` | `number` | The caller supplies the body's origin in world pixels along x. | | `y` | `number` | The caller supplies the body's origin in world pixels along y, positive downward. | | `angle` | `number` | The caller supplies radians or nil to keep the current `Transform2D.rotation`. Teleportation does not sweep the gap. | #### Returns None. ### tecs.physics.velocity Static Reads a body's velocity, live from Rapier, in pixels per second. Pixels match every other linear number this module accepts and returns: extents, radius, impulse components and plugin gravity. A caller that wants meters divides by `physics.pixelsPerMeter`. This reports what a body does now. [`Motion`](/modules/physics/#tecs.physics.Motion) stores velocity only at a pause or save; it does not mirror live motion. ```teal function tecs.physics.velocity( world: types.World, entity: integer ): number, number ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `world` | [`types.World`](/modules/ecs/#tecs.World) | The caller supplies the world holding the entity. | | `entity` | `integer` | The caller supplies the target entity. | #### Returns | Type | Description | | --- | --- | | `number` | Returns horizontal velocity in pixels per second, or zero without a live body. | | `number` | Returns vertical velocity in pixels per second, positive downward, or zero without a live body. | ## Values ### tecs.physics.ColliderOf variable Read-only. [`ColliderOf`](/modules/physics/#tecs.physics.ColliderOf) relates a secondary collider to its owning body. ```teal tecs.physics.ColliderOf: Component ``` ### tecs.physics.pixelsPerMeter variable Read-only. `pixelsPerMeter` reports the fixed conversion between public pixels and Rapier meters. ```teal tecs.physics.pixelsPerMeter: number ```