Game Runs System
Manages the meta-game loop: starting runs, tracking progress, handling win/loss.
Key Classes
GameRunOrchestrator
Location: Assets/_Game/Scripts/Managers/GameRunOrchestrator.cs
The single source of truth for state transitions:
// Always use this for state changesGameRunOrchestrator.Instance.TransitionToState(GameRunState.Gameplay);Responsibilities:
- UI visibility management
- Camera switching
- Scene management
- Validates transitions via
IsValidTransition()
GameRunManager
Location: Assets/_Game/Scripts/Managers/GameRunManager.cs
Central coordinator for run-level logic:
| Method | Purpose |
|---|---|
StartRun(difficulty) | Initialize new campaign attempt |
ActivateRun() | Begin after “Start Adventure” click |
SelectRestaurant(id, star) | Choose restaurant and star level |
HandleStateChange(state) | React to state transitions |
ReturnToHubWorld() | Return after run ends |
WorkDayProgress
Location: Assets/_Game/Scripts/Data/WorkDayProgress.cs
Tracks position in the campaign:
public class WorkDayProgress{ public int CurrentMichelinStar; // Which star level (week) public int CurrentDayLevel; // Day in current star public string CurrentRestaurantId; public int TotalDaysInRun;
public int GetPrestige(); // Accumulated currency public void AdvanceDay();}State System
Scene-Level States
Each scene represents a high-level game phase:
- MainMenuScene — Profile selection, settings
- OverworldScene — Hub world exploration (managed by
GameOverworldManager) - GameRunScene — Active game run (managed by
GameRunOrchestrator)
GameRun States (GameRunState)
States within a game run (scoped to GameRunScene):
public enum GameRunState{ Initializing, // Scene loading RunIntro, // Run introduction ShopPrepareNextWorkShiftState, // Shop/results Gameplay, // Active shift GameplayLost, // Failed run Cutscene // Playing cutscene}Note: GameRunState.Overworld still exists with [Obsolete] for save data backward compatibility but is never used in new code.
Access via: GameRunOrchestrator.Instance.CurrentState or GameRunManager.Instance.CurrentState
Overworld Sub-states (OverworldSubstate)
Internal states within OverworldScene:
public enum OverworldSubstate{ Exploration, // Free movement and interaction CharacterCustomization, // Customizing cat appearance Cutscene // Cutscene playing in overworld context}Access via: GameOverworldManager.Instance.CurrentSubstate
Compound Query Properties
For non-obvious multi-condition checks, use these compound properties:
GameRunManager
// True when gameplay is actively running (not paused, not in cutscene, not lost)// Use for spawning, timers, game logic updatesbool IsGameplayActive => ...;
// Alias for IsGameplayActive - clearer intent for spawning systemsbool CanSpawnEntities => IsGameplayActive;GameRunOrchestrator
// True if in cutscene statebool IsInAnyCutscene => ...;When to Use What
| Check Type | What to Use |
|---|---|
| Simple state check | CurrentState == GameRunState.Gameplay |
| Active gameplay (for game logic) | gameRunManager.IsGameplayActive |
| Can spawn entities | gameRunManager.CanSpawnEntities |
| In any cutscene | orchestrator.IsInAnyCutscene |
| Return to overworld | GameRunOrchestrator.Instance.ReturnToOverworld() |
Internal Managers
GameRunManager delegates to specialized handlers:
| Handler | Purpose |
|---|---|
GameSessionManager | Session completion handling |
GameRunStateManager | State change logic |
GameRunControlManager | Run start/stop |
GameRunCutscenesHandler | Cutscene scheduling |
GameRunPlayerUIEventsHandler | UI button responses |
Run Flow
First-Time Flow (with Tutorial)
1. Profile created → GameSceneInitializer → no save → StartNewRun()2. GameRunControlManager.StartRun() → first playthrough: plays START_OF_GAME_PLAYTHROUGH cutscene3. Cutscene completes → GameRunCutscenesHandler.OnCutsceneCompleteHandler() → TutorialRunManager.ShouldPlayTutorial() → true → TutorialRunManager.Instance.StartTutorial()4. Tutorial runs 3 levels (shop-free, wave-based spawning, with dialogue)5. Tutorial completes → hasCompletedTutorial = true → saves → OverworldIf there is no intro cutscene, the tutorial check also runs in the no-cutscene fallback path of StartRun().
See Tutorial doc for full tutorial system details.
Returning Player Flow
1. Profile loaded with save data → GameSceneInitializer → has save → RestoreSaveData()2. hasPlayedIntroCutscene = true, hasCompletedTutorial = true3. Normal flow: Overworld → select restaurant → ActivateRun → shop → gameplayNew Run (Normal)
1. Overworld → Player clicks interactable2. SelectRestaurant(id, starLevel) called3. ActivateRun() transitions to shop4. Player prepares, clicks "Start Shift"5. StartWorkDay() begins gameplayDay Completion (Normal)
1. GameManager.GameOver() fires2. OnGameSessionCompleteWithMetadata(metadata) invoked3. GameRunManager receives metadata4. Awards prestige, advances day5. Transitions to ShopPrepareNextWorkShiftStateDay Completion (Tutorial)
1. GameManager.GameOver() fires2. GameRunStateManager detects tutorial active3. TutorialRunManager.AdvanceToNextLevel()4. Plays AFTER_LEVEL dialogue (if configured)5. Auto-starts next tutorial level (no shop)6. On final level: CompleteTutorial() → OverworldLevel Selection Routing
GameRunStateManager.HandleShopPrepareState() checks level source in this order:
| Priority | Check | Behavior |
|---|---|---|
| 1 | TutorialRunManager.IsTutorialActive | Gets level from tutorial config, skips shop entirely, goes straight to Gameplay |
| 2 | CustomRunConfigManager.HasActiveCustomRun | Gets level from custom run config |
| 3 | ProgressionDataManager.IsDataLoaded() | Gets level from restaurant/star/day progression |
Save/Load Integration
Runs auto-save at:
- Entering OverworldScene (via
OverworldSceneInitializer) - Entering Shop state (via
GameRunOrchestrator) - After level completion
Never during active gameplay (prevents save scumming).
Restoration flow:
ProfileManagerloads save data- Determines which scene to load based on
currentGameState - For mid-run saves:
SceneTransitionCoordinator.TransitionToGameRun(config)withStartMode.RestoreSave GameRunSceneInitializer.RestoreSave()restores helper cats, progression, flags, deck- Calls
GameRunOrchestrator.RestoreSavedRunAfterSceneLoad() - Transitions to saved state
Events
public static event Action<GameRunState> OnGameRunStateChanged;public static event Action<WorkDayResult> OnWorkDayCompleted;public static event Action OnRunCompleted;public static event Action OnRunFailed;