Debug mode - TheVNConnoisseur/MICo_Guide GitHub Wiki
Main characteristics
Purpose of this feature
Help the developers debug any possible issue in-game, and have an exact idea of what function calls the game is using and with what parameters.
What engine revisions have it?
| Version number | Feature present |
|---|---|
| 1 | :x: |
| 2 | :white_check_mark: |
How to activate it
According to the following IDA decompilation:
WinMain
SDT_Key_Length = strlen(&SDT_Key);
if ( SDT_Key_Length )
{
Dat_Key_Length = strlen(Dat_Key);
SDT_Key_ShufflerByte[SDT_Key_Length] += 47 * (Dat_Key_Length / 47) - Dat_Key_Length; // recalculate the first and last byte of sdt_key based on its length
}
SDT_Key -= strlen(Dat_Key); // recalculate the first byte of the sdt_key based on the length of dat_key
wsprintfA(::FileName, "%s\\%s\\%s.ini", "", "MICo_Debug", "MICo_Debug");
if ( GetFileAttributesA(::FileName) != -1 )
{
GetPrivateProfileStringA("Debug", "DebugKey", Default, DebugKey, 0x104u, ::FileName);
KeyDebugLength = strlen(DebugKey);
for ( i = 0; i < KeyDebugLength; ++i )
DebugKey[i] = (16 * DebugKey[i]) | (DebugKey[i] >> 4); // nibble swap the DebugKey from the ini file
DebugKeyIsInvalid = strcmp(DebugKey, &SDT_Key);
if ( DebugKeyIsInvalid )
DebugKeyIsInvalid = DebugKeyIsInvalid < 0 ? -1 : 1; // normalize the value obtained from strcmp
if ( !DebugKeyIsInvalid ) // if the DebugKey value is valid, let the user activate the debug mode if desired
{
if ( ::GetPrivateProfileIntA("Debug", "DebugON", 0, ::FileName) == 1 ) // check if DebugON is set 1
*(_DWORD *)DebugModeActivated = *(_DWORD *)DebugModeValueToBeActivated; // activate the debug mode
So, to put in a more organized way, here's what one should do to activate debug mode.
1. Create a file called MICo_Debug.ini in a folder called MICo_Debug in the root of the game's folder.
2. Inside said initialization file, put the following text:
[Debug]
DebugKey=
DebugON=1
3. To get the value for DebugKey, one must retread the steps indicated in the decompilation above. To make it more easy to understand, we will use these values as an example:
- DAT key:
93 F1 94 FC 95 50 82 CC 83 7D 83 8A 83 49 83 6C 83 62 83 67 81 60 8D 82 8B 4D 82 C8 82 E9 8E 6F 96 85 82 CC 91 B8 8C B5 95 F6 89 F3 81 60 - SDT encrypted key:
93 14 C4 D2 03 03 73 41 - SDT key shuffler byte:
00
3.1. Calculate the string lengths of SDT encrypted key and DAT key:
- DAT key length: 46 bytes
- SDT key length: 8 bytes
3.2. Calculate the first and last byte for the SDT key:
SDT_Key_ShufflerByte[SDT_Key_Length] += 47 * (Dat_Key_Length / 47) - Dat_Key_Length
Which becomes:
SDT_Key_ShufflerByte[8] += 47 * (46 / 47) - 46 = -46 = -0x2E
Since we know that SDT_Key_ShufflerByte[8] is basically the last byte for SDT_Key, this ends up modifying the last byte for the SDT Key.
Also, since the operation was +=, we need to make the addition to the initial byte, which was 0x41. In this case, we end up doing this to obtain the last byte for the SDT Key:
0x41 + (-0x2E) = 0x13
Now, for the first byte we have to do this:
SDT_Key[0] -= Dat_Key_Length
Or in other words:
SDT_Key[0] -= 0x93 - 46 bytes = 0x93 - 0x2E = 0x65
So, the resulting SDT key is 65 14 C4 D2 03 03 73 13.
3.3. Proceed to do a nibble swap to all bytes in the SDT key:
65 14 C4 D2 03 03 73 13 to 56 41 4C 2D 30 30 37 31
3.4. Convert to bytes from the SDT key to an ASCII string:
56 41 4C 2D 30 30 37 31 to VAL-0071.
3.5. Write the obtained value in the subkey called DebugKey created in step 2.
You will know when the key is the correct one when the game's title window includes information about the current .sdt file that is being used, assuming that DebugON is set to 1.
It is worth noting, that, albeit not all games have been confirmed, but it seems to be that all of their games use their catalogue product number as their respective debug keys, rendering the whole protection kinda pointless. To know which is the catalogue of a specific product of theirs, it is recommended to check Valkyria's online store page, or just the game's executable name.
Ways to access the debug features
The game features a plethora of tools to work with in-game, which can be accessed by clicking the game's icon in the title window. As per mentioned in the system.dat page, the debug menus have not an English variant.
Another place where some other debug features lie present, is once again with the file MICo_Debug.ini created to unlock the debug mode.
How to configure the debug options?
Every configuration must be done through the MICo_Debug.ini file.
[Debug] section
Debug mode status
This section is for debug mode status, and the key to allow said mode to be activated.
DebugKey
This allows the activation of the debug mode, if said value is what the game expects based on the parameters given in the system.dat file.
| Value | Outcome |
|---|---|
| Correct | Allow the activation of debug mode |
| Incorrect | Not allow the activation of debug mode |
- Default value: empty string
DebugON
This allows the activation of the debug mode, if said value is what the game expects based on the parameters given in the system.dat file.
| Value | Outcome |
|---|---|
| 0 | Deactivate debug mode |
| 1 | Activate debug mode, if DebugKey is correct |
- Default value: 0
Logging
All the logging for what happens in-game, which will be done to a file called MICo_Log1.csv next to the MICo_Debug.ini one.
MICoLog
This controls the status of the logging of the game session onto a file.
| Value | Outcome |
|---|---|
| 0 | Deactivate the logging |
| 1 | Activate the logging |
- Default value: 1
MICoLogProcNo
While not that well understood, it seems that this parameter serves to be the way to only log events that get triggered by flags with a specific slot number. This is probably used to ensure that the log file doesn't get filled to the brim with unnecessary information.
| Value | Outcome |
|---|---|
| -1 | Use the MICoLogProcOutputFlgXX settings |
| -2 | Not understood |
| 0 - 256 | Log only the flags with that number. |
- Default value: -1
MICoLogFileSize
Indicates the maximum size of the MICo_Log1.csv in bits. When exceeded, the log will continue with a file called MICo_Log2.csv. If that file gets exceeded in terms of size, the game will stop logging more events.
- Default value: 10000000
MICoLogProcOutputFlgXX
Enable logging for the flag #1, and can be done up to flag number 255. The number has to be put in hexadecimal where the XX is in the name key. Its purpose is not well understood yet.
| Value | Outcome |
|---|---|
| 0 | Disable logging for that flag |
| 1 | Enable logging |
- Default value: 0
Quick access for debug menus
If one so desires, they can make so that when pressing a specific button they configure, to open whatever debug menu(s) they want. The configuration must be done through what Microsoft refers to as Virtual-Key codes.
MICoDebugBT_TextSearchSkip
Open the debug menu called DEBUG_テキストスキップサーチ.
- Default value: 0x00
MICoDebugBT_RepeatSE
Open the debug menu called DEBUG_SEリピート.
- Default value: 0x00
MICoDebugBT_ClipBoard
Open the debug menu called DEBUG_テキストクリップボードコピー.
- Default value: 0x00
MICoDebugBT_RealTimeTextLog
Open the debug menu called DEBUG_テキストログ表示.
- Default value: 0x00
MICoDebugBT_TextLog
Executes the functionality from the debug menu called DEBUG_テキストログ表示, but saves the result to a file called TextLog.txt inside the game's root folder.
- Default value: 0x00
MICoDebugBT_RealTimeAll
Open the debug menu called DEBUG_全体情報表示.
- Default value: 0x00
MICoDebugBT_All
Executes the functionality from the debug menu called DEBUG_全体情報表示, but saves the result to a file called SysData.txt inside the game's root folder.
- Default value: 0x00
MICoDebugBT_RealTimeFlg
Open the debug menu called DEBUG_フラグ表示.
- Default value: 0x00
MICoDebugBT_Flg
Executes the functionality from the debug menu called DEBUG_フラグ表示, but saves the result to a file called FlgData.txt inside the game's root folder.
- Default value: 0x00
Miscellanous
SeenNo
Enter a specific data06-/seenXXXX.sdt scene in boot up. This can be prone to some bugs depending on which scene you enter into, like for example the main menu.
- Default value: 0000
TextLogMax
Indicates the maximum amount of messages that can be logged at the same time inside the DEBUG_テキストログ表示 debug window.
- Default value: 5
- Maximum value: 100
SoundDummyMode
Used for during development, it allows the game to avoid displaying an error in case that the playback of a specific audio file has failed.
| Value | Playback failed reported |
|---|---|
| Even number | :x: |
| Odd number and 0 | :white_check_mark: |
- Default value: 0
Debug windows positions
This allows the user to configure the exact positions in-screen for the debug windows that aren't just a single pop-up. If the user moves them around, the values represented in the .ini file will also be updated to reflect those changes.
DBW_TXT_left, DBW_TXT_top, DBW_TXT_right, DBW_TXT_bottom
Sets the position in-screen for the DEBUG_テキストログ表示 window.
DBW_ALL_left, DBW_ALL_top, DBW_ALL_right, DBW_ALL_bottom
Sets the position in-screen for the DEBUG_全体情報表示 window.
DBW_FLG_left, DBW_FLG_top, DBW_FLG_right, DBW_FLG_bottom
Sets the position in-screen for the DEBUG_フラグ表示 window.
DBW_TextSearchSkip_left, DBW_TextSearchSkip_top, DBW_TextSearchSkip_right, DBW_TextSearchSkip_bottom
Sets the position in-screen for the DEBUG_テキストスキップサーチ window.
Flags and slots
In order to store variables in memory and in the save files, the MICo engine creates something called flags. In reality, they are nothing more than just simple variables of different types. Regarding slots, they are simply used to keep track of what objects are in screen and what sound files are currently being executed.
All of them are created and managed the same way, each type of flag and slot has its own section, and then we have two keys (at minimum). Here's an example:
## [DebugDefine_Example]
## DebugList_Example_Kazu=2
## DebugList_Example_0001=1453:EntryName1 ## Each entry needs to have the ID that the game will keep track off, and separated with an ":", the name of said entry that will show up in the debugger
## DebugList_Example_0002=0075:EntryName2
In this case, the key DebugList_Example_Kazu indicates the number of variables to keep track (kazu means number in Japanese). It is important that this value is never higher than the amount set in system.dat for that specific type of flag or slot.
After that, we need to create at most the amount of variables specified before to keep track by creating one key per variable the following way: DebugList_Example_XXXX, XXXX being an incremental value starting from 0001.
The value for said key is the following: ID of variable to keep track:Name that will show up in debug window. The idea is that first goes the ID of that variable, and what follows is the name of said variable inside its corresponding debug window.
| Section | Key #1 | Key #2 | Type | Purpose |
|---|---|---|---|---|
| [DebugDefine_FlgLocal] | FList_FlgLocal_Kazu | FList_FlgLocal_XXXX | Flag | Current save game status |
| [DebugDefine_FlgGlobal] | FList_FlgGlobal_Kazu | FList_FlgGlobal_XXXX | Flag | General save game status |
| [DebugDefine_DI] | FList_DI_Kazu | FList_DI_XXXX | Flag | Local numeric variables |
| [DebugDefine_DG] | FList_DG_Kazu | FList_DG_XXXX | Flag | Global numeric variables |
| [DebugDefine_DT] | FList_DT_Kazu | FList_DT_XXXX | Flag | Temporary numeric variables |
| [DebugDefine_SI] | FList_SI_Kazu | FList_SI_XXXX | Flag | Local string variables |
| [DebugDefine_ST] | FList_ST_Kazu | FList_ST_XXXX | Flag | Temporary string variables |
| [DebugDefine_SG] | FList_SG_Kazu | FList_SG_XXXX | Flag | Global string variables |
| [DebugDefine_obj] | OList_Kazu | OList_XXXX | Slot | Images |
| [DebugDefine_VOICE] | VOICEList_Kazu | VOICEList_XXXX | Slot | Character's voices |
| [DebugDefine_BGM] | BGMList_Kazu | BGMList_XXXX | Slot | Background music |
| [DebugDefine_SE] | SEList_Kazu | SEList_XXXX | Slot | Sound effects |
| [DebugDefine_BGVOICE] | BGVOICEList_Kazu | BGVOICEList_XXXX | Slot | Background voices |
| [DebugDefine_BGSE] | BGSEList_Kazu | BGSEList_XXXX | Slot | Background sound effects |
Main features
All of the features will be listed in order that they appear in-game:
Activate automatic read mode (fast)
This makes the game increase the automatic read mode to be slightly faster than the default one.
Activate automatic read mode (faster)
The same as with the previous option, but way faster.
Activate automatic read mode (faster and skipping animations)
The same as with the previous option, but way faster, and it also skips the animations done with the CGs.
Reset the position of all debug windows
Like the title of this section says, this option just does that. In the values for these parameters inside the .ini file, if those are not set yet, they will get set to 0 automatically.
Automatically skip all dialog text until string matches
The game will automatically skip all dialog in the text until it finds the current message text has any match with the text introduced in the MessageBox. The button on the same window will only reset the query.
Replay all current sound effects
The game will show a popup with the current sound effect that is replaying, and so on until it reaches the last one. This is meant to be used inside the main game where sound effects play during specific lines, but this can be applied to things like moving the cursor around a menu and hovering over buttons.
Show all of the metadata about the current message and copy it to clipboard
If the user is inside the game's story, it will show up all of the metadata from the current message. The available information is as follows:
- Scenario number: the Seen file currently loaded.
- Line number: the current line of the Seen file that is being loaded to show this message. This makes more sense to understand if one checks the structure of a script file from version 1 of this engine.
- Voiced character number: the game assigns an ID to each character that needs to be voiced, mostly for adjusting the voice of specific characters in the settings menu.
- Voice file: the name of the currently loaded voice file.
- Character name: the name of the character that is speaking.
- Message text: the raw text for the message itself. If there is any escape code used, it will be shown here.
It also copies all of that information to the clipboard.
Show a more detailed message log
It recompiles all of the seen messages, with all of the same metadata that is being recompiled in the previous option, and with the addition of being updated in real time.
List the information about all loaded objects and the metadata for the current message
It shows the metadata of the current message, and the information about the currently loaded elements that occupy slots, which is the name assigned in the MICo_Debug.ini alongside the file path to the loaded file (for each slot respectively). This window keeps getting updated in real time.
List the information about all loaded objects and the metadata for the current message
The same as with the previous window, but this time applied to the flags.
Copy current message to clipboard and Seen file status
Copies to the clipboard the currently loaded message, and where in the currently loaded Seen file is this message at.
Flags monitor window
Opens a window where the user can keep track of any arbitrary flag (and change its value), as long as it was created during the bootup process. It is very important that none of the searched indexes is equal or lower than the values specified in the system.dat file.
It also lets the user know at what Seen the game is currently at.
The user first to select the type of flag, which are the following ones:
| First column | Second column |
|---|---|
| DG | SG |
| DI | SI |
| DT | ST |
Then, the box below asks the user to input the index of said flag, then press the button on its right, and it will show up in the window like so:
Force game quit
In a case of an emergency, the user can force quit the game in case it is not responding anymore.