ExCollision (ExCollision v1.1.0)
View SourceLibrary for server-side collisions, physics world simulation, tilemap pathfinding, and Tiled TMX parsing.
Main features
- TMX parsing — load Tiled maps (tile layers, objectgroup, tilesets)
- Collision world — static and dynamic bodies (AABB), intersection checks and step simulation
- Pathfinding — A* over tilemap with
TileSourceprotocol support - TMX → World integration — build collision world from map layers (Walls, objectgroup)
Server loop
World.step(world, dt) is called every server tick (e.g. 60 times per second).
Use a fixed dt = 1/60 for determinism or the actual interval between ticks.
Example
# Parse TMX
map = ExCollision.TMX.Parser.parse!("data/Dun.tmx")
# Collision world from map ("Walls" layer and objectgroup)
world = ExCollision.TMX.WorldBuilder.from_tmx(map, collision_layer: "Walls")
# Pathfinding over layer (walkability: GID=0). In Dun.tmx lines 18–28 are all zeros
layer = ExCollision.TMX.Map.layer_by_name(map, "Floor")
source = ExCollision.TMX.TileLayerTileSource.new(layer)
{:ok, path} = ExCollision.Pathfinding.AStar.find_path(source, {5, 20}, {30, 25})
# Player — Body. Every server tick: step(world, 1/60)
{world, player_id} = ExCollision.World.add_body(world, ExCollision.World.Body.from_xywh(:player, 50, 50, 16, 16, velocity: {0, 0}))
{:ok, world} = ExCollision.World.set_velocity(world, player_id, 32, 0)
world = ExCollision.World.step(world, 1/60) # every server tick
# Interpolation for smooth rendering (alpha = time since last step / step interval)
{:ok, {x, y}} = ExCollision.World.get_interpolated_position(world, player_id, 0.5)
# Optional: clamp alpha to [0, 1]: get_interpolated_position(..., clamp: true) or get_interpolated_position_clamped/3
Summary
Functions
A* pathfinding. Options: :allow_diagonal — allow diagonal movement (8 directions)
Add object (Body) to world. Returns {world, id}.
List of body ids intersecting the AABB (exclude_id — body to ignore). For bullets: where it would move — who it hit.
Get object by id
Check if object with id exists in world
Interpolated body center. Pass clamp: true in opts to clamp alpha to [0, 1].
Same as world_interpolated_center/4 with alpha clamped to [0, 1].
Interpolated body position for rendering. Pass clamp: true in opts to clamp alpha to [0, 1].
Same as world_interpolated_position/4 with alpha clamped to [0, 1].
List of all object ids in world
Рейкастинг: ближайшее попадание луча from → to со статическими/динамическими телами.
Возвращает {:hit, t, {x, y}, tag} или :miss.
tag = {:static, aabb} | {:body, body_id}. t ∈ [0, 1] — где вдоль луча попало.
Опции: :check_static, :check_dynamic, :exclude_body_id.
Рейкастинг: все попадания луча from → to, отсортированные от ближайшего к дальнему.
Каждый элемент: {t, {x, y}, tag}. Опции: те же, что у world_raycast/4.
Remove object from world by id.
Remove static AABB by index. Returns {:ok, world} or {:error, :out_of_range}.
Set body velocity (vx, vy) in pixels/sec
World simulation step. Call every server tick, e.g.: world_step(world, 1/60)
Functions
A* pathfinding. Options: :allow_diagonal — allow diagonal movement (8 directions)
Add object (Body) to world. Returns {world, id}.
List of body ids intersecting the AABB (exclude_id — body to ignore). For bullets: where it would move — who it hit.
Get object by id
Check if object with id exists in world
Interpolated body center. Pass clamp: true in opts to clamp alpha to [0, 1].
Same as world_interpolated_center/4 with alpha clamped to [0, 1].
Interpolated body position for rendering. Pass clamp: true in opts to clamp alpha to [0, 1].
Same as world_interpolated_position/4 with alpha clamped to [0, 1].
List of all object ids in world
Рейкастинг: ближайшее попадание луча from → to со статическими/динамическими телами.
Возвращает {:hit, t, {x, y}, tag} или :miss.
tag = {:static, aabb} | {:body, body_id}. t ∈ [0, 1] — где вдоль луча попало.
Опции: :check_static, :check_dynamic, :exclude_body_id.
Рейкастинг: все попадания луча from → to, отсортированные от ближайшего к дальнему.
Каждый элемент: {t, {x, y}, tag}. Опции: те же, что у world_raycast/4.
Remove object from world by id.
Remove static AABB by index. Returns {:ok, world} or {:error, :out_of_range}.
Set body velocity (vx, vy) in pixels/sec
World simulation step. Call every server tick, e.g.: world_step(world, 1/60)