Game.StorageTransferSystem
Assembly:
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
Manages requested storage transfers between buildings, outside connections and transport stations. The system:
- Scans entities with StorageTransfer components and decides whether to resolve transfers immediately or to enqueue pathfinding requests (TransferJob).
- Handles finalized transfers by computing transport costs, updating trade cost buffers and storage transfer requests, and recording last trade partners for storage companies (HandleTransfersJob).
- Integrates with PathfindSetupSystem to find destinations, EndFrameBarrier to produce structural changes safely, ResourceSystem for resource prefabs/data, VehicleCapacitySystem for selecting truck types and CitySystem for city-level buffers.
- Exposes a deterministic helper CalculateTransferableAmount for computing how much can be transferred given source/target capacities and amounts.
Primary internal constructs: - TransferJob (IJobChunk, Burst compiled): inspects StorageTransfer components, computes transferable quantities, enqueues pathfinding setup items or immediate transfer events. - HandleTransfersJob (IJob, Burst compiled): consumes transfer events, splits the path into cargo path sections (to/from storage companies and transport nodes), updates requests, trade costs, and company metadata.
Fields
-
public static readonly float kStorageProfit
Constant multiplier used to compute money gained by storage buildings handling transfers (0.01f). -
public static readonly float kMaxTransportUnitCost
Maximum acceptable per-unit transport cost for dispatching a transport unit (0.01f). -
private EntityQuery m_TransferGroup
EntityQuery used to find entities with StorageTransfer, PrefabRef and resources that need processing. -
private PathfindSetupSystem m_PathfindSetupSystem
Reference to the PathfindSetupSystem used to enqueue pathfinding jobs/requests. -
private EndFrameBarrier m_EndFrameBarrier
Barrier system used to create command buffers for structural changes created by TransferJob. -
private ResourceSystem m_ResourceSystem
Reference to the ResourceSystem (provides ResourcePrefabs and resource data readers). -
private VehicleCapacitySystem m_VehicleCapacitySystem
Reference used to select delivery truck types/capacities/costs. -
private CitySystem m_CitySystem
Reference providing the city entity (for global trade cost buffer access). -
private NativeQueue<StorageTransferEvent> m_TransferQueue
Thread-safe queue holding StorageTransferEvent items enqueued by TransferJob and consumed by HandleTransfersJob. -
private TypeHandle __TypeHandle
Compiler-generated struct that stores component/handle lookups used in job scheduling.
Properties
- None (no public properties exposed by this system).
Constructors
public StorageTransferSystem()
Default constructor (preserved). Initialization of managed references is done in OnCreate.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns the update interval for this system. This system updates at interval 16 (i.e., it runs every N frames/steps as configured). -
protected override void OnCreate()
Sets up references to other world systems (PathfindSetupSystem, EndFrameBarrier, ResourceSystem, VehicleCapacitySystem, CitySystem), allocates the internal NativeQueue for transfer events, constructs the entity query used to find transfer candidates, and calls RequireForUpdate on that query. -
protected override void OnDestroy()
Disposes the internal NativeQueue and does base cleanup. -
public static int CalculateTransferableAmount(int original, int sourceAmount, int sourceCapacity, int targetAmount, int targetCapacity)
Utility to compute how much can be transferred given: - original: requested positive (to send out) or negative (to pull in) amount,
- sourceAmount/sourceCapacity: current fill and per-resource capacity at source,
-
targetAmount/targetCapacity: current fill and per-resource capacity at target. Returns an adjusted amount (signed) limited by available free capacity or available stock.
-
protected override void OnUpdate()
Schedules and wires the two jobs: - Schedules TransferJob in parallel over the m_TransferGroup. TransferJob inspects StorageTransfer components, optionally combines upgrades, computes per-resource capacity and decides whether to:
- remove StorageTransfer and PathInformation if invalid,
- call FindTarget to enqueue a pathfinding SetupQueueItem (when no active PathInformation exists),
- or produce a StorageTransferEvent for later handling (by enqueuing into m_TransferQueue). TransferJob uses m_PathfindSetupSystem, m_EndFrameBarrier CommandBuffer, m_ResourceSystem and vehicle selection data.
-
Schedules HandleTransfersJob that reads the m_TransferQueue, walks path buffers and path information (if present), computes transport cost per path section (AddCargoPathSection / HandleCargoPath), updates storage transfer requests buffers, trade costs buffers for city / source / destination, and updates the StorageCompany components' last trade partners.
-
private void __AssignQueries(ref SystemState state)
Compiler-generated query assignment stub. -
protected override void OnCreateForCompiler()
Compiler-time helper to assign handles and queries (__TypeHandle.__AssignHandles and __AssignQueries). -
Nested types (internal, Burst compiled jobs) — summarized responsibilities:
-
TransferJob : IJobChunk
Reads components: StorageTransfer, PrefabRef, Resources buffers, installed upgrades, storage limits, pathinformation, etc. Decides transfer amounts, applies upgrades to prefab stats, computes per-resource capacity, uses CalculateTransferableAmount, selects appropriate truck via VehicleCapacitySystem, enqueues PathfindSetupItem if needed, and/or enqueues StorageTransferEvent into the transfer queue. Uses EndFrameBarrier command buffer to add/remove PathInformation / PathElement components. Important helpers inside TransferJob:- GetStorageLimit(Entity entity, Entity prefab): compute adjusted storage limit including upgrades and property/warehouse adjustments.
- FindTarget(...): creates PathInformation (Pending), adds PathElement buffer and enqueues a SetupQueueItem to PathfindSetupSystem to find a target.
-
HandleTransfersJob : IJob
Consumes StorageTransferEvent items from the queue and:- Validates presence of PathInformation and PathElement buffers,
- Computes weight and calls HandleCargoPath to break the route into cargo-handling sections,
- Updates TradeCost buffers for source, destination and city,
- Adds money to building resource buffers based on kStorageProfit and route cost,
- Sets last trade partner Entity on StorageCompany components for both source and destination. Important helpers inside HandleTransfersJob:
- GetStorageCompanyFromLane / GetStorageCompanyFromWaypoint: attempt to resolve an owning/renting storage company connected to a lane or waypoint (used for splitting path into company-handled sections).
- GetStorageCompaniesFromSegment: read route segment to identify storage companies at start and end waypoints of the segment.
- HandleCargoPath: iterates PathElement buffer and detects lane/segment types to construct subsections where storage companies or transport modes change, accumulating transport cost via AddCargoPathSection.
- AddCargoPathSection / AddRequest: add StorageTransferRequest entries on the origin/destination request buffers, compute and return transport cost for section.
Notes on safety and threading: - TransferJob is Burst compiled and scheduled parallel. It uses AsParallelWriter for m_PathfindQueue, m_TransferQueue and the EndFrameBarrier command buffer to avoid race conditions. - HandleTransfersJob runs as a separate IJob after TransferJob and consumes the m_TransferQueue. The system wires resource readers/writers and adds dependencies properly (m_ResourceSystem.AddPrefabsReader).
Usage Example
This system runs automatically in the world. Modders typically interact with it by adding a StorageTransfer component to an entity (with a PrefabRef and resources buffer present). Example of initiating a transfer request from code:
// Example pseudo-code to request transfer of 100 units of Resource.Goods from entity 'warehouse'
var storageTransfer = new StorageTransfer
{
m_Resource = Resource.Goods,
m_Amount = 100
};
EntityManager.AddComponentData(warehouseEntity, storageTransfer);
// The StorageTransferSystem will pick up the new component on its next update,
// either start pathfinding to find a trade partner or enqueue a transfer event.
If you need to inspect resulting requests or costs after transfers are handled, read the StorageTransferRequest buffers and TradeCost buffers on the relevant entities (source/destination/city). For advanced integration, consider using PathfindSetupSystem to add custom SetupQueueItem entries or VehicleCapacitySystem to provide custom truck selection data.