TO:R Data Map

Debug and test switches

Source
docs/executable/debug-switches.md
SHA-256
29a668b4…3562ce68

What is left in the executable of the developers' debug and test switches, and whether any of it can be reached in the shipped game: the auto_test switch, the shop's debug sequence, the @debug font and the debug memory heaps. Also the settings file config.ini, the one outside file the game reads switches from. None of it gives a debug menu: each piece is either compiled out, never offered, or ordinary code with a debug name. The work it serves is R14, testing edits in the game.

Based on The unpacked executable, SHA-256 7b0230a11498f40396c9048345e7cfe0ef442cb7ca8faffc6f197920d2669599; menu/menu_data.dat entries #7 and #20, for the shop command texts.
Checked 2026-10-11
Method Static analysis with Ghidra 12.1.4: the decompiled code in local/exe/decomp/, the indexes exe.calls and exe.strings (The indexes), objdump -d of the call sites, and xxd of the executable's key table and string pool. Every fact here is at most likely.

Summary

Switch What it does Can it be reached?
config.ini The display settings: screen mode, monitor, adapter, resolution, window placement (config.ini). Yes, by editing the file.
auto_test When set, the game never writes config.ini (auto_test). No: the check always answers "not set".
Shop DebugSequence Shop commands 8 and 9: enter the hero's name again, or the birthday (The shop's debug sequence). No: no shop lists commands 8 or 9. Only a code patch could add them.
@debug font The name given to a font's first face when it's loaded (The @debug font). Not a switch: ordinary font loading.
DEBUG, DEBUG_MENU, debug heaps Memory heaps registered at startup (The debug heaps). No code allocates from them.

config.ini

The game keeps its display settings in config.ini, a text file of Key=Value lines in the user's save folder. It isn't a game data file and isn't in Data/; the game writes it, so a mod never ships one.

Keys

Eleven keys, in this order, which is also the order the game writes them. Their names and types are a table of 0x24-byte records at 0x140687050 (a 32-byte name, then a type: 0 text, 1 integer, 2 decimal); the values live from 0x140F22490, 0x88 bytes each (127 characters of text, then an s32 and an f32). Source: xxd of both; the struct the loader fills (0x14032d070) and the code that applies it (0x14032c610).

Key Type Default What it sets
ScreenMode text FullScreen; Window when a debugger is attached (0x14032ce60) Window, FullScreen (exclusive full screen) or FullScreenVirtual (a borderless window the size of the monitor), matched ignoring case (0x14032cbc0). Anything else is Window.
Monitor integer 1 The monitor, counting from 1. Out of range is the first monitor.
Adapter integer 1 Nothing: the loader replaces it with the adapter in use (0x14032d070). The adapter is picked by GraphicDeviceId.
MonitorDeviceId text empty A monitor's device name; when it names a connected monitor, it picks the monitor instead of Monitor (0x14032c610).
GraphicDeviceId text empty The graphics adapter, read at startup by App init (0x140034d30).
ScreenWidth integer 0 In Window mode, the window's width, at least 800; 0 or less is the display's current width. In FullScreen, the display mode to use, with ScreenHeight: an exact match from the monitor's list of modes, else the list's last mode. Not used in FullScreenVirtual.
ScreenHeight integer 0 The height, as ScreenWidth; at least 450 in Window mode.
WindowPosX integer 0 The window's position, passed to the renderer with the mode.
WindowPosY integer 0
WindowWidth integer 0 The window's size, passed the same way.
WindowHeight integer 0

How the game reads it

For in-game tests, ScreenMode=Window with ScreenWidth and ScreenHeight runs the game in a window.

auto_test

likely: the switch only stops the game writing config.ini, and it can't be turned on. The save (0x14032d2f0) first asks the framework (the object at 0x140F6C778) whether an option named auto_test is set, by a direct call to 0x1400349d0, and writes the file only when it isn't. 0x1400349d0 is three bytes, xor al, al; ret: it always answers false. Source: objdump -d of both.

The shop's debug sequence

likely: the shop has a ninth mode, Taco::Application::DebugSequence, that no shop offers. Every shop builds all nine of its mode objects (0x14030d0c0, ShopMenu::vfunction4), and the top menu (0x14040e430, TopMenuSequence::vfunction6) maps the chosen command to a mode:

Command Mode Constructor
0 1, buy BuyListMenuSequence
1 2, sell SellMenuSequence
2 3, hire EmployMenuSequence
3 4, auction AuctionSequence
4 5, craft ItemBlendSequence
5 6, upgrade ItemUpgradeSequence
6 7, organize OrganizeSequence
7 exit —
8, 9 8, debug DebugSequence

The @debug font

likely: not a debug feature. While the language's font package is read (0x1402ac010), every face of every outline font gets a slot and is registered under its family name; the first face of the first font whose debug_font field is set is also registered, in slot 0, as @debug font, with the value 52 (0x34) set on that text font (font.md). Nothing else refers to the name.

The debug heaps

likely: the memory system (0x140036e10) registers 28 named heaps, among them DEBUG (ID 0x14), DEBUG_MENU (0x15) and debug (0x1C), but no allocation in the code names any of the three: the allocator 0x140198c90 is called only with other heap IDs (MENU, 8, for the shop windows; SAVELOAD, 0x12, for the system settings), or with a heap chosen at run time. Source: the heap table in 0x140036e10 and its name strings at 0x1406AF5A8; every constant heap ID passed to 0x140198c90 in the decompiled code.

Leads