Skip to content

Game.LifePathUISystem

Assembly: Game
Namespace: Game.UI.InGame

Type: class

Base: UISystemBase

Summary:
Manages the Life Path UI bindings and interactions for citizens in the in-game UI. It registers bindings for followed citizens, life path details and life path items, and exposes trigger bindings to follow/unfollow citizens. The system queries and reacts to ECS component order version changes for Followed, LifePathEntry and Chirp components to refresh its bindings. Internally it uses other systems (LifePathEventSystem, NameSystem, SelectedInfoUISystem, ChirperUISystem) to collect and format the data sent to the UI.


Fields

  • private struct FollowedCitizenComparer : IComparer<Entity>
    A private comparer used to sort followed citizen entities by their Followed.m_Priority and then by entity id. It holds an EntityManager instance to read the Followed component during comparisons.

  • private const string kGroup = "lifePath"
    Constant group name used when creating bindings (group identifier for the UI bindings).

  • private LifePathEventSystem m_LifePathEventSystem
    Cached reference to the LifePathEventSystem used to follow/unfollow citizens and to inspect life path events.

  • private NameSystem m_NameSystem
    Cached reference to the NameSystem used to resolve and bind human-readable names for entities (citizens, buildings, companies, etc.) in the UI.

  • private SelectedInfoUISystem m_SelectedInfoUISystem
    Cached reference to the SelectedInfoUISystem; used to mark selected info UI as dirty when unfollowing a citizen.

  • private ChirperUISystem m_ChirperUISystem
    Cached reference to the ChirperUISystem for binding chirp entries associated with life path items.

  • private EntityQuery m_FollowedQuery
    EntityQuery that matches Citizen entities that are Followed (and not Temp or Deleted). Used to enumerate followed citizens.

  • private EntityQuery m_HappinessParameterQuery
    EntityQuery to access CitizenHappinessParameterData singleton needed for computing household wealth/happiness related values.

  • private int m_FollowedVersion
    Tracks the component order version of Followed components last seen by this system to determine when to update bindings.

  • private int m_LifePathEntryVersion
    Tracks the component order version of LifePathEntry components last seen.

  • private int m_ChirpVersion
    Tracks the component order version of Chirp components last seen.

  • private RawValueBinding m_FollowedCitizensBinding
    RawValueBinding registered under the "lifePath" group with key "followedCitizens". Produces an array of followed citizen objects for the UI.

  • private RawMapBinding<Entity> m_LifePathDetailsBinding
    RawMapBinding registered under "lifePath" group with key "lifePathDetails". Maps a citizen entity to its detailed life path data for the UI.

  • private RawMapBinding<Entity> m_LifePathItemsBinding
    RawMapBinding registered under "lifePath" group with key "lifePathItems". Maps a citizen entity to an array of life path items (chirps, life path events, etc.) for the UI.

Properties

  • No public properties. All state is managed via private fields and bindings. (The system registers UI bindings and trigger bindings rather than exposing properties.)

Constructors

  • public LifePathUISystem()
    Default constructor. The class uses the usual ECS lifecycle (OnCreate/OnUpdate) — constructor does not perform initialization beyond default construction. The OnCreate override performs system initialization and binding registration.

Methods

  • protected override void OnCreate()
    Initializes and caches references to dependent systems (LifePathEventSystem, NameSystem, SelectedInfoUISystem, ChirperUISystem). Creates entity queries for followed citizens and happiness parameters. Registers UI bindings:
  • RawValueBinding "lifePath" / "followedCitizens" -> BindFollowedCitizens
  • RawMapBinding "lifePath" / "lifePathDetails" -> BindLifePathDetails
  • RawMapBinding "lifePath" / "lifePathItems" -> BindLifePathItems
  • TriggerBinding "lifePath" / "followCitizen" -> FollowCitizen
  • TriggerBinding "lifePath" / "unfollowCitizen" -> UnfollowCitizen
  • ValueBinding "lifePath" / "maxFollowedCitizens" -> LifePathEventSystem.kMaxFollowed

This method is marked with [Preserve] to avoid stripping.

  • protected override void OnUpdate()
    Checks component order version numbers to detect changes that require updating bindings:
  • If the Followed component order version changed -> updates followed citizens binding and life path details map.
  • If LifePathEntry or Chirp component order version changed -> updates life path items map. It caches the observed versions in m_FollowedVersion, m_LifePathEntryVersion and m_ChirpVersion. This ensures the UI stays in sync with ECS changes efficiently.

  • private void FollowCitizen(Entity citizen)
    Trigger handler that calls LifePathEventSystem.FollowCitizen(citizen) to mark a citizen as followed.

  • private void UnfollowCitizen(Entity citizen)
    Trigger handler that calls LifePathEventSystem.UnfollowCitizen(citizen) and marks the SelectedInfoUISystem dirty so the selected info UI updates accordingly.

  • private void BindFollowedCitizens(IJsonWriter binder)
    Binding function for producing the followedCitizens array for the UI. It:

  • Retrieves followed citizens via GetSortedFollowedCitizens (which uses m_FollowedQuery and sorts by Followed priority).
  • Writes an array of objects with properties: entity, name (via NameSystem), age, dead.
  • Disposes the temporary NativeArray after writing.

  • private NativeArray<Entity> GetSortedFollowedCitizens()
    Helper that obtains entities from m_FollowedQuery into a temporary NativeArray (Allocator.Temp), sorts them using FollowedCitizenComparer (priority then entity id), and returns the array. Caller is responsible for disposing the returned array.

  • private void BindLifePathDetails(IJsonWriter binder, Entity entity)
    Produces life path detail data for a single citizen entity. If the entity has a Citizen component and is Followed, it gathers:

  • Residence, workplace, company, school (and school level)
  • Occupation, job level, age, education
  • Household member data, citizen conditions (a NativeList populated and disposed), household wealth, birthDay, randomIndex (from RandomLocalizationIndex buffer) and happiness/state It writes a typed object "lifePath.LifePathDetails" with many properties (entity, name, avatar, randomIndex, birthDay, age, education, wealth, occupation, jobLevel, residenceName/entity/key, workplaceName/entity/key, schoolName/entity, conditions array or empty when dead, happiness or null when dead, state). If the citizen is not followed or missing components, it writes null.

  • private void BindLifePathItems(IJsonWriter binder, Entity citizen)
    Binds life path items (events/chirps) for the given citizen. If the citizen has a DynamicBuffer, it iterates from newest to oldest (buffer.Length - 1 down to 0) and for each life path entry entity:

  • If the entity is Deleted -> writes null
  • Else if entity has Chirp component -> delegates to ChirperUISystem.BindChirp(binder, entity)
  • Else if entity has LifePathEvent component -> calls BindLifePathEvent(binder, entity)
  • Else -> writes null If no buffer exists, writes an empty array.

  • private void BindLifePathEvent(IJsonWriter binder, Entity entity)
    Binds a life path event entry. Retrieves a message ID using ChirperUISystem.GetMessageID(entity) and reads LifePathEvent component data (date). Writes a typed object "lifePath.LifePathEvent" with properties entity, date and messageId.

  • private int GetRandomIndex(Entity entity)
    Tries to read a DynamicBuffer from the entity; returns buffer[0].m_Index if available and non-empty, otherwise returns 0. Used to provide a localization/random avatar index for the UI.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();

    // Typical initialization performed by this system: cache dependent systems,
    // create queries and register UI bindings/triggers.
    m_LifePathEventSystem = World.GetOrCreateSystemManaged<LifePathEventSystem>();
    m_NameSystem = World.GetOrCreateSystemManaged<NameSystem>();
    m_SelectedInfoUISystem = World.GetOrCreateSystemManaged<SelectedInfoUISystem>();
    m_ChirperUISystem = World.GetOrCreateSystemManaged<ChirperUISystem>();

    // Register bindings (example snippet — actual class registers several bindings):
    AddBinding(new RawValueBinding("lifePath", "followedCitizens", BindFollowedCitizens));
    AddBinding(new RawMapBinding<Entity>("lifePath", "lifePathDetails", (w, e) => BindLifePathDetails(w, e)));
    AddBinding(new TriggerBinding<Entity>("lifePath", "followCitizen", FollowCitizen));
    AddBinding(new TriggerBinding<Entity>("lifePath", "unfollowCitizen", UnfollowCitizen));
}

Notes and tips for modders: - BindFollowedCitizens and BindLifePathDetails use temporary Native containers (NativeArray / NativeList). Ensure callers/disposers follow the same pattern (this system disposes them properly). - The system relies on component order/version checks to refresh UI state; if you add/remove Followed, LifePathEntry or Chirp components in custom code, ensure to update component order/version where appropriate (typically automatic) so the UI bindings refresh. - To programmatically follow/unfollow a citizen from other code, call LifePathEventSystem.FollowCitizen/UnfollowCitizen or invoke the trigger bindings registered here.