Namespace Core.SaveLoad
Classes
- CustomSystemSerializers
ENGINE LAYER - Custom serialization logic for specific systems
Purpose: Some systems (TimeManager, ResourceSystem) have custom serialization needs that don't fit the generic SaveState/LoadState pattern.
This class centralizes that custom logic, keeping SaveManager clean.
Systems with generic SaveState/LoadState:
- ProvinceSystem, ModifierSystem, CountrySystem, UnitSystem (These use SystemSerializer directly, no custom logic needed)
Systems with custom serialization:
- TimeManager (multiple fields, not a single SaveState method)
- ResourceSystem (iterates all resources, special capacity handling)
- SaveFileSerializer
ENGINE LAYER - Binary save file format serializer
Responsibilities:
- Write SaveGameData to binary file format
- Read SaveGameData from binary file format
- Handle file format: magic bytes, headers, metadata
- Atomic writes (temp file → rename) to prevent corruption
- Version validation
File Format:
- Magic bytes: "HGSV" (4 bytes)
- Metadata: version, save name, date, tick, speed, scenario
- System data: count + (name, bytes) pairs
- Command log: count + bytes[]
- Checksum: uint32
Usage: SaveFileSerializer.WriteToDisk(saveData, filePath); SaveGameData data = SaveFileSerializer.ReadFromDisk(filePath);
- SaveGameData
ENGINE LAYER - Container for all save game data
Architecture:
- Generic container, systems populate their own sections
- Metadata for version compatibility and UI display
- State snapshot for fast loading
- Command log for determinism verification
Usage: SaveManager creates this, passes to systems via OnSave() Systems populate their data sections SaveManager serializes to disk
- SaveManager
ENGINE LAYER - Orchestrates save/load operations across all systems
Responsibilities:
- Coordinate OnSave/OnLoad calls to all systems (via SystemRegistry)
- Serialize/deserialize SaveGameData to disk (binary format)
- Manage save file paths and naming
- Atomic writes (temp file → rename to prevent corruption)
- Version compatibility checks
Architecture:
- Pure orchestrator, doesn't own game state
- Systems serialize their own data via OnSave/OnLoad
- Dependency order handled by SystemRegistry
- GAME layer hooks OnPostLoadFinalize for game-specific finalization
Usage: saveManager.SaveGame("my_save"); saveManager.LoadGame("my_save"); saveManager.QuickSave();
- SerializationHelper
ENGINE LAYER - Low-level binary serialization utilities
Principles:
- Deterministic serialization (same data = same bytes)
- Platform-independent (works on Windows/Mac/Linux)
- Efficient binary format (no JSON/XML overhead)
- Type-safe helpers for common patterns
Handles:
- FixedPoint64 (as long RawValue for determinism)
- NativeArray (raw memory copy)
- Primitives (int, ushort, string, etc.)
- Arrays of primitives
- SystemSerializer
ENGINE LAYER - Generic system serialization helper
Responsibilities:
- Provide generic Save/Load methods for systems with SaveState/LoadState
- Handle MemoryStream/BinaryWriter/BinaryReader boilerplate
- Store/retrieve serialized data in SaveGameData
- Reduce SaveManager code duplication
Pattern: Instead of writing 6+ pairs of SaveXXX/LoadXXX methods with identical patterns, use generic methods that work with any system implementing the save/load pattern.
Usage: systemSerializer.SaveSystem(saveData, "TimeManager", gameState.Time); systemSerializer.LoadSystem(saveData, "TimeManager", gameState.Time);