Skip to content

Game.Debug.NetDebugSystem

Assembly: Game
Namespace: Game.Debug

Type: class

Base: BaseDebugSystem

Summary:
NetDebugSystem is an ECS system used for drawing debug gizmos for the network (roads/rails/paths) in Cities: Skylines 2. It schedules a Burst-compiled IJobChunk (NetGizmoJob) that iterates over entities containing Edge and/or Node components and issues draw calls to a GizmosSystem's GizmoBatcher. The system exposes three debug options (Draw Nodes, Draw Edges, Draw Outlines) that control which parts of the network are visualized. It filters out entities marked Deleted or Hidden and requires an EntityQuery that matches Node or Edge components. The job uses ComponentTypeHandle/BufferTypeHandle/ComponentLookup to access runtime ECS data and draws curves, lines and wireframe nodes and edge outlines depending on available geometry and composition data. The system is created disabled by default and can be enabled at runtime for debugging.


Fields

  • private EntityQuery m_NetGroup
    This EntityQuery selects entities that have either Node or Edge components and excludes those with Deleted or Hidden. It is used with RequireForUpdate to control when the system runs.

  • private GizmosSystem m_GizmosSystem
    Reference to the GizmosSystem (managed system) used to obtain a GizmosBatcher for issuing draw calls from jobs.

  • private Option m_NodeOption
    Debug option created via AddOption("Draw Nodes", defaultEnabled: true). Controls whether node positions/wire-nodes are drawn.

  • private Option m_EdgeOption
    Debug option created via AddOption("Draw Edges", defaultEnabled: true). Controls whether edges/curves are drawn.

  • private Option m_OutlineOption
    Debug option created via AddOption("Draw Outlines", defaultEnabled: true). Controls whether edge outlines (geometry) are drawn.

  • private TypeHandle __TypeHandle
    Struct used to cache ComponentTypeHandle/BufferTypeHandle/ComponentLookup instances for the job. It is assigned during OnCreateForCompiler to prepare the type handles used when scheduling the NetGizmoJob.

Properties

  • This system does not expose public properties. It inherits Enabled and other functionality from BaseDebugSystem/SystemBase.

Constructors

  • public NetDebugSystem()
    Default constructor. The system initialization is primarily done in OnCreate. The constructor is preserved but contains no custom logic.

Methods

  • protected override void OnCreate()
    Creates the system state: obtains the GizmosSystem, builds the EntityQuery (m_NetGroup) which matches nodes or edges and excludes Deleted/Hidden, registers three debug options ("Draw Nodes", "Draw Edges", "Draw Outlines") with default enabled values, calls RequireForUpdate(m_NetGroup) so the system runs only when relevant entities exist, and sets base.Enabled = false (system remains disabled by default). Marked with Preserve to avoid stripping.

  • protected override JobHandle OnUpdate(JobHandle inputDeps)
    Schedules the Burst-compiled NetGizmoJob in parallel over m_NetGroup. It:

  • Reads the current enabled state of the three Option fields and passes them into the job.
  • Retrieves ComponentTypeHandle/BufferTypeHandle/ComponentLookup instances through InternalCompilerInterface.GetComponentTypeHandle / GetBufferTypeHandle / GetComponentLookup using cached __TypeHandle entries and the system's CheckedStateRef.
  • Calls m_GizmosSystem.GetGizmosBatcher(out dependencies) to get a GizmosBatcher suitable for use in the job and to obtain dependencies required by the batcher.
  • Schedules the job via JobChunkExtensions.ScheduleParallel combining inputDeps with the batcher dependencies.
  • Registers the returned JobHandle with m_GizmosSystem via AddGizmosBatcherWriter and returns the job handle.

  • private void __AssignQueries(ref SystemState state)
    Called from OnCreateForCompiler to initialize any query-related structures the compiler needs. In this build it simply constructs and disposes an EntityQueryBuilder (no persistent queries created here).

  • protected override void OnCreateForCompiler()
    Compiler helper invoked to assign query/type handles at compile-time: it calls __AssignQueries and __TypeHandle.__AssignHandles to initialize cached type handles (ComponentTypeHandle/BufferTypeHandle/ComponentLookup) using the system's CheckedStateRef. This method ensures the type handles are prepared for later use by the generated scheduling code.

  • private struct TypeHandle
    Holds read-only ComponentTypeHandle and BufferTypeHandle and ComponentLookup fields used by the NetGizmoJob. It provides __AssignHandles(ref SystemState state) which calls state.GetComponentTypeHandle / GetBufferTypeHandle / GetComponentLookup to populate the fields with read-only handles.

  • private struct NetGizmoJob : IJobChunk (BurstCompile)
    The job executed per-chunk that performs the actual gizmo drawing. Key behaviors:

  • Fields: read-only flags for options, several ComponentTypeHandle/BufferTypeHandle/ComponentLookup, and a GizmoBatcher instance for drawing.
  • Execute: fetches component arrays (Edge/Node/Curve/EdgeGeometry/etc.) and draws:
    • Edges as curves (or simple straight lines if curve data missing).
    • Node positions and wire nodes if m_NodeOption enabled.
    • Connected nodes and their positions along curves (drawn with lines and small wire nodes).
    • Outlines/geometry: constructs Bezier4x3 segments for left/right/top/bottom edge geometry using NetCompositionData heights and draws curves and boundary lines depending on continuity checks.
  • Helper methods inside the job:
    • IsValid(EdgeNodeGeometry): checks whether the node geometry contains meaningful geometry by inspecting vector lengths.
    • IsStartContinuous / IsEndContinuous: determine continuity between an edge geometry and node geometry by comparing positions and height ranges.
    • DrawSegment(Segment, NetCompositionData, Color, left, right, start, end): draws the four boundary Bezier curves and joins based on the given parameters and composition height ranges.
  • The job uses math.lengthsq, math.select, math.abs, and MathUtils.Position to compute points.

Notes on concurrency and safety: - The job is Burst-compiled and scheduled parallel; all ComponentTypeHandles / BufferTypeHandles / ComponentLookup fields are set read-only where appropriate. - The GizmoBatcher returned by GizmosSystem.GetGizmosBatcher is used in the job; the system adds the returned job as a writer via m_GizmosSystem.AddGizmosBatcherWriter to ensure proper synchronization.

Usage Example

// Enable the NetDebugSystem at runtime to start drawing network debug gizmos.
var world = World.DefaultGameObjectInjectionWorld;
var netDebug = world.GetExistingSystemManaged<Game.Debug.NetDebugSystem>();
if (netDebug != null)
{
    // The system is created disabled by default; enable it to have it schedule the job.
    netDebug.Enabled = true;
}

Additional example showing how the system sets up options (inside the system's OnCreate):

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_NodeOption = AddOption("Draw Nodes", defaultEnabled: true);
    m_EdgeOption = AddOption("Draw Edges", defaultEnabled: true);
    m_OutlineOption = AddOption("Draw Outlines", defaultEnabled: true);
    RequireForUpdate(m_NetGroup);
    base.Enabled = false; // default disabled until user enables it
}

Notes and tips for modders: - The NetGizmoJob relies on specific component types (Edge, Node, Curve, Composition, EdgeGeometry, StartNodeGeometry, EndNodeGeometry, ConnectedNode buffer, NetCompositionData lookups). Ensure those components exist and are populated correctly when debugging custom net prefabs or runtime modifications. - The system filters entities with Deleted or Hidden to avoid drawing removed/hidden elements. - Because the job uses Burst and IJobChunk, injecting additional drawing behavior should be done carefully and typically requires adjusting the TypeHandle and job fields in a similar manner. - To change which parts are drawn, toggle the three options via UI (if exposed) or programmatically by accessing the Option objects (if the base class exposes them) or by enabling/disabling the system.