Skip to content

The tick

designed · Phase 1 (#29) · PLAN §5.1, §5.2, §18.6, §13.5

One tick is one fixed slice of simulated time (about seven sim-minutes at the default 200 ticks per day). Everything below happens, in this order, every tick.

SimClock        world_time = tick × 1440 / ticks_per_day  →  SetAttribute(World, world_time)

for phase in [Environment, Agency, Event]:
    view   = graph.CreateReadOnlyView()        # a wrapper, not a copy — nothing writes until the batch
    batch  = []
    if phase == Agency:
        ctx.Options = OptionBus.Collect(activePublishers, view, ctx)     # scored options, transient
    for system in active(phase) ordered by (Priority, Name):
        batch += system.Process(view, ctx)     # reads the frozen view, yields intents
    applied, events = Resolver.ResolveAndApply(graph, batch)             # ONE batch per phase
    Trace.Record(tick, phase, applied, rejected, conflicts, decisions, events, propagations)
    ctx.Events += events

SnapshotManager.MaybeKeyframe(tick)          # every 50 ticks
EventBus.Publish(ctx.Events)                 # SignalR, InterestScorer

What each line guarantees

  • The view is frozen for the whole phase because the resolver runs only after the last system has returned (PLAN §18.6). Systems within a phase cannot see each other's writes; order within a phase changes nothing about what they read. This is also why the view needs no copy.
  • One batch per phase is what makes priority meaningful: a high-priority player intent beats a system's Set regardless of which ran first, deltas from every producer sum, and a contested contains edge has one winner across all producers at once.
  • Options bypass the resolver. They are not intents and never touch the graph; they are collected, consumed by DecisionSystem in the same phase, and discarded (PLAN §7.4.2, §3.3).
  • The trace records after each phase, in resolution order, with ordinals that the events and the digest refer to.
  • Nothing cascades inside a tick. A rule or system reacting to a change sees it next phase or next tick (PLAN §5.3).

Latency you should expect

A change made in the Environment phase of tick N is visible to the Agency phase of the same tick (each phase takes a fresh view). Within the Agency phase, Perception, Decision and Action all read the same frozen view, so each link waits a tick: perceived at N, decided at N+1, acted on at N+2 — about a quarter of a sim-hour from "the inn is hot" to "Kira is walking". Accepted by design (PLAN §7.4.1); the option bus exists because scores are the one link where that lag is unacceptable.

Phase order and priorities

Phase Priority System
Environment 5 DayNightSystem
20 HeatSystem
40 FireSystem
100 GrowthSystem
Agency 1 PlayerActionSystem (engine, not toggleable)
10 PerceptionSystem
20 HungerSystem
21–29 option publishers (BaselineOptions)
30 DecisionSystem
40 ActionSystem
Event — LifecycleSystem; RuleSystem from Phase 3

See also

Tick pipeline and systems · Intents and the resolver · Views, snapshots and the ring buffer · Causal trace