ECSComb
ECSComb is an Entity-Component-System framework for Elixir built on BEAM and ETS.
It focuses on a small runtime surface:
ECSComb.Worldowns entity lifecycle and component storage.ECSComb.Queryprovides runtimeall/any/nonequeries.ECSComb.Systemdefines the scheduler contract.ECSComb.Schedulergroups non-conflicting systems into parallel layers.ECSComb.TickLoopdrives the world at a fixed tick rate.
Design Highlights
- ETS-backed storage with public named tables and direct read access
-
Entity IDs use
{index, generation}to reject stale references - Components are plain structs with no macros or registration
- System ordering is inferred from declared read/write sets
- Runtime add/remove of systems is supported between ticks
Quick Example
defmodule Demo.Position do
defstruct [:x, :y]
end
defmodule Demo.Velocity do
defstruct [:dx, :dy]
end
defmodule Demo.MoveSystem do
@behaviour ECSComb.System
alias ECSComb.Query
alias ECSComb.World
alias Demo.Position
alias Demo.Velocity
@impl true
def access do
%{reads: [Position, Velocity], writes: [Position]}
end
@impl true
def run(world) do
Query.select(world, all: [Position, Velocity])
|> Enum.each(fn entity_id ->
{:ok, %Position{x: x, y: y}} = World.get(world, entity_id, Position)
{:ok, %Velocity{dx: dx, dy: dy}} = World.get(world, entity_id, Velocity)
:ok = World.put(world, entity_id, %Position{x: x + dx, y: y + dy})
end)
:ok
end
end
{:ok, world} = ECSComb.World.start_link()
{:ok, entity_id} = ECSComb.World.spawn_entity(world)
:ok = ECSComb.World.put(world, entity_id, %Demo.Position{x: 0, y: 0})
:ok = ECSComb.World.put(world, entity_id, %Demo.Velocity{dx: 1, dy: 1})
scheduler =
ECSComb.Scheduler.new()
|> ECSComb.Scheduler.add_system(Demo.MoveSystem)
|> ECSComb.Scheduler.build_graph()
{:ok, tick_loop} =
ECSComb.TickLoop.start_link(
world: world,
scheduler: scheduler,
tick_rate: 20
)
Process.sleep(120)
{:ok, %Demo.Position{x: x, y: y}} = ECSComb.World.get(world, entity_id, Demo.Position)
IO.inspect({x, y}, label: "updated position")
:ok = ECSComb.TickLoop.stop(tick_loop)Test Coverage
The project includes tests for:
- Entity lifecycle and component CRUD
- Transactions, name indexes, and concurrent reads/writes
- Query filtering and indexed lookup correctness
- Behaviour validation for systems
- Scheduler conflict detection, graph layering, and parallel execution
- Tick timing, cron callbacks, and end-to-end runtime integration
Status
Implemented and covered by mix test.