Infinite Replay Value

Air Traffic Control Simulation
and the Business Value
of Event Sourcing

Ben Glassman

Email @
CTO @ Vermont Design Works

w/ contributions from Ross Carlson at VDW / Metacraft

Interested in writing apps in React with ES6?
We are hiring front-end and back-end devs!


  • SimSuite ATC Simulation Software
  • Air Traffic Control (ATC) Overview
  • New Customer Requirements
  • Traditional OOP State Management
  • What is Event Sourcing
  • Event Sourcing Benefits
  • Code Example
  • Business Value from Event Sourcing

About the SimSuite™ Software

  • Domain: Air Traffic Control (ATC) Simulation
  • Summary: Comprehensive ATC training and simulation platform with components for ground, tower, terminal and enroute training.
  • Users: Instructors, ATC Students, Pilot Students
  • Environment: ATC Simulation labs at colleges & universities with ATC training programs
  • Components: SimCab (Tower/Ground), SimScope (Radar), SimTarget (Traffic Generation) & SimVox (Communication)

SimCab Tower & Ground

SimCab Tower & Ground Simulation Software Screenshot

Tower controllers manage traffic on the runways, takeoffs and landings. They can physically see the grounds of the airport out the tower window. They give planes instructions based on this information (e.g. taxi to runway 7, follow that plane).

SimScope Radar

SimScope Radar Software Screenshot

Radar ATCs give planes instructions based on radar info (e.g. Climb to 5000 feet). Approach/Departure Radar ATCs control the plane during approach/departure. En Route Radar ATCs control the plane during flight. Planes may be handed off between multiple en route ATCs throughout their flight.

SimTarget Traffic Generation

SimTarget Traffic Generation Software Screenshot

Remote Pilot Operator (RPO or Ghost Pilots) Instructor or student who generates aircraft and adds them to the simulation at various points and issues commands to aircraft (altitude, speed changes). The auto-pilot that flies the plane based on commands from the RPO.

SimVox Communication

SimCab, SimScope and SimVox Software Screenshot

Voice communication system that supports the various types of radio and interphone channels used in modern air traffic control facilities. Installed on a tablet which can be used to issue commands via voice or buttons.

Sessions & Scenarios

  • Session: An isolated simulation instance to which multiple lab stations (tower, radar, rpo, etc.) can connect. (analog: game server).
  • Scenario: A set of aircraft in pre-defined positions (altitude, lat/lng) and behaviors (taxiing, turning, landing) from which a session can be started. Created to give students the opportunity to practice specific skills such as landing a plane.

New Requirements

  • Replay When a session includes a failed or successful attempt that has educational value, students and instructors can watch the session as a class.
  • Retry When a student fails a scenario, the instructor can rewind the recorded scenario to a chosen point in time to allow the student to retry without the need to start from the beginning.
  • Scenario from Session When a session contains a moment that can serve as a learning experience, instructors can create a new scenario from a certain point in the session to use as the basis of future simulations.

State Management in SimSuite

  • Models: Objects or data structures which model our domain. State is stored as properties of models. Example: Aircraft with an altitude property.
  • State Change: Mutate the state of the objects through public methods which change the values of the model's properties. Example: setAltitude(int newAltitude)
  • Persistence: Serialized version of the model stored in a persistent storage layer (e.g. database, filesystem)
  • How would we implement these new requirements with this approach? What challenges do we encounter?

What is Event Sourcing?

  • Each change to a model's state is recorded in an event object.
  • The ordered event stream is persisted instead of the model.
  • The model can be reconstituted from it's event history.

Event Sourcing: Step By Step

Instead of directly modifying properties or using setters, use public mutator methods that:

  • create an event object and push onto a stack (e.g. new AircraftAltitudeChangedEvent(newAltitude))
  • call an event-specific method to mutate the model's state (e.g. ApplyAircraftAltitudeChangedEvent)
  • increment a version number so we can tell the model has changed (and which version of it we have)

Event Classes

abstract class ModelChangedEvent
  public string modelId;
  public int version = 0;

class AltitudeChangedEvent : ModelChangedEvent
  public int altitude;

class Aircraft
  public string id;
  public int version;
  public int altitude;
  public List<ModelChangedEvent> events = new List<ModelChangedEvent>();
  public void SetAltitude(int newAltitude) {
    RecordThat(new AltitudeChangedEvent(id, newAltitude));
  protected void RecordThat(ModelChangedEvent evt) {
    evt.version = version + 1;
  protected void Apply(ModelChangedEvent evt) {
    switch (evt.GetType().Name) {
      case "AltitudeChangedEvent":
        ApplyAltitudeChangedEvent((AltitudeChangedEvent) evt);
    version = evt.version;
  protected void ApplyAltitudeChangedEvent(AltitudeChangedEvent evt) {
    altitude = evt.altitude;

Persisting Models

To persist a model, flush any events from the stack and save them to the storage engine (database, eventstore).

class Aircraft
  public List<ModelChangedEvent> ReleaseEvents() {
    List<ModelChangedEvent> releasedEvents = events;
    events = new List<ModelChangedEvent>();
    return releasedEvents;

Reconsituting Models

To load a model from an event stream, pull the events history from the storage engine and re-apply them in order.

class Aircraft
  public void ReconstituteFromEvents(List<ModelChangedEvent> evts) {
    foreach (var evt in evts) {

Benefits of Event Sourcing

  • Auditing: Event stream gives the "Why" of state change
  • Versioning: Tell whether a model has changed and if its different from your copy
  • Replay/rewind: Free redo/undo functionality through replay of only some events (all but the last one).
  • Debugability: Developers can load state from a bug report's event stream to reproduce bugs and look at the history to see where things went wrong.
  • Real-Time Updates: Push small event messages to clients to trigger updates

Problems with Event Sourcing

  • Large # of Events: Recording and storing large numbers of events could be slow or take a lot of storage space. Solution: Measure first, might not be a problem
  • Frequently Reconsituting Models: Replaying large numbers of events on larger numbers of models could be slow. Solution: Snapshots
  • Querying & Reporting: Event streams don't lend themselves to querying. Solution: CQRS/Read Models

Business Value

  • Better learning experience for future classes to learn from past classes mistakes/successes, instructor can teach entire class concurrently
  • Software developers and schools can easily demo the software at trade shows (dog and pony show in the lab for important visitors such as senators who might fund their training program)
  • Instructors can easily create scenarios based on past simulations makes it easy for them to generate new materials for a specific issue