The VM refused C0 (register conditional), so cheats like C046B400 FFFFFFFF were greyed out as unsupported. C0 now runs with dmnt's operand types 0-5, widths and conditions; C1 and C2 save, restore and clear registers, C3 moves registers to and from the static registers. tools/cheats.py gives the same opcode lengths and accepts the same opcodes. skip() took the end of a nested block at depth 1 for the else of the failed outer block; it now counts depth the way dmnt does, and 2x000000 is an else only for x = 1. tests/cheats_vm_check.py runs tools/cheats.py and runtime/cheats.c on cheats of its own, the two from the issue included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.2 KiB
Cheats
The port reads Atmosphère cheat files, the format Switch homebrew and the emulators use. It ships no cheat files: a cheat file goes into a mod in the mods folder next to totk.exe, like any other mod (mods.md). Open the menu (F1) and switch the cheats on the Cheats tab. The switches are saved under [cheats] in totk.ini.
Adding a cheat file
-
Find the cheat file for your update. Cheat sites and collections name it after the first 8 bytes of the game's build id:
Update File 1.2.1 9B4E43650501A4D4.txt1.4.3 277178B7DBA1B6D4.txtThe Cheats tab names the file the installed game reads when no mod holds one, and
logs\totk.logsayscheats: no enabled mod holds cheats/<id>.txt. -
Put it in the
cheatsfolder of a mod, a folder of its own undermods:mods\ My cheats\ cheats\ 277178B7DBA1B6D4.txtA download laid out for the Switch's SD card or an emulator works as it is: unpack it into a folder of its own under
mods, and the port findsatmosphere\contents\0100F2C0115B6000\cheats,contents\0100F2C0115B6000\cheatsor0100F2C0115B6000\cheatsinside it. The file name's case does not matter. -
Start the game. Cheats that write the game's memory work now.
-
Cheats that change the game's code need the game rebuilt with them. When the game starts and finds such cheats it did not build, it opens the setup's rebuild window, which builds them in (a few minutes; the shaders stay prepared) and starts the game again. Until then they are greyed out with "after the rebuild". When the rebuild fails or you cancel it, the game starts without them and does not try again for the same cheats; "Rebuild the game now" on the Cheats tab tries again.
mods_rebuild = offunder[mods]intotk.initurns the automatic rebuild off; runningTotK-Setup.exeon the same folder does the same job by hand. Saves and settings are kept. -
Switch the cheats on the Cheats tab of the menu.
The Cheats tab lists the cheats grouped by mod, in the order of the Mods tab. A mod switched off on the Mods tab, or one the port cannot use, contributes no cheats; the change applies at the next start. The Mods tab says how many cheats each mod brought.
The file format
Standard Atmosphère: a [name] line starts a cheat, {name} a master cheat that is always on, and the cheat's opcodes follow as 8-digit hex words. A name with no opcodes is shown as a heading. The file's title line (the one with TID=) is not shown.
[The Legend of Zelda: Tears of the Kingdom v1.4.3 TID=0100F2C0115B6000 BID=277178B7DBA1B6D4]
[Player]
[A code cheat]
040A0000 XXXXXXXX YYYYYYYY
[A data cheat (Hold ZL+X)]
80000104
580F0000 XXXXXXXX
640F0000 00000000 YYYYYYYY
20000000
The words above are placeholders: XXXXXXXX an offset, YYYYYYYY a value.
Each cheat's switch is cheat_<hash> = 1, where the hash is FNV-1a 32 of <mod folder name>/<cheat name>. A name repeated in one file gets #2, #3 and so on. The build names each code cheat the same way, so renaming a mod's folder resets its cheats' switches to off and makes the next start rebuild its code cheats. Rename the folder before you switch its cheats on.
How cheats run
The game's code is compiled ahead of time, so a cheat cannot write new instructions into it while the game runs. The port sorts each cheat by what it writes (tools/cheats.py at setup, runtime/cheats.c in game):
| Kind | What the cheat does | How the port runs it |
|---|---|---|
| code | Opcode 0 writes into main's code | Built into the game at setup as a patch set (recomp/patches.py); switches at once. |
| key | Code writes inside a button condition (8 mask, writes, 21 else, the original words, 20) |
A patch set that is on while the cheat is on and the buttons are held. |
| data | Writes data only: heap, main's data, pointer chains, button conditions | Runs in a cheat VM after dmnt's, opcodes 0 to A and C0 to C3, every presented frame while on. |
| master | {name} with code writes |
A patch set that is always on. |
| restore | Writes back only the game's original instructions | Not needed: switching a cheat off restores them. Greyed out. |
A cheat whose code writes call or jump into a code cave the cheat writes itself (into main's zero padding) gets the cave inlined at the call site. The setup builds the code cheats of every mod in the mods folder, switched on or off, so switching a mod on later needs only a restart. A code cheat added or edited after the last build waits for the rebuild; a data cheat runs at the next start.
Not supported, and shown greyed out with the reason:
- opcode C4 (extended button condition) and the 0xF extensions (FF0 pause, FF1 resume, FFF debug log);
- opcode 5 with a register offset;
- code writes mixed with other opcodes, except the button pattern above;
- code writes that change the CPU flags differently from the game's instruction, or code caves with branches or pc-relative instructions.
build-cache\cheats.status next to totk.exe, written by the setup, records which cheats were built and how; the log line cheats: ... sums them up at start. When the code cheats cannot be built, the setup warns and installs the game without them.