Skip to content

Game.AchievementsUISystem

Assembly: Assembly-CSharp
Namespace: Game.UI.InGame

Type: class

Base: UISystemBase

Summary:
System responsible for exposing platform achievements to the in-game UI. It creates JSON bindings for the achievements list and for the achievement-tab status, listens to PlatformManager achievement updates, and queries CityConfigurationSystem to determine whether mods are in use (which affects achievement availability). The system serializes achievement properties (name, image path, locked state, progress, DLC image, development flag) for use by the UI.


Fields

  • private enum AchievementTabStatus
    Internal enum used to represent tab states the UI consumes (mapped by GetAchievementTabStatus). Values used in code:
  • Available = 0
  • Hidden = 1
  • ModsDisabled = 2
  • OptionsDisabled = 3

  • private const string kGroup = "achievements"
    Constant string used as the binding group name for the UI.

  • private CityConfigurationSystem m_CityConfigurationSystem
    Cached reference to the CityConfigurationSystem retrieved in OnCreate. Used to check whether mods are used in the current city (affects achievement tab state).

  • private RawValueBinding m_AchievementsBinding
    RawValueBinding that serializes the achievements array into JSON for the UI. Updated when PlatformManager reports achievement changes.

  • private GetterValueBinding<int> m_TabStatusBinding
    GetterValueBinding that provides an integer tab status (based on AchievementTabStatus) to the UI. Backed by GetAchievementTabStatus().

Properties

  • None

Constructors

  • public AchievementsUISystem()
    Default (parameterless) constructor. Marked with Preserve attribute in the source to prevent stripping during AOT/linking.

Methods

  • [Preserve] protected override void OnCreate()
    Initializes the system:
  • Retrieves/creates CityConfigurationSystem via base.World.GetOrCreateSystemManaged().
  • Subscribes to PlatformManager.instance.onAchievementUpdated to call UpdateAchievements when the platform reports a change.
  • Registers two bindings:

    • m_AchievementsBinding — "achievements" / "achievements" bound to BindAchievements(IJsonWriter).
    • m_TabStatusBinding — "achievements" / "achievementTabStatus" bound to GetAchievementTabStatus(). This sets up the UI-facing JSON data and the tab status.
  • private int GetAchievementTabStatus()
    Computes and returns an integer representing the achievement tab status:

  • If PlatformManager.instance.CountAchievements() == 0 => returns 1 (Hidden).
  • Else if m_CityConfigurationSystem.usedMods.Count > 0 => returns 2 (ModsDisabled).
  • Else if !PlatformManager.instance.achievementsEnabled => returns 3 (OptionsDisabled).
  • Otherwise => returns 0 (Available). Note: the integers map to the AchievementTabStatus enum described above.

  • [Preserve] protected override void OnUpdate()
    Empty override. No per-frame work required by this system.

  • protected override void OnGameLoadingComplete(Purpose purpose, GameMode mode)
    Called when game loading completes — triggers m_TabStatusBinding.Update() to refresh the UI representation of the achievements tab status.

  • private void UpdateAchievements(IAchievementsSupport backend, AchievementId id)
    Callback invoked by PlatformManager when an achievement is updated; calls m_AchievementsBinding.Update() to refresh the achievements JSON bound to the UI.

  • private void BindAchievements(IJsonWriter binder)
    Serializes the achievements array into the provided IJsonWriter:

  • Gets achievement count via PlatformManager.instance.CountAchievements().
  • Calls m_TabStatusBinding.Update() to ensure tab status is up-to-date.
  • Writes an array: if count>0 iterates PlatformManager.instance.EnumerateAchievements() and calls BindAchievement for each; otherwise writes an empty array.

  • private void BindAchievement(IJsonWriter binder, IAchievement achievement)
    Serializes a single achievement object with these properties:

  • localeKey: achievement.internalName
  • imagePath: computed by GetImagePath(achievement, locked)
  • locked: true when achievement.achieved == false
  • isIncremental: achievement.isIncremental
  • progress: achievement.progress
  • maxProgress: achievement.maxProgress
  • dlcImage: computed by GetDlcImage(achievement.dlcId)
  • isDevelopment: whether the achievement is a DevelopmentAchievementsManager.DevelopmentAchievement The method wraps the properties inside TypeBegin("achievements.Achievement") / TypeEnd().

  • private static string GetDlcImage(DlcId dlcId)
    Returns null for DlcId.BaseGame; otherwise returns a path like "Media/DLC/{dlcName}.svg" where dlcName is resolved from PlatformManager.instance.GetDlcName(dlcId).

  • private static string GetImagePath(IAchievement achievement, bool locked)
    Returns the local media path for the achievement image: "Media/Game/Achievements/{internalName}{_locked if locked}.png"

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_CityConfigurationSystem = base.World.GetOrCreateSystemManaged<CityConfigurationSystem>();
    PlatformManager.instance.onAchievementUpdated += UpdateAchievements;
    AddBinding(m_AchievementsBinding = new RawValueBinding("achievements", "achievements", BindAchievements));
    AddBinding(m_TabStatusBinding = new GetterValueBinding<int>("achievements", "achievementTabStatus", GetAchievementTabStatus));
}

Notes and modding hints: - This system relies on PlatformManager and CityConfigurationSystem. For unit testing or mocking, provide compatible implementations for those systems. - The code subscribes to PlatformManager.instance.onAchievementUpdated but does not explicitly unsubscribe; lifecycle management is tied to the system lifetime (it exists while the game/window is running). - The tab status ordering is important: an absence of achievements results in "hidden" before checking mods or options. If your mod affects achievement availability or DLC names, ensure PlatformManager APIs reflect those changes so the UI bindings update correctly.