Skip to content

Game.Prefabs.ReplacePrefabSystem

Assembly: Assembly-CSharp.dll
Namespace: Game.Prefabs

Type: class ReplacePrefabSystem

Base: GameSystemBase

Summary:
ReplacePrefabSystem is an Entity Component System (ECS) game system used by the game to perform safe, batched replacement of prefab references across the world/entities. It handles:

  • Replacing references to one prefab entity with another across many component types and dynamic buffers (sub-objects, sub-nets, sub-areas, UI groups, tutorial refs, etc.).
  • Handling mesh -> mesh replacements via batch/group removal and remapping so rendered instances are updated correctly (RemoveBatchGroupsJob + mesh replace list).
  • Scheduling jobs that update instance elements (Finalize.Finalize) such as recreating area instances, nets and lanes when prefab composition changed.
  • Using EntityCommandBuffer and multithreaded Jobs (IJobChunk, IJobParallelFor, IJob) to perform replacements efficiently and safely on worker threads, then applying changes on the main thread.

It is intended for modding and internal game systems that need to change prefab relationships at runtime (for example when replacing a building prefab with another), and ensures associated derived entities (areas, nets, lanes) and rendering batches are updated accordingly.


Fields

  • private ToolSystem m_ToolSystem
    Used to require/update tool-related state (e.g., editor mode) while replacing prefabs.

  • private CityConfigurationSystem m_CityConfigurationSystem
    Provides city-level configuration values used during replacement (e.g., left-hand traffic flag).

  • private Finalize m_FinalizeSystem
    Reference to the nested Finalize system that performs follow-up instance updates after a replacement.

  • private BatchManagerSystem m_BatchManagerSystem
    Used to access native batch/group/instance structures for mesh/batch updates.

  • private ManagedBatchSystem m_ManagedBatchSystem
    Managed system for batch/mesh handling; used for mesh removal and mesh remapping operations.

  • private PrefabSystem m_PrefabSystem
    Provides prefab metadata and utilities (used when checking archetype components and prefab data).

  • private EntityQuery m_PrefabRefQuery
    Query selecting entities that may contain prefab references or related buffers; used to schedule ReplacePrefabJob.

  • private Entity m_OldPrefab
    Old prefab entity being replaced.

  • private Entity m_NewPrefab
    New prefab entity replacing the old prefab.

  • private Entity m_SourceInstance
    Optional source instance (entity) driving the replacement (keeps that instance updated/enqueued).

  • private NativeList<ReplaceMesh> m_MeshReplaces
    List of mesh replacements collected during batch removal jobs. Persistent native list.

  • private NativeQueue<Entity> m_UpdateInstances
    Queue of instance entities that need to be updated (enqueued by replace job and processed in Finalize).

  • private NativeHashMap<Entity, ReplacePrefabData> m_ReplacePrefabData
    Map from new-prefab -> ReplacePrefabData (stores old prefab, source instance and flags that indicate whether areas/nets/lanes need updating).

  • private TypeHandle __TypeHandle
    Internal generated type handle grouping many Component/Buffer lookups used by jobs.

  • (Also contains several nested structs and jobs: ReplaceMesh, ReplacePrefabData, nested Finalize class with UpdateInstanceElementsJob and CheckPrefabReplacesJob, RemoveBatchGroupsJob, ReplacePrefabJob, and nested TypeHandle structs.)

Properties

  • (No public properties exposed by this system.)

Constructors

  • public ReplacePrefabSystem()
    Default constructor (preserved). System initialization is primarily in OnCreate.

Methods

  • protected override void OnCreate()
    Initializes references to other managed systems, creates queries, allocates persistent native containers (m_MeshReplaces, m_UpdateInstances, m_ReplacePrefabData) and calls RequireForUpdate for the prefab-ref query. The system is initially disabled (base.Enabled = false) and only enabled when a replace is requested.

  • protected override void OnDestroy()
    Disposes persistent native containers (m_MeshReplaces, m_UpdateInstances). Ensures native resources are freed.

  • public void ReplacePrefab(Entity oldPrefab, Entity newPrefab, Entity sourceInstance)
    Entry point to request a prefab replacement. Sets internal fields (m_OldPrefab, m_NewPrefab, m_SourceInstance), temporarily enables the system and calls Update() inside a try/finally block to ensure the system is disabled afterwards. This schedules jobs and performs the replacement work synchronously on the calling thread (Update is called immediately).

  • public void FinalizeReplaces()
    Calls the nested Finalize system's Update to run the follow-up jobs that examine instances enqueued during replacement. Finalize stage performs comparisons of prefab sub-structures and recreates dependent elements (areas, nets, lanes) as needed.

  • private void CheckInstanceComponents(Entity instance, HashSet<ComponentType> checkedComponents, HashSet<ComponentType> archetypeComponents)
    Utility used after mesh/batch updates: compares the current entity chunk component types with what the new prefab archetype expects and adds/removes components accordingly for the instance (ensures instance archetype components match new prefab where relevant). Uses PrefabSystem.GetPrefab(...) to query archetype component list.

  • protected override void OnUpdate()
    Core replacement logic executed when the system is enabled. Responsibilities:

  • Ensures tools ask for full update via m_ToolSystem.RequireFullUpdate().
  • If the old prefab has MeshData, schedules RemoveBatchGroupsJob to remove batch groups referencing the old-mesh entity and produces mesh replacement entries (m_MeshReplaces) so rendering can swap meshes safely.
  • Otherwise, adds an entry to m_ReplacePrefabData so Finalize can inspect sub-areas/sub-nets/sub-lanes differences.
  • Enqueues the source instance for update (m_UpdateInstances).
  • Schedules ReplacePrefabJob (IJobChunk) across all entities matching m_PrefabRefQuery. ReplacePrefabJob:
    • For entities with a PrefabRef component, updates PrefabRef.m_Prefab and EditorContainer references, marks Updated component and enqueues instances for finalization (if not source).
    • For chunked entities that don't have PrefabRef but do have buffers, iterates buffer elements and replaces any references to m_OldPrefab with m_NewPrefab (handles SubObject, SubNet, SubArea, PlaceholderObjectElement, ServiceUpgradeBuilding, BuildingUpgradeElement, Effect, ActivityLocationElement, SubMesh, LodMesh, UIGroupElement, TutorialPhaseRef, etc.). Removes buffer entries that reference removed upgrade/placeholder/UI entries.
  • Copies BuildingUpgradeElement buffer from old prefab to new prefab if present.
  • Plays back command buffers and finalizes entity-command-buffers from RemoveBatchGroupsJob if used.

  • protected override void OnCreateForCompiler()
    Internal/compiler helper used by generated type handle wiring.

  • protected override void OnCreate() (nested Finalize.OnCreate) and protected override void OnUpdate() (nested Finalize.OnUpdate)
    Nested finalize system methods implement finalization pipeline: creating CheckPrefabReplacesJob to compare new/old prefab sub-structures (areas/nets/lanes) and UpdateInstanceElementsJob (IJobParallelFor) to create/update area/net/lane child entities based on prefab differences. These jobs use ComponentLookup/BufferLookup to read/write entity data and an EntityCommandBuffer. They may create temporary entities with CreationDefinition to spawn recreated sub-areas or net segments.

Notes about nested jobs and types: - RemoveBatchGroupsJob (BurstCompile) walks native batch/group/instance structures to remove batch groups referencing the old mesh and mark instances/batches updated (writes BatchesUpdated). - ReplacePrefabJob (BurstCompile IJobChunk) is the chunk-level replacer described above. - Finalize.Finalize contains: - CheckPrefabReplacesJob (IJob) that computes whether areas, nets or lanes changed for given prefabs (CompareAreas, CompareNets, CompareLanes). - UpdateInstanceElementsJob (IJobParallelFor) that for each instance creates or removes area/net/lane child entities according to prefab sub-data and queued ReplacePrefabData entries (it uses RandomSeed, editor mode flag, and left-hand traffic flag).

Usage Example

// Example usage from other managed code (e.g., a mod or game system):
var replaceSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<Game.Prefabs.ReplacePrefabSystem>();

// Replace all references to oldPrefabEntity with newPrefabEntity.
// Optionally provide a sourceInstance entity that should be used as the "source" (keeps it updated).
replaceSystem.ReplacePrefab(oldPrefabEntity, newPrefabEntity, sourceInstanceEntity);

// After ReplacePrefab completes you may need to finalize instance-specific updates:
replaceSystem.FinalizeReplaces();

Notes and tips for modders: - The system performs many operations using Jobs and EntityCommandBuffers; calling ReplacePrefab will run the replacement synchronously (Update called immediately) but internal finalization may use additional jobs — call FinalizeReplaces() to process instance recreation and ensure areas/nets/lanes are consistent. - If replacing mesh prefabs (old prefab has MeshData), the system schedules batch removals and uses ManagedBatchSystem to swap shared meshes. Be careful when manipulating rendering data or custom batch managers. - This class touches many internal types (SubArea, SubNet, SubLane, CreationDefinition, NetCourse, etc.) — ensure your mod's code uses compatible prefab entity IDs and understands how prefab composition affects child entity creation.