overbound / SonicTimeTwisted

Source Code for a Sonic Fan Game Made in Game Maker Studio
https://overboundstudio.com/
GNU General Public License v3.0
58 stars 16 forks source link

PPZ Galacnik fight: softlock #58

Closed AlexKhayrullin closed 3 years ago

AlexKhayrullin commented 4 years ago

The Galacnik fight gets softlocked when he gets into the background: the first projectile he fires dissipates before hitting a platform, and after that, he does nothing, not even returning into the foreground.

AlexKhayrullin commented 4 years ago

Not reproduced in the master branch.

AlexKhayrullin commented 4 years ago

objGalanikFireball relies on two variables for its state machine: fire (a boolean) and image_index.

Basically, a couple of actions rely on image_index. On 4, image_speed is set to 0, allowing the fireball to take its time to reach a platform; on 7 and if the targeted platform has been hit, the image_speed is set to 0 again to set off the alpha decrease upon which the object is destroyed. If none of the above are triggered, the fireball is deleted when the animation ends. The variable "fire" serves to enable the state machine.

On the master branch, by the time "fire" is set to true, the object's image_index has just reached 4. Immediately the image_speed is set to 0, giving the fireball time to reach its target.

On the rebuild branch, by the time "fire" is set to true, the object's image_index has reached 4,25, overshooting that milestone. image_speed is not set to 0, the chances of the fireball to reach the targeted platform by the time the animation ends are slim to none, and so the event "animation end" is what deletes the instance.

Apparently, this is not GMS version-related, the behavior remains consistent between 1.4.1804 and 1.4.9999.

AlexKhayrullin commented 4 years ago

It turns out the culprit was, of all things... the reordering of the items in the asset tree. objGalacnikFireball used to be after objGalacnikSmall, and so Galanik's step event was executed first and the fireball's event was executed afterwards, which is the intended behavior.

After the reordering, objGalacnikFireball's step event became executed before objGalacnikSmall's. The weirdest part is, from what I read online, depth is supposed to be taken into account, but I'm doubtful. I also though the order of creation of instances also was the order of execution of their step events, but it turns out, no. All I can confirm is that I've tried it out, simply moving objGalacnikFireball in the asset tree below objGalacnikSmall removes the bug.

In order to force the order of execution in a safer manner, I replaced objGalacnikFireball's step event with a User Defined event 0, which is explicitly called by objGalacnikSmall at the end of its step event. I also, just in case, forced the deletion of all objGalacnikFireball instances when objGalacnikSmall is deleted.

AlexKhayrullin commented 4 years ago

Not yet ported into the 1.1 branch.

nkrapivin commented 4 years ago

The commit is in the 1.1 branch, so the issue should be fixed?

AlexKhayrullin commented 4 years ago

Not the latest (and MUCH better) fix by @VectorSatyr , I haven't ported it yet, and I can't merge automatically.

nkrapivin commented 4 years ago

@AlexKhayrullin I've manually ported the VectorSatyr's fix to the latest commit and made a test build: https://drive.google.com/file/d/1zZ5NISUCxL-Qg47f4RrbBLBcqbhVAE8c/view?usp=sharing

Does it fix the issue?

nkrapivin commented 4 years ago

(le branch: https://github.com/nkrapivin/SonicTimeTwisted/tree/galanick)

AlexKhayrullin commented 4 years ago

Hi. Sorry for not responding, between real life and working on maybe the biggest ticket related to Android (BT/USB gamepad support), I kinda went dead for a moment there :)

Thanks, I'll check it out first thing when I'm done with the gamepad support.

nkrapivin commented 4 years ago

That's fine. Take as much time as you need. :)

AlexKhayrullin commented 3 years ago

Fix by @VectorSatyr merged by @nkrapivin . Confirmed to be working.