Game.AnimalNavigationSystem
Assembly:
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
AnimalNavigationSystem is the simulation system responsible for driving animal movement and navigation logic in the Cities: Skylines 2 simulation. It schedules two main jobs that run on specific simulation frames: GroupNavigationJob (keeps group members following their leader) and UpdateNavigationJob (computes each animal's navigation target, speed and collision/blocker logic). The system integrates with many engine subsystems (terrain, water, net/area/object search trees, prefab data, path owners, etc.), and uses JobChunk-based ECS jobs with Burst for high performance. It also creates and uses a nested Actions helper that manages a LaneObjectUpdater job-buffer used while computing navigation. This system runs periodically (when frameIndex % 16 == 5, 9 or 13) and sets up dependencies/readers with other systems to correctly read terrain, water and search trees.
Fields
-
private SimulationSystem m_SimulationSystem
Reference to the SimulationSystem used to obtain the current simulation frame index and other simulation-wide data. -
private CityConfigurationSystem m_CityConfigurationSystem
Access to city configuration settings (for example left-/right-hand traffic options used when calculating lane positions). -
private Game.Net.SearchSystem m_NetSearchSystem
Used to obtain the net search tree for road/lane lookups. -
private Game.Areas.SearchSystem m_AreaSearchSystem
Used to obtain the area search tree used for area-lane lookups. -
private Game.Objects.SearchSystem m_ObjectSearchSystem
Used to obtain static and moving object search trees used in collision and transform searches. -
private TerrainSystem m_TerrainSystem
Provides terrain height data used to snap animal targets to terrain. -
private WaterSystem m_WaterSystem
Provides water surface data used to handle swimming targets and swim depths. -
private Actions m_Actions
Nested Actions system instance used to manage lane object updates and a lane object command buffer used by the UpdateNavigationJob. -
private EntityQuery m_CreatureQuery
EntityQuery used to select Animal entities to process (reads Animal, UpdateFrame shared component, and reads/writes AnimalCurrentLane). -
private TypeHandle __TypeHandle
Internal container for component/lookup handles used to build and schedule the jobs. Populated in OnCreateForCompiler.
Properties
- (none public on this system)
Nested types (short overview)
-
Groups
Nested GameSystemBase that schedules GroupNavigationJob to synchronize group members with their leaders (runs on the same frames as main system). Uses EntityQuery filtering by UpdateFrame. -
Actions
Nested GameSystemBase that owns a LaneObjectUpdater and applies its results. It exposes an internal JobHandlem_Dependency
and the LaneObjectUpdater which UpdateNavigationJob uses to write lane-object related commands. -
GroupNavigationJob : IJobChunk
Job that updates AnimalCurrentLane for group members by copying lane/curve position/flags from their leader (leader can be HumanCurrentLane or AnimalCurrentLane). -
UpdateNavigationJob : IJobChunk
Main heavy job that computes navigation per animal: finds/updates current lane, computes target position/direction/activity/max speed, resolves blockers and collisions, clamps to terrain/water/flying/swimming rules, and writes results into AnimalNavigation, Blocker and AnimalCurrentLane components. It uses many lookup buffers/quadtrees and helper iterators (CreatureTargetIterator, CreatureCollisionIterator, etc.). -
TypeHandle
(struct)
Internal struct used to store handles to many component types and buffer/lookup handles required by the jobs.
Constructors
public AnimalNavigationSystem()
Default constructor. System initialization happens in OnCreate. (Marked with [Preserve] attribute in code for stripping/serialization safety.)
Methods
-
protected override void OnCreate()
Initializes references to other systems (SimulationSystem, CityConfigurationSystem, SearchSystems, Terrain/Water systems) and creates the nested Actions system. Also builds the m_CreatureQuery to select Animal entities that should be processed. -
protected override void OnUpdate()
Main update method. Executes only when the simulation frame index modulo 16 equals 5, 9 or 13. For those frames it: - Resets and filters m_CreatureQuery by UpdateFrame shared component.
- Schedules UpdateNavigationJob (IJobChunk) over the query with many component lookups, buffers and search-tree readers.
- Hooks the returned jobHandle as readers into the terrain/water/search systems so they know the job is using their data.
- Passes the job handle to the nested Actions system (m_Actions.m_Dependency) so lane object updates can be applied safely.
-
Uses RandomSeed.Next(), left-hand-traffic flag and obtains height/surface/search trees for read-only access.
-
protected override void OnCreateForCompiler()
Helper to assign queries and component handles for compiler-managed builds. Calls __AssignQueries and assigns handles in __TypeHandle. -
private void __AssignQueries(ref SystemState state)
Internal helper (compiler-generated pattern) used to create/validate entity queries during compilation-time initialization. -
(Nested types expose additional methods; the most important are:)
GroupNavigationJob.Execute(...)
— copies lane/curve and flags from leader to group member AnimalCurrentLane.UpdateNavigationJob.Execute(...)
— per-chunk logic to update AnimalNavigation, Blocker and AnimalCurrentLane. Contains many private helpers:- UpdateStumbling(...)
- TryFindCurrentLane(...)
- UpdateNavigationTarget(...) — main logic for target selection, speed calculation, collisions and blockers.
- CalculateTargetPos(...) (two overloads)
- MoveAreaTarget(...)
- MoveTransformTarget(...)
- GetTransformTarget(...)
- MoveLaneTarget(...) These helpers implement area-lane targeting, transform targets (activity locations / building positions), lane-based navigation, braking/speed clamping, roaming/group/follow logic, and collision/blocker resolution.
Behavior notes / important implementation details
-
Frame scheduling: the system is designed to run only on specific frames (frameIndex % 16 == 5, 9 or 13). That spreads work across frames and aligns with UpdateFrame shared component filtering used to process subsets of animals each frame.
-
Read/Write access: UpdateNavigationJob writes AnimalNavigation and Blocker components and writes AnimalCurrentLane back into the ComponentLookup passed in (m_AnimalCurrentLaneData). It reads a large set of lookup components (curves, lanes, prefab data, path elements, etc.) and uses multiple QuadTrees (nets, static objects, moving objects, areas) for spatial queries.
-
Integration with search systems: Before/after scheduling the job, OnUpdate registers the job as a reader with terrain, water and search systems so those systems can account for concurrent reads.
-
Collision & blocking: The job computes provisional max speed and runs a CreatureCollisionIterator which considers other creatures, owners, lane reservations and lane objects to determine final max speed, queueing and blocking behavior. Blocker information is stored in the Blocker component and blocker.m_MaxSpeed is encoded into a byte value scaled appropriately.
-
Roaming vs path-following: Animals with the AnimalFlags.Roaming flag use roaming logic (pick random nearby targets), while non-roaming animals follow area/path/connection lanes and may follow a leader (human or animal). Group members copy leaders' lane info in GroupNavigationJob.
-
Swimming/Flying: The system honors swim/fly flags by modifying lane flags and clamping vertical target positions using water/terrain height data and prefab swim/fly bounds.
Usage Example
// Example: Obtain the AnimalNavigationSystem and inspect whether it exists.
// Note: AnimalNavigationSystem has mostly internal/private fields; mods typically interact
// with the ECS world or specific components rather than calling system internals directly.
var world = World.DefaultGameObjectInjectionWorld;
var animalNavSystem = world.GetOrCreateSystemManaged<Game.Simulation.AnimalNavigationSystem>();
// You can log that the system exists and rely on its normal scheduling.
// For more advanced behavior you would operate on the Animal/AnimalCurrentLane/AnimalNavigation components
// or hook into the search/terrain systems that the job reads.
Debug.Log($"AnimalNavigationSystem present: {animalNavSystem != null}");
If you want to influence animal navigation from a mod, consider: - Adding/modifying components on Animal entities (Animal, AnimalCurrentLane, AnimalNavigation) using ECS APIs. - Altering prefab data (AnimalData, CreatureData, ObjectGeometryData) or owner/activity data used by the job. - Interacting with search/terrain/water systems with proper reader registration if you schedule your own jobs that read the same data. - Respect the system's UpdateFrame pattern (UpdateFrame shared component) if you want to run custom per-animal jobs in the same staggered schedule.