Documentation
¶
Index ¶
- type ActiveContacts
- func (c ActiveContacts) FromProto(p *pbcomponent.ActiveContacts) ActiveContacts
- func (c ActiveContacts) MarshalWire() []byte
- func (ActiveContacts) Name() string
- func (c ActiveContacts) ProtoDescriptor() protoreflect.MessageDescriptor
- func (c ActiveContacts) ToProto() *pbcomponent.ActiveContacts
- func (c ActiveContacts) UnmarshalWire(data []byte) (any, error)
- type BodyType
- type ColliderShape
- type ContactPairEntry
- type PhysicsBody2D
- func (c PhysicsBody2D) FromProto(p *pbcomponent.PhysicsBody2D) PhysicsBody2D
- func (c PhysicsBody2D) MarshalWire() []byte
- func (PhysicsBody2D) Name() string
- func (c PhysicsBody2D) ProtoDescriptor() protoreflect.MessageDescriptor
- func (c PhysicsBody2D) ToProto() *pbcomponent.PhysicsBody2D
- func (p *PhysicsBody2D) UnmarshalJSON(data []byte) error
- func (c PhysicsBody2D) UnmarshalWire(data []byte) (any, error)
- func (p PhysicsBody2D) Validate() error
- type PhysicsSingletonTag
- func (c PhysicsSingletonTag) FromProto(p *pbcomponent.PhysicsSingletonTag) PhysicsSingletonTag
- func (c PhysicsSingletonTag) MarshalWire() []byte
- func (PhysicsSingletonTag) Name() string
- func (c PhysicsSingletonTag) ProtoDescriptor() protoreflect.MessageDescriptor
- func (c PhysicsSingletonTag) ToProto() *pbcomponent.PhysicsSingletonTag
- func (c PhysicsSingletonTag) UnmarshalWire(data []byte) (any, error)
- type ShapeType
- type Transform2D
- func (c Transform2D) FromProto(p *pbcomponent.Transform2D) Transform2D
- func (c Transform2D) MarshalWire() []byte
- func (Transform2D) Name() string
- func (c Transform2D) ProtoDescriptor() protoreflect.MessageDescriptor
- func (c Transform2D) ToProto() *pbcomponent.Transform2D
- func (c Transform2D) UnmarshalWire(data []byte) (any, error)
- func (t Transform2D) Validate() error
- type Vec2
- type Velocity2D
- func (c Velocity2D) FromProto(p *pbcomponent.Velocity2D) Velocity2D
- func (c Velocity2D) MarshalWire() []byte
- func (Velocity2D) Name() string
- func (c Velocity2D) ProtoDescriptor() protoreflect.MessageDescriptor
- func (c Velocity2D) ToProto() *pbcomponent.Velocity2D
- func (c Velocity2D) UnmarshalWire(data []byte) (any, error)
- func (v Velocity2D) Validate() error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ActiveContacts ¶
type ActiveContacts struct {
Pairs []ContactPairEntry `json:"pairs"`
}
ActiveContacts persists which contact pairs have had Begin emitted (and not yet End). After a rebuild, the physics step diffs this against Box2D's live contact list to emit correct Begin/End events without duplicates or missed ends.
func (ActiveContacts) FromProto ¶ added in v0.15.0
func (c ActiveContacts) FromProto(p *pbcomponent.ActiveContacts) ActiveContacts
func (ActiveContacts) MarshalWire ¶ added in v0.15.0
func (c ActiveContacts) MarshalWire() []byte
func (ActiveContacts) Name ¶
func (ActiveContacts) Name() string
func (ActiveContacts) ProtoDescriptor ¶ added in v0.16.4
func (c ActiveContacts) ProtoDescriptor() protoreflect.MessageDescriptor
func (ActiveContacts) ToProto ¶ added in v0.15.0
func (c ActiveContacts) ToProto() *pbcomponent.ActiveContacts
func (ActiveContacts) UnmarshalWire ¶ added in v0.15.0
func (c ActiveContacts) UnmarshalWire(data []byte) (any, error)
type BodyType ¶
type BodyType uint8
BodyType selects how the rigid body participates in the simulation.
const ( // BodyTypeStatic is immovable world geometry; zero velocity; does not respond to forces. BodyTypeStatic BodyType = iota + 1 // BodyTypeDynamic is fully simulated: forces, collisions, and integration apply. BodyTypeDynamic // BodyTypeKinematic is moved by setting velocity from gameplay; Box2D integrates velocity // into position each step. Does not respond to forces but can push dynamic bodies on // contact. Post-step writeback keeps ECS in sync with Box2D's integrated position. BodyTypeKinematic // BodyTypeManual is for gameplay-driven entities that use Box2D only for contact detection. // Under the hood it creates a kinematic body, but post-step writeback is skipped: ECS owns // position and velocity, and the reconciler pushes ECS values into Box2D each tick. // Use this for characters, enemies, and other entities where gameplay code (input handling, // AI, pathfinding) computes position directly. // // Box2D collision rules apply: manual bodies generate contacts with dynamic bodies only, // not with static or other kinematic/manual bodies. BodyTypeManual )
type ColliderShape ¶
type ColliderShape struct {
ShapeType ShapeType `json:"shape_type"`
LocalOffset Vec2 `json:"local_offset"`
LocalRotation float64 `json:"local_rotation"`
IsSensor bool `json:"is_sensor"`
// Geometry (use fields matching ShapeType).
Radius float64 `json:"radius,omitempty"`
HalfExtents Vec2 `json:"half_extents,omitempty"`
Vertices []Vec2 `json:"vertices,omitempty"`
ChainPoints []Vec2 `json:"chain_points,omitempty"`
EdgeVertices [2]Vec2 `json:"edge_vertices,omitempty"`
CapsuleCenter1 Vec2 `json:"capsule_center1,omitempty"`
CapsuleCenter2 Vec2 `json:"capsule_center2,omitempty"`
// Material and per-shape collision filtering (fixture-level in Box2D).
Friction float64 `json:"friction"`
Restitution float64 `json:"restitution"`
Density float64 `json:"density"`
CategoryBits uint64 `json:"category_bits"`
MaskBits uint64 `json:"mask_bits"`
GroupIndex int32 `json:"group_index,omitempty"`
}
ColliderShape is one child shape inside a compound PhysicsBody2D.
Each entry has its own local transform, sensor flag, material, and collision filter (category, mask, group). Geometry fields are a tagged-union style: only the fields that match ShapeType are used.
- ShapeTypeCircle → Radius
- ShapeTypeBox → HalfExtents (half-width on X, half-height on Y, axis-aligned before LocalOffset/LocalRotation)
- ShapeTypeConvexPolygon → Vertices (convex polygon, respect backend limits)
- ShapeTypeStaticChain → ChainPoints (open polyline in local space)
- ShapeTypeStaticChainLoop → ChainPoints (closed loop in local space)
- ShapeTypeEdge → EdgeVertices (exactly 2 points in local space)
- ShapeTypeCapsule → CapsuleCenter1, CapsuleCenter2, Radius (two semicircles connected by a rectangle)
func (ColliderShape) FromProto ¶ added in v0.15.0
func (c ColliderShape) FromProto(p *pbcomponent.ColliderShape) ColliderShape
func (ColliderShape) ToProto ¶ added in v0.15.0
func (c ColliderShape) ToProto() *pbcomponent.ColliderShape
func (ColliderShape) Validate ¶
func (s ColliderShape) Validate() error
Validate checks for NaN/Inf in all float fields and a valid ShapeType tag.
type ContactPairEntry ¶
type ContactPairEntry struct {
EntityA cardinal.EntityID `json:"a"`
ShapeIndexA int `json:"sa"`
EntityB cardinal.EntityID `json:"b"`
ShapeIndexB int `json:"sb"`
IsSensor bool `json:"sensor"`
// Fixture filters for normalized EntityA/B (recovery End / trigger vs contact routing).
// Omitempty keeps older snapshots valid.
FilterACategoryBits uint64 `json:"fa_cat,omitempty"`
FilterAMaskBits uint64 `json:"fa_mask,omitempty"`
FilterAGroupIndex int32 `json:"fa_grp,omitempty"`
FilterBCategoryBits uint64 `json:"fb_cat,omitempty"`
FilterBMaskBits uint64 `json:"fb_mask,omitempty"`
FilterBGroupIndex int32 `json:"fb_grp,omitempty"`
}
ContactPairEntry is one active contact pair tracked by the physics engine. Entries are normalized: EntityA < EntityB (or if equal, ShapeIndexA <= ShapeIndexB).
func (ContactPairEntry) FromProto ¶ added in v0.15.0
func (c ContactPairEntry) FromProto(p *pbcomponent.ContactPairEntry) ContactPairEntry
func (ContactPairEntry) ToProto ¶ added in v0.15.0
func (c ContactPairEntry) ToProto() *pbcomponent.ContactPairEntry
type PhysicsBody2D ¶
type PhysicsBody2D struct {
BodyType BodyType `json:"body_type"`
LinearDamping float64 `json:"linear_damping"`
AngularDamping float64 `json:"angular_damping"`
GravityScale float64 `json:"gravity_scale"`
Active bool `json:"active"`
Awake bool `json:"awake"`
SleepingAllowed bool `json:"sleeping_allowed"`
Bullet bool `json:"bullet"`
FixedRotation bool `json:"fixed_rotation"`
Shapes []ColliderShape `json:"shapes"`
}
PhysicsBody2D holds simulation parameters for a rigid body and its collider shapes.
BodyType selects static vs dynamic vs kinematic behavior. LinearDamping and AngularDamping are simulation damping coefficients. GravityScale multiplies the world's gravity vector for this body; world gravity itself is runtime configuration, not a component field.
Body flags ¶
Active controls whether the body participates in the simulation at all. An inactive body has no contacts, no collisions, and is effectively removed from Box2D without destroying it. Set Active=false to temporarily disable an entity's physics (e.g. a dormant trap).
Awake controls whether the body is currently awake in the simulation. Setting Awake=true wakes a sleeping body; Box2D may put it back to sleep on subsequent ticks if nothing disturbs it and SleepingAllowed is true. The plugin mirrors solver sleep state back into this field after each step, and wakes the body when you change another param without touching Awake. A rebuild (snapshot restore, Plugin.Reset) wakes bodies that had active contacts; others keep their Awake value.
SleepingAllowed controls whether Box2D is permitted to put the body to sleep when it comes to rest. When false, the body stays awake indefinitely.
Note: Box2D v3 processes sensors in a separate overlap pass that runs regardless of body sleep state (only disabled bodies are skipped). Sensor contacts are not affected by sleeping.
Bullet enables continuous collision detection (CCD) for fast-moving dynamic bodies to prevent tunneling through thin geometry. Has a performance cost; only enable for projectiles or similarly fast objects.
FixedRotation prevents the body from rotating in response to torques or collisions. Useful for top-down characters that should not spin.
Shapes ¶
Shapes holds the compound collider description. Cardinal allows one instance per component type per entity, so compound colliders are modeled as multiple ColliderShape entries. Shape identity (v1): index i in Shapes identifies fixture slot i.
Defaults ¶
Box2D defaults Active, Awake, and SleepingAllowed to true and GravityScale to 1. Use NewPhysicsBody2D to create a PhysicsBody2D with these defaults set correctly. Bare struct literals leave bool fields at false and GravityScale at 0, which produces an inactive, sleeping body with no gravity — almost never what you want.
When deserializing from JSON (e.g. snapshot recovery), missing fields are defaulted to their Box2D values automatically via a custom UnmarshalJSON. Explicitly serialized false values are preserved exactly.
Bullet and FixedRotation default to false (off), matching Box2D defaults.
Post-step writeback ¶
Writeback applies to dynamic and kinematic bodies: position, rotation, velocity and Awake. Static and manual bodies are not written back.
func NewPhysicsBody2D ¶
func NewPhysicsBody2D(bodyType BodyType, shapes ...ColliderShape) PhysicsBody2D
NewPhysicsBody2D returns a PhysicsBody2D with the given body type, Box2D-compatible defaults (Active=true, Awake=true, SleepingAllowed=true, GravityScale=1), and the provided shapes.
func (PhysicsBody2D) FromProto ¶ added in v0.15.0
func (c PhysicsBody2D) FromProto(p *pbcomponent.PhysicsBody2D) PhysicsBody2D
func (PhysicsBody2D) MarshalWire ¶ added in v0.15.0
func (c PhysicsBody2D) MarshalWire() []byte
func (PhysicsBody2D) ProtoDescriptor ¶ added in v0.16.4
func (c PhysicsBody2D) ProtoDescriptor() protoreflect.MessageDescriptor
func (PhysicsBody2D) ToProto ¶ added in v0.15.0
func (c PhysicsBody2D) ToProto() *pbcomponent.PhysicsBody2D
func (*PhysicsBody2D) UnmarshalJSON ¶
func (p *PhysicsBody2D) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes a PhysicsBody2D from JSON, applying Box2D-compatible defaults for fields missing from the payload. This handles old snapshots that predate the body flags (Active, Awake, SleepingAllowed default to true; GravityScale defaults to 1) while preserving explicitly serialized values including false.
func (PhysicsBody2D) UnmarshalWire ¶ added in v0.15.0
func (c PhysicsBody2D) UnmarshalWire(data []byte) (any, error)
func (PhysicsBody2D) Validate ¶
func (p PhysicsBody2D) Validate() error
Validate guards against NaN/Inf in float fields, an invalid body type tag, and invalid shapes.
type PhysicsSingletonTag ¶
type PhysicsSingletonTag struct{}
PhysicsSingletonTag marks the single entity that holds physics plugin state (ActiveContacts).
func (PhysicsSingletonTag) FromProto ¶ added in v0.15.0
func (c PhysicsSingletonTag) FromProto(p *pbcomponent.PhysicsSingletonTag) PhysicsSingletonTag
func (PhysicsSingletonTag) MarshalWire ¶ added in v0.15.0
func (c PhysicsSingletonTag) MarshalWire() []byte
func (PhysicsSingletonTag) Name ¶
func (PhysicsSingletonTag) Name() string
func (PhysicsSingletonTag) ProtoDescriptor ¶ added in v0.16.4
func (c PhysicsSingletonTag) ProtoDescriptor() protoreflect.MessageDescriptor
func (PhysicsSingletonTag) ToProto ¶ added in v0.15.0
func (c PhysicsSingletonTag) ToProto() *pbcomponent.PhysicsSingletonTag
func (PhysicsSingletonTag) UnmarshalWire ¶ added in v0.15.0
func (c PhysicsSingletonTag) UnmarshalWire(data []byte) (any, error)
type ShapeType ¶
type ShapeType uint8
ShapeType selects which geometry fields in ColliderShape are valid.
Callers must set ShapeType consistently with the populated geometry fields. Box2D validates geometry internally (convexity, vertex count, welding) and will panic on invalid input. This is caught during development.
const ( // ShapeTypeCircle uses Radius; fixture is a circle in the shape's local frame. ShapeTypeCircle ShapeType = iota + 1 // ShapeTypeBox uses HalfExtents (half-width, half-height) for an axis-aligned box in the // shape's local frame before applying LocalOffset/LocalRotation. ShapeTypeBox // ShapeTypeConvexPolygon uses Vertices as a convex polygon in the shape's local frame. ShapeTypeConvexPolygon // ShapeTypeStaticChain uses ChainPoints for open chain segments (static or kinematic // bodies only; not for dynamic bodies which require mass). ShapeTypeStaticChain // ShapeTypeStaticChainLoop uses ChainPoints for closed chain loops (static or kinematic // bodies only; not for dynamic bodies). Unlike ShapeTypeStaticChain, the last vertex // automatically connects back to the first, creating a sealed boundary. ShapeTypeStaticChainLoop // ShapeTypeEdge uses EdgeVertices (exactly 2 points) for a single line segment // (static or kinematic bodies only). Lighter than a 2-point chain for isolated barriers // or triggers. ShapeTypeEdge // ShapeTypeCapsule uses CapsuleCenter1, CapsuleCenter2, and Radius; fixture is a capsule // (two semicircles connected by a rectangle) in the shape's local frame. ShapeTypeCapsule )
type Transform2D ¶
Transform2D is the authoritative world-space pose of an entity.
Position is the world-space origin of the body transform. Rotation is the world-space orientation in radians (see package doc for handedness and sign).
func (Transform2D) FromProto ¶ added in v0.15.0
func (c Transform2D) FromProto(p *pbcomponent.Transform2D) Transform2D
func (Transform2D) MarshalWire ¶ added in v0.15.0
func (c Transform2D) MarshalWire() []byte
func (Transform2D) ProtoDescriptor ¶ added in v0.16.4
func (c Transform2D) ProtoDescriptor() protoreflect.MessageDescriptor
func (Transform2D) ToProto ¶ added in v0.15.0
func (c Transform2D) ToProto() *pbcomponent.Transform2D
func (Transform2D) UnmarshalWire ¶ added in v0.15.0
func (c Transform2D) UnmarshalWire(data []byte) (any, error)
func (Transform2D) Validate ¶
func (t Transform2D) Validate() error
Validate checks that the transform uses finite scalars only.
type Vec2 ¶
Vec2 is a 2D vector in world space, used by physics-facing components and APIs.
func (Vec2) ToProto ¶ added in v0.15.0
func (c Vec2) ToProto() *pbcomponent.Vec2
type Velocity2D ¶
Velocity2D is the authoritative linear and angular motion state.
Linear is world-space linear velocity. Angular is angular velocity in radians per second about the axis perpendicular to the XY plane (required for rotating rigid bodies and oriented colliders).
func (Velocity2D) FromProto ¶ added in v0.15.0
func (c Velocity2D) FromProto(p *pbcomponent.Velocity2D) Velocity2D
func (Velocity2D) MarshalWire ¶ added in v0.15.0
func (c Velocity2D) MarshalWire() []byte
func (Velocity2D) ProtoDescriptor ¶ added in v0.16.4
func (c Velocity2D) ProtoDescriptor() protoreflect.MessageDescriptor
func (Velocity2D) ToProto ¶ added in v0.15.0
func (c Velocity2D) ToProto() *pbcomponent.Velocity2D
func (Velocity2D) UnmarshalWire ¶ added in v0.15.0
func (c Velocity2D) UnmarshalWire(data []byte) (any, error)
func (Velocity2D) Validate ¶
func (v Velocity2D) Validate() error
Validate checks that linear and angular velocity are finite.