[FIXED] [BUG] [PLAYER] Bashers turn inconsistently at steel

Started by Nepster, March 13, 2016, 07:41:02 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ccexplore

More technical background: in L1, steel areas are set up separately from the steel terrain pieces.  Ignoring that point though, the steel checking is done such that it's actually the inverse that works in L1 and not exactly the setup given by Nepster:  The lowest 4 pixels from ground level are not checked for steel, only the upper 4 pixels (and due to multiple-of-4 alignments in how steel areas are tracked, in some cases it can actually be up to lowest 7 pixels).  So the lower portions of steel can be bashed away, which is typically considered a form of steel destruction glitch in L1.  A particularly egregious form of that is ceiling steel-bashing (where the location the game actually looks for steel is off the level's top boundary, so even though the steel reaches the top boundary and likely was never intended to be bypassable with a basher, you still can by starting to bash high enough).

The actual terrain removal mask in L1 is 9 pixels tall IIRC, so if the lowest steel is located at that 9th row, it is not detected either.  While this sound sort of bad, in practice it seems that (some?) people would rather have a slight margin of error and be okay with one or two rows of pixels at the top and/or bottom be ignored for steel checking.

L2 has more honest steel treatment in that steel pixels are never destructible.  I forgot exactly how it checks for steel during bashing, but I believe there is some forgiveness so that something like the bottom row and 9th row (and perhaps more?) may be ignored when checking for steel.  Ignore means they don't stop the basher, but they remain indestructible and are simply not removed as part of the bash stroke.

Anyway, the setup described by Nepster does sound very counterintuitive and probably should not be kept.  (Having a margin of error in steel checking would not require maintaining such behavior--the margins are set up to be outside the zone that is checked to determine whether there is more ahead to bash.)  In fact, it feels like the margin of error for steel may be too forgiving for such a setup?

namida

QuoteAnyway, given your code (using experimental version 2) I would have expected that a basher falling down has its falling distance reduced by 3, because it got moved down already 3 pixels during the basher function. However experiments show that being a basher doesn't matter whether a lemmig splats or not. Where is my mistake?

TLemmingGame.Transition
    if (aAction = baFalling) then
    begin
      LemFallen := -2;
      if LemAction in [baWalking] then LemFallen := 0;
      if LemAction in [baBashing] then LemFallen := -1;
      if LemAction in [baMining, baDigging] then LemFallen := -3;
    end;

This code handles setting the initial fall distance. I couldn't tell you off-hand why these values work - they were derived a very long time ago, by trial-and-error rather than by analysing code. However, just in case, I tested it now and can confirm - both a walker or a basher, falling from a 64 pixel height, will splat. Either one falling from a 63 pixel height will not. So while the code may be a bit strange here, there is no inconsistency in the end result.

QuoteStill if the basher is a floater, he opens the parachute one pixel higher than usual lemmings falling down. So there is something not completely right with the faller transition.

This (which probably should be fixed) is because a walker is moved downwards by one pixel more than a basher is, before transitioning to a faller. Although the splat distance is, unlike L1, checked on a pixel-perfect basis; the timing of pulling out a floater is unchanged from L1. For a floater this generally won't make a huge difference (in some cases it may mean a walker arrives at the ground one frame sooner than a basher, even if both begun falling at the same time - this also holds true for regular fallers as well), but I could see this being significant when it comes to Gliders.

QuoteDo we even need the steel check on assignment at all, if we use the new checks during the basher animation?

I was wondering the same thing myself. However, as far as I recall, no one suggests changing the check-on-assign for the digger. People also seem to want the check-on-assign for miners to be made more strict. In light of this, making the basher check less strict seems a bit strange.

QuoteJust looked a bit more at the experimental code and found some more bugs:
- Bashers can now climb much steeper inclines (about three times as steep)
- If a basher moved up or down, the steel checks are at the wrong height

The first one might be desirable for consistency (and at any rate, is a very unusual setup, though it might occur in the Sky set or by very well-timed use of Stoners, or perhaps even Stackers). The only reason the lemming couldn't do so before is because the steel check caused him to revert to a walker. In the absence of this - perhaps if the aforementioned stoner / stacker timing setup was used to create such a layout - the basher would have been able to do this too, I believe.

The second one I'll look into.

QuoteFinally I noticed the following: If the lowest 5 pixels are air and from pixel 6 on there is steel, then the lemming will happily continue bashing forward without removing any terrain pixel at all. Do we want to keep this behavior?

No, we do not. We should compare this to a digger - although steel (other than right underneath the lemming) won't stop the lemming, they don't count as solid pixels for the terrain check.


In regards to your proposed code - I'm planning to overhaul the way the code is written in the near future, so I don't want to worry too much about improving the way the current code is laid out. Rather, my intention is - decide on and implement new physics by adjusting the current code, then when that's done, do the overhaul, at which point the improved-readability etc changes would also be made.

FWIW though, as far as I can (without actually testing it) tell that code is mostly fine, except for "Return :=" rather than "Result :=" in the first snippet. Although the new functions should probably be defined as private functions of TLemmingGame, rather than standalone ones.
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)

Nepster

Quote from: ccexplore on March 16, 2016, 11:13:50 PM
In fact, it feels like the margin of error for steel may be too forgiving for such a setup?
Interesting suggestion.
- Pixels 1 and 2: Should not be checked, because the basher may step upon them.
- Pixels 3, 4 and 5: Already checked.
- Pixels 6, 7: Might result in improved basher mechanics.
- Pixels 8, 9: Steel checks here might surprise some people: Why should lemmings turn around if their hair touches steel?

Quote from: namida on March 17, 2016, 02:31:11 AM
QuoteDo we even need the steel check on assignment at all, if we use the new checks during the basher animation?

I was wondering the same thing myself. However, as far as I recall, no one suggests changing the check-on-assign for the digger. People also seem to want the check-on-assign for miners to be made more strict. In light of this, making the basher check less strict seems a bit strange.
These checks are not really consistent anyway. The first question should be: What behavior do we actually want? Then I would implement the checks according to the answer to this question. If it turns out that we want miner to be more strict and basher less strict, then so be it.
But all of this is better discussed in the assignment check topic.

Quote from: namida on March 17, 2016, 02:31:11 AM
QuoteJust looked a bit more at the experimental code and found some more bugs:
- Bashers can now climb much steeper inclines (about three times as steep)

The first one might be desirable for consistency (and at any rate, is a very unusual setup, though it might occur in the Sky set or by very well-timed use of Stoners, or perhaps even Stackers). The only reason the lemming couldn't do so before is because the steel check caused him to revert to a walker. In the absence of this - perhaps if the aforementioned stoner / stacker timing setup was used to create such a layout - the basher would have been able to do this too, I believe.
You forget slopes made out of steel or wrong OWW. I seriously doubt that we want the behavior in the attached image.

Quote from: namida on March 17, 2016, 02:31:11 AM
In regards to your proposed code - I'm planning to overhaul the way the code is written in the near future, so I don't want to worry too much about improving the way the current code is laid out. Rather, my intention is - decide on and implement new physics by adjusting the current code, then when that's done, do the overhaul, at which point the improved-readability etc changes would also be made.
Sorry, but this does not make any sense. With the current mostly unreadable code, we can create a few test maps (which might be a good thing to do anyway), but nothing more. In particular we will certainly miss some bugs or glitches in the code. So after making the code readable, we have to do the same testing again and have subsequent physics changes which annoy all the level designers by breaking their replays yet again.
Moreover I will take any bet, that nobody can overhaul the code without introducing a few new subtle bugs or glitches.
So I see three options how to proceed:
1) I stop testing experimental releases and stop reporting physics bugs until the code got readable, because it is currently wasted time to do so.
2) Whenever you fix some bugs/glitches in some function, you overhaul this function and make it readable.
3) You outsource overhauling the game mechanics code, by giving this task to me. Prerequisites are that you don't plan changing major global design decisions for the code and that I get a free Delphi compiler from somewhere in order to test the mess I code.
What do you prefer?

namida

I can't make any promises in regards to the lack of global changes. In particular, one that's likely to overlap with the mechanics code (almost by definition) is seperating the rendering and physics from each other; you've probably noticed that currently they're quite intertwined.

I get that the plan here seems strange, but by knowing exactly what I'm trying to implement, what information each skill needs, etc, when overhauling it, I can ultimately produce better code, even if the code remains a bit messier in the meantime. Until then, any changes should be made as local as possible to the specific action, and anything not explicitly decided on changing should be unchanged, so that we don't end up with unexpected accidental results.

I don't plan on making any release that includes these physics changes until both deciding on them, and the overhaul of how physics is implemented, are both done. So, unless authors are updating their replays for the experimental versions, it is not going to result in a case of double-breakage.

It is not wasted time to report the bugs, because the idea isn't "scratch everything, make a new set of physics". It's "firstly get the physics right, then tidy up the code for them". In particular (as you may have seen in IRC discussions if you follow the logs), I'm wanting to move much of the processing from TLemmingGame to TLemming, and implement objects that define the behaviours. This would, of course, require knowing what those behaviours are going to do. The alternative here is to do that now, and potentially end up with suboptimal code due to all the additions / removals / changes that occur when investigating physics.
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)

Nepster

That's all fine and good, but my two main concerns remain: If you do "firstly get the physics right, then tidy up the code for them", then
1) How do we know that we got the physics right, if the code is barely readable?
2) How do we know that we did not change the physics while tidying up the code?

namida

1. "Barely readable" is perhaps an exaggeration. "Not as tidy and efficient as it could be" is more accurate. It's not so bad that bugs can't be spotted (I've already found several by looking through the code, that were never discovered in regular gameplay - the assigning-skills-to-stonesploder glitch being an example of such), and I also wouldn't say I'm not going to tidy up little things as I go - more just not going out of my way to do so. If I see commented-out or never-used code, I'll probably remove it.

2. Test maps and replay checking. Which I do need to get around to making more of, I'm thinking I should probably make a graphic set specifically designed for test map purposes (ie: no emphasis at all on looking nice; the emphasis rather is on being able to put together the kind of structures that are useful for test maps, and designed so that where applicable, distances can be accurately determined visually without having to back-calculate them from the physics or check in a graphic editing program).
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)

Nepster

Yes, "barely readable" was an exaggeration. But let's have a look at the latest bugs I found:
- Bashers move up too steep slopes: Found via test map.
- Misplaced steel checks if basher steps up/down: Found via looking at the original code.
- Basher continues with steel at height 6: Only noticed after looking at my rewritten code.
- Basher turns if (LemX, LemY) is empty, but (LemX, LemY - n) is steel for n > 0: I noticed this already yesterday in the original code. However when I tested this, I got confused, because I mistakenly thought the lemming actually correctly transitions to a faller. So I spent one hour trying to understand where the code makes such a lemming a faller. I gave up and spent today again about half an hour, before testing it again and realizing my mistake. Lots and lots of time wasted!
PS: I believe that my rewritten code already fixes this bug, too ;).

Nepster

Here is new experimental version of NeoLemmix, that in addition to namida's version, includes the following bugfixes:
- Basher turns at steep slopes (similar, but not 100% equivalent to the V1.43 behavior)
- Steel checks for turning around are always at correct height.
- Falling down has priority over turning, when both are applicable in one frame.
- Falling behavior is precisely the same as for walkers->fallers.
- Basher does no longer continue when steel is at height 6, but air elsewhere.

The fourth point breaks some of the replays, because now falling bashers are one pixel faster when falling down. So there is a 33% probability that they reach the ground one frame earlier, which may have the usual side effects that break replays.
For the NepsterLems replays approx. 5% of all replays fail due to this reason.

namida

In regards to a point about what slopes bashers should or shouldn't be able to ascend - perhaps it's worthwhile getting some feedback.

I've attached a map with slopes of various steepness (note that for 3:2 and 2:3, I've done two versions of each to test for any inconsistencies between whether the 2px or the 1px section comes first). This map isnt' quite in shape for the test map pack yet, but does use the style from it. http://www.lemmingsforums.net/index.php?topic=2591.0

What I'd like is if everyone could tell me which bashers they would expect to get to the top, and which they'd expect to turn around. For record - the correct order to assign the bashers is top-to-bottom, left-to-right (the lemming positions are slightly offset from each other such that, if assigned in this order, one per frame, they'll all start at the same position).

For the record, the results on V1.43n-E, and the two recent test versions (the newer copy of mine, and Nepster's):

V1.43n-E
The lemmings with the 1:1 slope, the 1:2 slope, and the 2:3 slopes turn around. All others pass.

My test version
All lemmings pass.

Nepster's test version
The lemmings with the 1:1 slope, the 1:2 slope, and the 2:3 slopes turn around. All others pass. (Same as V1.43n-E.)

I do need to add some more inbetween angles (4:3 / 3:4 and perhaps 5:3 / 3:5).
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)

IchoTolot

As I said in IRC:

My vote goes to the Nepster/ 1.43 E way, as the basher in the namida test version goes waaaay too steep for my taste.

Also this way the upwards behavior stays consistant ;P

namida

#25
One problem I have noticed occurs in the intended solution replay to Dodgy 16 of Lemmings Plus III (both the game and the replay can be obtained here).

Specifically, the basher who attempts to bash through the bottom-left part of the central structure.

In Nepster's first test version posted above, the basher, after moving downwards slightly, turns around. This is despite having one pixel remaining of his forwards movement, which has only a one pixel upwards step. Assign the basher a frame earlier, and the problem here becomes even more noticable. (Two frames earlier, and he doesn't encounter trouble.)

Nepster sent me a second test version which he hasn't uploaded here (EDIT: see post below). In this, although the basher doesn't stop at this position, he is still delayed, which seems equally strange.

Apart from this - and overall deciding what should be the limit - I do think Nepster's verison handles things very well, and the code is certianly much more readable.

In this case, the lemming has one pixel to step up ahead of him. If he were to take one step further forwards, the next would be a 2 pixel rise.

There's quite a lot of discussion going on on IRC in regards to both this specific situation and the basher behaviour in general. I recommend checking the logs (starting from about 18:04:15) for more details on what's being discussed.
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)

Nepster

Here is the version with the fix for the bug mentioned by namida, if anyone wants to test is.