Table of Contents

Scheduler & phases

In one line: from each system's declared reads/writes, the engine derives the execution graph once and rejects unsafe schedules at build time.

The runtime walks a fixed structure you declare at startup: Track → DAG → Phase → System. Phases (Input / Simulation / Output / Cleanup, or your own) are a DAG-local total order, but not a barrier. Within and across phases, two systems may run concurrently unless a declared access conflict or an explicit edge connects them, directly or through other systems; that is the only way a Simulation system waits for an Input system.

Access declarations are the heart of it. Reads<T> / Writes<T> state what a system touches; ReadsFresh<T> wants this tick's value (ordered after the writer), ReadsSnapshot<T> accepts last tick's (runs concurrently with the writer — Versioned-only). Two unordered writers of the same component in the same phase is a build-time error, not a production race. After/Before add explicit edges when you need them.

How it relates

  • System — supplies the access declarations the scheduler consumes.
  • Runtime — executes the derived graph every tick.
  • Storage mode — ReadsSnapshot<T> requires a Versioned T (history to hand out).
  • Snapshot isolation — what a snapshot read returns.

In the API

Learn & use