PhysicsAPI reference
Class TilePhysicsWorld2D
Namespace: MicroEngine.Physics.Tiles
Assembly: MicroEngine.Physics.Tiles.dll
Guide: Physics worlds
The tile backend of IPhysicsWorld2D: static and kinematic bodies with axis-aligned box shapes, tile grids as static geometry (AddTiles), and an exact swept mover. It declares TileGeometry, OneWayPlatforms and MovingSolids; it has no dynamic bodies, so ContactEvents is always empty, and every other capability throws PhysicsCapabilityException.
public sealed class TilePhysicsWorld2D : IPhysicsWorld2D, IStateHashedInheritance
Implements
Remarks
Space is the engine's 2D space: Y grows downward and [Up](/docs/api/microengine.physics.tiles.tilephysicsworld2d/#MicroEngine_Physics_Tiles_TilePhysicsWorld2D_Up) is (0, -1); units are whatever the game
uses (pixels in a pixel-art game). [Move](/docs/api/microengine.physics.tiles.tilephysicsworld2d/#MicroEngine_Physics_Tiles_TilePhysicsWorld2D_Move_MicroEngine_Physics_BodyId_System_Numerics_Vector2_MicroEngine_Physics_QueryFilter__) resolves X, then Y, each as one exact swept test: the box stops
flush against the first surface in its way however thin it is or however fast the box moves, and rests on it exactly
([Skin](/docs/api/microengine.physics.tiles.tilephysicsworld2d/#MicroEngine_Physics_Tiles_TilePhysicsWorld2D_Skin) is 0; a flush box may end within 0.001 units inside a surface from rounding, which never
counts as overlapping).
A tile grid is one shape made of cells: its [Solid](/docs/api/microengine.world.tileflags/) cells block from every side, its [OneWay](/docs/api/microengine.world.tileflags/) cells are one-way platforms, and other cells are not geometry (read hazards and water with [TouchedFlags](/docs/api/microengine.world.tilemotion/#MicroEngine_World_TileMotion_TouchedFlags_MicroEngine_RectF_MicroEngine_World_ICollisionGrid_)). Changing a tile changes collisions at once. Cells a box overlaps when a move starts do not block it.
Deterministic: the same calls give the same results on every target (managed code with no threads). The world takes part in the per-step state hash ([IStateHashed](/docs/api/microengine.kernel.istatehashed/)).
A broad phase keeps moves, queries and sensors from looking at every shape: box shapes are filed in a grid of [DefaultCellSize](/docs/api/microengine.physics.tiles.tilephysicsworld2d/#MicroEngine_Physics_Tiles_TilePhysicsWorld2D_DefaultCellSize)-unit cells, and each operation looks only at the shapes in the cells it reaches (tile grids are always looked at). It changes the work, never a result: candidates are taken in creation-slot order, the order of a full scan.
Constructors
TilePhysicsWorld2D()
Creates an empty world.
public TilePhysicsWorld2D()Fields
ContactDistance
The distance within which a surface counts as touching a box at the end of a move (the ground probe).
public const float ContactDistance = 0.01Field Value
Declared
The capabilities this backend declares.
public const PhysicsCapabilities Declared = TileGeometry | OneWayPlatforms | MovingSolids | ShapeInspectionField Value
DefaultCellSize
The side of the broad phase’s cells, in world units (four 16-pixel tiles).
public const float DefaultCellSize = 64Field Value
Properties
Backend
The backend’s name, for messages (“tiles”, “box2d”).
public string Backend { get; }Property Value
Bodies
The live bodies, in creation order (a destroyed body leaves its place).
public ReadOnlySpan<BodyId> Bodies { get; }Property Value
Capabilities
What the backend offers beyond the common contract.
public PhysicsCapabilities Capabilities { get; }Property Value
ContactEvents
Always empty: this backend has no dynamic bodies.
public ReadOnlySpan<ContactEvent> ContactEvents { get; }Property Value
SensorEvents
The sensor entries and exits of the latest step: exits first, then entries, each in sensor then visitor order.
public ReadOnlySpan<SensorEvent> SensorEvents { get; }Property Value
Skin
0: Move rests exactly on surfaces.
public float Skin { get; }Property Value
StepCount
How many times Step ran.
public long StepCount { get; }Property Value
Up
(0, -1): Y grows downward.
public Vector2 Up { get; }Property Value
Methods
AddShape(BodyId, in ShapeDescription)
public ShapeId AddShape(BodyId body, in ShapeDescription shape)Parameters
body BodyId
shape ShapeDescription
Returns
AddTiles(BodyId, ICollisionGrid, ulong, ulong)
Attaches grid to a static body as one shape (TileGeometry):
cell (x, y) covers the body’s origin plus (x, y) × TileSize. Solid cells block, one-way
cells are one-way platforms; the grid is read at every query, so changing a tile changes collisions at once.
public ShapeId AddTiles(BodyId body, ICollisionGrid grid, ulong category = 1, ulong mask = 18446744073709551615)Parameters
body BodyId
A static body.
grid ICollisionGrid
The tiles.
category ulong
The layers the grid is in.
mask ulong
The layers it collides with.
Returns
Exceptions
The body is stale or not static.
BodyOf(ShapeId)
The body shape is attached to.
public BodyId BodyOf(ShapeId shape)Parameters
shape ShapeId
Returns
Exceptions
The id is stale.
CreateBody(EntityId, in BodyDescription)
public BodyId CreateBody(EntityId owner, in BodyDescription body)Parameters
owner EntityId
body BodyDescription
Returns
DescriptionOf(ShapeId)
The description shape was added with (its geometry is relative to its body’s origin).
public ShapeDescription DescriptionOf(ShapeId shape)Parameters
shape ShapeId
Returns
Exceptions
The id is stale.
The backend does not declare ShapeInspection.
DestroyBody(BodyId)
Destroys the body and its shapes; nothing for a stale or none id. Their sensor pairs end at the next step.
public void DestroyBody(BodyId body)Parameters
body BodyId
GridOf(ShapeId)
The tiles shape stands for when it was added with AddTiles; null for any other shape.
public ICollisionGrid? GridOf(ShapeId shape)Parameters
shape ShapeId
Returns
Exceptions
The id is stale.
HashState(StateHasher)
Adds the world’s simulation state: the step count, every live body (id, kind, position, shapes) and the sensor pairs.
public void HashState(StateHasher hash)Parameters
hash StateHasher
IsAlive(BodyId)
Whether body exists.
public bool IsAlive(BodyId body)Parameters
body BodyId
Returns
IsAlive(ShapeId)
Whether shape exists.
public bool IsAlive(ShapeId shape)Parameters
shape ShapeId
Returns
KindOf(BodyId)
How body moves.
public BodyKind KindOf(BodyId body)Parameters
body BodyId
Returns
Exceptions
The id is stale.
Move(BodyId, Vector2, in QueryFilter)
public MoveResult Move(BodyId body, Vector2 delta, in QueryFilter filter = default)Parameters
body BodyId
delta Vector2
filter QueryFilter
Returns
Overlap(in RectF, in QueryFilter, Span<ShapeId>)
public int Overlap(in RectF area, in QueryFilter filter, Span<ShapeId> results)Parameters
area RectF
filter QueryFilter
Returns
OwnerOf(BodyId)
The entity that owns body.
public EntityId OwnerOf(BodyId body)Parameters
body BodyId
Returns
Exceptions
The id is stale.
PositionOf(BodyId)
The body’s origin.
public Vector2 PositionOf(BodyId body)Parameters
body BodyId
Returns
Exceptions
The id is stale.
RayCast(Vector2, Vector2, in QueryFilter, out RayHit)
public bool RayCast(Vector2 from, Vector2 to, in QueryFilter filter, out RayHit hit)Parameters
from Vector2
to Vector2
filter QueryFilter
hit RayHit
Returns
RemoveShape(ShapeId)
Removes a shape; nothing for a stale or none id. Its sensor pairs end at the next step.
public void RemoveShape(ShapeId shape)Parameters
shape ShapeId
RotationOf(BodyId)
Always 0: this backend has no rotation.
public float RotationOf(BodyId body)Parameters
body BodyId
Returns
SetPosition(BodyId, Vector2)
Teleports the body: no collision, no pushing; sensor events follow at the next step.
public void SetPosition(BodyId body, Vector2 position)Parameters
body BodyId
position Vector2
Exceptions
The id is stale.
The position is not finite.
SetVelocity(BodyId, Vector2)
Always throws: this backend has no dynamic bodies.
public void SetVelocity(BodyId body, Vector2 velocity)Parameters
body BodyId
velocity Vector2
Exceptions
Always.
ShapesOf(BodyId, Span<ShapeId>)
Writes the live shapes of body, in the order they were added, into results
and returns how many it has (which may exceed the span’s length: only the first ones are written).
public int ShapesOf(BodyId body, Span<ShapeId> results)Parameters
body BodyId
Returns
Exceptions
The body is stale.
The backend does not declare ShapeInspection.
Step(float)
Advances the world by dt seconds: dynamic bodies move, and the events of this step replace the
previous ones. No game code runs during it.
public void Step(float dt)Parameters
dt float
Exceptions
dt is negative or not finite.
VelocityOf(BodyId)
Always throws: this backend has no dynamic bodies.
public Vector2 VelocityOf(BodyId body)Parameters
body BodyId
Returns
Exceptions
Always.