Config file¶
There is a file persisted on disk by the game that doesn't contain any of the save data in the save files.
This file is called config.dat
which is persisted at the same place than the save files which is the game's directory (right next to Unity's player's .exe file). It contains other types of information to persist globally that applies regardless of the save file used. The vast majority of the data contains the settings configured.
Config file structure¶
The layout of the file is similar to the save file where it contains different fields's values split by newlines. All fields contains a simple primitive value except for one which contains a list of primitives.
The amount of lines / fields in the file and which line index corresponds to which field is platform dependant meaning the exact fields and their order depends on the platform the game is built for. This page ONLY documents the format of the file the Steam, GOG and Itch.io versions of the game on PC.
The parsing of the file is done by MainManager.ReadSettings:
public static void ReadSettings(string[] c)
It sets all fields backed by a setting value where c
is the string array read by reading the config.dat
file.
To get the string to save to the file MainManager.SaveSettings is called:
public static string SaveSettings()
It returns a config.dat
compliant text from the current settings fields's values, the same ones that were read by ReadSettings, but it takes into account the changes that happened during the game session.
Config.dat
fields table¶
The following table shows the fields present in config.dat
and their format ordered by their line index in the file:
Line | Format | Name | Description |
---|---|---|---|
0 | A KeyCode enum value as string or int | InputIO.keys[0] |
The keybaord input bound to the up game input |
1 | A KeyCode enum value as string or int | InputIO.keys[1] |
The keybaord input bound to the down game input |
2 | A KeyCode enum value as string or int | InputIO.keys[2] |
The keybaord input bound to the left game input |
3 | A KeyCode enum value as string or int | InputIO.keys[3] |
The keybaord input bound to the right game input |
4 | A KeyCode enum value as string or int | InputIO.keys[4] |
The keybaord input bound to the confirm game input |
5 | A KeyCode enum value as string or int | InputIO.keys[5] |
The keybaord input bound to the cancel game input |
6 | A KeyCode enum value as string or int | InputIO.keys[6] |
The keybaord input bound to the switch party game input |
7 | A KeyCode enum value as string or int | InputIO.keys[7] |
The keybaord input bound to the toggle HUD game input |
8 | A KeyCode enum value as string or int | InputIO.keys[8] |
The keybaord input bound to the pause game input |
9 | A KeyCode enum value as string or int | InputIO.keys[9] |
The keybaord input bound to the help game input |
10 | int between 0 and 7 | MainManager.resolutionindex |
The game resolution to use among different presets. Here are the mapping of the values to their resolutions:
|
11 | True or False |
MainManager.fullscreen |
Tells whether or not the game should be rendered in fullscreen mode. If it isn't, it is rendered in windowed mode |
12 | int between 0 and 2 | MainManager.fps |
Tells what value shouls be set to Application.targetFrameRate:
|
13 | True or False |
MainManager.lowshadows |
Whether or not QualitySettings.shadowResolution should be set to Low. If the value is false, it is set to High |
14 | True or False |
MainManager.lowtexture |
Whether or not QualitySettings.masterTextureLimit should be set to 1. If the value is false, it is set to 0 |
15 | float between 0.0 and 1.0 | MainManager.musicvolume |
The base value to scale music playback's volume |
16 | float between 0.0 and 1.0 | MainManager.soundvolume |
The base value to scale sound playback's volume |
17 | True or False |
The enablement of the FXAA compoent of the MainCamera |
Tells if the FXAA shader should apply when rendering the game |
18 | int corresponding to a valid languageid | MainManager.languageid |
The language the game is set to. This is the only required value for the game to boot to the StartMenu and it influences a lot of logic in the game that are language dependant or changes several assets being read |
19 | True or False |
MainManager.nowindeffect |
Tells whether or not any wind effects should be disabled. They are left enabled if the value is false. More specifically, it causes any Wind component to leave the GameObject attached disabled (done on the Wind's Start) and it prevents any BeetleGrass from getting the MainManager.windShader on their SetUp |
20 | int between 0 and 2 | MainManager.enableoutline |
Determines which value to set the GlobalOutline global shader property on MainManager.UpdateOutlines:
|
21 | int between 0 and 6 | MainManager.downsample |
Determines the factor at which to downsample the render texture of the camera. Here are the mappings of the values:
|
22 | int between 0 and 2 | MainManager.particlelevel |
Controls the rendering of different particles effects. Here are the behaviors of each values:
|
23 | int between 0 and 5 | MainManager.usejoystick |
Tells how the game should treat controllers, here are the values mapping:
|
24 | float between 0.0 and 1.0 | MainManager.bleepvolume |
The base value to scale bleeps's volume |
25 | int | MainManager.vsync |
Determines the value of QualitySettings.vSyncCount that the game will use. If the config file value is 0, the vSyncCount used will be 0 (vsync is disabled). Otherwise (any other value than 0), vSyncCount will be set to Screen.currentResolution.refreshRate / 60.0 floored and clamped from 1 to 4 (vsync is enabled, but in a way to target the closest FPS number to 60.0 such that the FPS is still at least 60.0) |
26 | int being -1 or higher | MainManager.forcejoystick |
The meaning depends on MainManager.usejoystick and if it's 4 (PRE-CONFIGURED), the mapping of the values goes as follows:
|
27 | True or False |
MainManager.keepmusicafterbattle |
Determines if the music timestamp should be saved when entering a battle and restored when leaving it. NOTE: Some maps override this logic and allows an incorrect playback issue to occur under specific conditions when this setting is enabled |
28 | True or False |
MainManager.mashcommandalt |
If true, some ActionCommands will have their command overriden to another |
29 | int | MainManager.joybinds[0] |
The virtual axis id bound to the analogue vertical game input |
30 | int | MainManager.joybinds[1] |
The virtual axis id bound to the analogue horizontal game input |
31 | int | MainManager.joybinds[2] |
The virtual axis id bound to the d-pad vertical game input |
32 | int | MainManager.joybinds[3] |
The virtual axis id bound to the d-pad horizontal input |
33 | int | MainManager.joybinds[4] |
The controller's physical button id bound to the confirm game input |
34 | int | MainManager.joybinds[5] |
The controller's physical button id input bound to the cancel game input |
35 | int | MainManager.joybinds[6] |
The controller's physical button id input bound to the switch party game input |
36 | int | MainManager.joybinds[7] |
The controller's physical button id input bound to the toggle HUD game input |
37 | int | MainManager.joybinds[8] |
The controller's physical button id input bound to the pause game input |
38 | int | MainManager.joybinds[9] |
The controller's physical button id input bound to the help game input |
39 | True or False |
MainManager.monoaudio |
Determines if AudioSettings.speakerMode should be set to Mono . If the value is false, it is set to Stereo |
40 | A , seprated list of bool, each containing True or False |
MainManager.secretunlocks |
The list of secret codes allows to be toggled on the StartMenu's secret menu when creating a new file (it can be accessed by pressing the Help input when selecting an empty save slot). The list is normally 5 elements with the indexes mapping to the following codes:
|
41 | int between 0 and 2 | MainManager.analog |
Controls the sensitivity of analogue input when moving in the overworld. It determines the value of walkdelta on PlayerControl.Update and controls some Movement on PlayerControl.Movement. 0 means OFF, 1 means LOW and 2 means HIGH |
42 | True or False |
MainManager.pauseonfocus |
Determines the value of Application.runInBackground. If the config file value is false, Application.runInBackground is set to true. If the config file value is true, Application.runInBackground is set to false |
43 | True or False |
MainManager.snapTo8 |
If true, it changes the logic of DoActionTap when Bee is the party leader where the Beemerang's heading direction will be the player's heading direction snapped to a vector whose components will be snapped to -1.0, 0.0 or 1.0 depending on the closest one (so 8 cardinal directions) |
NOTE: Any fields with an index of 29 and above are optional, but if any is omited, field 29 and any further field won't be read from the file. Also, field 26 (MainManager.
forcejoystick
) is optional if field 23 (MainManager.usejoystick
) isn't 4 or 5 (it's not PRE-CONFIGURED or CUSTOM BINDINGS), but if field 26 is present, field 27 and 28 become required.
ApplySettings¶
There is another method that applies all changes done to the settings values during the game without necessarily saving them directly. That method is MainManager.ApplySettings:
public static void ApplySettings()
Most of the logic this method does is explained in the table above, but there's also some additional logic. Here are the additional steps the method does:
- If
music[0]
is currently playing while instance.inmusicrange
is -1 (no MusicRange is active),music[0]
.volume is set to the newmusicvolume
value - All
sounds
's volume are set to the newsoundvolume
value - If
usejoystick
is 5 (CUSTOM BINDINGS),joyid
is set to the newforcejoystick
value - If
usejoystick
is 3 (CHOOSE MANUALLY) whileforcejoystick
isn't negative (it's not set to NONE) or ifusejoystick
is 0 (DISABLED) whilejoystick
is true (a controller was used while controllers are supposed to be disabled):- InputIO.GetJoyButtons called
forcecontrollerupdate
set to true
- If AudioSettings.speakerMode indicates a different value than the new
monoaudio
value andmusic[0]
is currently playing an AudioClip, it is replayed by doing the following:- ChangeMusic called with
music[0]
.clip.name music[0]
.Play calledmusic[0]
.time is reset to the value it had before the above happened
- ChangeMusic called with
- If InputIO.
isConsole
is true (a console platform), Application.runInBackground is set to false - If Application.isMobilePlatform is false, the resolution settings are ignored and the Screen resolution is instead set to 1024 x 576 without fullscreen
- If
map
exists (a map isn't being loaded),map
.RefreshSoundVolume is called which sets all SoundControl'ssource
.volume present in the scene to theirstartvalue
* the newsoundvolume
value - If
analog
is higher than 2, it is set to 0. This can't happen under normal gameplay