Namespace Core.Data
Classes
- CalendarConstants
ENGINE: Single source of truth for calendar constants. All time-related code should reference these constants instead of hardcoding values.
Design Rationale:
- Real Earth calendar: 365 days, real month lengths (31/30/28)
- No leap years: Deterministic for multiplayer (Feb always 28 days)
- Pre-calculated derived constants: Avoid multiplication in hot paths
MULTIPLAYER CRITICAL: These constants define the time unit conversions that must be identical across all clients.
- CircularBuffer<T>
Fixed-size circular buffer to prevent unbounded memory growth
- CompressedHistory
Compressed history for medium-term storage
- CountryColdData
Cold data for countries - loaded on-demand, stored separately. Contains detailed information not needed for core simulation.
ENGINE layer - generic country data only. Game-specific data should be stored in customData dictionary.
- CountryData
Complete country data combining hot and cold data Used for runtime access with performance considerations
- CountryDataCollection
Collection for managing multiple countries with performance optimization Implements structure-of-arrays for hot data
- CountryDataLoadResult
Wrapper around CountryDataCollection to provide consistent result API Matches the expected interface for integration with CountrySystem
- HistoryStatistics
Long-term statistical summary
- LoadingStatistics
Loading statistics for performance monitoring
- ProvinceColdData
Cold data storage for provinces (accessed rarely, loaded on-demand) This data is NOT synchronized in multiplayer - it's presentation/metadata only
ENGINE layer - generic province data only. Game-specific data (buildings, trade values, etc.) should be stored in customData dictionary.
- ProvinceHistoryDatabase
Cold data storage for province historical events Implements tiered history with compression to prevent unbounded growth Follows performance architecture: recent events + compressed history + statistics
- ProvinceStateSerializer
High-performance serialization for province state data. Optimized for networking with minimal bandwidth usage. Uses ProvinceSystem's double-buffered state for thread-safe reads.
Structs
- CompressedEvent
Compressed event for medium-term storage (4 bytes)
- CountryHotData
Country data following dual-layer architecture principles Hot data: Frequently accessed, performance-critical (8 bytes) Cold data: Rarely accessed, can be loaded on-demand
ENGINE layer - generic country data only. Game-specific data should be stored via customData dictionary in CountryColdData.
- DeterministicRandom
Deterministic random number generator for multiplayer consistency Uses xorshift128+ algorithm for fast, high-quality random numbers Guarantees identical results across all platforms and clients
- FixedPoint2
Fixed-point 2D vector for deterministic calculations
- FixedPoint32
32-bit fixed-point number for deterministic calculations Format: 16.16 (16 integer bits, 16 fractional bits) Range: -32,768 to 32,767 with ~0.00002 precision
Use when memory is constrained or smaller range is acceptable. For most simulation math, prefer FixedPoint64 for its larger range.
- FixedPoint64
64-bit fixed-point number for deterministic calculations across all platforms Format: 32.32 (32 integer bits, 32 fractional bits) Range: -2,147,483,648 to 2,147,483,647 with ~0.0000000002 precision
CRITICAL: This type is used for ALL simulation math to ensure multiplayer determinism. Float operations produce different results on different CPUs/compilers. Fixed-point math guarantees identical results across all platforms.
- HistoricalEvent
Historical event structure for recent history
- Json5CountryLoadResult
Result of JSON5 country loading phase
- Json5ProvinceLoadResult
Result of JSON5 province loading phase
- ProvinceInitialState
Initial state data extracted from province history files Used to initialize ProvinceState (hot data) at game start This is the Burst-compatible version of province history
- ProvinceInitialStateLoadResult
Result container for Burst-compatible province history loading
- ProvinceState
ENGINE LAYER - Core province simulation state - EXACTLY 8 bytes This is the foundation of the dual-layer architecture
ARCHITECTURE: Engine provides MECHANISM (how ownership works) Game layer provides POLICY (what game-specific data means)
This struct contains ONLY generic engine primitives:
- Ownership (who owns this province)
- Control (who controls it militarily)
- Terrain (what type of land)
- Game data slot (index into game-specific data)
Game-specific fields (development, forts, etc.) belong in Game layer.
CRITICAL: Never change the size of this struct - it must remain exactly 8 bytes for performance targets (10,000 provinces × 8 bytes = 80KB total)
- ProvinceStateSerializer.DeserializeResult
Result of deserialization
- ProvinceStateSerializer.SerializationStats
Serialization statistics
- RawCountryData
Burst-compatible struct for country data extracted from JSON5 Used as intermediate format between JSON parsing and burst processing
ENGINE layer - generic country data only. Game-specific fields (religion, revolutionary colors, etc.) should be parsed by game layer and stored in CountryColdData.customData.
- RawProvinceData
Burst-compatible struct for province data extracted from JSON5 Used as intermediate format between JSON parsing and burst processing
ENGINE layer - generic province data only. Game-specific fields (culture, religion, trade goods, development, etc.) should be parsed by game layer and stored in ProvinceColdData.CustomData.
Enums
- TerrainType
Terrain types for provinces (engine-defined generic types) Games can define their own terrain interpretations in game layer