Skip to content

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 changes
GameRunOrchestrator.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:

MethodPurpose
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 updates
bool IsGameplayActive => ...;
// Alias for IsGameplayActive - clearer intent for spawning systems
bool CanSpawnEntities => IsGameplayActive;

GameRunOrchestrator

// True if in cutscene state
bool IsInAnyCutscene => ...;

When to Use What

Check TypeWhat to Use
Simple state checkCurrentState == GameRunState.Gameplay
Active gameplay (for game logic)gameRunManager.IsGameplayActive
Can spawn entitiesgameRunManager.CanSpawnEntities
In any cutsceneorchestrator.IsInAnyCutscene
Return to overworldGameRunOrchestrator.Instance.ReturnToOverworld()

Internal Managers

GameRunManager delegates to specialized handlers:

HandlerPurpose
GameSessionManagerSession completion handling
GameRunStateManagerState change logic
GameRunControlManagerRun start/stop
GameRunCutscenesHandlerCutscene scheduling
GameRunPlayerUIEventsHandlerUI 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 cutscene
3. 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 → Overworld

If 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 = true
3. Normal flow: Overworld → select restaurant → ActivateRun → shop → gameplay

New Run (Normal)

1. Overworld → Player clicks interactable
2. SelectRestaurant(id, starLevel) called
3. ActivateRun() transitions to shop
4. Player prepares, clicks "Start Shift"
5. StartWorkDay() begins gameplay

Day Completion (Normal)

1. GameManager.GameOver() fires
2. OnGameSessionCompleteWithMetadata(metadata) invoked
3. GameRunManager receives metadata
4. Awards prestige, advances day
5. Transitions to ShopPrepareNextWorkShiftState

Day Completion (Tutorial)

1. GameManager.GameOver() fires
2. GameRunStateManager detects tutorial active
3. TutorialRunManager.AdvanceToNextLevel()
4. Plays AFTER_LEVEL dialogue (if configured)
5. Auto-starts next tutorial level (no shop)
6. On final level: CompleteTutorial() → Overworld

Level Selection Routing

GameRunStateManager.HandleShopPrepareState() checks level source in this order:

PriorityCheckBehavior
1TutorialRunManager.IsTutorialActiveGets level from tutorial config, skips shop entirely, goes straight to Gameplay
2CustomRunConfigManager.HasActiveCustomRunGets level from custom run config
3ProgressionDataManager.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:

  1. ProfileManager loads save data
  2. Determines which scene to load based on currentGameState
  3. For mid-run saves: SceneTransitionCoordinator.TransitionToGameRun(config) with StartMode.RestoreSave
  4. GameRunSceneInitializer.RestoreSave() restores helper cats, progression, flags, deck
  5. Calls GameRunOrchestrator.RestoreSavedRunAfterSceneLoad()
  6. 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;