Skip to content

Archived on 2026-10-24. The Godot rewrite is cancelled. Migration decisions and work checklists below are withdrawn. Original claims, code examples, file paths, and completion statements have not all been revalidated. Use the current documentation and issue register for maintenance decisions.

GameManager Analysis

Purpose

GameManager is the current gameplay scene singleton. It coordinates run state, player references, reward flow, UI, scoring, game over, save/progression, stage unlocks, and leaderboard data. It should not be copied directly into Godot.

Current Unity Implementation

Main file: Assets/Script/Game/Managers/GameManager.cs

Important collaborators:

Script Relationship
GameInitialization Called by GameManager.Start() to prepare run data.
GameStateService Encapsulates pause/reward/game-over/boss-defeated flags.
PlayerManager Handles XP/level and emits OnRewardReady.
RewardRoller Created by GameManager and uses many serialized GameManager UI/data fields.
UpgradeSelection Component on the same object; used by reward UI.
SpawnerEventManager Component on the same object; provides spawn state and timer bar reference.
Timer Component on the same object; run timers.
GameEndManager Game-over UI references.
GameDataCount Run counters and achievement checks.
LeaderboardManager Read and write leaderboard payload.
Save Static save facade for currencies, config, unlocks, counters.

Key Data

Important public fields and properties:

  • Scene references: init, dataCounter, gameEnd, menuManager, menuController, player.
  • Player/run: PlayerManager, level, NumberOfPlayer, Character.
  • HUD: scoreText, scoreString, levelText, xpBar, playerStatus, ammoText.
  • Reward data: BasicRewardTable, SpecialRewardTable, UltimateRewardTable, currentUpgrade, upgradeButton, upgradeButtonUI, chestDisplay, bossChestDisplay, buttonCount, totalWeight, rerollAmount.
  • State: isPaused, IsGameOver, IsBossDefeated, GameState.
  • Score/currency: score, soulPoint, chaosFrag.
  • Damage popup limiter: popUpDamageList.

Important methods:

Method Responsibility
Awake Singleton assignment, state reset, PlayerManager init, component lookup, reward roller construction, effect reset.
Start Starts initialization, starts hidden UI state, pauses.
Update Waits for init, updates reroll text, checks end time, processes reward queue, updates level/xp bar.
AddExp, AddScore, AddGold, AddChaosFrag Runtime counters/currencies.
OpenGate, StartUI, ShowUI, HideUI Gate/HUD flow.
PauseGame, ResumeGame Pause flag/time scale and post-resume level evaluation.
CheckGame Detects both players dead.
GameOver End-run pipeline, UI, save, leaderboard, achievements, final pause.
UnlockStage Unlocks next difficulty/stage/character after boss defeat.
HardLimitPopUpDamage Caps visible damage popups.
PushLeaderBoardData, ClearPreviousData Builds and submits leaderboard payload.

Runtime Flow

  1. Awake() sets instance, resets state, initializes players, and subscribes PlayerManager.OnRewardReady to EnqueueReward.
  2. Start() starts GameInitialization, initializes hidden HUD, and pauses.
  3. During Update(), the manager waits until GameInitialization.Instance.gameManagerInit is true.
  4. Every frame it:
  5. updates reroll amount text,
  6. checks Timer.currentTime against SpawnManager.EndGameTime,
  7. starts GameOver() if the run has ended,
  8. asks RewardRoller to process queued rewards,
  9. updates level text and animates XP bar if the normalized XP changed.
  10. Reward events enter via EnqueueReward.
  11. Game over stops spawn/timers, saves progress, prepares game-over UI, submits leaderboard, checks achievements, saves, plays UI animation, makes enemies flee, stops footstep audio, then pauses.

Dependencies

GameManager is a hub used directly by:

  • AbilityHolder, Player, PlayerWeapon, PlayerCollectItem, Items, StatusPanel.
  • SpawnerEventManager, RewardRoller, UpgradeSelection, UpgradeFunction.
  • UI/menu scripts and game-over buttons.
  • GameDataCount, leaderboard, save/progression systems.

Problems / Risks

  • Responsibilities are mixed:
  • core gameplay state,
  • UI animation,
  • reward orchestration,
  • score/currency,
  • save/progression,
  • stage unlock,
  • leaderboard serialization,
  • pause/time-scale handling.
  • GameManager exposes many mutable public fields used by unrelated systems.
  • RewardRoller is a separate class but still depends on GameManager as a bag of serialized references.
  • GameOver() is long and high-risk: it changes battle state, timers, save data, UI, leaderboard, achievements, enemy behavior, audio, and pause state.
  • PushLeaderBoardData() loops through all leaderboard entries and all player abilities/upgrades, building comma-separated strings manually.
  • UnlockStage() mutates LevelData/Character assets and then writes those values to save through GameDataLoader.SaveResources.
  • HardLimitPopUpDamage is an anti-lag patch on top of popup spawning rather than a proper feedback pool policy.
  • Pause and reward states are not consistently routed through one method. isPaused calls UpdateTimeScale, but SetRewarding does not.

Migration Notes for Godot

Preserve:

  • Public-facing run progression and game-over rewards.
  • Reward queue semantics.
  • Stage unlock rules:
  • Medium boss defeat unlocks hard for this stage, unlocks this stage character, and unlocks easy/medium next stage.
  • Hard boss defeat unlocks insane.
  • Insane boss defeat unlocks chaos.
  • Damage popup cap behavior, though implementation should move to the feedback pool.
  • Leaderboard payload content if leaderboard service remains compatible.

Redesign into separate Godot services/controllers:

Current Responsibility Suggested Godot Owner
paused/rewarding/game-over/boss-defeated flags RunState
timers and stage completion StageController
enemy waves and boss transitions SpawnDirector
score/soul/chaos counters ScoreManager or RunRewards
XP and level-up reward events PlayerManager / RunProgression
reward queue/card roll logic RewardDirector
reward UI and card input RewardUIController
game-over panel GameOverController
save updates/stage unlocks ProgressionService
leaderboard payload/post LeaderboardService
damage popup cap FeedbackController

Do not copy:

  • Singleton GameManager.instance as the central dependency.
  • Long GameOver() monolith.
  • UI references stored on core game state.
  • Runtime mutation of resource assets as the authority for save progression.

Open Questions

  • Whether GameStateService.OnStateChanged is used anywhere else; current scan found no meaningful subscribers.
  • Whether reward state should pause time, or whether current behavior intentionally lets time continue while cards animate.
  • Whether leaderboard post should happen synchronously at game over or be queued/retried.
  • Unknown / needs manual confirmation.