Skip to content

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 JobHandle m_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.