Skip to content

Game.UI.Tooltip.TempCostTooltipSystem

Assembly:
Game (Assembly-CSharp) {{ If you build the base game, this type is typically in the main game assembly (commonly Assembly-CSharp). Modders referencing compiled game types should reference the same assembly. }}

Namespace:
Game.UI.Tooltip

Type:
class (SystemBase-derived ECS system)
{{ This is an ECS system used by the game's UI layer to display temporary cost/refund tooltips for "Temp" entities created by tools. It is a managed (Game) system that runs in the main world and integrates with the game's TooltipSystemBase. }}

Base:
TooltipSystemBase
{{ Inherits tooltip helper functionality and mouse tooltip registration from TooltipSystemBase. }}

Summary:
{{ TempCostTooltipSystem monitors temporary "Temp" components used by building/placement tools and aggregates their cost impacts (creation, deletion, modification, upgrades, etc.). During update it sums the costs for active Temp components that are not cancelled, and shows a cost tooltip (red if the player has insufficient funds) or a refund tooltip if the total is negative. It depends on CitySystem to read the player's current money amount. The system uses an EntityQuery on Temp (excluding Deleted) and reads component data via a ComponentTypeHandle for performance. }}


Fields

  • private CitySystem m_CitySystem
    {{ Reference to the CitySystem used to check current moneyAmount. Obtained in OnCreate via World.GetOrCreateSystemManaged(). This is used to decide tooltip color (Error if not enough money, Info otherwise). }}

  • private EntityQuery m_TempQuery
    {{ EntityQuery that selects entities with the Temp component and excludes Deleted. Used every update to iterate chunks containing Temp components. Required for update via RequireForUpdate(m_TempQuery) so the system only runs when relevant Temp entities exist. }}

  • private IntTooltip m_Cost
    {{ Preconfigured IntTooltip instance used to display an aggregated cost (when total cost > 0). Initialized in OnCreate with path "cost", a money icon, and unit "money". Its value and color are set in OnUpdate before being added to the mouse tooltip. }}

  • private IntTooltip m_Refund
    {{ Preconfigured IntTooltip instance used to display an aggregated refund (when total cost < 0). Initialized in OnCreate with path "refund", a money icon, label localized via LocalizedString.Id("Tools.REFUND_AMOUNT_LABEL"), and unit "money". Its value is set to -totalCost when displaying. }}

  • private TypeHandle __TypeHandle
    {{ Internal compiler-generated struct used to cache and assign a ComponentTypeHandle for fast, read-only access to Temp component data in chunk iteration. The TypeHandle struct has an __AssignHandles method called in compiler-related initialization to wire up the ComponentTypeHandle from the SystemState. }}

Nested (compiler-generated) TypeHandle:

  • struct TypeHandle
  • public ComponentTypeHandle<Temp> __Game_Tools_Temp_RO_ComponentTypeHandle
    {{ Read-only ComponentTypeHandle for Temp. }}

  • public void __AssignHandles(ref SystemState state)
    {{ Assigns the ComponentTypeHandle by calling state.GetComponentTypeHandle(isReadOnly: true). This is used by the OnCreateForCompiler plumbing to initialize handles before runtime access. }}

Properties

  • (none)
    {{ This system exposes no public properties. It uses private fields and the ECS lifecycle methods to operate. }}

Constructors

  • public TempCostTooltipSystem()
    {{ Default constructor. There is also a parameterless constructor with [Preserve] attribute in the code; it simply constructs the managed system instance. Typically you don't need to instantiate this yourself — the ECS world creates it. }}

Methods

  • [Preserve] protected override void OnCreate()
    {{ Lifecycle initialization. Calls base.OnCreate(), obtains CitySystem via base.World.GetOrCreateSystemManaged(), constructs m_TempQuery to select Temp components excluding Deleted, initializes the two IntTooltip instances (m_Cost and m_Refund) with icons/paths/labels/units, and calls RequireForUpdate(m_TempQuery) so the system only runs when Temp entities exist. This is where the system sets up its dependencies and static tooltip templates. }}

  • [Preserve] protected override void OnUpdate()
    {{ Main runtime logic executed each frame (when the system is scheduled). Steps:

  • Calls CompleteDependency() to ensure prior jobs are completed (synchronous read).
  • Converts the m_TempQuery to a NativeArray (Allocator.TempJob) and iterates chunks.
  • Uses an InternalCompilerInterface.GetComponentTypeHandle to get the ComponentTypeHandle from the cached __TypeHandle.
  • Iterates Temp component instances inside each chunk and sums m_Cost for Temp entries that contain any of the flags: Create, Delete, Modify, Replace, Upgrade, RemoveCost, and which are not Cancel.
  • If aggregated sum > 0: sets m_Cost.value to sum, sets m_Cost.color to TooltipColor.Error if city moneyAmount < sum else TooltipColor.Info, and registers the tooltip via AddMouseTooltip(m_Cost).
  • If aggregated sum < 0: sets m_Refund.value to -sum and registers via AddMouseTooltip(m_Refund).
  • Disposes of the nativeArray in a finally block to ensure proper cleanup.

Notes: This method runs on the main thread and reads component data; it uses TempJob allocator for chunk array and must dispose it. The checks on TempFlags determine whether the Temp entry contributes to cost or refund. }}

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    {{ Compiler-generated helper called from OnCreateForCompiler. In this compiled code it currently creates and disposes a new EntityQueryBuilder(Allocator.Temp) but no persistent queries are assigned here; real query wiring is done in OnCreate. This method exists for compiler plumbing and should not normally be modified. }}

  • protected override void OnCreateForCompiler()
    {{ Compiler helper called by generated code. Calls base.OnCreateForCompiler(), then __AssignQueries(ref base.CheckedStateRef) and __TypeHandle.__AssignHandles(ref base.CheckedStateRef) to let the compiler initialize cached handles for component access. This method is part of ECS code generation patterns. }}

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] on TypeHandle.__AssignHandles and other small methods
    {{ Several small helper methods are marked AggressiveInlining for performance; these are implementation details and safe to ignore when using the system. }}

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Obtain CitySystem for money checks:
    m_CitySystem = base.World.GetOrCreateSystemManaged<CitySystem>();

    // Query Temp components (exclude Deleted):
    m_TempQuery = GetEntityQuery(ComponentType.ReadOnly<Temp>(), ComponentType.Exclude<Deleted>());

    // Setup cost tooltip template:
    m_Cost = new IntTooltip
    {
        path = "cost",
        icon = "Media/Game/Icons/Money.svg",
        unit = "money"
    };

    // Setup refund tooltip template:
    m_Refund = new IntTooltip
    {
        path = "refund",
        icon = "Media/Game/Icons/Money.svg",
        label = LocalizedString.Id("Tools.REFUND_AMOUNT_LABEL"),
        unit = "money"
    };

    // Only run the system when Temp entities are present:
    RequireForUpdate(m_TempQuery);
}

Additional notes for modders: - The system reads Temp component data and relies on TempFlags semantics. If you introduce new TempFlags or change how costs are computed, ensure the logic here still matches. - Tooltip color uses TooltipColor.Error when the player's money is insufficient. If you want different UI behavior, either subclass or replace the tooltip registration. - When iterating chunks, the system uses a read-only ComponentTypeHandle for Temp. If you change the system to write Temp component data, update the handle to non-read-only and adjust synchronization. - Because this system calls CompleteDependency() and uses ToArchetypeChunkArray with Allocator.TempJob, avoid long-running work inside OnUpdate to keep frame times stable.