Skip to content

Game.Simulation.ExtractorFacilityAISystem

Assembly:
Assembly-CSharp (game runtime assembly containing simulation systems)

Namespace:
Game.Simulation

Type:
class

Base:
GameSystemBase

Summary:
System responsible for ticking all ExtractorFacility components in the world. It schedules a Burst-compiled IJobChunk (ExtractorFacilityTickJob) that iterates over entities with Game.Buildings.ExtractorFacility (excluding Temp/Destroyed/Deleted), applying randomized behavior for rotating and working states, updating timers, computing points of interest for visual effects, checking building efficiency, and emitting component changes via an EndFrameBarrier command buffer when needed. The system runs infrequently (see GetUpdateInterval/GetUpdateOffset) to spread work across simulation frames.


Fields

  • private EntityQuery m_BuildingQuery
    Holds the query that matches ExtractorFacility components (and excludes Temp/Destroyed/Deleted). Used to schedule the chunk job.

  • private EndFrameBarrier m_EndFrameBarrier
    Barrier system used to create an EntityCommandBuffer.ParallelWriter. The job uses this to safely add component changes (for example EffectsUpdated) from worker threads; the barrier collects and plays back those commands at the appropriate point in the frame.

  • private TypeHandle __TypeHandle
    Generated helper that stores Entity/Component type handles and ComponentLookup/BufferLookup handles used by the job. Assigned during system creation/compilation (OnCreateForCompiler).


Properties

  • None (the system has no public properties exposed)

Constructors

  • public ExtractorFacilityAISystem()
    Default constructor. The system is created/registered by the world; no custom constructor logic in user code.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns 256. The system is configured to run only once every 256 simulation ticks (or uses that as an interval unit to reduce frequency).

  • public override int GetUpdateOffset(SystemUpdatePhase phase)
    Returns 224. Combined with the interval, this offsets the system's execution to distribute load across ticks.

  • [Preserve] protected override void OnCreate()
    Initializes the system: obtains the EndFrameBarrier system, constructs the EntityQuery for ExtractorFacility entities, and calls RequireForUpdate with that query so the system only runs when matching entities exist.

  • [Preserve] protected override void OnUpdate()
    Schedules the ExtractorFacilityTickJob as a JobChunk over m_BuildingQuery. It fills job fields (EntityTypeHandle, component type handles, component lookups, buffer lookups, a parallel command buffer from m_EndFrameBarrier, and a RandomSeed). After scheduling, it registers the returned JobHandle with m_EndFrameBarrier via AddJobHandleForProducer and stores the job handle into base.Dependency.

  • protected override void OnCreateForCompiler()
    Called by compiled code path to assign type handles and to run any compile-time assignment helpers. It calls __AssignQueries and assigns handles via __TypeHandle.__AssignHandles.

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    Internal generated helper used during compilation; currently creates (and disposes) an EntityQueryBuilder temporary. Present for compiler compatibility.

Nested: ExtractorFacilityTickJob (Burst compiled IJobChunk) - Purpose: Iterates chunks of extractor facility entities and updates runtime state (rotating / working, timers, point of interest position, and effect updates). - Key fields used by the job: - EntityTypeHandle, ComponentTypeHandle, ComponentTypeHandle, ComponentTypeHandle, ComponentTypeHandle - ComponentLookup, ComponentLookup, ComponentLookup, ComponentLookup - BufferLookup for reading building efficiency buffer - ComponentLookup, ComponentLookup to read prefab data - RandomSeed to obtain a thread-random instance per chunk - EntityCommandBuffer.ParallelWriter m_CommandBuffer to record changes (e.g., add EffectsUpdated) - Important job methods: - Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
Iterates over entities in the chunk, gathers component arrays, obtains a per-chunk Random, and calls Tick(...) for each entity. - private void Tick(int jobIndex, Entity entity, ref Unity.Mathematics.Random random, ref Game.Buildings.ExtractorFacility extractorFacility, ref PointOfInterest pointOfInterest, Owner owner, PrefabRef prefabRef)
High-level tick logic: - Retrieves prefab ExtractorFacilityData and object geometry if present. - Resolves the top-level owner entity (traversing Owner chain and Attachment). - Computes current building efficiency via BuildingUtils.GetEfficiency. - If the resolved building flags changed in a way that affects efficiency (LowEfficiency flag), the job adds EffectsUpdated component via the command buffer and caches the building flags on the extractor facility. - Uses a randomized check against efficiency to early-out (the facility only proceeds with state updates with probability equal to efficiency). - Updates extractor state machine: - If Working and timer reaches 0 -> stop working and either start rotating or start working again depending on rotation range. - If Rotating and timer reaches 0 -> stop rotating and start working. - If neither Rotating nor Working -> decide to start rotating (if prefab rotation range varies) or start working immediately. - private void StartRotating(...)
Computes a random rotation angle within prefab's rotation range, computes a point on the object bounds (using prefab object geometry) and the point of interest for visual effect, ensures the chosen direction isn't coincident with a reversal direction, computes an angular distance to rotate, sets the point of interest position transformed into world space, sets the Rotating flag on the component, and initialises a randomized timer based on angle. - private void StartWorking(...)
Sets Working flag and a random timer (10..30 ticks). If a point of interest exists, adjusts its vertical offset based on prefab heightOffset so visual effects line up correctly.

Notes about behavior and modding: - The system is burst compiled and uses an IJobChunk pattern; changing behavior in the job requires modifying the system source and recompiling. - EffectsUpdated is added via an EndFrameBarrier parallel command buffer; any additional component writes should use that same pattern to avoid race conditions. - Prefab-driven data (ExtractorFacilityData, ObjectGeometryData) control rotation ranges, height offsets, etc. Mods can alter prefab component data to change visual/behavioral parameters. - The system respects building efficiency: many actions are probabilistic and gated by BuildingUtils.GetEfficiency and the RandomSeed per-chunk, so efficiency and random seed changes affect how often extractors animate or produce effects.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Example: obtain the EndFrameBarrier (similar to what ExtractorFacilityAISystem does)
    var endFrameBarrier = World.GetOrCreateSystemManaged<EndFrameBarrier>();
    // You might create a system that issues commands in a job and needs a parallel ECB:
    var commandBuffer = endFrameBarrier.CreateCommandBuffer().AsParallelWriter();
}

If you are modding extractor behavior, consider: - Adjusting ExtractorFacilityData or ObjectGeometryData on the prefab to change rotation ranges, timers and height offsets. - Adding or removing EffectsUpdated reactions in other systems; ExtractorFacilityAISystem only schedules that component when building flags affecting efficiency change. - Be mindful of randomization (RandomSeed.Next()) and the job's probabilistic gating by building efficiency when debugging intermittent behavior.