GameScene
GameScene is a critical subsystem that is responsible for core functionality such as initialising other components, creating stages (world, title screen, etc.) and handling the game's main loop.
Subsystem | |
---|---|
Official name | Yes |
Description | Handles the main loop and stages |
Init function |
Switch 1.5.0: 0x71007D1DD8 Wii U 1.5.0: ??? |
Debug only | No |
Unlike most other subsystems, GameScene is not a singleton: it is a member of the uking::frm::System structure[1].
Definitions
Stages
Also called scenes in XLink code.
Type | Description | Map types |
---|---|---|
0 | Invalid ("None") | - |
1 | Open world stage (except GameTestField) ("オープンワールド") | MainField, AocField |
2 | Indoor stage ("Cダンジョン") | CDungeon, MainFieldSpot, GameTestDungeon |
3 | Open world stage (GameTestField) ("GameTset") | GameTestField |
4 | MainFieldDungeon ("四大遺物") | MainFieldDungeon |
5 | Indoor stage or viewer stage ("ビューワー") | ActorViewer |
Maps that have the same stage type typically use the same subsystems and share most characteristics. For example, all open world stages use the Tera height map terrain system and load map units in the same way.
StageBinders
Type | Description |
---|---|
0 | OpenWorldStage |
1 | IndoorStage (CDungeon, ...) |
2 | MainFieldDungeonStage |
3 | TitleStage |
4 | StartupSaveCheckStage |
5 | Viewer |
Fade types
Type | Description |
---|---|
0 | |
1 | |
2 | Show logo[3] |
GameScene state strings
Name | Description |
---|---|
1st | Demo mode [check] |
2nd | Demo mode |
初回シーケンス | Initial sequence - New save |
TitleMenu | Title menu |
Presentation | Demo mode |
E3_2016/Presentation | Demo mode |
StartupSaveCheckStage | |
Viewer | |
CDungeon | |
MainFieldDungeonStage | |
MainField | |
GameTestField | |
GameTestField2 | |
AocField | |
GameTestDungeon | |
MonolithTestDungeon | |
SrdTestDungeon | |
MarioClubTestDungeon | |
TestField | |
研修用 | |
MonolithTest100enemy | |
MinimumField | |
ActorViewer |
Init
- GameScene::initialize (0x71007A8014)
- Load the environment graphics archive (Env.sgenvb)
- Create the GameScene heap
- Create the StageBinder heap
- Start the GameScene TaskMgr (thread)
- InitializeSubSystem (note: some of the below names are unofficial, see Subsystems for more details)
- AutoPlacementFlowMgr
- FadeProgress
- DungeonPackMgr
- PlayerInfo
- PlayerResetPosMgr
- GameSceneSubsys3
- GameSceneSubsys4
- GameSceneSubsys5
- ActorHeapUtil
- E3Mgr
- aoc2
- aoc3
- DamageInfoMgr
- CookingMgr
- GameSceneSubsys7
- ActorLimiter
- GameSceneSubsys9
- GameSceneSubsys10
- IceBlockMgr
- AmiiboMgr
- GameSceneSubsys11
- GameSceneSubsys12
- GameSceneSubsys13
- GameSceneSubsys14
- GameSceneSubsys15
- ResidentActorMgr
- Create UI heap
- uiManager
- Load the Fade screen
- OnUiActorMgr
- CreatePlayerEquipActorMgr
- CreatePlayerTrashActorMgr
- TipsMgr
- nxargs
- GameScene::initializeGraphicsLayer_
- ErrorViewerTask init
- Set Get Demo handler
- Set Check Weapon Free Slot handler (1, 2)
- ...
- SaveSystem init
- Set initial state
- nn::err::ShowUnacceptableAddOnContentVersionError if needed
-
- [Debug] StarterPackMgr: Load Title pack
- GlobalParameter
- GlobalParameter: Load actorpack
- E3Mgr: Load System/BuildTime.txt (stubbed in release versions)
- TipsMgr: Load tips
- ResidentActorMgr: Load configuration (ResidentActors.byml)
- AutoPlacementFlowMgr: Load auto placement event flows
- KingEditor: Stubbed
- E3Mgr: init
Initial state
The initial state the game launches into is determined by GameScene[5].
const bool isFirstLaunch = SaveSystem::sInstance->isFirstLaunch();
State* state = isFirstLaunch ? &state_NewSave : &state_LunchTitle;
if ( aocManager::sInstance && aocManager::sInstance->flags & 2 )
nn::err::ShowUnacceptableAddOnContentVersionError();
const bool isDemo = E3Mgr::sInstance && E3Mgr::sInstance->isDemoMode();
if (isDemo)
state = &state_LunchTitle;
if (!isDemo && isFirstLaunch)
sIsFirstNonDemoLaunch = 1;
StateMachine::changeState(&this->stateMachine, state);
States
Note: when the Indoor stage binder is initialised and if the map name changes, a "dungeon" telemetry report is emitted with "leave" or "enter" as the event name and the old/new map name as additional data[6].
StageMgr
This section is empty. You can help by adding to it. |
StageSelect
This section is empty. You can help by adding to it. |
StageTransition
Entered before stage generation starts and after Fade (loading screen) has been initialised and made visible. This state machine state is a noop.
LunchTitle
LunchTitle (sic) is entered when the game is launched. The internal state string is "TitleMenu" or (in demo mode) "2nd".
The run function is extremely simple: it simply creates the TitleStage binder (with doNotShowLogo=true[7]) when the "common run" status (see below) is 0xa, then calls the "common run" function (with isNewSave=false[8]).
NewSave
This section needs expansion. You can help by adding to it. |
Entered on the first boot or when the new game option is selected. The associated state string is "初回シーケンス" ("initial sequence").
PatchError
This section is empty. You can help by adding to it. |
Main loop
Three GameScene functions are called in a row from RootTask (see Executable) after initialisation has completed, i.e. in the game's main loop. (Note: these 3 names are unofficial.)
precalc
- FadeProgress: Update the progress gauge on the Fade screen (animated).
- Update current map name based on player position (when Link is not in a dungeon).
- Run StageMgr and StageSelect code.
- If a flag is set, run the final step of stage generation. (Unused?)
- If stage status is "NeedsGeneration":
- Call some MCMgr function at 0x71007A9198.
- Run save upload subsystem if needed.
- Call GameScene::genStage with second argument being
!EventMgr::sInstance->hasActiveEvent() || EventMgr::sInstance->getActiveEvent()->name != "Demo169_0"
.
- If stage status is "NeedsUnload":
- Call some MCMgr function at 0x71007A9198.
- Run save upload subsystem if needed.
- Call GameScene::unloadStage.
- If no stage is being unloaded, call
this->activeStageBinder->getStage()->preCalc
. - ??? (something involving GameScene Subsystem #12)
- Call some MCMgr function at 0x71007A9198, again.
- If the current state is StageMgr:
- Reset the current stage binder by setting a flag for StageMgr if needed (after a Blood Moon[check])
- If a forced blood moon is ready
- If panic blood moons can be triggered (see Blood moon), call the Blood Moon demo (Demo011_0).
- Report the panic blood moon via the telemetry system.
- If any panic condition is true, request a panic blood moon by setting a SkyMgr flag. SkyMgr will start a 90 frame timer (3 seconds) and set a ready flag once it has expired. The timer is reset every time the panic blood moon is temporarily inhibited.
calc
This section is empty. You can help by adding to it. |
postcalc
This section is empty. You can help by adding to it. |
Common state run function
Called from StageSelectRun, LunchTitleRun and NewSaveRun.
- Status 0:
- Start loading
- Finish startup logo (Switch)[9]
- If the state string is set to 初回シーケンス, clear the Resource system cache ("ClearAllCaches")[10].
- Debug stuff[11].
- E3 Demo stuff[12].
- Show the Fade screen (loading screen) if the state string does not[13] end with "Viewer" or is not any of the following strings: 1st, 2nd, Presentation, TitleMenu, 初回シーケンス, StartupSaveCheckStage
- StageSelect stuff[17].
- Stop "resource compaction" and wait for it to be stopped[18].
- If the stage string starts with CDungeon[19] or MainFieldDungeonStage[20], start loading the associated DungeonPack[21].
- BaseProcMgr: start ActorCreate initializer thread[22][check].
- FadeProgress: reset internal state[23], set progress to 0%[24] and mark loading as active[25].
- Start loading
- Status 2:
- If the GameScene state machine's current state is StageSelect or NewSave, do something involving LayerMgrTask and the Renderer.[check]
- Status 0xa:
- TipsMgr: update tips if the loading screen is visible (not just opened). TipsMgr will load tips depending on the stage that is being loaded.
- Status 0xb:
Stage generation
- Terrain::sInstance->flags |= 0x180u
- Step 0
- Step 1
- If a pack was loaded by DungeonPackMgr, wait for DungeonPack loading to finish[30] and switch active pack to the dungeon pack.
- Step 2
- If the stage to load is TitleStage, wait for TitlePack loading to finish[31] and switch active pack to the title pack.
- Step 3: start stage generation[32]
- PlacementMgr
- ActorSystem::sInstance->field_13A = 0
- Update current map flags (e.g. sIsDungeon)
- Clear BaseProcMgr ActorCreate queue[check]
- Create uking::Stage::ForBaseProcDual heap (if not already done), which will be used for actors, ActorCreator and BaseProcMgr
- ActorSystem::sInstance->field_139 = 0
- If the state string starts with 初回シーケンス, MainField, GameTestField, GameTestField2, AocField, CDungeon, MainFieldDungeonStage, GameTestDungeon, MonolithTestDungeon, SrdTestDungeon, MarioClubTestDungeon, TestField, 研修用, MonolithTest100enemy, MinimumField, or ActorViewer, call GameScene::startBgProcessing (0x71007B2054)
- If "new save" was selected, initialize PauseMenuDataMgr data
- If the stage to load is TitleStage, load Layout/Title.blarc for ui::LayoutResourceMgr.
- If "new save" was selected and the awakening demo hasn't been played since the game was launched[33], ask EventMgr to call Demo169_0.
- Some PhysicsMemSys stuff (0x71007ADBE0).
- Step 4
- Wait for completion of Title BG processing (20% of the loading bar)
- uiManager (0x71007ACD04)
- Initialize StatisticsMgr paths depending on current map type.
- Update aoc2's mapType and mapName fields.
- Step 5
- Step 6
- Load env.genvb binary (gsys::ModelSceneEnv::clearImpl + loadBinaryImpl)
- If the stage binder type is 0, 1 or 2 (OpenWorldStage, IndoorStage or MainFieldDungeonStage):
- Set loading progress to 40%.
- Graphics stuff, again
- OnUiActorMgr
- GameScene::loadTera (on a separate thread)
- Step 7
- If the stage binder type is 0, 1 or 2 (OpenWorldStage, IndoorStage or MainFieldDungeonStage):
- Wait for Tera to load[35]
- If the stage binder type is 0, 1 or 2 (OpenWorldStage, IndoorStage or MainFieldDungeonStage):
- Step 8
- ...
- Wait for Tera to generate collision
- ...
- Step 9
- Step 10
- Step 11
- Step 12
- Step 13
References
- ↑ uking::frm::System::gameScene @ 0x10 (Switch)
- ↑ As returned by the first virtual function in the StageBinderBase interface
- ↑ See 0x71007B8CD0 and AIDef:Action/ExitGame
- ↑ The state string is a sead::FixedSafeString<0x100> stored in GameScene @ 0x720.
- ↑ GameScene::initialize, 0x71007A86CC
- ↑ StageBinder::initAndReportDungeonLeaveEnter[unofficial name] at 0x71007B79A8
- ↑ 0x71007B47D8
- ↑ 0x71007B47F4
- ↑ 0x71007AF6F8
- ↑ 0x71007AFBDC
- ↑ 0x71007AFDE4
- ↑ 0x71007AFEF4
- ↑ 0x71007AFF08
- ↑ 0x71007AFFC4
- ↑ 0x71007AFFCC
- ↑ See function at 0x71007B0C60
- ↑ 0x71007B0000
- ↑ 0x71007B00B4 (stop compaction) to 0x71007B010C (end of the busy loop)
- ↑ 0x71007B0124
- ↑ 0x71007B0160
- ↑ 0x71007B0190
- ↑ 0x71011BF1C4
- ↑ 0x71007B01D4
- ↑ 0x71007B01E0
- ↑ 0x71007B01E8
- ↑ 0x71007B1058
- ↑ 0x71007B105C
- ↑ 0x71007AC8A0
- ↑ 0x71007AD3AC
- ↑ DungeonPack読み込み待ち
- ↑ TitlePack読み込み待ち
- ↑ ステージ生成開始
- ↑ 0x71007ADB3C
- ↑ 0x71007ACDE4
- ↑ tera読み込み待ち