Game.Simulation.WorkCarAISystem
Assembly: Assembly-CSharp
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
WorkCarAISystem is an ECS System responsible for driving "work" vehicles (harvesters, collectors, storage/cargo movers) in the simulation. It runs a parallel IJobChunk (WorkCarTickJob) to update each work vehicle's pathing, state, targeting and partial work progress, enqueues pathfinding requests to PathfindSetupSystem, and collects work actions into a queue. A follow-up single-threaded IJob (WorkCarWorkJob) processes the queued WorkAction items to apply world mutations (for example changing tree state or updating extractor stats). The system uses an EndFrameBarrier to safely emit EntityCommandBuffer commands from jobs at end of frame scheduling.
Fields
-
private struct WorkAction
An internal data structure used to describe a unit of work that must be applied on the world (e.g., harvested wood, collected flags). Contains the VehicleWorkType, target entity, owner entity, and a work amount float. Instances are enqueued by the tick job and consumed by the work job. -
private struct WorkCarTickJob : IJobChunk
Burst-compiled IJobChunk that iterates matching vehicle archetype chunks. Responsible for per-vehicle logic each tick: resetting and requesting paths, detecting path end/stuck states, marking vehicles returning to depot, distributing work amounts among vehicles in a layout, enqueuing pathfind requests, and pushing WorkAction items into a NativeQueue for later processing. Also writes component changes via a parallel EntityCommandBuffer. -
private struct WorkCarWorkJob : IJob
Burst-compiled single-threaded job that dequeues WorkAction items and applies world changes that can't be done in the parallel tick (for example mutating Tree or Extractor components). Runs after the tick job finishes and before the end of the system update completes. -
private struct TypeHandle
A generated helper struct that holds all EntityTypeHandle / ComponentTypeHandle / BufferTypeHandle and ComponentLookup/BufferLookup objects used by the jobs. It exposes an __AssignHandles method used in OnCreateForCompiler to populate the handles from the SystemState. -
private EndFrameBarrier m_EndFrameBarrier
EndFrameBarrier obtained from the World. Used to create a parallel EntityCommandBuffer for safe structural/component changes requested by jobs. The tick job uses m_EndFrameBarrier.CreateCommandBuffer().AsParallelWriter(). -
private PathfindSetupSystem m_PathfindSetupSystem
Reference to the PathfindSetupSystem used to get or create a pathfinding request queue. WorkCarTickJob pushes SetupQueueItem path requests into this queue. -
private EntityQuery m_VehicleQuery
EntityQuery used to select work vehicles to update. The query includes WorkVehicle (read/write), CarCurrentLane, Owner, PrefabRef, PathOwner, Target and excludes Deleted, Temp, TripSource, OutOfControl. The system RequireForUpdate's this query so it only runs when there are matching vehicles. -
private TypeHandle __TypeHandle
Instance of the generated TypeHandle struct used to pass type handles to the jobs. Populated during OnCreateForCompiler.
Properties
- (none)
There are no public properties exposed by this system.
Constructors
public WorkCarAISystem()
Default constructor. The system uses [Preserve] on lifecycle methods; construction itself does not perform initialization beyond base.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns 16. This system is scheduled at a reduced update frequency (every 16 frames by whatever driver uses this interval). -
public override int GetUpdateOffset(SystemUpdatePhase phase)
Returns 12. The system applies an offset so it runs at a specific phase offset relative to other systems. -
protected override void OnCreate()
Initializes runtime references: obtains EndFrameBarrier and PathfindSetupSystem from the world and builds the Vehicle query used by the system. Calls RequireForUpdate(m_VehicleQuery) so the system only updates if there are matching entities. -
protected override void OnUpdate()
Core scheduling method. Creates a NativeQueue(temporary job) then configures WorkCarTickJob (IJobChunk) with all required type handles, lookups and writers including: - m_CommandBuffer := m_EndFrameBarrier.CreateCommandBuffer().AsParallelWriter()
- m_PathfindQueue := m_PathfindSetupSystem.GetQueue(...).AsParallelWriter()
- m_WorkQueue := workQueue.AsParallelWriter()
Schedules the WorkCarTickJob (parallel chunk job), then schedules WorkCarWorkJob (IJob) dependent on the tick job. Disposes the workQueue after the work job completes, registers the pathfind queue writer with PathfindSetupSystem, adds the tick job handle to the EndFrameBarrier as a producer, and updates base.Dependency to the final job handle.
The job graph ensures per-vehicle updates run in parallel, but world-mutation operations (tree/ extractor state changes) are applied safely in the follow-up single-threaded job.
-
protected override void OnCreateForCompiler()
Compiler-time helper used to assign empty queries and to call __TypeHandle.__AssignHandles to populate all type handles from the SystemState. (This is part of the generated ECS boilerplate used by Unity's DOTS conversion.) -
private void __AssignQueries(ref SystemState state)
Currently contains a no-op EntityQueryBuilder call. Present for generated-query assignment and kept for compiler compatibility. -
(Nested)
TypeHandle.__AssignHandles(ref SystemState state)
Assigns all EntityTypeHandle / ComponentTypeHandle / BufferTypeHandle and Component/BufferLookups used by the jobs from the provided SystemState. This is used during setup so Job structs can get their handles.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Typical setup performed by the real system: get barriers and setup systems, create vehicle query
m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
m_PathfindSetupSystem = base.World.GetOrCreateSystemManaged<PathfindSetupSystem>();
m_VehicleQuery = GetEntityQuery(
ComponentType.ReadWrite<Game.Vehicles.WorkVehicle>(),
ComponentType.ReadWrite<CarCurrentLane>(),
ComponentType.ReadOnly<Owner>(),
ComponentType.ReadOnly<PrefabRef>(),
ComponentType.ReadWrite<PathOwner>(),
ComponentType.ReadWrite<Target>(),
ComponentType.Exclude<Deleted>(),
ComponentType.Exclude<Temp>(),
ComponentType.Exclude<TripSource>(),
ComponentType.Exclude<OutOfControl>());
RequireForUpdate(m_VehicleQuery);
}
Notes / Implementation tips: - WorkCarTickJob is Burst compiled and designed for parallel iteration; avoid introducing non-thread-safe state into the job. - All structural or component changes from parallel context are emitted using the parallel EntityCommandBuffer created from m_EndFrameBarrier. - Pathfinding requests are batched through PathfindSetupSystem; the job enqueues SetupQueueItem instances rather than performing pathfinding inline. - The WorkCarWorkJob must run single-threaded (IJob) since it performs direct ComponentLookup writes (mutable tree and extractor updates) and dequeues the work queue.