Skip to content

Initialization file

The VN connoisseur edited this page Oct 6, 2026 · 25 revisions

Main characteristics

Purpose of the file

Initialize the game system, allowing the developer to modify generic parameters that are not specific to each game release. An example would be the game's resolution, and the position of the message window.

What engine revisions have it?

Version number Name of file Comments
1 system.ini Introduced in Princess Knight☆Catue -Ochita Ryuuki Hime-
2 system.dat system.ini is also present, but is unused

Version 1

File structure

The file is structured in 4 main parts, according to the following IDA decompilation:

ReadSystemIniFile

LengthFirstEncryptedString = 0;
PendingPreviousBytesToRead_LengthFirstString = 4;// indicate that the game wants to read the first 4 bytes of the file
do
{
  --PendingPreviousBytesToRead_LengthFirstString;
  LengthFirstEncryptedString = fgetc(Stream) + 10 * LengthFirstEncryptedString - 48;
}
while ( PendingPreviousBytesToRead_LengthFirstString );
if ( LengthFirstEncryptedString > 0 )
{
  do
    CatalogNumber[PendingPreviousBytesToRead_LengthFirstString++] = fgetc(Stream) ^ 0xD1;
  while ( PendingPreviousBytesToRead_LengthFirstString < LengthFirstEncryptedString );
}
LengthSecondEncryptedString = 0;
CatalogNumber[PendingPreviousBytesToRead_LengthFirstString] = 0;
PendingPreviousBytesToRead_LengthSecondString = 4;
do
{
  --PendingPreviousBytesToRead_LengthSecondString;
  LengthSecondEncryptedString = fgetc(Stream) + 10 * LengthSecondEncryptedString - 48;
}
while ( PendingPreviousBytesToRead_LengthSecondString );
if ( LengthSecondEncryptedString > 0 )
{
  do
    Game_Title[PendingPreviousBytesToRead_LengthSecondString++] = fgetc(Stream) ^ 0xD1;
  while ( PendingPreviousBytesToRead_LengthSecondString < LengthSecondEncryptedString );
}
v10 = Stream;
Game_Title[PendingPreviousBytesToRead_LengthSecondString] = 0;
GameResolution = fgetc(v10);
if ( GameResolution )
{
  if ( GameResolution == 1 )
  {
    Game_Width_1 = 800;
    Game_Height_1 = 600;
  }
  else if ( GameResolution == 2 )
  {
    Game_Width_1 = 1024;
    Game_Height_1 = 768;
  }
}
else
{
  Game_Width_1 = 640;
  Game_Height_1 = 480;
}
Game_Width = Game_Width_1;
Game_Height = Game_Height_1;
NumberOfVoiceChannels = fgetc(Stream) - 48;
for ( i = 0; i < 48; ++i )
{
  FirstVoiceCharacterName[i] = fgetc(Stream);
  v8 = fgetc(Stream);
  v9 = Stream;
  SecondVoiceCharacterName[i] = v8;
  ThirdVoiceCharacterName[i] = fgetc(v9);
}
strcpy_s(WindowName, 0x64u, Game_Title);

Catalog number length

  • Length: 4 bytes
  • Type of value: unsigned integer
  • Purpose: indicates the length of the catalog number string. To obtain the actual value, one can take two approaches.

Let's use the value 30 30 31 32 as an example:

Method 1

Convert the value to an ASCII string.

30 30 31 32 becomes 0012. If we trim the initial zeros, we get 12.

Method 2

Do the following operation 4 times, and making sure that LengthFirstEncryptedString and IterationNumber are 0 during the first iteration:

LengthFirstEncryptedString = CatalogNumberLength[IterationNumber] + 10 * LengthFirstEncryptedString - 48

Also, after each iteration, remember to increase by 1 the value of IterationNumber.

After doing the 4 loops, 30 30 31 32 becomes the number 12.

Catalog number

  • Length: Catalog number length bytes
  • Type of value: string
  • Purpose: it does not seem to be used, but its value is the official's catalog number for that product (if it's the digital version that also gets included, like they do in the game's executable name). To decode each of the bytes successfully, one must XOR each byte by 0xD1. From what it seems, it's not exactly the catalog number but rather, the executable's name. That can be inferred based on what the earlier games did with this variable.

Window title length

  • Length: 4 bytes
  • Type of value: unsigned integer
  • Purpose: indicates the length of the window title string. To calculate its exact value, one must follow the steps specified in the catalog number length section.

Window title

  • Length: Window title length bytes
  • Type of value: string
  • Purpose: the title for the game's window. To decode each of the bytes successfully, one must XOR each byte by 0xD1.

Game resolution

  • Length: Window title length bytes
  • Type of value: unsigned byte
  • Purpose: the size of the game's window. Sadly due to how the engine assigns memory to each process, modifying said value causes adverse situations.
Value Resolution
1 800x600
2 1024x768
Anything else 640x480

Number of voice channels

  • Length: 1 byte
  • Type of value: unsigned byte
  • Purpose: probably a value used for an unavailable debug mode. The idea is to allow the developer from a toolbar to activate and deactivate specific sound channels. From the get-go, the BGM and SE channels are already typed out, but for the channels specific to each characters need the names of said characters to create the labels for those buttons. To calculate its exact value, one must follow the steps specified in the catalog number length section.

Voice channels (character names)

  • Length: 144 bytes
  • Type of value: string
  • Purpose: each of the character name for each voice channel. Even though the previous variable does state how many bytes one should read, that never happens, and the game assumes that the 3 slots are occupied. The names are interleaved between themselves.

For example, if we have this array (the remaining bytes that follow are all 0x00):

83 83 00 4A 4A 00 83 83 00 60 60 00 83 83 00 85 85 00 83 83 00 41 41 00

So, in this case, each of the character names would be:

- 1st character: 83 4A 83 60 83 85 83 41 which equals to カチュア.

- 2nd character: 83 4A 83 60 83 85 83 41 which equals to カチュア.

- 3rd character: 00 00 00 00 00 00 00 00 which equals to an empty string.

Version 2

File structure

The file is divided into three parts, according to to the following IDA decompilation:

WinMain

wsprintfA(FileName, "%s\\system.dat", "");
SystemDatFileHandler = CreateFileA(FileName, 0x80000000, 1u, 0, 3u, 0x80u, 0);
if ( SystemDatFileHandler == (HANDLE)-1 )
{
  MessageBoxA(0, &FailureReadInitializationFile, Default, 0);
  return 0;
}
ReadFile(SystemDatFileHandler, &GameIdentifier, 0x2194u, &NumberOfBytesRead, 0);
ReadFile(SystemDatFileHandler, DialogBox_Message_BackgroundFill_Enabled, 0x37F0u, &NumberOfBytesRead, 0);
ReadFile(SystemDatFileHandler, ChoiceBox_Text_Alignment, 0x6A90u, &NumberOfBytesRead, 0);
CloseHandle(SystemDatFileHandler);

So, we can see that file size of system.dat is hardcoded, and its always 0x2194 + 0x37F0 + 0x6A90 = 0xC414 bytes, or in decimal, 50196 bytes.

1st section

Game identifier

  • Length: 4 bytes
  • Type of value: time_t
  • Purpose: the general save file and save states can be interchanged between games, because they only store flags values, so in order to avoid the game from loading saves generated from other games, they include this value in the header in order to let the game know that they are in theory valid save files.

Game system mode

  • Length: 4 bytes
  • Type of value: unsigned int
  • Purpose: unused. Maybe it could be used at a later date for setting up demo versions of the game, but at this point in time, they have never created any.

Exclusive fullscreen mode

  • Length: 1 byte
  • Type of value: unsigned byte
  • Purpose: it is meant to be used for really old systems, in case that they need the game to be executed in exclusive fullscreen mode.
Value Outcome
0 Disabled
1 Enabled

Game locale is English

  • Length: 1 byte
  • Type of value: unsigned byte
  • Purpose: when clicking the game icon in the top bar, a lot of options will show up, like disabling DirectX, and the speed text. If enabled, the game will load the English version of those options, and some MessageBox calls will also have their message translated to English. It is important to note that all debug menus won't be translated to English.
Value Locale language
0 Japanese
1 English

Game title

  • Length: 260 bytes
  • Type of value: string
  • Purpose: on all MessageBox windows and in the main window title, this is what it will appear as the game's name. The game will consider the first null byte to be the end of the string.

DAT key

  • Length: 260 bytes
  • Type of value: unsigned byte
  • Purpose: used for decryption purposes, primarily for decrypting the .dat files, but also is used for getting the actual SDT key during runtime.

Window width

  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: indicates the width of the game's window.

Window height

  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: indicates the height of the game's window.

Bytes to skip

  • Length: 2 bytes

Flags

Amount of DI flags
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of DI flag slots will be created on boot.
Amount of DG flags
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of DG flag slots will be created on boot.
Amount of DT flags
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of DT flag slots will be created on boot.
Amount of SI flags
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of SI flag slots will be created on boot.
Amount of SG flags
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of SG flag slot will be created on boot.
Amount of ST flags
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of ST flag slots will be created on boot.

Slots

Amount of obj slots
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of obj slots will be created on boot.
Amount of MSK slots
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of MSK slots will be created on boot.
Amount of CGB slots
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of CGB slots will be created on boot.
Amount of Button slots
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of Button slots will be created on boot.
Amount of Box slots
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of Box slots will be created on boot.
Size of message log
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the amount of messages the game will store at the same time. A message in this case indicates any piece of dialog said during the story, and if the limit is exceeded, the oldest message in the log will disappear to make space for the latest one, which will be the one displayed outside the message log window.

Message window obj ID

  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the ID that will be used for the messages window, which is necessary for the in-game configuration of configuring the its opacity and color.

In this image, the RECT that has the image of the message window is the one that will be colored and its opacity changed.

obj ID maximum value on initialization

  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: indicates the biggest ID for any obj that will be accepted on boot. This seems to be used because some images, like the one used to change the game from windowed to fullscreen mode can have a value higher than the one accepted here, but at no point this image gets loaded on boot.

Folder names

data06
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the .sdt files. The game will consider the first null byte to be the end of the string.
data00
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the .mg2 files. The game will consider the first null byte to be the end of the string.
data02
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the .mal files. The game will consider the first null byte to be the end of the string.
data05
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the BGM files. The game will consider the first null byte to be the end of the string.
data03
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the voice files. The game will consider the first null byte to be the end of the string.
data04
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the sound effect files. The game will consider the first null byte to be the end of the string.
data01
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the game uses this value to know what's the folder name (or file if compressed) to store the .am2 files. The game will consider the first null byte to be the end of the string.
Unused data folder
  • Length: 260 bytes
  • Type of value: string
  • Purpose: it is unused, but it would fulfill the same role as the other folder names. The game will consider the first null byte to be the end of the string.

Save files

Save data folder name
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the game uses this value to know what's the folder name to store the save files. The game will consider the first null byte to be the end of the string.
Main save file name
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the game uses this value to know what's the file name to store the configuration and general progress of the game. The game will consider the first null byte to be the end of the string.

Close game process

Close game with MessageBox
  • Length: 1 byte
  • Type of value: unsigned byte
  • Purpose: when closing the game, the game can either offer to show a standard MessageBox window to ask the user for confirmation to close the game, or show the custom image the game uses to ask the user for confirmation.
Value Outcome
1 MessageBox
Anything else Official window
Byte to skip
  • Length: 1 byte
Close game Seen number
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: when closing the game, if Close game with MessageBox is not set to 1, when closing the game it needs to know to what scene it should go into. For example, if the file that contains the exit screen is seen0010.sdt, the value that should be set in system.dat is 10.
Close game Jump label
  • Length: 260 bytes
  • Type of value: string
  • Purpose: following the explanation in Close game Seen number, the game also needs to know the name of the label to jump to from the .sdt file in order to know exactly what to show to the user. The game will consider the first null byte to be the end of the string.

Screen mode process

Activate full screen mode Seen number
  • Length: 4 bytes
  • Type of value: unsigned int
  • Purpose: the explanation from Close game Seen number applies here too, but here it's for the game knowing what to do when the user decides to make the game be full screen (when pressing the SCREEN button).
Activate full screen mode Jump label
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the explanation from Close game Jump label applies here too, but here it's for the game knowing what to do when the user decides to make the game be full screen (when pressing the SCREEN button). The game will consider the first null byte to be the end of the string.
Activate windowed screen mode Seen number
  • Length: 4 bytes
  • Type of value: unsigned int
  • Purpose: the explanation from Activate full screen mode Seen number applies here too, but here it's for the game knowing what to do when the user decides to make the game be in a window (when pressing the SCREEN button).
Activate windowed screen mode Jump label
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the explanation from Activate full screen mode Jump label applies here too, but here it's for the game knowing what to do when the user decides to make the game be in a window (when pressing the SCREEN button). The game will consider the first null byte to be the end of the string.

Font name

  • Length: 260 bytes
  • Type of value: string
  • Purpose: for all text drawn in-game, the game needs to know the name of the font to be used. The game will consider the first null byte to be the end of the string.

Fonts

  • Length: 28 bytes * 50 fonts = 1400 bytes
  • Type of value: signed int
  • Purpose: for all text drawn in-game, the game creates 50 slots, so that different types of fonts are allowed.
Font height
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: for the current font slot, indicate the height of said font.
Font width
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: for the current font slot, indicate the width of said font.
Font weight
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: for the current font slot, indicate the weight of said font.
Drop shadow (horizontal distance from the actual text)
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: for the current font slot, indicate the distance in the X-axis from the drop shadow to the actual text.
Drop shadow (vertical distance from the actual text)
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: for the current font slot, indicate the distance in the Y-axis from the drop shadow to the actual text.
Drop shadow (RGBA)
  • Length: 4 bytes
  • Type of value: signed bytes
  • Purpose: for the current font slot, indicate the color that the drop shadow will have. It assigns 1 byte per color.
Bytes to skip
  • Length: 4 bytes

Message window

Character name part: custom color (Character name)
  • Length: 50 names * 50 bytes = 2500 bytes
  • Type of value: string
  • Purpose: when a character is speaking, one can assign a custom color to the text that holds its name. This part contains the name of the character that will be assigned to its corresponding RGB values assigned later on. The game will consider the first null byte to be the end of the string.
Character name part: custom color (RGB)
Character name part: default color
Character name part: enable custom colors
Value Status
0 Disabled
1 Enabled
Message part: default color
  • Length: 3 bytes
  • Type of value: signed bytes
  • Purpose: like with Character name part: default color, but in this case this applies for the text that holds the current message.

Background fill

The game does allow to create a RECT that is linked to specific objects within the game, like the Message window and Choice boxes. Why they were decided to be put in there is not known, since they go completely unused. My guess would be that instead of loading actual images for those two objects, one could make them be 1 solid color, reducing the RAM consumption, although it seems kinda pointless nowadays.

Background fill: color
  • Length: 3 bytes
  • Type of value: signed bytes
  • Purpose: indicates the color in RGB that will have all of the background fill objects.
Background fill: opacity
  • Length: 1 byte
  • Type of value: signed byte
  • Purpose: indicates the level of opacity that will have all of the background fill objects.

Unused

  • Length: 1 byte
  • Type of value: signed byte
  • Purpose: none, it only gets copied onto the main save file when closing the game.

Unused

  • Length: 1 byte
  • Type of value: signed byte
  • Purpose: none, it only gets copied onto the main save file when closing the game.

Byte to skip

  • Length: 1 byte

Unused

  • Length: 2 bytes
  • Type of value: signed bytes
  • Purpose: none, it only gets copied onto the main save file when closing the game.

Message window

Message part: font ID
  • Length: 2 bytes
  • Type of value: signed short
  • Purpose: following the explanation given in Fonts, this indicates what font type to use for the dialogue text.

RECT order: surface for the image
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: while not fully understood, it seems that the engine expects to be given the order of layers for each element in screen, the smaller the number being even further behind the other objects on screen. In this case, we have the Surface created to accommodate the entire Message window.
RECT order: image
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the image for the Message window itself.
RECT order: surface for the message text
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the surface that holds the text for the current message.
RECT order: surface for the character's name text
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the surface that holds the text for the current character's name.
RECT order: message text
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the current message text.
RECT order: character name text
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: following the explanation from RECT order: surface for the image, but in this case applied to the current character's name text.

Choice box

These boxes are the ones included inside the game for selecting a choice, or a different story branch to put in other words (each choice box has 4 obj assigned to them).

Choice box - First obj ID
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: the game needs to know what is going to be the obj ID assigned for all of the choice boxes, so it needs to know the first slot number.
Choice box - Last obj ID
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: like with Choice box - First obj ID, but in this case for the last obj ID. This lets the game know how many slots in total needs to assign for the choice boxes, since this determines the last ID reserved for choice boxes.

Audio instances

The game delegates all sound functions to a custom DLL called Ayame (apparently is also used on some games by other companies too), which is dropped on the %TEMP% folder at runtime.

Audio instances: total amount
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: the total amount of instances that Ayame must create at runtime. Any petition to create a sound slot with an ID bigger than the number stated here will throw an error.
Audio instances: BGM
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: the instance ID given to the currently played BGM track.
Audio instances: voice
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: the instance ID given to the currently played voice file.
Audio instances: unused
  • Length: 1 byte
  • Type of value: unsigned byte
  • Purpose: this variable comes out unused. It only ends up writing at the end of the main save file the amount specified here of null bytes. Sadly due to bug in their code, if the value is set to 0, we get a violation access error:

OpcodeResolver

case 0x813u:
          WriteToLogFile(v3107, "KoeVolume");
          v291 = (unsigned __int16)GetNumberFlag((unsigned __int16 *)v3107);
          v292 = GetNumberFlag((unsigned __int16 *)v3107);
          *(_BYTE *)(v291 + *(_DWORD *)(v3107 + 820)) = v292;  --> The crash happens here
          v293 = *(_BYTE *)(*(unsigned __int16 *)(v3107 + 1088) + *(_DWORD *)(v3107 + 820));
          if ( v293 )
            sub_6484E0((int)AyameDLL, (unsigned __int16)AudioSlots_Voice, (float)v293);
          goto LABEL_616;
.text:00682CC7 mov     ecx, [esp+23DE0h+var_1EC70]     ; jumptable 00681A1A case 2067
.text:00682CCE push    offset aKoevolume               ; "KoeVolume"
.text:00682CD3 call    WriteToLogFile
.text:00682CD8 mov     ecx, [esp+23DE0h+var_1EC70]
.text:00682CDF call    GetNumberFlag
.text:00682CE4 mov     ecx, [esp+23DE0h+var_1EC70]
.text:00682CEB movzx   esi, ax
.text:00682CEE call    GetNumberFlag
.text:00682CF3 mov     dl, al
.text:00682CF5 mov     ecx, esi
.text:00682CF7 mov     eax, [esp+23DE0h+var_1EC70]
.text:00682CFE mov     eax, [eax+334h]   --> eax+334h is where this unused variable gets stored during runtime
.text:00682D04 mov     [ecx+eax], dl   --> The crash happens here
.text:00682D07 mov     eax, [esp+23DE0h+var_1EC70]
.text:00682D0E movzx   ecx, word ptr [eax+440h]
.text:00682D15 mov     eax, [eax+334h]
.text:00682D1B mov     al, [ecx+eax]
.text:00682D1E test    al, al

SDT key

SDT key shuffler byte
  • Length: 1 byte
  • Type of value: unsigned byte
  • Purpose: for obfuscation purposes, the game uses this byte to shuffle the first and last byte of the actual SDT key, by using the length of the Dat key.
SDT encrypted key
  • Length: 1 byte
  • Type of value: unsigned byte
  • Purpose: the actual key the game to decrypt all .sdt files and to keep debug mode secured.

2nd section

Message window

Message part: enable the background fill
  • Length: 1 byte
  • Type of value: signed byte
  • Purpose: the game for some reason allows for a RECT to be created alongside certain obj in the screen, and each of them are completely independent from the others, and they simply pop up when the obj they are linked to are present on screen. This functionality goes completely unused in the game, but regardless, the engine allows to be customize this RECT with some basic parameters.
Value Outcome
0 Disabled
1 Enabled
Byte to skip
  • Length: 1 byte

Message part: RECT for image (x axis origin)
  • Length: 2 bytes
  • Type of value: signed short
  • Purpose: indicates the coordinate in the x axis of the game screen where the top-left corner of the RECT that contains the image for the message part of the dialogue window should be placed at.
Message part: RECT for image (y axis origin)
Message part: RECT for text (x axis origin)
Message part: RECT for text (y axis origin)
Message part: RECT for text (width)
Message part: RECT for text (height)
Message part: RECT for the background fill (x axis origin)
Message part: RECT for the background fill (y axis origin)
Message part: RECT for the background fill (width)
Message part: RECT for the background fill (height)
Message part: RECT for image (file name)
  • Length: 260 bytes
  • Type of value: string
  • Purpose: indicates the name of the .mg2 file that corresponds to the background of the message window for the text. The game will consider the first null byte to be the end of the string.

Character name part

Character name part: font ID
  • Length: 2 bytes
  • Type of value: signed short
  • Purpose: the same as with Message part: font ID, but for the name of the current character.
Character name part: enable the background fill
  • Length: 1 byte
  • Type of value: signed byte
  • Purpose: exactly the same as for Message part: enable the background fill, but applied to the character name. When the current message has no character associated to it, the background fill gets removed from the screen too.
Byte to skip
  • Length: 1 byte

Character name part: RECT for image (x axis origin)
  • Length: 2 bytes
  • Type of value: signed short
  • Purpose: indicates the coordinate in the x axis of the game screen where the top-left corner of the RECT that contains the image for the character name part of the dialogue window should be placed at.
Character name part: RECT for image (y axis origin)
Character namesage part: RECT for text (x axis origin)
Character name part: RECT for text (y axis origin)
Character name part: RECT for text (width)
Character name part: RECT for text (height)
Character name part: RECT for the background fill (x axis origin)
Character name part: RECT for the background fill (y axis origin)
Character name part: RECT for the background fill (width)
Character name part: RECT for the background fill (height)
Character name part: unknown
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: not known, it does not seem to do anything at all.
Character name part: unknown
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: not known, it does not seem to do anything at all.
Character name part: unknown
  • Length: 1 byte
  • Type of value: unsigned byte
  • Purpose: not known, it does not seem to do anything at all.
Character name part: RECT for image (file name)
  • Length: 260 bytes
  • Type of value: string
  • Purpose: indicates the name of the .mg2 file that corresponds to the background of the character name window for the text. The game will consider the first null byte to be the end of the string.

Unused part

Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes

Bytes to skip

  • Length: 8 bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes

Bytes to skip

  • Length: 40 bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes
Unused variable
  • Length: 4 bytes
  • Type of value: signed bytes

Bytes to skip (until the next section)

  • Length: 13644 bytes (or the remaining bytes needed to fill the size of the 2nd section, as indicated in File structure

3rd section

Choice boxes

As any visual novel should do, there are branching paths in the plot. So each option given to the user constitutes a choice box that has to be created.

Choice boxes: text alignment
  • Length: 1 byte
  • Type of value: signed byte
  • Purpose: indicates the alignment the text inside the choice box should have. This value should be taken into consideration with what's the value put in Choice boxes: RECT for text (x axis origin).
Value Alignment
0, 3 Center
1, 4 Left
2, 5 Right

(While these values will vary depending on the opcode called in-game, it seems that the only times that this value gets used for, is it for the SelExLoop opcode.

Byte to skip
  • Length: 1 byte
Choice boxes: font ID
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: following the explanation given in Fonts, this indicates what font type to use for the choice boxes.
Choice boxes: custom color (RGB)
  • Length: 3 bytes
  • Type of value: signed bytes
  • Purpose: this holds the RGB values that the text inside each choice box will have.
Choice boxes: enable the background fill

Choice boxes: RECT for text (x axis origin)
Choice boxes: RECT for text (y axis origin)
Choice boxes: RECT for text (width)
Choice boxes: RECT for text (height)

Choice boxes: unknown
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: not known, it does not seem to do anything at all.
Choice boxes: unknown
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: not known, it does not seem to do anything at all.
Choice boxes: unknown
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: not known, it does not seem to do anything at all.

Choice boxes: RECT for the background fill (height)
  • Length: 2 bytes
  • Type of value: unsigned short
  • Purpose: the background fill created for each Choice box, this parameter indicates their height.
Choice boxes: RECT for the background fill (width)

Choice boxes: unknown
  • Length: 2 bytes
  • Type of value: signed short
  • Purpose: not known, it does not seem to do anything at all.

Choice boxes: margin between each choice box (y axis)
  • Length: 2 bytes
  • Type of value: signed short
  • Purpose: between each choice box there must be some space, this parameter indicates how much vertical space there should between each of them. In reality this value what does do is indicate how much distance there should be between the top edge of the game's screen and the center of the image for the latest choice box.
Choice boxes: margin between the left edge of the game screen and each choice box (x axis)
  • Length: 2 bytes
  • Type of value: signed short
  • Purpose: between the left edge of the game's screen and each choice box there should be some space, this parameter determines that.

Choice boxes: unknown
  • Length: 2 bytes
  • Type of value: signed short
  • Purpose: not known, it does not seem to do anything at all.

Choice boxes: image with option not chosen
  • Length: 260 bytes
  • Type of value: string
  • Purpose: the name of the .mg2 file that contains the choice box, but it has not been selected by the user previously. The game will consider the first null byte to be the end of the string.
Choice boxes: image with option not chosen (hovered)
Choice boxes: image with option already chosen
Choice boxes: image with option already chosen (hovered)

Bytes to skip

  • Length: 2 bytes
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Bytes to skip
  • Length: 4 bytes
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Bytes to skip
  • Length: 40 bytes
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Bytes to skip
  • Length: 4 bytes
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Bytes to skip
  • Length: 40 bytes
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Bytes to skip
  • Length: 16 bytes
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Bytes to skip
  • Length: 40 bytes
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Bytes to skip
  • Length: 12 bytes
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Choice boxes: unused
  • Length: 4 bytes
  • Type of value: signed int
  • Purpose: not used at any point in time, probably created for future games that might use it.
Bytes to skip (until the end of the section)
  • Length: 25952 bytes (or the remaining bytes needed to fill the size of the 3rd section, as indicated in File structure.

Clone this wiki locally