Game.Simulation.DomesticatedAISystem
Assembly:
Assembly-CSharp (typical runtime assembly for game code; adjust if different in your environment)
Namespace:
Game.Simulation
Type:
public class DomesticatedAISystem
Base:
GameSystemBase
Summary:
DomesticatedAISystem is an ECS system responsible for driving the AI/tick logic of domesticated creatures in the world. It schedules two Burst-compiled IJobChunk jobs:
- DomesticatedTickJob — handles individual (non-group) domesticated animals: roaming/idling/wandering, path end behavior, target selection around the owner, handling swimming/flying targets, sampling terrain and water heights, and eventually deleting entities that are stuck or out-of-area.
- DomesticatedGroupTickJob — handles group members: ensures they get an AnimalCurrentLane if missing, propagates certain flags from the group leader (swimming/flying targets and roaming state), and deletes stuck group members.
The system integrates with TerrainSystem and WaterSystem to sample heights, uses a RandomSeed per job batch, and writes structural changes via an EndFrameBarrier-provided EntityCommandBuffer (ParallelWriter). It also sets up EntityQueries to select domesticated creatures and group creatures, and ensures the jobs are registered as producers with the EndFrameBarrier and readers with Terrain/Water systems for correct dependency management.
Fields
-
private EndFrameBarrier m_EndFrameBarrier
Holds the EndFrameBarrier system instance used to create a parallel EntityCommandBuffer for structural changes (AddComponent/Delete). Jobs produced by this system are registered via m_EndFrameBarrier.AddJobHandleForProducer to ensure correct ordering. -
private TerrainSystem m_TerrainSystem
Reference to the TerrainSystem used to obtain CPU-side height data required for ground placement and sampling. -
private WaterSystem m_WaterSystem
Reference to the WaterSystem used to obtain water surface data for sampling water heights and swim-depth bounds. -
private EntityQuery m_CreatureQuery
EntityQuery selecting individual domesticated creatures (non-group members) to run DomesticatedTickJob. Includes read/write components like Animal and Domesticated and read-only PrefabRef and UpdateFrame. Excludes Deleted, Temp, Stumbling, GroupMember. -
private EntityQuery m_GroupCreatureQuery
EntityQuery selecting group-member domesticated creatures to run DomesticatedGroupTickJob. Targets entities with GroupMember component and excludes Deleted, Temp, Stumbling. -
private TypeHandle __TypeHandle
Internal struct that caches component/entity type handles and component lookups used when scheduling jobs. It is assigned in OnCreateForCompiler and used to produce ComponentTypeHandle/ComponentLookup for the jobs in OnUpdate.
Properties
- (none public)
This system does not expose public properties. All important orchestration is internal and done through the EntityQueries and scheduled jobs.
Constructors
public DomesticatedAISystem()
Default constructor (preserved). The system initialization and wiring are done in OnCreate/OnCreateForCompiler rather than the constructor.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns the update interval used by the game to decide how often this system should run. This system returns 16, meaning it updates at that interval (in the engine's scheduling scheme). -
public override int GetUpdateOffset(SystemUpdatePhase phase)
Returns the update offset for scheduling. This system returns 9. -
[Preserve] protected override void OnCreate()
Initializes the system: obtains EndFrameBarrier, TerrainSystem, WaterSystem instances; creates the EntityQueries (m_CreatureQuery and m_GroupCreatureQuery); calls RequireAnyForUpdate to require at least one of the queries for the system to run. This is where system-level dependencies and queries are defined. -
[Preserve] protected override void OnUpdate()
Prepares and schedules the Burst IJobChunk jobs: - Builds a DomesticatedTickJob with component handles, component lookups (transform, owner, lane, building, prefab data, prefab-specific AnimalData/DomesticatedData), RandomSeed, terrain/water height data, and an EndFrameBarrier command buffer (ParallelWriter).
- Builds a DomesticatedGroupTickJob with handles and an Animal component lookup so group members can access leader animal data.
- Schedules DomesticatedTickJob in parallel for m_CreatureQuery, then schedules DomesticatedGroupTickJob dependent on the first job.
- Registers job handles with TerrainSystem and WaterSystem readers and with the EndFrameBarrier producer, and stores resulting dependency in base.Dependency.
The jobs do the main AI work: idling/wandering state machine, path continuation/selection, setting navigation target positions (with terrain/water sampling), flipping roaming/flying/swimming flags, and deleting entities that are stuck or outside valid lanes.
-
protected override void OnCreateForCompiler()
Used by the generated code path to initialize TypeHandle and to assign component type/lookup handles for the Burst jobs. Calls __AssignQueries and __TypeHandle.__AssignHandles. -
private void __AssignQueries(ref SystemState state)
Internal helper used at compile-time to set up any query-related scaffolding; in the decompiled code it creates and disposes an EntityQueryBuilder (placeholder for compiler-only wiring). -
[MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignHandles(ref SystemState state)
(inside TypeHandle)
Assigns all required ComponentTypeHandle, ComponentLookup and BufferLookup instances from the SystemState so they can be converted to job-accessible handles in OnUpdate. -
Nested job structs:
-
DomesticatedTickJob (private struct, BurstCompile, implements IJobChunk)
Handles the per-chunk AI update for single domesticated animals. Key behaviors:- Ensures AnimalCurrentLane exists on the entity.
- Uses CreatureUtils.CheckUnspawned to handle unspawned state.
- Toggles AnimalFlags.Roaming based on whether currentLane.m_Lane is set.
- If path end is reached, executes PathEndReached which:
- Handles idling <> wandering state transitions using DomesticatedData m_IdleTime.
- If roaming, selects a new navigation target near the owner (using owner transform and owner prefab geometry).
- Chooses between swimming/flying/ground placement and samples water/terrain heights accordingly.
- Handles sub-lane area transitions for lane-based navigation (random choice among connected sublanes).
- Deletes the entity when it cannot find a new target or is outside valid areas.
- Uses RandomSeed per batch and reads data from PrefabRef-based component lookups (AnimalData, DomesticatedData, ObjectGeometryData).
- Writes structural changes using m_CommandBuffer (parallel).
-
DomesticatedGroupTickJob (private struct, BurstCompile, implements IJobChunk)
Handles the per-chunk AI update for group-member domesticated animals. Key behaviors:- Ensures AnimalCurrentLane exists.
- Uses CreatureUtils.CheckUnspawned to handle unspawned state.
- If creature is stuck, marks it Deleted.
- If leader exists and has an Animal component, copies leader's SwimmingTarget/FlyingTarget flags and synchronizes roaming flag transitions at path end.
- Uses a ComponentLookup
to read/write animal data for both member and leader.
Notes about jobs: - Both jobs run with BurstCompile and are scheduled via ScheduleParallel; they use ComponentTypeHandle/ComponentLookup conversions through InternalCompilerInterface to produce job-safe handles. - Randomization: DomesticatedTickJob uses a RandomSeed.Next() per chunk to pick random wander times, directions and sub-lane choices. - Safety: structural changes (AddComponent/Delete) are done via the EndFrameBarrier command buffer to remain thread-safe.
Usage Example
// Example: Accessing the DomesticatedAISystem from game code (typical in a mod).
using UnityEngine;
using Unity.Entities;
using Game.Simulation;
public class MyMod
{
public void PrintSystemUpdateInfo()
{
var world = World.DefaultGameObjectInjectionWorld;
if (world == null) return;
var domSystem = world.GetExistingSystemManaged<DomesticatedAISystem>();
if (domSystem != null)
{
// GetUpdateInterval is public and can be queried with a SystemUpdatePhase value
int interval = domSystem.GetUpdateInterval(SystemUpdatePhase.Simulation);
Debug.Log($"DomesticatedAISystem update interval: {interval}");
}
}
}
Additional notes for modders: - If you need to modify or extend behavior, prefer adding separate systems that run before/after this system (use update ordering or SystemUpdatePhase offsets) or hook into entity prefabs (PrefabRef) or CreatureUtils helpers rather than editing game assemblies directly. - Be mindful of Burst/job safety rules: jobs operate on chunk data using component handles/lookups and must not access managed objects. Structural changes are done via the EndFrameBarrier's command buffer; follow the same pattern if you create your own jobs.