Skip to content

Game.Net.OutsideConnectionSystem

Assembly:
Namespace: Game.Net

Type: class

Base: GameSystemBase

Summary:
System responsible for generating and maintaining "outside" net lanes that connect the city to external network edges and prefab route connections (roads, tracks, pedestrian paths, parking links). It scans outside-connection entities and connected edges, computes node positions and connection types, updates existing lanes or creates/removes lane entities via a ModificationBarrier command buffer. The heavy work is performed inside a Burst-compiled IJob (UpdateOutsideConnectionsJob) for multithreaded processing. This system triggers when outside connections are updated (Updated/Deleted components) or when a forced regeneration is required (for example, when loading old save versions). It ensures lanes have correct Curve, ConnectionLane, Lane and Owner components and marks changed lanes with Updated.


Fields

  • private ModificationBarrier4 m_ModificationBarrier
    Holds the modification barrier used to obtain an EntityCommandBuffer for producing structural changes (create/remove/set components) from the scheduled job.

  • private EntityQuery m_UpdatedQuery
    Query used to detect outside-connection entities that have been Updated or Deleted (excluding temp/power/water outside connections). When not empty, it triggers the update job.

  • private EntityQuery m_ConnectionQuery
    Query that selects all outside connection entities (with Transform) and also matches existing outside connection Lane entities (separate query) so the job can iterate both connection prefabs and existing lanes.

  • private EntityQuery m_PrefabQuery
    Query to find a suitable connection lane prefab archetype (ConnectionLaneData + PrefabData). Used to instantiate new lane entities when needed.

  • private bool m_Regenerate
    Flag set during game load if old save versions require full regeneration of outside connections. Forces the system to run a regeneration pass.

  • private TypeHandle __TypeHandle
    Compiler-generated container for all Entity/Component type handles and lookups used by the job. Assigned in OnCreateForCompiler and used to get ComponentTypeHandle/BufferTypeHandle/ComponentLookup instances for scheduling the job.

  • private enum ConnectionType (nested)
    Defines connection types created/handled by the system: Pedestrian, Road, Track, Parking.

  • private struct NodeData (nested)
    Temporary data structure used by the job to represent computed nodes for connections. Holds positions, ordering angle, remoteness, path node indices, connection/track/road types and owner entity. Implements IComparable so these nodes can be sorted (by order, then type) before lane creation.

  • private struct LaneData (nested)
    Lightweight key representing a lane start/end pair. Used as a key in a NativeParallelHashMap to match existing lanes to computed nodes. Implements equality and hash code so it can be used in hash maps.

  • private struct UpdateOutsideConnectionsJob (nested)
    Burst-compiled IJob that performs the core outside connection logic:

  • Iterates connection chunks and lane chunks.
  • Builds a sorted NativeList of candidate nodes.
  • Builds a NativeParallelHashMap of existing lanes.
  • Tries to match existing lanes to computed nodes, updating curves when needed.
  • Creates new lane entities with proper components if no matching lane exists and a prefab is available.
  • Deletes leftover lanes in the lane map by marking them Deleted.
  • Adds Updated to affected waypoints (connected routes) if lanes were removed.
  • Uses the command buffer from m_ModificationBarrier to perform structural changes.

Properties

  • None (this system exposes no public properties).
    As an ECS system, it relies on EntityQuery and internal state; triggering is done by component changes (Updated/Deleted) or the internal m_Regenerate flag.

Constructors

  • public OutsideConnectionSystem()
    Default, compiler-preserved constructor. The system initializes queries and the TypeHandle and obtains the ModificationBarrier in OnCreate. No runtime work is done in the constructor itself.

Methods

  • protected override void OnCreate()
    Initializes the system:
  • Retrieves ModificationBarrier4 from the World.
  • Builds three EntityQueries:
    • m_UpdatedQuery: select OutsideConnection entities with Updated or Deleted (and exclude Temp, Electricity/Water outside connections).
    • m_ConnectionQuery: select OutsideConnection + Transform entities (and a parallel alternative for Lane entities).
    • m_PrefabQuery: query for ConnectionLaneData + PrefabData used to find lane archetype prefabs.
  • Prepares the system for updates.

  • protected override void OnGameLoaded(Context context)
    Checks the saved game version; if the save predates the outsideConnectionRemoteness version, sets m_Regenerate = true so a full regeneration occurs on the next update pass.

  • protected override void OnUpdate()
    Main scheduling logic:

  • If m_Regenerate is set or there are updated outside-connection entities, it schedules UpdateOutsideConnectionsJob.
  • Collects connection archetype chunks and candidate prefab entities asynchronously (ToArchetypeChunkListAsync / ToEntityListAsync).
  • Builds the job struct, providing type handles, lookups, buffers and a command buffer from m_ModificationBarrier.
  • Schedules the job combining the job dependencies and disposes temp NativeLists once the job is scheduled.
  • Adds job handle to the modification barrier and updates base.Dependency.

  • protected override void OnCreateForCompiler()
    Compiler helper: assigns queries and type handles (calls __AssignQueries and __TypeHandle.__AssignHandles). Used by generated code paths; modders normally do not call it manually.

  • private void __AssignQueries(ref SystemState state)
    Compiler-generated placeholder used to initialize queries for AOT/IL2CPP compilation. It creates an EntityQueryBuilder temporary here (no op in the compiled listing). Present for compiled/serialized system compatibility.

  • Nested job helper methods inside UpdateOutsideConnectionsJob:

  • FillNodeData(Entity owner, Transform transform, OutsideConnectionData, RouteConnectionData, NativeList)
    Builds NodeData entries for prefab route connections (road + pedestrian entries where applicable).
  • FillNodeData(Entity node, DynamicBuffer, OutsideConnectionData, NativeList)
    Builds NodeData entries from connected edges (either using sub-lanes or prefab composition lanes), computes pedestrian/road/track counts and may add a pedestrian averaged node; also creates parking nodes linking road/pedestrian.
  • TryCreateLane(NodeData, NativeParallelHashMap)
    Attempts to match an existing lane for a single-node outside lane (start->end). Updates Curve if needed; otherwise creates a new lane entity using a prefab archetype and sets components (PrefabRef, Lane, Curve, ConnectionLane, OutsideConnection, Owner).
  • TryCreateLane(NodeData, NodeData, NativeParallelHashMap)
    Attempts to match or create a distance lane between two nodes (used for outside-to-outside links).
  • CalculateEndPos(float3)
    Small helper that offsets end position by normalized xz direction (used to place a virtual "end" point for straight short lanes).
  • CalculateCurve(NodeData) and CalculateCurve(NodeData, NodeData)
    Compute Bezier curves for lanes (straight for single node lanes, cubic with control points for two-node links). Curve length is estimated/derived and stored in Curve struct.

Usage Example

// Typical ways a mod might trigger or cooperate with this system:

// 1) Force regeneration after changing outside connection data on load:
// (called inside a loading hook or initialization)
var world = World.DefaultGameObjectInjectionWorld;
var sys = world.GetExistingSystemManaged<Game.Net.OutsideConnectionSystem>();
if (sys != null)
{
    // There's no public API to set m_Regenerate, but you can mark outside connection
    // entities with Updated so the system will pick them up on next tick.
    var entityManager = world.EntityManager;
    // assume outsideEntity is an Entity you modified:
    entityManager.AddComponent<Updated>(outsideEntity);
}

// 2) Manually add Updated to an outside connection to force its lanes to be recalculated:
var em = World.DefaultGameObjectInjectionWorld.EntityManager;
if (em.HasComponent<Game.Objects.OutsideConnection>(outsideEntity))
{
    if (!em.HasComponent<Updated>(outsideEntity))
        em.AddComponent<Updated>(outsideEntity);
}

// Note: structural updates (create/delete lanes) are performed by the scheduled job via
// the ModificationBarrier (command buffer). Avoid making conflicting structural changes
// on the main thread while the job is running.

Notes and tips for modders: - The heavy node/lane computation is done on worker threads (Burst), so any custom changes to lane archetypes or component layouts must match what this system expects (PrefabRef -> lookup into prefab tables, Lane component layout, ConnectionLane flags). - To add new lane prefab types for outside connections, ensure ConnectionLaneData/PrefabData and NetLaneArchetypeData are available in the prefab registry so m_PrefabQuery returns a matching archetype. - If you observe missing links after changing net prefabs, try adding Updated to the relevant outside connection entity or trigger a full regeneration by running code at load-time that mimics the version check (setting m_Regenerate equivalent by marking outside connections Updated). - Be careful when modifying components that the system reads (Curve, Composition, EdgeGeometry, etc.) — inconsistent states or missing expected flags can make the job skip lanes or produce unexpected results.