[P-BUG][PLAYER] Inconsistency in climber head-hitting

Started by namida, October 10, 2021, 12:21:02 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

namida

Fix to be included in 12.13.0.

See attached image. If the climber falls down the bottom, climbs all the way up to the top, hits his head, then falls onto the bridge, he survives. A climber that climbs from the top of the bridge on the other hand, splats. The splat ruler (as well as simply it being the "typical" situation) confirms that it is the second climber who is behaving correctly.

For reference - not including the floor, bridge or ceiling themselves, there are 69 pixels between the ceiling and the top bridge step; 96 between the below floor and the ceiling.

EDIT: Attached a level that reproduces this setup. Make the first lemming build at the edge, then make lemmings climbers.
My projects
2D Lemmings: NeoLemmix (engine) | Lemmings Plus Series (level packs) | Doomsday Lemmings (level pack)
3D Lemmings: Loap (engine) | L3DEdit (level / graphics editor) | L3DUtils (replay / etc utility) | Lemmings Plus 3D (level pack)
Non-Lemmings: Commander Keen: Galaxy Reimagined (a Commander Keen fangame)

Simon

#1
Lovely bug.

Surprising that the bug slept in the game for so long. The climber raises by at most 1 pixel per frame. I would have assumed that if there were different climber-to-faller behavior in the different frames of the cycle, we would have run into the inconsistency much sooner.

Normal fall heights are ≤ 63 pixels safe, ≥ 64 pixels splat. The faller from the ceiling will fall less than the full air distance, so we get some survival bonus distance.

Are you sure that 69 air pixels between floor and ceiling should already be deadly? That would mean that the falling lemming is only 5 or 6 pixels tall (69 - 64 ± 1 for nasty off-by-one). Normal lemmings are 8-10 pixels high, therefore (69 pixels are correctly deadly) would mean that the lemming starts falling with its entire head in the ceiling.

-- Simon

IchoTolot

Quote
Are you sure that 69 air pixels between floor and ceiling should already be deadly? That would mean that the falling lemming is only 5 or 6 pixels tall (69 - 64 ± 1 for nasty off-by-one). Normal lemmings are 8-10 pixels high, therefore (69 pixels are correctly deadly) would mean that the lemming starts falling with its entire head in the ceiling.

I think the core question here is not if 69 air pixels between floor and ceiling should already be deadly as that train has already departed long ago, but rather why this inconsisteny triggers.

My bet is on the animation cycle:

Normally situation is that all climbers start on the same floor so no inconsistancy can happen there.

Here the 2 climbers start on different levels --> they are in different states in the animation cycle.

The height gain in the cycle is not constant as the lemming crawls up in little "bursts" -- there are frames in the cycle where he does not gain height.

So the bug only comes to shine when we have a floor change to a level which is exactly splat height + climbers in different anymation cycles (started on different levels). -- This is extremely rare! So I am not surprised it only surfaced now.

--------------------------------------------------------------------------------------------------------

What scratches my head is though is that even if the height gain is not constant all the time the head check of the climber should always trigger the "hit head" scenario at the same time.
At some point the height of the climber head check simply reaches the ceiling point.

The only ways I can think of a difference here:

- Somehow the bobbing back and fourth of the climber head is taken into account! Then the cycle would matter and different cycles can result in an extra pixel of survival.

- At some point the climber gains 2 pixels of height in 1 frame of the cycle. (I do not think this is the case)

Either that or some weird extra check reveals its head.

Otherwise I just imagine a static point inside the climber slowly reaching the critical ceiling point and for that the cycle should not matter if there are no 2 pixel height gains and it should always result in the same fall distance.

One more thought:

Maybe at some point the advancement of the animation cycle comes before the check so that the climber gains an extra pixel. Basically the order of checks is being mixed up.


A fix for this most likely calls for a RC version to assess impact as I can imagine this could have some serious consequences for levels/replays due to the basic hitting head situation is quite common.
Even 2 climbers in different cycle states is much more common now due to the existence of jumpers!


So I would advice for a deeper assessment of the impact of the fix here just to be on the safe side.

namida

QuoteA fix for this most likely calls for a RC version to assess impact as I can imagine this could have some serious consequences for levels/replays due to the basic hitting head situation is quite common.
Even 2 climbers in different cycle states is much more common now due to the existence of jumpers!

A bugfix for this would come as part of 12.13.X, not a 12.12.X update, and so would absolutely go through an RC phase.
My projects
2D Lemmings: NeoLemmix (engine) | Lemmings Plus Series (level packs) | Doomsday Lemmings (level pack)
3D Lemmings: Loap (engine) | L3DEdit (level / graphics editor) | L3DUtils (replay / etc utility) | Lemmings Plus 3D (level pack)
Non-Lemmings: Commander Keen: Galaxy Reimagined (a Commander Keen fangame)

namida

The cause of this turns out to be that, during the frames where the climber actually moves, the position he'll be after a head-hit is one pixel higher than it would be during the frames where he doesn't move. There are four frames of each; moving the bottom floor upwards by up to 3px will result in the climber still hitting his head during a frame where this triggers.

Leaving the positioning as-is would mean almost zero breakage, but also that an inconsistency that can affect exact timings / etc is preserved. We have accepted a similar minor inconsistency with the floater already (but conversely, fixed the Glider variant of the same, as it actually lead to highly exploitable outcomes whereas the Floater version does not, it would just break replays for little gain).

Therefore, the solution I have decided to go with is simply that, in the case where a Climber transitions to a Faller on such a frame that this bug would trigger, 1 is added to its distance fallen immediately - this negates the difference as far as splat height is concerned, and all other impacts are on the "you wouldn't notice it if it wasn't pointed out, and it can't really be exploited in any particularly useful way" level of severity much like the Floater case.

This fix is implemented in commit 4da2f88. Leaving this topic open for further discussion.

To avoid any doubt, this fix will not be included in any 12.12.X update. This is so that it can go through the proper RC phase, just in case.
My projects
2D Lemmings: NeoLemmix (engine) | Lemmings Plus Series (level packs) | Doomsday Lemmings (level pack)
3D Lemmings: Loap (engine) | L3DEdit (level / graphics editor) | L3DUtils (replay / etc utility) | Lemmings Plus 3D (level pack)
Non-Lemmings: Commander Keen: Galaxy Reimagined (a Commander Keen fangame)