Skip to content

Game.Tools.TerrainToolSystem

Assembly: Game (Assembly-CSharp)
Namespace: Game.Tools

Type: class

Base: ToolBaseSystem

Summary:
TerrainToolSystem implements the gameplay tool that handles all terrain/terraforming interactions (raise/lower/level/slope/soften, paint/erase materials and resources) in Cities: Skylines 2. It integrates raycasting, brush management, UI sound feedback, and creates entity "creation definitions" that are consumed by other systems to apply terrain changes. The system uses Unity's ECS jobs (including a Burst-compiled job) and works with the tool input/action system to map player input to terrain operations.


Nested Types

  • private enum State
    Represents the current interaction state of the tool: Default (idle), Adding (applying terrain), Removing (erasing/inverting).

  • [BurstCompile] private struct CreateDefinitionsJob : IJob
    Burst-compiled job that creates CreationDefinition and BrushDefinition entities when called. The job is read-only for its inputs and writes via an EntityCommandBuffer. It packages brush/prefab references, brush parameters (size, angle, strength, time), the target/line to apply and will create an entity with CreationDefinition, BrushDefinition and Updated components for downstream processing.

  • private struct TypeHandle
    Holds a ComponentTypeHandle for efficient chunk reads in jobs. Provides __AssignHandles(ref SystemState) to initialize the handle from a SystemState.


Fields

  • private AudioManager m_AudioManager
    Holds reference to the game's AudioManager system used to play UI/terraforming sounds.

  • private UnityEngine.AudioSource m_AudioSource
    The currently playing AudioSource for the exclusive terraform UI sound (if any). Used to stop sound when finishing/canceling.

  • private ToolOutputBarrier m_ToolOutputBarrier
    Barrier system used to create entities (CreationDefinition / BrushDefinition) in a job-safe manner with an EntityCommandBuffer.

  • private Unity.Entities.EntityQuery m_DefinitionQuery
    EntityQuery used to find and destroy existing definition entities (CreationDefinition/BrushDefinition) before creating new ones.

  • private Unity.Entities.EntityQuery m_BrushQuery
    EntityQuery used to find available brush prefabs.

  • private Unity.Entities.EntityQuery m_TempQuery
    EntityQuery selecting temporary brush entities (Component) — used when inverting brushes (e.g., cancel path).

  • private Unity.Entities.EntityQuery m_SoundQuery
    Query used to fetch ToolUXSoundSettingsData for the terraform UI sound.

  • private Unity.Entities.EntityQuery m_VisibleQuery
    Query selecting all visible Brush components (Brush && !Hidden && !Deleted) used to detect brush setting changes.

  • private IProxyAction m_EraseMaterial
    Input action proxy for "Erase Material" (tool action mapping).

  • private IProxyAction m_EraseResource
    Input action proxy for "Erase Resource".

  • private IProxyAction m_FastSoften
    Input action proxy for "Fast Soften".

  • private IProxyAction m_LevelTerrain
    Input action proxy for "Level Terrain".

  • private IProxyAction m_LowerTerrain
    Input action proxy for "Lower Terrain".

  • private IProxyAction m_PaintMaterial
    Input action proxy for "Paint Material".

  • private IProxyAction m_PaintResource
    Input action proxy for "Paint Resource".

  • private IProxyAction m_RaiseTerrain
    Input action proxy for "Raise Terrain".

  • private IProxyAction m_SetLevelTarget
    Input action proxy for "Set Level Target".

  • private IProxyAction m_SetSlopeTarget
    Input action proxy for "Set Slope Target".

  • private IProxyAction m_SlopeTerrain
    Input action proxy for "Slope Terrain".

  • private IProxyAction m_SoftenTerrain
    Input action proxy for "Soften Terrain".

  • private ControlPoint m_RaycastPoint
    Stores the latest raycast ControlPoint (hit information) from the tool raycast system.

  • private ControlPoint m_StartPoint
    Start ControlPoint for a drag/application operation (used to form a line for brush application).

  • private float3 m_TargetPosition
    Optional explicit target height/position for certain terraform operations. If set, brush uses this target Y instead of raycast Y.

  • private float3 m_ApplyPosition
    Position at the time Apply was initiated (used by CreateDefinitionsJob.m_ApplyStart).

  • private bool m_TargetSet
    Flag indicating whether m_TargetPosition has been set by the user.

  • private State m_State
    Current tool state (Default, Adding, Removing).

  • private TypeHandle __TypeHandle
    Cached TypeHandle wrapper used by internal methods for fast component access (holds Brush ComponentTypeHandle).


Properties

  • public override string toolID { get; }
    Returns the tool identifier string: "Terrain Tool". Used by the tool manager and UI to identify this tool.

  • public TerraformingPrefab prefab { get; private set; }
    Currently selected TerraformingPrefab (the prefab which defines type of operation — Shift/Level/Slope/Soften and target). Setter is private; SetPrefab or TrySetPrefab should be used.

  • public override bool brushing { get; }
    Overrides base to indicate this tool uses brushing (true).

  • private protected override IEnumerable<IProxyAction> toolActions { get; }
    Enumerates all IProxyAction instances used by this tool. The system yields actions in a deterministic order so the tool framework can register and show them in UI.

  • public float brushHeight { get; set; }
    Gets or sets the explicit brush height Y. Getter returns WaterSystem.SeaLevel when no target set; setter sets m_TargetPosition.y and flips m_TargetSet to true.


Constructors

  • [Preserve] public TerrainToolSystem()
    Default constructor. Marked with Preserve attribute to avoid stripping. Initialization of most runtime state happens in OnCreate/OnStartRunning.

Methods

  • [Preserve] protected override void OnCreate()
    Initializes system references when the system is created. Retrieves the AudioManager, ToolOutputBarrier, sets up the EntityQueries (definition, brush, visible, temp, sound), and fetches IProxyAction instances from InputManager. Also sets default brush size/angle/strength.

  • protected override void OnGameLoaded(Context serializationContext)
    Called when a saved game is loaded. Ensures a default brush is selected and resets brush size/angle/strength to defaults appropriate for the tool.

  • public void SetDisableFX()
    Stops any currently playing exclusive terraform UI sound (via m_AudioManager) and clears m_AudioSource. Call when applying/canceling operations to stop sound effects.

  • [Preserve] protected override void OnStartRunning()
    Called when the system starts running. Resets ControlPoints and tool state (m_RaycastPoint, m_StartPoint, m_State).

  • private protected override void UpdateActions()
    Updates proxy action overrides (applyActionOverride and secondaryApplyActionOverride) according to the currently selected prefab (TerraformingType and TerraformingTarget). Uses ProxyAction.DeferStateUpdating() to batch updates. Called whenever prefab or action availability changes.

  • public override PrefabBase GetPrefab()
    Returns the prefab currently used by the tool (casts TerraformingPrefab to PrefabBase).

  • public override bool TrySetPrefab(PrefabBase prefab)
    Attempts to set the tool's prefab. If the provided prefab is a TerraformingPrefab, SetPrefab is called and true returned. Otherwise returns false.

  • public override void InitializeRaycast()
    Configures the internal tool raycast system according to whether a prefab and brush type are selected. When valid, sets the raycast TypeMask to Terrain and enables RaycastFlags.Outside; otherwise disables raycasting.

  • [Preserve] protected override JobHandle OnUpdate(JobHandle inputDeps)
    Main per-frame update. Validates brush selection, sets requirements for networked layers and pipelines, handles focus/state transitions, processes input (apply/secondary apply) and routes to Apply/Cancel/Update/Clear flows. Creates/updates definitions when necessary and updates infoview. Returns combined JobHandle for any scheduled jobs.

  • public override void GetAvailableSnapMask(out Snap onMask, out Snap offMask)
    Extends base snap mask behavior: when prefab target is Height, it adds ContourLines snapping to both on and off masks.

  • private JobHandle Clear(JobHandle inputDeps)
    Sets applyMode to Clear and disables FX (stops audio). Returns the passed inputDeps (no jobs scheduled).

  • private JobHandle Cancel(JobHandle inputDeps, bool singleFrameOnly = false)
    Handles the secondary-apply (cancel) behavior. If starting a cancel interaction from Default, switches to Removing state and plays sound, sets target, inverts temporary brushes and schedules definition updates. If ending a cancel, reverts to Default, stops sound and schedules definition updates. Returns a JobHandle combining any scheduled jobs.

  • private JobHandle Apply(JobHandle inputDeps, bool singleFrameOnly = false)
    Handles the primary apply behavior. From Default initiates Adding state (unless singleFrameOnly), plays audio, records apply start position and schedules definition updates. When finishing, reverts to Default and stops FX. Returns JobHandle for scheduled jobs.

  • private JobHandle Update(JobHandle inputDeps)
    Handles pointer movement/hover updates. If raycast produces a new ControlPoint, updates m_RaycastPoint and generates new definitions as needed. Also ensures applyMode is set appropriately (Apply/Clear/None) depending on state. Returns the JobHandle from UpdateDefinitions if definitions are changed, otherwise returns inputDeps.

  • private bool HaveBrushSettingsChanged()
    Checks visible brush entities to determine whether the brush size stored in the Brush components matches base.brushSize. Used to detect when brush prefab settings changed externally and force definition updates. Iterates chunks with a ComponentTypeHandle.

  • private JobHandle UpdateDefinitions(JobHandle inputDeps)
    Destroys existing creation definitions via DestroyDefinitions(m_DefinitionQuery, m_ToolOutputBarrier, inputDeps) and, if a prefab and brush type are selected, schedules a CreateDefinitionsJob (populating CreationDefinition/BrushDefinition) using the ToolOutputBarrier command buffer. Combines dependencies and ensures cached brush data if applyMode == ApplyMode.Apply. Returns combined JobHandle.

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    Compiler-generated helper (empty in decompiled form) intended to initialize EntityQueryBuilder usage during compilation. Called from OnCreateForCompiler.

  • protected override void OnCreateForCompiler()
    Compiler helper invoked to assign query handles and component type handles in the compiled system; it calls __AssignQueries and __TypeHandle.__AssignHandles.


Usage Example

A minimal example showing typical interactions you might call from editor code or another mod system:

// Obtain the system (example from a system method)
var terrainTool = World.GetExistingSystemManaged<TerrainToolSystem>();

// Select a TerraformingPrefab (prefab lookup via PrefabSystem)
var terraformPrefab = PrefabCollection<TerraformingPrefab>.FindLoaded("MyRaisePrefab");
if (terraformPrefab != null)
{
    terrainTool.SetPrefab(terraformPrefab);
}

// Optionally set an explicit brush height (e.g., set level target)
terrainTool.brushHeight = 30.0f; // sets m_TargetPosition.y and marks target as set

// Start tool usage: the tool handles input internally during OnUpdate.
// To cancel any in-progress FX programmatically:
terrainTool.SetDisableFX();

Notes: - The system schedules CreateDefinitionsJob which produces CreationDefinition/BrushDefinition entities; another system consumes those to perform the actual terrain modification. Do not try to directly manipulate those entities here. - This system relies on the InputManager tool action mappings; to add new actions or change bindings, use InputManager.instance.toolActionCollection. - Because the CreateDefinitionsJob is Burst-compiled and scheduled, be careful to only pass blittable data to it and respect job scheduling patterns (it uses ToolOutputBarrier's EntityCommandBuffer).