docs
Systems
Execution
InitializationSystem
Key Components

This page describes the classes and interfaces in InitializationSystem, how they interact with each other, and how they connect to the messaging and signal classes they depend on. This system defines no event or data classes of its own.

InitializationManager

Role: scene-level bootstrapper. Attach it to a GameObject in the first scene by creating a concrete subclass.

What it does:

  • In Awake, builds a BusRegistry containing a QueryBus, CommandBus, EventBus, SignalBus, and RequestDispatcher, and passes it to ServiceLocator.Initialize.
  • In Awake, calls the abstract RegisterSystems hook. Derived classes call SafeRegister from there.
  • In Start, creates an InitializationOrchestrator, runs the sync phase, awaits the async phase, clears the registry, and calls BusUtility.Raise with a Signal for SaffronLibrarySignals.SystemsReady.

Interactions with dependencies:

  • BusRegistry and ServiceLocator receive the buses it creates. Other systems retrieve them from ServiceLocator after this point.
  • BusUtility is used only to raise the SystemsReady signal.

InitializationOrchestrator

Role: executes the initialization sequence. It is created and driven by InitializationManager.Start.

What it does:

  • InitializeSyncSystems runs Init on the event receivers, then on the other sync components. It does not catch exceptions.
  • InitializeAsyncSystems starts InitAsync on every async component at once, wraps each call so its failure is logged without faulting the others, and returns a task that completes when all have finished.

Interactions:

  • Reads InitializationRegistry.SyncInitializableEventReceivers, InitializationRegistry.SyncInitializables, and InitializationRegistry.AsyncInitializables directly. It does not hold its own copies.
  • Does not interact with the bus or signal dependencies.

InitializationRegistry

Role: static holding area for components between registration and initialization.

What it does:

  • Holds the sync and async component lists.
  • Register (sync overload) sorts sync components into the event receiver list or the general list.
  • Register (async overload) adds async components.
  • RegisterInitializable adds an object to each list it qualifies for, so one object can be in both.
  • Clear empties all lists after initialization.

Interactions:

  • Called by InitializationManager.SafeRegister during Awake.
  • Called directly by scene components that register themselves in their own Awake.
  • Its classification step is meant to check the IEventReceiver interface from the events dependency.

IInitializable

Role: contract for synchronous setup.

Implemented by any component that needs its Init method called during startup. Registered through SafeRegister or InitializationRegistry.

IAsyncInitializable

Role: contract for asynchronous setup.

Implemented by any component that needs to await work, such as loading external resources, during startup. The orchestrator runs these after all sync components and awaits them together. A failure in one is logged and does not stop the rest.

Dependency connections

DependencyHow this system uses it
BusRegistryCreated by InitializationManager and given to ServiceLocator.
ServiceLocatorReceives the BusRegistry during Awake, so later code can reach the buses.
BusUtilityUsed in Start to raise the SystemsReady signal.
SaffronLibrarySignals.SystemsReadyThe signal raised once initialization completes.
SignalCreated to carry the SystemsReady key when it is raised.
IEventReceiverIntended to mark sync components that should initialize first.