GameManager

Overview

Central game loop and global state coordinator. Orchestrates ticks, long ticks, win/lose checks, route navigation for end-of-game screens, and keeps global counters/atoms in sync. Maintains a static, ordered list of TickBehavior instances (Regions first, then Labs, then others) and invokes their Tick() each cycle.

Serialized Atoms

  • Timing & flow: FloatVariable tickTime, IntVariable longTickInterval, IntVariable longTickCounter, BoolVariable paused, IntVariable sharedAbilityCooldown
  • Economy & meta: FloatVariable currentMoney, FloatVariable moneyGainedLastTick, FloatVariable totalMoneyGained, FloatVariable maxDebtReached, FloatVariable playTime
  • Sentiment & capture: FloatVariable loyalty, FloatVariable loyaltyLossLesser, FloatVariable loyaltyLossGreater, FloatVariable loyaltyLossThreshold, FloatVariable loyaltyLossLimit, FloatVariable loyaltyLossMultiplier, FloatVariable captureProgress
  • UI/navigation: StringVariable navigationRoute
  • Events: VoidEvent longTickEvent, VoidEvent earlyLongTickEvent, VoidEvent winEvent, VoidEvent loseEvent, VoidEvent restartEvent, VoidEvent QuitEvent

Lifecycle

  • Start():
    • Sets PlayerPrefs["HasStartedGame"]=1 and navigationRoute="sec/game/sub/gameplay".
    • Starts the main Tick coroutine.
    • Initializes earlyLongTickCounter = longTickCounter + 10 (delta = 10).
    • Registers restart / quit handlers.
  • Update(): accumulates playTime += Time.deltaTime.
  • OnDestroy(): stops all coroutines.

Tick Loop

Each cycle (while not paused):

  1. Decrement sharedAbilityCooldown if > 0.
  2. Call Tick() on every registered TickBehavior (in maintained order).
  3. Increment early and regular long-tick counters:
    • If earlyLongTickCounter >= longTickInterval → raise earlyLongTickEvent, subtract interval.
    • If ++longTickCounter >= longTickInterval → raise longTickEvent, reset to 0.
  4. Compute moneyGainedLastTick = currentMoney - prevMoney; if positive, add to totalMoneyGained.
  5. If currentMoney < 0, apply DebtLoyaltyLoss().

Waits tickTime - elapsed seconds before the next iteration (logs optional elapsed).

Win/Lose Conditions

  • Lose: loyalty < 0 or captureProgress >= 1 → pause, set navigationRoute="sec/game", raise loseEvent.
  • Win: all Region behaviors report Control >= 1 → pause, set navigationRoute="sec/game", raise winEvent.

DebtLoyaltyLoss()

When in debt (currentMoney < 0):

  • Track the maximum debt reached.
  • If above threshold → subtract loyaltyLossLesser * loyaltyLossMultiplier.
  • Else apply a soft-limit curve using parameters Beta = 0.5 and ScaleS = 30000 to compute a stronger loss, then multiply by loyaltyLossMultiplier.

TickBehavior Registry

public static void Subscribe(TickBehavior b)
{
    if (b.IsRegion()) Insert at start;
    else if (b.IsLab()) Insert right after last Region;
    else Add at end;
}
public static void Unsubscribe(TickBehavior b) => Remove(b);

This preserves update order: Regions → Labs → Others for deterministic simulation.

Utility

  • static Region FindRegionByName(string name)
  • static List<Region> GetAllRegions()
  • static List<Laboratory> GetAllLabs()
  • void RestartGame() — reloads active scene.
  • void QuitGame()Application.Quit().