Skip to content

Instantly share code, notes, and snippets.

@Myriachan
Last active November 12, 2018 18:24
Show Gist options
  • Select an option

  • Save Myriachan/67270d5b78e8ce86c0856e1cdb1303e5 to your computer and use it in GitHub Desktop.

Select an option

Save Myriachan/67270d5b78e8ce86c0856e1cdb1303e5 to your computer and use it in GitHub Desktop.
Fix for Deltarune crash bug in Rudinn + Hathy battle
In Deltarune, the following steps crash the game. I didn't find this bug, but I know how to fix it.
1. Recruit Susie permanently.
2. Go to the location of the save point that is called "Field - Maze of Death".
3. Walk left to the next screen.
4. Walk past the puzzle and start an encounter with the Rudinn walking around. This starts a battle with the Rudinn and a Hathy.
5. Highlight Act and press Z.
6. Highlight Hathy and press Z.
7. Highlight S-Flatter and press X to cancel.
8. Highlight Act and press Z again.
9. Highlight Rudinn and press Z.
The game will crash with a negative subscript error in obj_battlecontroller_Draw_0. The heart cursor got pointed to a negative index.
In this battle, Rudinn has 3 Act possibilities (Check, Convince, Lecture), while Hathy has 4 (Check, Flatter, X-Flatter, S-Flatter).
Because the heart cursor remembers where it was pointed, the steps above cause the cursor to point to a position that no longer exists.
While initializing the Act list for the targeted monster, obj_battlecontroller_Step_0 tries to detect this situation and correct it,
but the code to correct it has a bug.
The broken code looks like the following. This came from UndertaleModTool, based on a disassembly. Naturally, I don't have the
source code, so this isn't exactly what the real code looks like.
if (global.bmenuno == 11) // battle menu ID of monster target select
{
global.bmenuno = 9; // battle menu ID of ACT select
self.actcoord = global.bmenucoord[((9 * 32000) + global.charturn)];
self.thisenemy = global.bmenucoord[((11 * 32000) + global.charturn)];
self.i = 0;
for (self.i = 0; i < 6; i += 1)
{
if (global.canact[((self.thisenemy * 32000) + self.actcoord)] == 0)
{
if (self.actcoord > 0)
{
global.bmenucoord[((9 * 32000) + global.charturn)] -= 1;
}
}
}
self.onebuffer = 1;
}
The bug is on the innermost "if" statement. The write to global.bmenucoord[((9 * 32000) + global.charturn)] is updating the value that
self.actcoord came from, but not self.actcoord itself! This means that 6 will be subtracted from the cursor location, which causes it
to go negative, and hence the crash later in Draw.
The fix is to make that innermost "if" statement like this:
if (self.actcoord > 0)
{
global.bmenucoord[((9 * 32000) + global.charturn)] -= 1;
self.actcoord -= 1;
}
Then it'll only subtract the necessary number of times to get the cursor to a safe location, fixing the bug with the intended behavior.
To fix this, you can use UndertaleModTool. Go to the disassembly tab for script gml_Object_obj_battlecontroller_Step_0. Find the line:
04234: pop.i.v [array]bmenucoord
Immediately after that line, add the following four lines (with no number before them):
push.v self.actcoord
pushi.e 1
sub.i.v
pop.v.v self.actcoord
When you then click the Decompiled tab, you'll see that the innermost "if" statement has been corrected. Save data.win, and the
bug will be fixed.
-- Myria 2018/11/11
@daneeko
Copy link

daneeko commented Nov 12, 2018

nice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment