Boot and GameRoot
In short
GameBootstrapadds a[Game]object with aGameRootafter any scene loads.GameRoot.Awakecreates every service in a fixed order and opens the main menu. Screens move between states only throughGameRootmethods (GoToMainMenu,OpenMapSelect,EnterCustomize,EnterIndex,EnterLobby,SetState).
How it works
1. Bootstrap
GameBootstrap has two [RuntimeInitializeOnLoadMethod] hooks:
SubsystemRegistration:GameEvents.ClearAll(), so Play mode without a domain reload starts with no stale subscribers.AfterSceneLoad: if noGameRootexists, createnew GameObject("[Game]").AddComponent<GameRoot>().
A hand-made scene that already holds a GameRoot is left alone. The build uses an empty scene (see Build and Release).
2. GameRoot.Awake, in order
- Singleton: a second
GameRootdestroys itself.DontDestroyOnLoad. Content = ContentDatabase.LoadOrDefault():Resources/ContentDatabaseorDefaultContent.Build().FitOverrides.LoadAndApply(...): Fit Mode saves on top of content, before any batter is built (Fit Mode).Save = SaveSystem.Load()(Save System).UI.DisplaySettings.Apply(Save.settings): fullscreen, resolution, V-Sync, FPS cap.Meta = new MetaProgression(Save, Content);Leaderboard = new LocalLeaderboardService(Save);Mode = GameModes.All[0](Solo).SetupCameraAndLight(): usesCamera.mainor makes one (with anAudioListener), addsCameraRig, callsPostFx.Setup, removes the thumbnail layer from the culling mask, finds a directional light or makes aSunwith soft shadows (Rendering).Field: aBallparkobject withBallparkBuilder.Init(Sun, camera)(Ballpark Building).AtBat:AtBatController.Init(CameraRig)on the same object (At-Bat Loop).- Add-on components on
[Game], in this order:TimingIndicator,GreenFeedback,SwingLog(Swing Log),GameAudio,ScreenFade,ThumbnailRenderer,Intro = MatchIntroDirectorandOutro = OutroDirector(Cutscenes; the outro adds its ownFireworks),ParkSnapshots(map-select pictures, UI System),FpsCounter. Net = NetRuntime; hooksSessionReplacedandJoinRequested, thenHookSession()so a session’sRunStartingcallsCoopRun.Start(Lobby and Session).Cage = BattingCage(Batting Cage).Runs = new RunManager(this).UIRoot(which addsDevMenuin the Editor and development builds).GoToMainMenu().
3. Navigation methods
| Method | What it does | State |
|---|---|---|
SetState(state) | Sets State and raises GameEvents.StateChanged. | any |
GoToMainMenu() | Time scale 1. Stops an active co-op run and leaves its session. Builds ballparks[0], shows the selected batter in preview. | MainMenu |
OpenMapSelect() | Preview batter, menu camera. MapSelectView builds the picked park. | MapSelect |
EnterCustomize() | Builds ballparks[0], preview batter on the stage (AtBat.SetStage(true)). | Customize |
EnterIndex() | Time scale 1; the INDEX screen under the lobby top bar (Index Screen). Keeps whatever park is built. | Index |
EnterLobby() | Stops any co-op run, builds ballparks[0], preview batter. | Lobby |
JoinFromPlatform(code) | Steam overlay “Join game”. Ignored (with a net log line) when busy in co-op, in a session or at bat. Switches to the Steam backend, enters the lobby and joins. | Lobby |
OnApplicationQuit saves save.json.
Numbers
| What | Value | Where to tune |
|---|---|---|
| Starting game mode | GameModes.All[0] (Solo) | GameRoot.Awake |
| Park behind the menus | Content.ballparks[0] (Sandlot Field) | GoToMainMenu, EnterLobby, EnterCustomize |
In the code
| File | What it does |
|---|---|
Scripts/Core/GameBootstrap.cs | ResetStatics, Boot. |
Scripts/Core/GameRoot.cs | Awake, SetupCameraAndLight, SetState, HookSession, JoinFromPlatform, EnterLobby, GoToMainMenu, OpenMapSelect, EnterCustomize, EnterIndex, IsReady, Run, and the Intro / Outro directors. |
Scripts/Data/ContentDatabase.cs | LoadOrDefault(). |
Gotchas
GameRoot.RunisActiveCoop ?? Runs. Code that wants “the run on screen” must useRun, notRuns.IsReady(Meta,RunsandAtBatset) goes false after a Play-mode recompile; the UI skips drawing rather than crash.- Every navigation method resets
Time.timeScaleto 1, so leaving a paused at-bat never leaves the game frozen. SwingInputhas its ownRuntimeInitializeOnLoadMethodhooks that create the swing input action (Controls).- The
IntroandOutrostates are not entered through a navigation method:RunManager,CoopRunand the directors’PreviewcallSetStatedirectly (Game States and Screens).
Related
- Architecture: the big picture
- Game States and Screens: what each state draws
- Save System: what loads in step 4
- Fit Mode: what loads in step 3
- Cutscenes: the two directors added in step 10