Scheduled system upgrade on Sunday 21 April 2024 15:00-16:00 UTC - On that day, the wiki and other services might go down for 5-15 minutes.

Executable and GameDataMgr: Difference between pages

From ZeldaMods (Breath of the Wild)
(Difference between pages)
Jump to navigation Jump to search
imported>Leoetlino
 
imported>Leoetlino
 
Line 1: Line 1:
The '''executable''' is where all the game code is stored. It is located in the title code directory on Wii U and in the [[switchbrew:ExeFS|ExeFS]] on Switch.
{{Subsystem infobox|name=GameDataMgr|is_name_official=1|description=Manages game data flags|init_addr_switch150=0000007100DCE964}}
{{stub}}


Important note: unless otherwise stated, all addresses on this wiki are for the Switch 1.5.0 executable.
GameDataMgr holds the date of all game data flags and provides functions to get, set and reset them. It is also responsible for keeping track of "shop sold out" flags and resetting them regularly.


== File ==
Flag data is loaded from [[bgdata]] files and stored in [[TriggerParam]] objects. Transferring data from and to save files is done by interacting with the [[SaveSystem]] and [[SaveMgr]] subsystems.
=== Switch ===
BotW's executable is a standard, compressed [[switchbrew:NSO|NSO]] which is larger than most other games (about 20MB compressed).


The build path is <code>D:\home\Cafe\U-King\trunk\Game\App\Rom\NX64\Product\code\U-King.nss</code>. For build IDs, see [[Versions#Switch_versions]].
In debug versions, GameDataMgr is able to sync save data from and to a computer.


=== Wii U ===
== TriggerParams ==
BotW's executable is a standard, compressed RPX.
There are at least two sets of TriggerParams at all times and up to four (param1, param, ???, GimmickResetBuffer). The exact purpose of each TriggerParam is currently unknown.


== Libraries ==
After all GameData flag info has been loaded into this->triggerParam from the GameData archive ([[gamedata.sarc]]), another TriggerParam instance called param1 (this->triggerParam1) is constructed and data is copied from this->triggerParam. The copy function also builds the lists of flags that need to be reset (with a non-zero ResetType) and of boolean flags with (initialValue >> 1) != 0.
{{Link_to_article|link=Software libraries}}


== Subsystems ==
== Flags ==
{{Link_to_article|link=Subsystems}}


== Symbols ==
== GameDataMgr::Flags ==
Unfortunately, release versions of ''The Legend of Zelda: Breath of the Wild'' are stripped and have absolutely no debugging symbols. This has been verified for Switch 1.0.0, Wii U 1.5.0, Switch 1.5.0, Switch 1.6.0 and Switch RID_Demo.
Stored at GameDataMgr+0xC18 on Switch 1.5.0. Most flags are still poorly understood.


The Switch 1.5.0 and 1.6.0 executables only have some RTTI data for UI classes. This is likely also the case for all older versions.
Flags are checked in the main update function (GameDataMgr::calc). Some flags are used to request actions such as resetting all flags to their initial value; these are automatically unset after GameDataMgr has processed the request.


However, the game uses lots of [[Software libraries|software libraries]], some of which are included in games that do ship with complete symbols such as ''Super Mario Odyssey''. BotW seems to have been compiled at a higher optimisation level that causes unused functions to be fully removed.
<source lang="c++">
enum GameDataMgr::Flags
{
  GameDataMgr::Flags_1 = 0x1,
  GameDataMgr::Flags_2 = 0x2,
  /// Causes GameDataMgr to call TriggerParam::resetToInitialValues(this->triggerParam1),
  /// clear some values of this->triggerParam and invoke reset callbacks
  GameDataMgr::Flags_NeedResetAllToInitial = 0x4,
  /// Causes GameDataMgr to call TriggerParam::reset(this->triggerParam1) (see below)
  GameDataMgr::Flags_NeedReset = 0x8,
  /// [Debug only] Creates a TriggerParam instance called "GimmickResetBuffer" (if needed)
  /// and copies data from param1.
  /// A pointer to the instance is stored in GameDataMgr.
  GameDataMgr::Flags_NeedGimmickReset = 0x10,
  /// If this->gimmickResetBufferParam is non-null, copy it to triggerParam and to triggerParam1 (args: 1, 0, 0).
  GameDataMgr::Flags_NeedCopyGimmickParam = 0x20,
  /// If this->gimmickResetBufferParam is non-null, copy it to triggerParam and to triggerParam1 (args: 1, 1, 0).
  GameDataMgr::Flags_40 = 0x40,
  GameDataMgr::Flags_80 = 0x80,
  GameDataMgr::Flags_100 = 0x100,
  GameDataMgr::Flags_200 = 0x200,
  GameDataMgr::Flags_400 = 0x400,
  /// Set from flag setter functions. The name is based on the fact that IsChangedByDebug gets set at the same time.
  GameDataMgr::Flags_IsChangedByDebugMaybe = 0x800,
  GameDataMgr::Flags_1000 = 0x1000,
  GameDataMgr::Flags_2000 = 0x2000,
  GameDataMgr::Flags_4000 = 0x4000,
  GameDataMgr::Flags_ChangeOnlyOnceMode = 0x8000,
  GameDataMgr::Flags_10000 = 0x10000,
  GameDataMgr::Flags_20000 = 0x20000,
  /// If set, GameDataMgr::calc will skip copying param1 to param (args: 0, 0, 0)
  GameDataMgr::Flags_DisableParam1ToParamSync = 0x40000,
  GameDataMgr::Flags_IsRestartFromGameOverMaybe = 0x80000,
  GameDataMgr::Flags_DoNotResetToInitialFromRadarMgr = 0x100000,
};
</source>


== Init and main loop outline ==
== Reset flags ==
=== Early init and main loop ===
Stored at GameDataMgr+0xC1C on Switch 1.5.0.
* '''main'''
{|class="wikitable"
** nn::oe::Initialize
! Flag !! Description
** sead::GameFrameworkNx::initialize (implicitly calls nn::oe::Initialize again; this looks like a mistake from the Zelda developers)
|-
***sead::HeapMgr and root heap
| 1 || ?
***sead::ThreadMgr
|-
***sead::GlobalRandom
| 2 || Corresponds to reset type 1.
***sead::ResourceMgr
|-
***sead::FileDeviceMgr
| 4 || Corresponds to reset type 2.
** GameConfig
|-
** Unknown 71025D1720
| 8 || Corresponds to reset type 3.
** uking::GameFramework (derived from sead::GameFrameworkNx)
|-
** GraphicsSystem
| 0x10 || Corresponds to reset type 4.
** sead::GameFrameworkNx::initializeGraphicsSystem
|}
** [Debug] sead::PrimitiveRenderer
** [Debug] sead::DebugFontMgrNvn
** [Debug] sead::DebugFontMgrJis1Nvn
** '''RootTask'''
*** sead::TaskBase::CreateArg
*** sead::Framework::RunArg
*** '''framework->run'''
**** Constructs a sead::MethodTreeMgr (note: a custom, derived MethodTreeMgr is used in BotW)
**** Constructs a sead::TaskMgr
***** sead::TaskMgr::doInit_
****** sead::TaskMgr::prepare (on the ''Prepare Thread'')
******* '''[[#RootTask::prepare|RootTask::prepare]]'''
**** framework->runImpl_
***** framework->waitStartDisplayLoop_
***** '''framework->mainLoop'''
****** framework->procFrame
******* framework->procCalc
******** '''methodTreeMgr->calc''' (sead::SingleScreenMethodTreeMgr). Runs the following methods (sead::MethodTreeNode):
********* RootCalc
********** SysCalc
********** AppCalc
*********** PreCalc
*********** Calc
************ '''[[#RootTask::calc|RootTask::calc]]'''
*********** PostCalc
*********** CalcDL
********* RootDraw
********** AppDraw
********** AppDrawFinal
********** SysDraw
******* framework->present
******* framework->procReset
******* framework->waitForGpuDone
****** framework->setVBlankWaitInterval


=== RootTask::prepare ===
== Reset process ==
* framework->createSystemTasks
All game data flags for which <code>(1 << resetType) & resetFlags</code> is true are reset to their initial values.
** sead::ControllerMgr
** sead::ProcessMeter
** [Debug] sead::SeadMenuMgr
** [Debug] sead::HostIOMgr
** sead::InfLoopChecker
** [?] sead::CuckooClock
* InfLoopChecker setup


=== RootTask::calc ===
TriggerParam::reset processes up to 1024 flags at a time. The function returns the number of remaining flags to reset and flag 0x08 (GameDataMgr::Flags_NeedReset) is only cleared when all flags have been reset.
* Step 0
** ErrorViewer
** Volante
** ErrorViewerTask
** [[KingSystem]] heap
** SoundCalcThread
*** The name is extremely misleading. What the thread does is set up sead::RegionLanguageMgr and initialise it by reading System/RegionLangMask.txt.
* Step 1
** Wait for the sound calc thread to finish executing, before destroying it
* Step 2
** ScreenFactory
** '''ksys::PreInitializeApp'''
*** [[Patrol]]
*** [[Account]]
*** [[Terminal]]
*** [[GlobalMessage]]
*** [[ActorSystem]]
*** Physics Memory System
*** [Debug] [[CurrentResNameMgr]]
*** [[HavokWorkerMgr]]
*** SoundResource
*** [[OverlayArenaSystem]]
*** [[ResourceMgrTask]]
*** [Debug] [[Revision]]
*** RequestFontLoad
**** eui::FontMgr
**** [[LayoutResourceMgr]]
*** [Debug] Visualizer-shader
*** [[StarterPackMgr]]
**** Loads Bootup_Graphics, Bootup and (in non-debug mode) Title and TitleBG packs.
*** LayoutResourceMgr::loadVersion
*** [[aocManager]] (in post-1.0.0 versions)
**** Add-on content is mounted in aocManager::init (nn::fs::MountAddOnContent).
**** Set up the [[resource system]] (sead::FileDeviceMgr::mount + path prefix mapping) and load the version file.
* Step 3
** Wait for pre-initialised subsystems to be ready (StarterPackMgr ([[Bootup_Graphics.pack]], [[Bootup.pack]], lang-specific bootup pack), LayoutResourceMgr, aocManager).
* Step 4
** ScreenFactory (again, which leaks the previous factory)
** '''ksys::InitializeApp'''
*** [Release] Load [[AocMainField.pack]]
*** ''Switch active pack to Bootup_Graphics.''
*** gsys::SystemTask::init
*** ShaderArchives::load
*** ''Unload Bootup_Graphics and set active pack to TitleBG.''
*** [Debug] Log resource loads to %PROJECT_ROOT%/Log/BootupPatrol/res_bootup_graphics.csv.
*** Sound
*** Physics System Data
*** ''Start of ActorInfoData init.''
*** [[ActorInfoData]]
*** [[ActorTemplate]]
*** [[EffectInfoData]]
*** [[SoundInfoData]]
*** [[XLinkInfoData]]
*** ''End of ActorInfoData init.''
*** [[EventInfoData]]
*** [[ModelResourceDivide]]
*** [Debug] MemoryProfiler
*** [Debug] CPUProfiler
*** [[Controller]]
*** [[Camera]]
*** [[Hio]]
*** [[Effect]]
*** [[Reaction]]
*** [Debug] CameraEdtior (sic)
*** [Debug] KingEditor
*** [[PlayReport]] (see also [[Telemetry]])
*** [[ActorPreLoadMgr]]
*** [[Ecosystem]]
*** [[VideoRecorder]]
*** [[ModelCreator]]
*** Unknown 710261F9C8 (used from GameScene)
*** [Debug] Replay
*** [Debug] DebugInput
*** [[MoviePlayer]]
*** [[AnimSequence]] (AS)
*** [[Terrain]]
*** [[LODMgr]]
*** [Debug] Visualizer
*** [[NFP]]
*** Physics
*** Worker
*** [[HavokAI]]
*** [[SeadMenu]]
*** [[VFR]]
*** [[MCMgr]]
*** [[LowPrioThreadMgr]]
*** [[GameDataMgr]]
*** [[QuestMgr]]
*** [[EventMgr]]
*** aocManager init
*** [[AIClassDef]]
*** [[ActorParam]]
*** [[Chemical]]
*** [[Awareness]]
*** [[WorldMgr]]
*** [[UI]]
*** [[XLink]]
*** [Debug] ActorDebug
*** [Debug] DebugFinder
*** [Debug] ModelPicker
*** [Debug] GameTool
*** [[StagePreActorCache]]
*** [Debug] AutoGenFramework
*** [[StatisticsMgr]]
*** [[WorkerSupportThreadMgr]]
*** [[BaseProcMgr]]
*** [[Attention]]
*** [[Vibration]]
*** [[AutoDim]]
*** [Debug] MessageCapture
*** [Debug] InitResourceReload (resource live reloading)
** KingSystem heap is resized to fit.
** Attention: unknown init
* Step 5: noop
* Step 6: noop
* Step 7
** Rumble
** Unknown 71025D04D8
** Scene change functions
** MapStaticLoadMgr (loads Static.mubin)
** LayerMgrTask
** Unknown 71025D1790
** Unknown 71025D1A28
** Unknown 71025D04F0
** Debug board (?)
** Unknown 71025D16C0 (has to do with [[GameScene]], [[E3Mgr]] and [[AIDef:Action/PlayerPullSword]])
** Unknown 71025D1710
** Unknown 71025D1538 (has to do with frame and key input?)
** SeadController (derived from sead::Controller)
** CameraMgrTask
** LayerMgrTask
** Camera
** Unknown 71025D2508
** Unknown 71025D24C0
** [[ActorFactory]]
** AI system init
** [[SaveSystem]]
** [[TalkSystem]]
** [[SceneMgr]]
** '''uking::frm::System'''
*** '''[[GameScene]]'''
*** Attaches a few methods to the method tree manager from unknown subsystems and [[GameDataMgr]].
* '''End of RootTask init'''
* Step 8
** Wait for init to complete (GameScene, [[GlobalParameter]], E3Mgr, [[TipsMgr]], [[ResidentActorMgr]], [[AutoPlacementFlowMgr]], GameSceneUnknownSubsystem6, StarterPackMgr)
** GameScene::finaliseBootup
** MCMgr::sInstance->flags |= 0x10u
* Step 9
** 1
*** GameScene
** 2
*** Controller update (?)
*** SaveSystem update (?)
*** GameScene
** 3
*** GameScene


== Internal version ==
=== bool and s32 flags with reset type 3 ===
1.0.0's nnMain prints "00000010", whereas 1.5.0 prints "0000002d".
bool and s32 flags with reset type 3, and with a flag name hash that is listed in ShopAreaInfo (in [[ShopGameDataInfo.byml]]) receive special treatment.


1.6.0 prints "0000002e".
If:
* the player is in none of the shop areas that are associated with the flag (or in the Dealer's area for area-less flags); or if the player is not on MainField
* '''and''', for items with the <code>Arrow</code> tag: if the player has fewer than {itemSaleRevivalCount} arrows in their inventory
Then:
* The flag is reset to its initial value.
* For bool flags: All associated sold out flags are reset to their initial values.


== Unused content ==
[[Category: Internals]]
=== Arguments ===
[[Category: Subsystems (BotW)]]
The game accepts three different options: -fhd (flag for Full HD?), -no_sead_log (flag), -out (string). However the code that handles these arguments does not exist in the release version.
 
=== Save-breaking bug ===
Some development versions (1523941 to 1548881) generated unusable saves. These strings are still present in the release version but they are unused.
 
<pre>
.rodata.2:0000007101DE98B0 a15239411548881 DCB "@1523941 ~ @1548881のROMからのセーブデータを利用しているようです。",0xA
.rodata.2:0000007101DE98B0                DCB "バグ報告をせずに、セーブデータを消去してください。",0xA
.rodata.2:0000007101DE98B0                DCB "@1523941 ~ @1548881からのセーブデータであるはずがないという場合のみ、バグ報告をしてください。",0xA
.rodata.2:0000007101DE98B0                DCB "num_valid_normal_mode %d/%d, num_valid_hard_mode %d%d",0
</pre>
 
=== Leftover debug or development tools ===
==== ActorCapture ====
See [[ActorCapture]] for more information.
 
The resource factory and resource classes are still present in release builds, but no ActorCapture parameter files are included in the ROM.
 
==== EventPatroller ====
Used to generate movies (prerendered cutscenes) for event flows. Receives orders via HostIO (in BYML format) in <code>%UKING_ROOT%/../workdir/EventPatroller/order.byml</code> and writes:
 
* A YAML report containing frame-by-frame data with camera position, actor information, etc. Written to <code>%s/report.yml</code> % (name).
* Screenshots for the entire event (maximum 18000 frames) captured using agl::utl::ScreenshotMgr, and written to <code>%s/%05d.tga</code> % (name, frame).
 
Throughout the execution of the order, <code>%%KSYS_ROOT%%/tools/EventPatroller/ChangeStatus.bat</code> is spawned to update the order status on the host computer.
 
EventPatroller can apparently make use of Havok script files (hks) in dev builds<ref><code>script_name</code> (in the order data) is a path to a hks file.</ref>. However, all script-related code is stubbed in release builds and both the <code>hks</code> and <code>lua</code> resource factories are unused.
 
==== Placement ====
The <code>bplacement</code> resource factory is stubbed in release builds. The associated resource class is also stubbed. It is unknown what Placement files would have contained. (Configuration for the [[PlacementMgr]]?)
 
Given the small resource size, it is likely that bplacement files are not [[AAMP]] resources but [[BYML]]s.
 
==== Demo ROM types ====
The game calls <code>sead::EnvUtil::getRomType()</code> to get the ROM type. The result is printed to a debug log along with SD card, revision and AoC (DLC) information.
 
The ROM type is loaded from System/RegionLangMask.txt. Possible values are:
 
* "Normal": used in retail versions (at least 1.0.0 and 1.5.0)
* "Show_2017_1st": demo version, used for 12S?
* "RID_Demo": Retail Interactive Display demo (aka kiosk version). Seen in the Switch kiosk version.
* Anything else is treated as "Normal".
 
The release build crashes if the ROM type is set to Show_2017_1st or RID_Demo, presumably because these types activate code paths that require a global debug heap which never gets initialised in release versions.
 
==== ErrorViewer and Stage Select ====
There are references to debugging tools like Error (an in-game integrated bug tracker) and a [[StageSelect|stage select]] mode (uking::StageSelect + more strings). UI data and structures for the ErrorViewerTask still exist to a certain extent, but whether these features can be reactivated or not is still unknown.
 
==== Disabled functionality ====
In 1.5.0, the Patrol subsystem has a reference to BUILD_URL. Unfortunately, the function that is supposed to set the BUILD_URL string (sub_7100B0B728) is stubbed in the release build.
 
Similarly, the Revision subsystem is disabled in release builds. According to strings in the stage select screen function, it would have contained information about a program number (int), resource number (int) and a 'build from' string.
 
==== ActorDebug ====
This is a rather large subsystem that interacts with the actor system and all related components such as demos, events and maps. It can print debug information about the current state and override actor creation behaviour.
 
==== Debug options ====
A large amount of debug config strings have been left in the executable. These show the existence of debug game config files that were used to make testing more convenient during development.
 
The debug config files do not exist in the release version; the config loading code was removed as well.
 
<pre>
.rodata.2:0000007101DC9625 aDebugGameconfi DCB "Debug/GameConfigSettingForGameROM.xml",0
.rodata.2:0000007101DC9625                                        ; DATA XREF: initDebugConfigFilePaths+18↑o
.rodata.2:0000007101DC9625                                        ; initDebugConfigFilePaths+2C↑o
.rodata.2:0000007101DC964B aDebugGameconfi_0 DCB "Debug/GameConfigForGameROM.xml",0
.rodata.2:0000007101DC964B                                        ; DATA XREF: initDebugConfigFilePaths+20↑o
.rodata.2:0000007101DC964B                                        ; initDebugConfigFilePaths+38↑o
.rodata.2:0000007101DC966A aDebugSystemgam DCB "Debug/SystemGameConfigForGameROM.xml",0
.rodata.2:0000007101DC966A                                        ; DATA XREF: initDebugConfigFilePaths+24↑o
.rodata.2:0000007101DC966A                                        ; initDebugConfigFilePaths+3C↑o
.rodata.2:0000007101DC968F aOpenworldOverr DCB "OpenWorld_OverrideStartPos",0
.rodata.2:0000007101DC96AA aOpenworldStart DCB "OpenWorld_StartX",0
.rodata.2:0000007101DC96BB aOpenworldStart_0 DCB "OpenWorld_StartY",0
.rodata.2:0000007101DC96CC aOpenworldStart_1 DCB "OpenWorld_StartZ",0
.rodata.2:0000007101DC96DD aOpenworlddesig DCB "OpenWorldDesign_OverrideStartPos",0
.rodata.2:0000007101DC96FE aOpenworlddesig_0 DCB "OpenWorldDesign_StartX",0
.rodata.2:0000007101DC9715 aOpenworlddesig_1 DCB "OpenWorldDesign_StartY",0
.rodata.2:0000007101DC972C aOpenworlddesig_2 DCB "OpenWorldDesign_StartZ",0
.rodata.2:0000007101DC9743 aIsdisabledpick DCB "IsDisabledPickUpDemo",0
.rodata.2:0000007101DC9758 aIsenabledcdung DCB "IsEnabledCDungeonEntranceDemo",0
.rodata.2:0000007101DC9776 aIsdisabledcdun DCB "IsDisabledCDungeonGoalTerminalDemo",0
.rodata.2:0000007101DC9799 aAlwayswaitscen DCB "AlwaysWaitSceneCreate",0
.rodata.2:0000007101DC97AF aIsequipweaponr DCB "IsEquipWeaponRandom",0
.rodata.2:0000007101DC97C3 aIsequiparmorra DCB "IsEquipArmorRandom",0
.rodata.2:0000007101DC97D6 aIssetweaponran DCB "IsSetWeaponRandom",0
.rodata.2:0000007101DC97E8 aIssetarmorrand DCB "IsSetArmorRandom",0
.rodata.2:0000007101DC97F9 aIssetarmorscri DCB "IsSetArmorScript",0
.rodata.2:0000007101DC980A aIssetitemrando DCB "IsSetItemRandom",0
.rodata.2:0000007101DC981A aIssetcookitemr DCB "IsSetCookItemRandom",0
.rodata.2:0000007101DC982E aDisabletimesto DCB "DisableTimeStop",0
.rodata.2:0000007101DC983E aSetdebugtime  DCB "SetDebugTime",0
.rodata.2:0000007101DC984B aDefaultfinewea DCB "DefaultFineWeather",0
.rodata.2:0000007101DC985E aDefaulttoolenv DCB "DefaultToolEnv",0
.rodata.2:0000007101DC986D aDefaultplayren DCB "DefaultPlayreNoTired",0
.rodata.2:0000007101DC9882 aDefaultplayern DCB "DefaultPlayerNoTemperture",0
.rodata.2:0000007101DC989C aAutoplacement  DCB "AutoPlacement",0
.rodata.2:0000007101DC98AA aTeam          DCB "Team",0
.rodata.2:0000007101DC98AF aShowmergeddung DCB "ShowMergedDungeonActor",0
.rodata.2:0000007101DC98C6 aShowmergedgrud DCB "ShowMergedGrudgeActor",0
.rodata.2:0000007101DC98DC aIsopenmapall  DCB "IsOpenMapAll",0
.rodata.2:0000007101DC98E9 aDebugcameraspe DCB "DebugCameraSpeed",0
.rodata.2:0000007101DC98FA aDebugcamerarep DCB "DebugCameraReplaceStick",0
.rodata.2:0000007101DC9912 aDebugcamerarev DCB "DebugCameraReverseVerticalRotation",0
.rodata.2:0000007101DC9935 aDebugcamerarev_0 DCB "DebugCameraReverseHorizontalRotation",0
.rodata.2:0000007101DC995A aDebugcameracon DCB "DebugCameraControlFovy",0
.rodata.2:0000007101DC9971 aIstexturememor DCB "IsTextureMemoryIncrese",0
.rodata.2:0000007101DC9988 aIstexturememor_0 DCB "IsTextureMemoryBothIncrease",0
.rodata.2:0000007101DC99A4 aIspilottexture DCB "IsPilotTextureMemoryIncrese",0
.rodata.2:0000007101DC99C0 aIspassstagesel DCB "IsPassStageSelect",0
.rodata.2:0000007101DC99D2 aIsstageselectr DCB "IsStageSelectRegularGameOver",0
.rodata.2:0000007101DC99EF aIsenableuidebu DCB "IsEnableUiDebugCommand",0
.rodata.2:0000007101DC9A06 aFirstscene    DCB "FirstScene",0
.rodata.2:0000007101DC9A11 aToolFrontEnd  DCB "Tool Front-End",0
.rodata.2:0000007101DC9A20 aDefaulttoolfro DCB "DefaultToolFrontEndPage",0
</pre>
 
Option values are hardcoded in the Switch kiosk version as well.
 
[[Category:Internals]]

Revision as of 09:47, 31 December 2018

GameDataMgr
Subsystem
Official name Yes
Description Manages game data flags
Init function Switch 1.5.0: 0000007100DCE964
Wii U 1.5.0: ???
Debug only No


GameDataMgr holds the date of all game data flags and provides functions to get, set and reset them. It is also responsible for keeping track of "shop sold out" flags and resetting them regularly.

Flag data is loaded from bgdata files and stored in TriggerParam objects. Transferring data from and to save files is done by interacting with the SaveSystem and SaveMgr subsystems.

In debug versions, GameDataMgr is able to sync save data from and to a computer.

TriggerParams

There are at least two sets of TriggerParams at all times and up to four (param1, param, ???, GimmickResetBuffer). The exact purpose of each TriggerParam is currently unknown.

After all GameData flag info has been loaded into this->triggerParam from the GameData archive (gamedata.sarc), another TriggerParam instance called param1 (this->triggerParam1) is constructed and data is copied from this->triggerParam. The copy function also builds the lists of flags that need to be reset (with a non-zero ResetType) and of boolean flags with (initialValue >> 1) != 0.

Flags

GameDataMgr::Flags

Stored at GameDataMgr+0xC18 on Switch 1.5.0. Most flags are still poorly understood.

Flags are checked in the main update function (GameDataMgr::calc). Some flags are used to request actions such as resetting all flags to their initial value; these are automatically unset after GameDataMgr has processed the request.

enum GameDataMgr::Flags
{
  GameDataMgr::Flags_1 = 0x1,
  GameDataMgr::Flags_2 = 0x2,
  /// Causes GameDataMgr to call TriggerParam::resetToInitialValues(this->triggerParam1),
  /// clear some values of this->triggerParam and invoke reset callbacks
  GameDataMgr::Flags_NeedResetAllToInitial = 0x4,
  /// Causes GameDataMgr to call TriggerParam::reset(this->triggerParam1) (see below)
  GameDataMgr::Flags_NeedReset = 0x8,
  /// [Debug only] Creates a TriggerParam instance called "GimmickResetBuffer" (if needed)
  /// and copies data from param1.
  /// A pointer to the instance is stored in GameDataMgr.
  GameDataMgr::Flags_NeedGimmickReset = 0x10,
  /// If this->gimmickResetBufferParam is non-null, copy it to triggerParam and to triggerParam1 (args: 1, 0, 0).
  GameDataMgr::Flags_NeedCopyGimmickParam = 0x20,
  /// If this->gimmickResetBufferParam is non-null, copy it to triggerParam and to triggerParam1 (args: 1, 1, 0).
  GameDataMgr::Flags_40 = 0x40,
  GameDataMgr::Flags_80 = 0x80,
  GameDataMgr::Flags_100 = 0x100,
  GameDataMgr::Flags_200 = 0x200,
  GameDataMgr::Flags_400 = 0x400,
  /// Set from flag setter functions. The name is based on the fact that IsChangedByDebug gets set at the same time.
  GameDataMgr::Flags_IsChangedByDebugMaybe = 0x800,
  GameDataMgr::Flags_1000 = 0x1000,
  GameDataMgr::Flags_2000 = 0x2000,
  GameDataMgr::Flags_4000 = 0x4000,
  GameDataMgr::Flags_ChangeOnlyOnceMode = 0x8000,
  GameDataMgr::Flags_10000 = 0x10000,
  GameDataMgr::Flags_20000 = 0x20000,
  /// If set, GameDataMgr::calc will skip copying param1 to param (args: 0, 0, 0)
  GameDataMgr::Flags_DisableParam1ToParamSync = 0x40000,
  GameDataMgr::Flags_IsRestartFromGameOverMaybe = 0x80000,
  GameDataMgr::Flags_DoNotResetToInitialFromRadarMgr = 0x100000,
};

Reset flags

Stored at GameDataMgr+0xC1C on Switch 1.5.0.

Flag Description
1 ?
2 Corresponds to reset type 1.
4 Corresponds to reset type 2.
8 Corresponds to reset type 3.
0x10 Corresponds to reset type 4.

Reset process

All game data flags for which (1 << resetType) & resetFlags is true are reset to their initial values.

TriggerParam::reset processes up to 1024 flags at a time. The function returns the number of remaining flags to reset and flag 0x08 (GameDataMgr::Flags_NeedReset) is only cleared when all flags have been reset.

bool and s32 flags with reset type 3

bool and s32 flags with reset type 3, and with a flag name hash that is listed in ShopAreaInfo (in ShopGameDataInfo.byml) receive special treatment.

If:

  • the player is in none of the shop areas that are associated with the flag (or in the Dealer's area for area-less flags); or if the player is not on MainField
  • and, for items with the Arrow tag: if the player has fewer than {itemSaleRevivalCount} arrows in their inventory

Then:

  • The flag is reset to its initial value.
  • For bool flags: All associated sold out flags are reset to their initial values.