Skip to content

Game.ResourceFlowSystem

Assembly: Assembly-CSharp.dll
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
ResourceFlowSystem is a simulation system that computes and propagates resource flows through the game's network (nodes, edges, subobjects). Each update it: - Clears previous ResourceConnection flow values, - Collects source nodes (nodes that produce resource flow), - Uses a Dijkstra-like search (min-heap) over connected edges, nodes and subobjects to find nearest consumer/target directions, - Writes aggregated flow values back into ResourceConnection components on edges and nodes. The heavy work is done in a Burst-compiled IJob (ResourceFlowJob) and uses Unity.Entities component lookups/buffer lookups and native containers for performance. The system also enforces an update interval tied to the extractor company system.


Fields

  • private ExtractorCompanySystem m_ExtractorCompanySystem
    Reference to the ExtractorCompanySystem used to validate/update relative update intervals. The system asserts a relationship between its update interval and the extractor company system (specifically it expects GetUpdateInterval(GameSimulation) == extractor interval * 16).

  • private EntityQuery m_NetQuery
    Query used to gather all entities that have a ResourceConnection component (and are not Deleted or Temp). This query is used to produce the chunk list passed into the ResourceFlowJob.

  • private TypeHandle __TypeHandle
    Internal container of EntityTypeHandle, ComponentTypeHandles, ComponentLookups and BufferLookups used to populate the job's handles. __TypeHandle.__AssignHandles(ref SystemState) is called to initialize these handles for the current SystemState.


Properties

  • None (no public properties on this system)

Constructors

  • public ResourceFlowSystem()
    Default constructor. Marked with [Preserve] attribute on lifecycle methods; constructor itself is parameterless and performs no extra runtime work beyond base initialization.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the update interval for this system. Implementation:
  • return 262144 / EconomyUtils.kCompanyUpdatesPerDay; This ties the execution frequency to the economy/company update rate.

  • [Preserve] protected override void OnCreate()
    System initialization:

  • Calls base.OnCreate().
  • Retrieves the ExtractorCompanySystem from the World and stores it in m_ExtractorCompanySystem.
  • Creates m_NetQuery to match entities with ResourceConnection (ReadWrite) and excluding Deleted and Temp.
  • Calls RequireForUpdate(m_NetQuery) so the system runs only when matching entities exist.
  • Asserts that this system's GameSimulation update interval equals extractor company's interval * 16.

  • [Preserve] protected override void OnUpdate()
    Main scheduling method:

  • Builds a ResourceFlowJob, filling it with:
    • a chunk list from m_NetQuery.ToArchetypeChunkListAsync (Allocator.TempJob) and the returned outJobHandle,
    • entity/component/buffer lookup handles from __TypeHandle through InternalCompilerInterface.
  • Schedules the job (IJob) with dependencies combined from the system base.Dependency and outJobHandle.
  • Ensures the temporary chunk list is disposed with job dependency (jobData.m_Chunks.Dispose(jobHandle)).
  • Stores the scheduled job handle back into base.Dependency.

  • private void __AssignQueries(ref SystemState state)
    Generated helper used at compile-time (empty here beyond creating/disposing a temporary EntityQueryBuilder). Called from OnCreateForCompiler to ensure queries are assigned for the codegen/IL2CPP/compilation path.

  • protected override void OnCreateForCompiler()
    Helper used for AOT/compile-time initialization paths. Calls:

  • base.OnCreateForCompiler()
  • __AssignQueries(ref base.CheckedStateRef)
  • __TypeHandle.__AssignHandles(ref base.CheckedStateRef)

Inner types and important behavior inside the ResourceFlowJob (Burst-compiled IJob): - ResourceFlowJob.Execute(): - Uses NativeList to collect sources (where ResourceConnection.m_Flow.y >> 1 != 0). - Uses NativeMinHeap to perform a shortest-distance expansion from candidate targets (consumers) to find appropriate target directions for sources. - Builds a NativeHashMap mapping nodes/subobjects/edges to the best next hop toward a consumer. - Traverses from each source, adding its flow to source.m_Flow.x and then iteratively applying flow deltas to edges and intermediate nodes according to the stored TargetDirectionData until reaching a node that does not map to a target (then subtracts the source flow from that terminal node). - Properly resets ResourceConnection.m_Flow to default before accumulation. - Uses many ComponentLookup and BufferLookup accesses (Edges, Curves, ConnectedEdges, ConnectedNodes, SubObjects, Transform, ServiceUpgrade) and checks for ServiceUpgrade to exclude certain buildings.

Notes about the algorithmic details: - The search is analogous to multi-source Dijkstra where target nodes are inserted into a min-heap keyed by squared distance (or edge-length-weighted distance) and expansion computes distances via edge curve lengths, relative curve positions, and subobject positions. - Direction vectors (int2) encode flow increments on the edge's ResourceConnection component (x and y components manipulated depending on direction along the edge). - The implementation uses safety-ignoring handles for writing ResourceConnection inside the job (NativeDisableContainerSafetyRestriction on m_ResourceConnectionType and m_ResourceConnectionData).


Usage Example

// Typical usage from other mod code: get the system and inspect its update interval or
// rely on ECS/World to run it automatically. You generally don't call its internals directly.

var world = World.DefaultGameObjectInjectionWorld; // or your mod's world
var resourceFlowSystem = world.GetExistingSystemManaged<Game.Simulation.ResourceFlowSystem>();
int interval = resourceFlowSystem.GetUpdateInterval(SystemUpdatePhase.GameSimulation);
Debug.Log($"ResourceFlowSystem update interval: {interval}");

// The system is automatically scheduled by the ECS runtime. If you need to force an immediate update
// (for debugging only), you can update the world manually:
// world.Update(); // runs all systems according to their schedule

If you want to read or modify flow values, query entities with ResourceConnection and inspect ResourceConnection.m_Flow after the system has run (observe required synchronization with system dependencies).