UndertaleModTool icon indicating copy to clipboard operation
UndertaleModTool copied to clipboard

Deltarune PC "gml_Object_obj_mainchara_Step_0" infinite loop freeze between lines 286-316

Open Grossley opened this issue 6 years ago • 12 comments

If Kris runs into a corner the game freezes. The cause is probably due to a missing "break" after "bkxy = 1" in the following section (lines 288-293) :

It currently decompiles to this:

            if (!place_meeting((x + i), (y + j), obj_solidblock))
            {
                px = i
                py = j
                bkxy = 1
            }

But it should decompile to this:

            if (!place_meeting((x + i), (y + j), obj_solidblock))
            {
                px = i
                py = j
                bkxy = 1
                break;
            }

Grossley avatar Aug 19 '19 20:08 Grossley

This should be tested after the decompiler is rewritten.

Kneesnap avatar Sep 02 '19 02:09 Kneesnap

This same error also occurs in "gml_Object_obj_heart_Step_0" between lines 177 and 182:

It decompiles to this:

        if (!place_meeting((x + i), (y + j), obj_battlesolid))
        {
            px = i
            py = j
            bkxy = 1
        }

When it should decompile to this:

        if (!place_meeting((x + i), (y + j), obj_battlesolid))
        {
            px = i
            py = j
            bkxy = 1
            break;
        }

Grossley avatar Oct 06 '19 02:10 Grossley

how to debug the decompiler to fix the bug

H-A-M-G-E-R avatar Jun 20 '23 03:06 H-A-M-G-E-R

a) remake the decompiler from scratch b) as a workaround, manually add the break to the decompiled code and do future edits to that code entry in an external editor that won't invoke the decompiler, or using the tool's "profile mode" that does the same in the built-in editor.

Jacky720 avatar Jun 20 '23 03:06 Jacky720

the decompiler can easily be fooled by unreachable sections

H-A-M-G-E-R avatar Jun 20 '23 17:06 H-A-M-G-E-R

I don't understand. There isn't anything unreachable here, it's just break/continue statements that don't work sometimes.

Jacky720 avatar Jun 20 '23 17:06 Jacky720

there's unreachable assembly in gml_Object_obj_heart_Step_0 look at the line that says ":[27]" of the assembly

H-A-M-G-E-R avatar Jun 20 '23 17:06 H-A-M-G-E-R

i don't know gml assembly very well..

H-A-M-G-E-R avatar Jun 20 '23 17:06 H-A-M-G-E-R

in lines 36-55 of gml_Object_DEVICE_CHOICE_Step_0 it should decompile to this:

            while move
            {
                ccc = NAME[CURX, CURY]
                if (ccc == ">")
                    CURX += 1
                else if (ccc == "<")
                    CURX -= 1
                else
                    move = 0
            }

instead of this:

            if move
            {
                ccc = NAME[CURX, CURY]
                if (ccc == ">")
                    CURX += 1
                else if (ccc == "<")
                    CURX -= 1
                else
                    move = 0
                while move
                {
                    ccc = NAME[CURX, CURY]
                    if (ccc == ">")
                        CURX += 1
                    else if (ccc == "<")
                        CURX -= 1
                    else
                        move = 0
                }
            }

H-A-M-G-E-R avatar Jun 20 '23 17:06 H-A-M-G-E-R

there are unnessessary elses and continues in gml_Object_obj_heart_Step_0 that change the compiled assembly that's the problem

H-A-M-G-E-R avatar Jun 21 '23 01:06 H-A-M-G-E-R

gml_Script_scr_armorget should decompile to this:

i = 0
loop = true
noroom = false
global.armor[12] = 999
while (loop == true)
{
    if (global.armor[i] == 0)
    {
        global.armor[i] = argument0
        break
    }
    if (i == 12)
    {
        noroom = true
        break
    }
    i += 1
}
script_execute(scr_armorinfo_all)

H-A-M-G-E-R avatar Jun 21 '23 01:06 H-A-M-G-E-R

For reference, here's what gml_Object_obj_heart_Step_0 should decompile to:

wallcheck = 0
press_l = 0
press_r = 0
press_d = 0
press_u = 0
bkx = 0
bky = 0
bkxy = 0
jelly = 2
if left_h()
    press_l = 1
if right_h()
    press_r = 1
if up_h()
    press_u = 1
if down_h()
    press_d = 1
px = 0
py = 0
if (press_r == 1)
    px = wspeed
if (press_l == 1)
    px = (-wspeed)
if (press_d == 1)
    py = wspeed
if (press_u == 1)
    py = (-wspeed)
xmeet = 0
ymeet = 0
xymeet = 0
if place_meeting((x + px), (y + py), obj_battlesolid)
    xymeet = 1
if place_meeting((x + px), y, obj_battlesolid)
{
    if place_meeting((x + px), y, obj_battlesolid)
    {
        g = wspeed
        while (g > 0)
        {
            mvd = 0
            if (press_d == 0 && (!(place_meeting((x + px), (y - g), obj_battlesolid))))
            {
                y -= g
                py = 0
                break
                mvd = 1
            }
            if (press_u == 0 && mvd == 0 && (!(place_meeting((x + px), (y + g), obj_battlesolid))))
            {
                y += g
                py = 0
                break
            }
            g -= 1
        }
    }
    xmeet = 1
    bkx = 0
    if (px > 0)
    {
        i = px
        while (i >= 0)
        {
            if (!(place_meeting((x + i), y, obj_battlesolid)))
            {
                px = i
                bkx = 1
                break
            }
            i -= 1
        }
    }
    if (px < 0)
    {
        i = px
        while (i <= 0)
        {
            if (!(place_meeting((x + i), y, obj_battlesolid)))
            {
                px = i
                bkx = 1
                break
            }
            i += 1
        }
    }
    if (bkx == 0)
        px = 0
}
if place_meeting(x, (y + py), obj_battlesolid)
{
    ymeet = 1
    bky = 0
    if place_meeting(x, (y + py), obj_battlesolid)
    {
        g = wspeed
        while (g > 0)
        {
            mvd = 0
            if (press_r == 0 && (!(place_meeting((x - g), (y + py), obj_battlesolid))))
            {
                x -= g
                px = 0
                break
                mvd = 1
            }
            if (mvd == 0 && press_l == 0 && (!(place_meeting((x + g), (y + py), obj_battlesolid))))
            {
                x += g
                px = 0
                break
            }
            g -= 1
        }
    }
    if (py > 0)
    {
        i = py
        while (i >= 0)
        {
            if (!(place_meeting(x, (y + i), obj_battlesolid)))
            {
                py = i
                bky = 1
                break
            }
            i -= 1
        }
    }
    if (py < 0)
    {
        i = py
        while (i <= 0)
        {
            if (!(place_meeting(x, (y + i), obj_battlesolid)))
            {
                py = i
                bky = 1
                break
            }
            i += 1
        }
    }
    if (bky == 0)
        py = 0
}
if place_meeting((x + px), (y + py), obj_battlesolid)
{
    xymeet = 1
    bkxy = 0
    i = px
    j = py
    while (j != 0 || i != 0)
    {
        if (!(place_meeting((x + i), (y + j), obj_battlesolid)))
        {
            px = i
            py = j
            bkxy = 1
            break
        }
        if (abs(j) >= 1)
        {
            if (j > 0)
                j -= 1
            if (j < 0)
                j += 1
        }
        else
            j = 0
        if (abs(i) >= 1)
        {
            if (i > 0)
                i -= 1
            if (i < 0)
                i += 1
        }
        else
            i = 0
    }
    if (bkxy == 0)
    {
        px = 0
        py = 0
    }
}
if ((x + px) >= ((__view_get(0, 0) + 640) - sprite_width))
    px = (((__view_get(0, 0) + 640) - sprite_width) - x)
if ((x + px) <= 0)
    px = (-x)
if ((y + py) <= 0)
    py = (-y)
if ((y + py) >= (((__view_get(1, 0) + 320) - sprite_height) + boundaryup))
    py = ((((__view_get(1, 0) + 320) - sprite_height) - y) + boundaryup)
x += px
y += py
if (dmgnoise == true)
{
    dmgnoise = false
    snd_stop(snd_hurt1)
    snd_play(snd_hurt1)
}
global.inv -= 1
if (global.inv > 0)
    image_speed = 0.25
else
{
    image_speed = 0
    image_index = 0
}
global.heartx = ((x + 2) - __view_get(0, 0))
global.hearty = ((y + 2) - __view_get(1, 0))

H-A-M-G-E-R avatar Jun 21 '23 01:06 H-A-M-G-E-R