Game.ElectricityFlowSystem
Assembly: Assembly-CSharp
Namespace: Game.Simulation
Type: class
Base: GameSystemBase, IDefaultSerializable, ISerializable, IPostDeserialize
Summary:
ElectricityFlowSystem is the ECS/System that prepares, runs and applies the electricity flow (max-flow / trade / battery charge/discharge) simulation for the game. It builds an internal flow graph (nodes, edges, connections) from ECS components, schedules Burst jobs to compute flows across multiple frames (split into Prepare → Flow → Apply phases to spread work across frames), and writes the computed flow values back to ElectricityFlowEdge components. The system also manages serialization/deserialization, legacy migration of "outside" nodes, and exposes archetypes used when creating flow nodes/edges. Several nested Burst-compiled job structs implement the chunked preparation and application phases as well as the distributed solver job.
Fields
-
private SimulationSystem m_SimulationSystem
Reference to the main SimulationSystem used for frame indexing and scheduling. -
private EntityQuery m_NodeGroup
EntityQuery selecting entities that represent flow nodes (ElectricityFlowNode + ConnectedFlowEdge). -
private EntityQuery m_EdgeGroup
EntityQuery selecting flow edge entities (ElectricityFlowEdge). -
private EntityArchetype m_NodeArchetype
Archetype used when creating a plain node entity. -
private EntityArchetype m_ChargeNodeArchetype
Archetype used for battery charge nodes. -
private EntityArchetype m_DischargeNodeArchetype
Archetype used for battery discharge nodes. -
private EntityArchetype m_EdgeArchetype
Archetype used when creating flow edge entities. -
private NativeList<Game.Simulation.Flow.Node> m_Nodes
Native list holding constructed graph nodes for the solver (allocated persistent). -
private NativeList<Game.Simulation.Flow.Edge> m_Edges
Native list holding constructed graph edges for the solver. -
private NativeList<Connection> m_Connections
Native list holding connections (adjacency) between nodes. -
private NativeReference<NodeIndices> m_NodeIndices
Native reference used to pass source/sink indices into jobs. -
private NativeList<int> m_ChargeNodes
List of node indices that are battery charge nodes. -
private NativeList<int> m_DischargeNodes
List of node indices that are battery discharge nodes. -
private NativeList<int> m_TradeNodes
List of node indices that participate in trading/outside connections. -
private NativeReference<ElectricityFlowJob.State> m_FlowJobState
Native reference holding mutable state used by repeated Flow jobs (solver state, buffers, etc). -
private NativeReference<MaxFlowSolverState> m_SolverState
Native reference storing solver-specific state for max-flow computation. -
private NativeList<LayerState> m_LayerStates
Native list used by the layered solver (internal layers bookkeeping). -
private NativeList<CutElement> m_LayerElements
Native list of cut elements used by solver internals. -
private NativeList<CutElementRef> m_LayerElementRefs
Native list of references into layer elements. -
private Entity m_SourceNode
Entity that acts as the virtual source node in the flow graph. -
private Entity m_SinkNode
Entity that acts as the virtual sink node in the flow graph. -
private Entity m_LegacyOutsideSourceNode
Temporary storage used during deserialization for older save formats (legacy outside source). -
private Entity m_LegacyOutsideSinkNode
Temporary storage used during deserialization for older save formats (legacy outside sink). -
private Phase m_NextPhase
Internal state machine phase (Prepare, Flow, Apply) used to spread the simulation across frames. -
private JobHandle m_DataDependency
JobHandle used to track scheduled job dependencies between phases. -
private TypeHandle __TypeHandle
Internal struct caching ComponentTypeHandle/BufferTypeHandle/ComponentLookup references for job scheduling. -
public const int kUpdateInterval = 128
Frame interval used to schedule the full electricity update cycle (Prepare+Flow+Apply spread across 128 frames). -
(other public constants present: kUpdatesPerDay, kUpdatesPerHour, kStartFrames, kAdjustFrame, kPrepareFrame, kFlowFrames, kFlowCompletionFrame, kEndFrames, kApplyFrame, kStatusFrame, kMaxEdgeCapacity, etc.)
Constants controlling scheduling, frame indices and maximum capacity sentinel used by the flow system.
Properties
-
public bool ready { get; private set; }
Indicates whether the last compute cycle has finished and the results have been applied (true after the Apply phase completes for a cycle). -
public EntityArchetype nodeArchetype => m_NodeArchetype
Getter for the node archetype; useful for creating flow nodes from other systems or tools. -
public EntityArchetype chargeNodeArchetype => m_ChargeNodeArchetype
Getter for battery charge node archetype. -
public EntityArchetype dischargeNodeArchetype => m_DischargeNodeArchetype
Getter for battery discharge node archetype. -
public EntityArchetype edgeArchetype => m_EdgeArchetype
Getter for the edge archetype; useful when creating flow edge entities. -
public Entity sourceNode => m_SourceNode
Getter for the internal virtual source node entity. -
public Entity sinkNode => m_SinkNode
Getter for the internal virtual sink node entity.
Constructors
public ElectricityFlowSystem()
Default constructor. The system initializes native containers and archetypes in OnCreate rather than here; the constructor is present so the runtime can instantiate the system.
Methods
-
protected override void OnCreate()
Initializes entity queries, archetypes and allocates all persistent Native containers and NativeReferences used by the system. Also retrieves SimulationSystem reference. Marked with [Preserve]. -
protected override void OnDestroy()
Completes outstanding jobs and disposes all persistent Native containers and references. Cleans up job dependencies before disposal. Marked with [Preserve]. -
public void Reset()
Resets internal scheduling state: completes any outstanding jobs, resets the flow job state to initial capacity and marks system not ready. Sets next phase to Prepare. -
protected override void OnUpdate()
State-machine loop: dispatches PreparePhase, FlowPhase or ApplyPhase depending on m_NextPhase. Called every frame by ECS. -
private void PreparePhase()
Executed during the Prepare phase (frame % 128 == 1). Gathers node and edge chunk counts, resizes and prepares m_Nodes/m_Edges/m_Connections, schedules PrepareNodesJob, PrepareEdgesJob, PrepareConnectionsJob and PopulateNodeIndicesJob. Sets up m_DataDependency and advances to Phase.Flow. -
private void FlowPhase()
Runs the electricity flow solver job(s). Assembles ElectricityFlowJob with persistent state, node/edge/connection arrays and other solver state; schedules the job and tracks dependency. The flow phase may run across many frames (m_FrameCount used by the job); on the final flow frame it transitions to Phase.Apply. -
private void ApplyPhase()
Applied at frame % 128 == 126. Schedules ApplyEdgesJob which writes computed flows and bottleneck flags back to ElectricityFlowEdge components. Marks system as ready and advances back to Phase.Prepare. -
public void Serialize<TWriter>(TWriter writer) where TWriter : IWriter
Writes minimal state required for save games: the source and sink node Entities and the flow job state's last total steps. Ensures outstanding jobs are completed before serialization. -
public void Deserialize<TReader>(TReader reader) where TReader : IReader
Reads previously serialized state handling multiple historical save-version formats. Completes outstanding jobs before modifying internal entities/state. Handles legacy outside nodes for older versions and conditionally reads older-formatted lists/integers. Restores last total steps for newer versions. -
public void SetDefaults(Context context)
Called when creating a new map or as default initialization. Calls Reset and clears source/sink Entities (they will be created in PostDeserialize or OnCreate as needed). -
public void PostDeserialize(Context context)
After deserialization, ensures source/sink nodes exist for new maps or new games with older versions; migrates or deletes legacy outside nodes and recreates trading edges for outside electricity connections in newer formats. Finally resets the system to start fresh. -
private void __AssignQueries(ref SystemState state)
Compiler helper used in OnCreateForCompiler; prepares any EntityQueryBuilders used at compile-time. -
protected override void OnCreateForCompiler()
Compiler helper which calls __AssignQueries and assigns cached TypeHandles (component type handles / lookups) used by jobs. -
(Nested job structs) PrepareNetworkJob, PrepareNodesJob, PrepareEdgesJob, PrepareConnectionsJob, PopulateNodeIndicesJob, ApplyEdgesJob and the ElectricityFlowJob (not shown in this file) implement the detailed chunked/burst-parallel preparation, population and application steps used by the system. Each is Burst-compiled and designed to run in ECS job pipelines.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Typical system will call the base initialization and then let the ElectricityFlowSystem
// prepare its internal archetypes and native containers.
// If you need to create flow nodes/edges from another system/tool, use the provided archetypes:
// var node = EntityManager.CreateEntity(electricityFlowSystem.nodeArchetype);
// var edge = EntityManager.CreateEntity(electricityFlowSystem.edgeArchetype);
}
Notes: - The system spreads expensive computation across 128-frame cycles (kUpdateInterval) to keep per-frame work small. - The flow algorithm is implemented as a staged job (Prepare → Flow → Apply) so the job pipeline and dependencies must be respected if interacting directly with the system's native containers. - If you modify the ECS components involved (ElectricityFlowNode, ElectricityFlowEdge, ConnectedFlowEdge) at runtime, ensure you respect the system's scheduling and complete dependencies where appropriate to avoid race conditions.