Option bus¶
OptionBus · IOptionPublisher
| Kind | Engine infrastructure (not toggleable); publishers are systems (toggleable) |
| Project | NextIteration.Engine/OptionBus.cs; NextIteration.Systems/Agency/BaselineOptions.cs |
| Exposes | Option, IOptionPublisher, ctx.Options, the action registry |
| Consumes | the Agency-phase view |
| Consumed by | DecisionSystem; the trace (decision records); gap detection (Phase 2) |
| Status | designed · Phase 1 (#35) |
| PLAN | §3.3, §7.4.1, §7.4.2, §7.5, §22.2 |
| Player | Needs |
DecisionSystem does not know what douse_fire is. Whoever introduces an action publishes scored options for actors; DecisionSystem applies personality weights and arbitrates. This is the Sims' "objects advertise what needs they satisfy", applied to systems and rules — and it is what lets a later phase add an action without editing the core.
record Option(
NodeId Actor, string Action, NodeId? Target,
string Need, // hunger · warmth · safety · rest · curiosity (Phase 1)
float Score, // before personality weighting
string Reason, // human text — the trace and Explain this show it
IReadOnlyDictionary<string, float> Inputs, // what the score was computed from
string Publisher);
interface IOptionPublisher { IEnumerable<Option> Publish(ReadOnlyGraphView view, TickContext ctx); }
How it runs¶
At the start of the Agency phase the engine calls every active publisher in (priority, name) order against the phase view and accumulates ctx.Options. Publishers run between PerceptionSystem (10) and DecisionSystem (30). Options never touch the graph — they are the one sanctioned within-phase channel, rebuilt every tick, discarded at phase end — so they bypass the resolver and the one-tick lag.
BaselineOptions (Phase 1)¶
The engine ships one publisher with the §7.4.1 formulas for eat, move, rest, pick_up, drop, fetch_water, douse_fire, tend_fire, gather_wood. Two rules it follows that every publisher must:
- Never read a target's live attributes for a score. Danger and warmth at a target come from perception or memory (
view.Facts,view.Known); the rememberedfood_valuedrives the hunger draw, not the bush's real one. Reading the truth is god-view, and it is what the spike's whole-map gradient did. - A composite score publishes one option with the dominant need.
moveto a target sumshunger_draw + safety_draw + explore_draw + warmth_draw − danger_at_target; the publisher emits one option per target with the full score,Need= the largest draw, and the components inInputs. "Kira fled" is amovewhose need issafety.
The action registry¶
Every publisher declares its actions under writes.actions in its manifest, each with its need. The world schema lists every action in the world and who offers it; capability-gap detection (Phase 2) classifies an unmet need against this list.
Hot-toggle and determinism¶
Toggle a publisher off and its actions stop being offered next tick; on, and they return. Publisher order is fixed; option order within a publisher is deterministic (iterate the view's query results in order, never a HashSet); arbitration is argmax with a StableHash tiebreak.
History¶
| Phase | Change |
|---|---|
| 1 | Introduced: Option with Need and Inputs, IOptionPublisher, BaselineOptions, the action registry, the five Phase 1 needs. |
See also¶
DecisionSystem · From perception to Explain this · PerceptionSystem