Skip to content

Game.Serialization.LoadGameSystem

Assembly: Assembly-CSharp
Namespace: Game.Serialization

Type: public class

Base: GameSystemBase

Summary:
LoadGameSystem is a small game system that coordinates deserialization of a saved game in an asynchronous, frame-driven way. It integrates with the game's UpdateSystem to drive the deserialization phase (SystemUpdatePhase.Deserialize), exposes an event that notifies listeners when the savegame has been loaded, and provides a RunOnce() method that returns a Task that completes once the load has finished. It holds a Context used for deserialization and an AsyncReadDescriptor describing the source for the data to be loaded. Note: the Context setter disposes the previously stored Context instance and therefore assumes the previous value is valid (see remarks below).


Fields

  • private TaskCompletionSource<bool> m_TaskCompletionSource
    Used to complete the Task returned by RunOnce(). RunOnce creates a new TaskCompletionSource and awaits its Task; OnUpdate sets the result to signal completion.

  • private UpdateSystem m_UpdateSystem
    Reference to the world's UpdateSystem instance. Obtained in OnCreate via World.GetOrCreateSystemManaged() and used to invoke the Deserialize update phase.

  • private Context m_Context
    Holds the serialization Context used for the loading/deserialization work. The context is disposed when replaced via the context property setter and also disposed in OnDestroy.

  • public EventGameLoaded onOnSaveGameLoaded
    Delegate/event field (declared as public delegate type) invoked when a save game finishes loading (invoked from OnUpdate).

  • public delegate void EventGameLoaded(Context serializationContext)
    Delegate type used by onOnSaveGameLoaded to pass the finished Context to subscribers.

Properties

  • public AsyncReadDescriptor dataDescriptor { get; set; }
    Descriptor describing the async read source for saved game data. Typical use: assign this before triggering the load so the deserialization system knows where to read from.

  • public Context context
    Getter/Setter for the internal Context used during deserialization.

  • Getter returns the current Context instance.
  • Setter disposes the existing m_Context and then replaces it with the provided value.
  • Important: the setter calls m_Context.Dispose() unconditionally before assignment; if m_Context is null this will throw a NullReferenceException. Callers should ensure the previous value is valid or the class should be updated to null-check before disposing.

Constructors

  • public LoadGameSystem()
    Default parameterless constructor. Marked with [Preserve] attribute in source to avoid being stripped by managed code linking.

Methods

  • protected override void OnCreate()
    Marked [Preserve]. Called when the system is created. It:
  • Calls base.OnCreate().
  • Retrieves (or creates) the UpdateSystem via base.World.GetOrCreateSystemManaged() and stores it in m_UpdateSystem.
  • Disables this system (base.Enabled = false) so it runs only when explicitly enabled (RunOnce sets Enabled = true).

  • public async Task RunOnce()
    Starts the one-shot loading operation:

  • Creates a new TaskCompletionSource and assigns it to m_TaskCompletionSource.
  • Enables the system (base.Enabled = true) so the next world update will invoke OnUpdate.
  • Awaits the TaskCompletionSource.Task, which will complete when OnUpdate finishes the load and calls SetResult(true).
  • Returns to the caller once the loading step has finished.

  • protected override void OnUpdate()
    Marked [Preserve]. This method is executed during the world update while the system is enabled. It:

  • Calls m_UpdateSystem.Update(SystemUpdatePhase.Deserialize) to drive the deserialization update phase (letting other systems/processes perform their deserialize-step work).
  • Disables the system (base.Enabled = false) so it does not repeatedly run each frame.
  • Invokes the onOnSaveGameLoaded event passing the current context (if any subscribers).
  • Sets the TaskCompletionSource result to signal the awaiting RunOnce() call to continue.

  • protected override void OnDestroy()
    Marked [Preserve]. Cleans up when the system is destroyed:

  • Disposes the stored m_Context.
  • Clears the onOnSaveGameLoaded event reference (sets to null).
  • Calls base.OnDestroy().

Remarks / Implementation notes: - The lifecycle uses Enable/Disable on the GameSystem to run exactly one frame of work: RunOnce enables the system, the system's OnUpdate runs once (drives Deserialize phase), disables itself, fires the event, and completes the Task. - The context property setter calls Dispose() on the existing m_Context without a null-check; this can throw if m_Context is null — callers should be aware or the setter should be guarded in future revisions. - m_TaskCompletionSource is created per call to RunOnce(); multiple concurrent RunOnce calls are not supported by the current implementation (the backing field would be overwritten). Ensure RunOnce is awaited/completed before calling again. - The code relies on the UpdateSystem and SystemUpdatePhase.Deserialize semantics provided by the game's engine to perform actual deserialization work; LoadGameSystem does not directly perform I/O or entity deserialization itself, it orchestrates the frame-phase that does.

Usage Example

// Example usage inside some manager or bootstrapper
var loadSystem = world.GetOrCreateSystemManaged<Game.Serialization.LoadGameSystem>();

// Prepare context and descriptor (these types depend on the modding APIs)
loadSystem.dataDescriptor = myAsyncReadDescriptor;
loadSystem.context = mySerializationContext; // be careful: setter disposes previous context

// Subscribe to notification
loadSystem.onOnSaveGameLoaded += (ctx) =>
{
    // Called after the Deserialize phase has run and the save is considered loaded.
    // Use ctx to inspect or finalize state.
    Debug.Log("Save game loaded.");
};

await loadSystem.RunOnce(); // returns when OnUpdate has completed and event has been invoked