Skip to content

Game.Simulation.TradeSystem

Assembly: Assembly-CSharp
Namespace: Game.Simulation

Type: class

Base: GameSystemBase, ITradeSystem, IDefaultSerializable, ISerializable

Summary:
TradeSystem is the simulation system responsible for outside-trade behaviour for storage / outside-connection prefabs. It maintains per-resource trade balances and a cached matrix of buy/sell costs for each outside-connection transfer type. Each update it schedules a Burst-compiled TradeJob that: - decays trade balances, - recalculates import/export costs (taking resource weight, distance parameters and city modifiers into account), - updates storage company buffers (adds/subtracts resources according to storage limits and facility types), - writes trade cost buffers on outside-connection entities and enqueues trade statistics events. The system also handles serialization of trade balances and initializes storage on new games.


Fields

  • private static readonly float kRefreshRate
    Used to decay trade balances each update. Value: 0.01f.

  • public static readonly int kUpdatesPerDay
    Number of updates per in-game day (128). Used to scale resource transfer rates.

  • private CityStatisticsSystem m_CityStatisticsSystem
    Reference to the CityStatisticsSystem used to obtain a parallel writer for statistics events.

  • private EntityQuery m_StorageGroup
    Query matching storage-company / outside-connection entities whose resource buffers and trade-cost buffers are updated.

  • private EntityQuery m_TradeParameterQuery
    Query to obtain the global OutsideTradeParameterData singleton (distance/weight cost parameters).

  • private EntityQuery m_CityQuery
    Query to obtain the city entity (for city modifiers).

  • private ResourceSystem m_ResourceSystem
    Reference to ResourceSystem used to access resource prefab indices.

  • private JobHandle m_DebugTradeBalanceDeps
    Debug-watch dependency handle (keeps track of last scheduled TradeJob).

  • private NativeArray<int> m_TradeBalances
    Persistent array containing per-resource trade balances used when computing import/export costs and decay every update. Serialized.

  • private NativeArray<float> m_CachedCosts
    Persistent array used as a cache for computed buy/sell costs per (resource, connection type, import/export) combination.

  • private TypeHandle __TypeHandle
    Internal TypeHandle struct holding Entity/Component/Buffer handles used when scheduling the TradeJob.

Properties

  • None (the class exposes behavior through methods; internal state is managed via fields).

Constructors

  • public TradeSystem()
    Default constructor. The real initialization happens in OnCreate; constructor is preserved for ECS/serialization purposes.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the system update interval in ticks derived from kUpdatesPerDay (this controls how frequently the system runs relative to the engine update phases).

  • public float GetTradePrice(Resource resource, OutsideConnectionTransferType type, bool import, DynamicBuffer<CityModifier> cityEffects)
    Returns the effective trade price for a resource for a given outside-connection transfer type. It picks the best (minimum) cached cost across enabled transfer-type flags, then applies city modifiers (ImportCost or ExportCost) to the value.

  • private static int GetCacheIndex(Resource resource, OutsideConnectionTransferType type, bool import)
    Maps a (resource, transfer-type, import/export) triple to an index into m_CachedCosts. The index formula uses a log2 of the transfer type and the resource index; this compact layout stores both buy/sell values for each resource/connection-type.

  • protected override void OnCreate()
    Initializes the system: acquires references to CityStatisticsSystem and ResourceSystem, allocates m_TradeBalances and m_CachedCosts (Persistent), builds entity queries (storage group, trade parameters, city), and calls RequireForUpdate for those queries. This prepares the system to execute only when relevant entities/data exist.

  • protected override void OnDestroy()
    Disposes persistent NativeArrays (m_CachedCosts and m_TradeBalances) and forwards to base.OnDestroy.

  • private static TradeCost CalculateTradeCost(Resource resource, int tradeBalance, OutsideConnectionTransferType type, float weight, ref OutsideTradeParameterData tradeParameters, DynamicBuffer<CityModifier> cityEffects)
    Computes buy/sell trade costs for a single resource/connection type. Uses parameterized weight cost and distance cost; distance cost scales with sqrt of absolute tradeBalance (and a minimum multiplier of 50). Applies city import/export modifiers before returning a TradeCost with buy/sell fields.

  • protected override void OnGameLoaded(Context context)
    On new-game loads (context.purpose == Purpose.NewGame) iterates all storage companies and fills their resource buffers to a half capacity baseline (based on storage limits and stored resource types). Special-cases outgoing mail and garbage facility capacities.

  • protected override void OnUpdate()
    Schedules the Burst-compiled TradeJob. Prepares type/component/buffer lookups via InternalCompilerInterface + TypeHandle, passes m_TradeBalances, m_CachedCosts, trade parameters, resource prefabs and the city singleton to the job. Combines job dependencies, marks the statistics queue and resource prefabs readers/writers, stores job handle into base.Dependency and into m_DebugTradeBalanceDeps.

  • public void Serialize<TWriter>(TWriter writer) where TWriter : IWriter
    Writes out the m_TradeBalances array to the provided writer (used for save serialization).

  • public void Deserialize<TReader>(TReader reader) where TReader : IReader
    Reads m_TradeBalances from reader depending on reader.context.version and format. Handles legacy formats that lack the FishResource entry by reading a 40-length subarray and setting the extra slot to 0 if needed.

  • public void SetDefaults()
    Zeroes the m_TradeBalances array (used by defaulting / reset logic).

  • public void SetDefaults(Context context)
    Calls SetDefaults() — context-aware overload used by serialization framework.

  • private void __AssignQueries(ref SystemState state)
    Compiler helper for query assignment at OnCreateForCompiler time (no runtime logic beyond setup).

  • protected override void OnCreateForCompiler()
    Compiler-time setup entry that calls __AssignQueries and assigns type handles via __TypeHandle.__AssignHandles.

Inner struct: TradeJob (private, [BurstCompile], implements IJob)
- Purpose: perform the per-update work on storage entities in a burst job. Main responsibilities: - Iterate all resources and decay the global m_TradeBalances (apply kRefreshRate). - For each resource, compute trade costs for each outside connection transfer type using CalculateTradeCost and store results into the m_CachedCosts cache. - Iterate storage-company chunks: for each storage entity, compute per-resource production/consumption (fills/empties storage according to limits and installed upgrades), add resource deltas to buffers, update the global trade balances, set the entity TradeCost buffer entries using cached costs, and enqueue StatisticsEvent entries for trade changes. - Key fields passed into the job include archetype chunks, type handles, component / buffer lookups, m_TradeBalances, m_CachedCosts, m_ResourcePrefabs and a parallel StatisticsEvent queue writer.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_CityStatisticsSystem = base.World.GetOrCreateSystemManaged<CityStatisticsSystem>();
    m_ResourceSystem = base.World.GetOrCreateSystemManaged<ResourceSystem>();
    // allocate persistent arrays sized by resource count / cache layout
    m_TradeBalances = new NativeArray<int>(EconomyUtils.ResourceCount, Allocator.Persistent);
    m_CachedCosts = new NativeArray<float>(2 * EconomyUtils.ResourceCount * Mathf.RoundToInt(math.log2(32f)), Allocator.Persistent);

    m_StorageGroup = GetEntityQuery(
        ComponentType.ReadOnly<Game.Companies.StorageCompany>(),
        ComponentType.ReadOnly<Game.Objects.OutsideConnection>(),
        ComponentType.ReadOnly<PrefabRef>(),
        ComponentType.ReadOnly<Game.Economy.Resources>(),
        ComponentType.ReadOnly<TradeCost>(),
        ComponentType.Exclude<Deleted>(),
        ComponentType.Exclude<Temp>());

    m_TradeParameterQuery = GetEntityQuery(ComponentType.ReadOnly<OutsideTradeParameterData>());
    m_CityQuery = GetEntityQuery(ComponentType.ReadOnly<Game.City.City>());
    RequireForUpdate(m_StorageGroup);
    RequireForUpdate(m_TradeParameterQuery);
    RequireForUpdate(m_CityQuery);
}

Notes and tips for modders: - TradeSystem relies on a compact cache index mapping (GetCacheIndex). If you need direct access to cached costs, use GetTradePrice to ensure city modifiers are applied. - When adding or changing outside-connection transfer types, ensure GetCacheIndex logic and cache sizing are updated accordingly. - Serializing trade balances is version-aware; if adding/removing resources, update deserialize logic and save-version checks to maintain compatibility.