Game.HouseholdAndCitizenRemoveSystem
Assembly:
Assembly-CSharp (game code / modding assembly)
Namespace:
Game.Citizens
Type:
class
Base:
GameSystemBase
Summary:
HouseholdAndCitizenRemoveSystem watches for entities marked with the Deleted component and that are either Household or Citizen entities (excluding Temp). It schedules a Burst-compiled IJobChunk (HouseholdAndCitizenRemoveJob) to perform safe, parallel cleanup/removal of citizens, households and their related data. The job removes related components and entities (job seekers, school seekers, pets, owned vehicles, occupants, patients, creatures used as transports, renters entries, etc.) and uses a ModificationBarrier2 command buffer to record structural changes safely from a job. The system creates RentersUpdated events when renters lists are changed and requires the Deleted query for system update. This system is optimized for DOTS (Entities + Jobs + Burst) workflows in Cities: Skylines 2 modding.
Fields
-
private EntityQuery m_DeletedQuery
{{ The EntityQuery used to find entities that have Deleted and are either Household or Citizen (and not Temp). This query is required for the system to run. It is configured in OnCreate with All = Deleted, Any = Household|Citizen, None = Temp. }} -
private EntityArchetype m_RentEventArchetype
{{ Archetype created in OnCreate used to spawn rent-change events. It contains Event and RentersUpdated components; used when a household/property renters list is modified so other systems can react. }} -
private ModificationBarrier2 m_ModificationBarrier
{{ A barrier system used to create an EntityCommandBuffer for recording structural changes from the job. The command buffer is produced by the job and the barrier tracks the job handle via AddJobHandleForProducer. This ensures safe, deferred application of entity/component structural changes. }} -
private TypeHandle __TypeHandle
{{ Internal struct instance that stores the EntityTypeHandle, ComponentTypeHandles, ComponentLookup and BufferLookup instances required by the job. __TypeHandle.__AssignHandles fills these handles from the SystemState in OnCreateForCompiler. This is an auto-generated pattern for DOTS jobs to access components efficiently. }}
Properties
- This type exposes no public properties.
{{ All data access is performed via fields and the nested job; there are no public properties on this system. }}
Constructors
public HouseholdAndCitizenRemoveSystem()
{{ Default parameterless constructor. The system is created by the World; initialization happens in OnCreate. The constructor itself is preserved for runtime, as marked by the [Preserve] attribute on lifecycle methods. }}
Methods
-
protected override void OnCreate()
{{ Initializes the system: obtains the ModificationBarrier2 system, constructs the m_DeletedQuery (All: Deleted, Any: Household|Citizen, None: Temp), creates the m_RentEventArchetype (Event + RentersUpdated), and calls RequireForUpdate(m_DeletedQuery) so the system only runs when there are matching entities. }} -
protected override void OnUpdate()
{{ Builds and schedules the HouseholdAndCitizenRemoveJob (Burst compiled) using JobChunkExtensions.Schedule against m_DeletedQuery. It fills the job's handles and lookups from __TypeHandle via InternalCompilerInterface.Get* wrappers and passes a command buffer from m_ModificationBarrier.CreateCommandBuffer(). After scheduling, it registers the returned JobHandle with the modification barrier via AddJobHandleForProducer and assigns the handle to base.Dependency. }} -
protected override void OnCreateForCompiler()
{{ Internal/auto-generated helper used to assign query and type handles for the DOTS compiler pathway; calls __AssignQueries and __TypeHandle.__AssignHandles. }} -
private void __AssignQueries(ref SystemState state)
{{ Internal method (auto-generated pattern) for query assignment; in this implementation it constructs and disposes an EntityQueryBuilder placeholder. The real query used by the system is built explicitly in OnCreate. }} -
Nested: HouseholdAndCitizenRemoveJob : IJobChunk (BurstCompile)
{{ The job processing logic executed per archetype chunk: - Uses an EntityTypeHandle, several ComponentTypeHandles/ComponentLookup/BufferLookup instances for read and read/write access.
- Execute() iterates over the chunk entity array. If the chunk contains Citizen component it:
- Calls RemoveCitizen(entity) which:
- Adds Deleted to the citizen (if not already deleted).
- Adds Deleted to any associated HasJobSeeker/HasSchoolSeeker seeker entities.
- Removes Student entries from school buffers if present.
- Removes Patient and Occupant entries from the CurrentBuilding's buffers if present.
- If the citizen's CurrentTransport is a Creature and not yet Deleted, marks that transport Deleted.
- If the chunk does not contain Citizen (i.e., it is a Household chunk) it:
- Calls RemoveHousehold(entity) which:
- Marks household pets (HouseholdPet) as Deleted.
- Iterates HouseholdCitizen buffer and calls RemoveCitizen for each member.
- Iterates OwnedVehicle buffer and deletes vehicles via VehicleUtils.DeleteVehicle (using layout buffer if present).
- If the household is a renter or homeless household, finds the property and removes the Renter entry from the property's Renter buffer, then creates a RentersUpdated event entity using the rent event archetype to notify other systems.
- Uses m_CommandBuffer (from ModificationBarrier2) to enqueue structural changes (AddComponent Deleted, CreateEntity, SetComponent, etc.).
- Uses ComponentLookup/BufferLookup patterns (some ReadOnly, some read/write) to access per-entity buffers and components safely from the job.
-
The job implements IJobChunk.Execute explicitly. }}
-
Nested: TypeHandle.__AssignHandles(ref SystemState state)
{{ Populates all EntityTypeHandle, ComponentTypeHandle, ComponentLookup and BufferLookup fields from the SystemState for use by the job. This method is marked AggressiveInlining for performance. }}
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Example: this mirrors what the system does in-game.
m_ModificationBarrier = base.World.GetOrCreateSystemManaged<ModificationBarrier2>();
m_DeletedQuery = GetEntityQuery(new EntityQueryDesc
{
All = new ComponentType[] { ComponentType.ReadOnly<Deleted>() },
Any = new ComponentType[] { ComponentType.ReadOnly<Household>(), ComponentType.ReadOnly<Citizen>() },
None = new ComponentType[] { ComponentType.ReadOnly<Temp>() }
});
m_RentEventArchetype = base.EntityManager.CreateArchetype(
ComponentType.ReadWrite<Event>(),
ComponentType.ReadWrite<RentersUpdated>());
RequireForUpdate(m_DeletedQuery);
}
Additional notes: - The system is optimized for DOTS: uses Burst, IJobChunk, ComponentLookup/BufferLookup, and a command buffer via ModificationBarrier2 for thread-safe structural changes. - When extending or interacting with this system in a mod, be cautious when altering component sets (e.g., HouseholdCitizen, HouseholdAnimal, OwnedVehicle buffers) to maintain compatibility with the job's expectations. Use the same Event/RentersUpdated pattern if you want other systems to observe renter list changes.