You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
HeadlessProgram and HeadlessRunner for running the Elmish update loop without graphics, input polling, or Raylib initialization. Use for unit testing, server-side simulation, and CLI debugging.
HeadlessProgram.mkHeadless init update — creates a headless program with the same Init/Update signatures as Program.
HeadlessRunner.Dispatch(msg) and DispatchMany(msgs) for sending messages from outside the update loop.
HeadlessRunner.Model, GameTime, ShouldQuit for accessing simulation state.
HeadlessRunner.Run(interval, ?ct) — returns seq<struct(GameTime * 'Model)>, a paced synchronous sequence of simulation frames. Uses spin-wait with Thread.Sleep(1) for timing.
HeadlessRunner.RunAsync(interval, ct) — returns IAsyncEnumerable<struct(GameTime * 'Model)>, a paced async sequence of simulation frames. Uses PeriodicTimer for efficient timing.
Observer support: HeadlessProgram.Observers field and withObserver DSL for registering System.IObserver<struct(GameContext * 'Model * GameTime)> factories. Observers fire every frame after the update loop, receiving the current model and game time. Observers implementing IDisposable are disposed when the runner is disposed.
27 unit tests for new features: step return values, observer lifecycle, observer correctness (post-update model, GameTime accumulation, multiple observers, window dimensions, subscription interaction), Run/RunAsync enumeration, cancellation, and ShouldQuit behavior. 47 total headless tests.
XML documentation for HeadlessProgram.withTick, withFixedStep, and withDispatchMode.
Headless mode documentation: Observers section (withObserver/observe), Run/RunAsync section with pacing and cancellation examples, server simulation example using observer-based broadcast.