From 942217f871bf1182ded3a915b8c26b90c04d561a Mon Sep 17 00:00:00 2001 From: Misa Date: Sat, 31 Oct 2020 11:52:06 -0700 Subject: [PATCH] Fix glitchy y-position when colliding with a conveyor There is this issue with conveyors where if you collide with them, your intended next y-position doesn't get updated to the position of the conveyor, and then your y-position gets set to your intended next y-position. This also applies to horizontally moving platforms. This bug used to not produce any problems, if at all, until #502 got merged. Since then, respawning from checkpoints that are on conveyors would sometimes not update your y-position at all, making it possible to get stuck inside a death loop that would require you to exit the game and re-enter it. But you can always reliably create this bug simply by going into the editor and placing down a conveyor and checkpoint on top of each other. Then enter and exit playtesting a bunch of times, and you'll notice the glitchy y-position Viridian keeps taking on. The root cause of this is how the game moves the player whenever they stand on the top or bottom of a conveyor (or a horizontally moving platform). The game sets their intended next x-position (newxp), then calls obj.entitymapcollision() on them. This would be okay, except their intended next y-position (newyp) doesn't get set along with their newxp, so entitymapcollision() will use the wrong newyp, then find that there is nothing that will collide with the player at that given newyp, then update the yp of the player to the wrong newyp. So, the platform logic simply doesn't set the player's newyp. Why does the player have the wrong newyp? It's because moving platforms (and conveyors) are updated first before all other entities are, and this includes the code that checks the player for collisions with moving platforms. That's right: the moving platform collision code gets ran before the player properly gets updated. This means that the game will use the newyp of the previous frame, which could be anything, really, but it most likely just means the intended next y-position of the player gets canceled, leaving the player with the same y-position they had before. Okay, but this bug only seems to happen when you put a checkpoint inside a conveyor (or a moving platform that hasn't started moving yet) and start playtesting from it, so why doesn't this bug happen more often, then? Well, it's probably because of luck and coincidence. Most of the time, if you're colliding with a conveyor or horizontally moving platform, you probably have a correct newyp from the previous frame of the game, so there'd be no problems. And before #502 got merged, this previous frame would be provided by the player having to fall to the surface due to the y-offset of their savepoint. However, if you make it so that you immediately teleport on to a conveyor (because you died), then this bug will rear its ugly head. --- desktop_version/src/Logic.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/desktop_version/src/Logic.cpp b/desktop_version/src/Logic.cpp index 8622c88e..5362077f 100644 --- a/desktop_version/src/Logic.cpp +++ b/desktop_version/src/Logic.cpp @@ -939,6 +939,7 @@ void gamelogic() if (INBOUNDS_VEC(i, obj.entities) && j > -1000) { obj.entities[i].newxp = obj.entities[i].xp + j; + obj.entities[i].newyp = obj.entities[i].yp; obj.entitymapcollision(i); } else @@ -947,6 +948,7 @@ void gamelogic() if (INBOUNDS_VEC(i, obj.entities) && j > -1000) { obj.entities[i].newxp = obj.entities[i].xp + j; + obj.entities[i].newyp = obj.entities[i].yp; obj.entitymapcollision(i); } }