Skip to content

Game.Simulation.ResourceProducerSystem

Assembly:
Game

Namespace:
Game.Simulation

Type:
class

Base:
GameSystemBase

Summary:
ResourceProducerSystem is a simulation system that processes all entities with a ResourceProducer component. It runs a Burst-compiled IJobChunk (ResourceProducerJob) on matching chunks to aggregate resource production data from the building prefab and any installed upgrades, inspects the entity's Resources buffer, and, when a resource's stored amount reaches the export threshold (math.min(2000, storageCapacity)), it enqueues an EntityCommandBuffer command to add a ResourceExporter component to that entity. The system is scheduled only for entities that match an UpdateFrame computed from the current simulation frame (kUpdatesPerDay = 16), and it uses an EndFrameBarrier to issue commands safely at the end of the frame.


Fields

  • public static readonly int kUpdatesPerDay
    {{ This constant defines how many update slices per day the system considers. It is used when computing the UpdateFrame filter in GetUpdateInterval/OnUpdate. Its value is 16. }}

  • private SimulationSystem m_SimulationSystem
    {{ Reference to the global SimulationSystem instance; used to get the current frameIndex to compute which UpdateFrame this system should run for. }}

  • private EndFrameBarrier m_EndFrameBarrier
    {{ EndFrameBarrier used to create an EntityCommandBuffer. The ResourceProducerJob gets a parallel writer from this barrier to add ResourceExporter components in a thread-safe way, and the barrier gets the job handle so commands are applied once the job finishes. }}

  • private EntityQuery m_ResourceProducerQuery
    {{ Query used to select all entities that are resource producers and that should run on a particular update slice. The query requires components: ResourceProducer (read-only), Resources (read-only buffer), UpdateFrame (read-only), and excludes Deleted, Destroyed and Temp. The query's shared filter is set each update based on SimulationUtils.GetUpdateFrame(...). }}

  • private TypeHandle __TypeHandle
    {{ Generated struct holding EntityTypeHandle, ComponentTypeHandle and BufferTypeHandle instances used by the job. __TypeHandle.__AssignHandles(ref SystemState) populates these handles. This is part of the ECS/IL post-compiler pattern. }}

  • (nested) private struct ResourceProducerJob (BurstCompile)
    {{ The chunk job that performs per-entity processing:

  • Reads PrefabRef (component), InstalledUpgrade (buffer), Resources (buffer).
  • Uses a BufferLookup to fetch production definitions from the prefab and upgrades.
  • Accumulates combined ResourceProductionData into an internal NativeList (allocated as Temp per worker when first used).
  • For each resource production entry, retrieves the current amount from the entity's Resources buffer via EconomyUtils.GetResources and compares it against math.min(2000, storageCapacity).
  • If above threshold, enqueues a ResourceExporter component with the resource type and amount using EntityCommandBuffer.ParallelWriter. Notes: the job uses [NativeDisableContainerSafetyRestriction] for the internal NativeList and is Burst-compiled for performance. }}

  • (nested) private struct TypeHandle
    {{ Holds the various type handles and lookup structures used by the job (EntityTypeHandle, ComponentTypeHandle, BufferTypeHandle, BufferTypeHandle, ComponentLookup, BufferLookup), and a method __AssignHandles to populate them from a SystemState. This is a generated helper to avoid repeatedly requesting handles. }}

Properties

  • (none)
    {{ This system does not expose public properties. All state is kept in private fields and via the nested type handles. }}

Constructors

  • public ResourceProducerSystem()
    {{ Default parameterless constructor. Marked with [Preserve], created by the runtime or world when instantiating managed systems. No custom initialization is performed here; initialization occurs in OnCreate. }}

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    {{ Returns the system's update interval in ticks (or the engine's update unit). The implementation returns 262144 / (kUpdatesPerDay * 16). This determines how often the system is considered for execution relative to the engine's scheduling cadence. }}

  • [Preserve] protected override void OnCreate()
    {{ OnCreate gets references to SimulationSystem and EndFrameBarrier via World.GetOrCreateSystemManaged, constructs the EntityQuery used to find resource producers, and calls RequireForUpdate(m_ResourceProducerQuery) so the system only runs when matching entities exist. The query reads ResourceProducer and Resources buffers and filters out Deleted/Destroyed/Temp entities. }}

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

  • Resets and sets a shared component filter on m_ResourceProducerQuery based on SimulationUtils.GetUpdateFrame(m_SimulationSystem.frameIndex, kUpdatesPerDay, 16) so only entities assigned to the current update slice are processed.
  • Constructs and schedules ResourceProducerJob via JobChunkExtensions.ScheduleParallel, passing in all required handles/lookups and the EndFrameBarrier's parallel command buffer writer.
  • Adds the returned JobHandle to the EndFrameBarrier via AddJobHandleForProducer and assigns it to base.Dependency. This method therefore performs the chunked (parallel) processing described in the job and ensures end-of-frame commands are applied safely. }}

  • private void __AssignQueries(ref SystemState state)
    {{ Generated helper for compiler-constructed code. In this implementation it only constructs and disposes a temporary EntityQueryBuilder; the important work is performed in OnCreate and OnUpdate. }}

  • protected override void OnCreateForCompiler()
    {{ Called by generated/compiled code: calls __AssignQueries and populates __TypeHandle via __AssignHandles(ref base.CheckedStateRef). This is part of the post-compiler wiring for ECS. }}

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    {{ Inline helper (duplicate declaration for clarity in the generated code). }}

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Get required systems and create the entity query for resource producers
    m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
    m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
    m_ResourceProducerQuery = GetEntityQuery(
        ComponentType.ReadOnly<Game.Buildings.ResourceProducer>(),
        ComponentType.ReadOnly<Game.Economy.Resources>(),
        ComponentType.ReadOnly<UpdateFrame>(),
        ComponentType.Exclude<Deleted>(),
        ComponentType.Exclude<Destroyed>(),
        ComponentType.Exclude<Temp>()
    );
    RequireForUpdate(m_ResourceProducerQuery);
}

Notes and tips: - The heavy lifting is done in ResourceProducerJob, which is Burst-compiled and scheduled in parallel over chunks. When inspecting or modifying this system for modding, be careful to preserve the way ResourceProductionData is combined (it merges prefab production and upgrade production) and how the ResourceExporter component is created via the EndFrameBarrier command buffer (to avoid race conditions). - The export threshold uses math.min(2000, storageCapacity), so large storageCapacity values are effectively clamped to 2000 for the export decision. - If you add or change resource production definitions (ResourceProductionData) for prefabs or upgrades, the job will pick them up via the BufferLookup from the prefab referenced in PrefabRef and installed upgrades.