Project

General

Profile

Bug #869

[Doom] E1M7 Comp Station column stuck

Added by mfnickster over 14 years ago. Updated almost 12 years ago.

Status:
Closed
Priority:
Urgent
Assignee:
Category:
-
Target version:
Start date:
2010-03-03
% Done:

100%


Description

There is a column that is supposed to raise/lower when you cross the sector threshold from the stairs. It's in a room near the lower left of the map. The column makes a noise like it's moving but stays up. If you can't ride this column up, there's no way to get to the secret areas in the sludge pits.

Running Beta Doomsday 1.9.0-beta6.8 on a MacBook Pro with Leopard 10.5.8, using Ultimate Doom DOOM.WAD.

Labels: Gameplay


Related issues

Related to Bug #1661: [Deathkings] Bad behavior of object in lift (mobj hitbox overlap)New2013-11-11

History

#1 Updated by sonicdoommario over 14 years ago

I have produced this all 3 times I have tested this out (twice on my desktop and once on my laptop) to confirm this too.

#2 Updated by danij over 14 years ago

Clearly when I attempted to replicate this last time around I must have been killing all monsters beforehand.

The reason the platform does not lower is because when it tries to it thinks the move is blocked by one particular Sergeant on it (index #11 - the top right of corner of the bounding box is precisely on linedef index #491).

Clearly this is not an issue in vanilla DOOM as the lift works. So, somewhere along the line we are rounding a calculation the "wrong" way (maybe the point on line side calculation?)

#3 Updated by rolandoftheeld over 14 years ago

This bug also occurs in E4M4: Unruly Evil. There is a lowering wall with three Pinky Demons atop it that does not lower when its trigger is activated. Using the "kill" command or noclipping into the wall to kill them will allow the wall to lower.

#4 Updated by skyjake over 14 years ago

(originally posted by anonymous SF.net user)

The result of P_BoxOnLineSide() is pretty much up to chance (i.e. rounding) if one of the corners is exactly on the line. The vanilla Doom engine used fixed point mathematics for all calculations while deng uses floating point. This is probably the reason why the Sergeant was considered to be entirely on one side of the line by the original game while deng considers one of it's corners to touch the neighbor sector. An easy workaround might be to minimally shrink the thing's bounding box before calling PIT_CheckLine(). I don't know if this could have any ill side-effects, though.

Of course it's a bit strange in the first place that Height Clipping is performed when moving a floor down (or a ceiling up). If anything the move will improve the situation for the affected things, i.e. increase the available headroom.

#5 Updated by danij about 14 years ago

Yes, I'm aware of the cause of this problem. I just haven't investigated a solution yet.

The problem with a load-time special case exception to the object's bbox is that all maps will be affected. Some, even within the original IWADs depend on the old calculation to decide their initial "stuck" state and I can see no alternative but do honour the original calculation (at least in a compatibility mode).

Similarly with the plane move height test, its counter-intuitive but DOOM depends on it. A lot of user made maps depend on its peculiar behaviour.

#6 Updated by skyjake about 14 years ago

(originally posted by anonymous SF.net user)

You mean there are maps that intentionally place enemies with one corner of their bounding box touching a line and that expect these to be stuck? If there are any those maps their behavior is currently undefined when playing them in deng. Shrinking the bounding box by a very small degree, e.g. by subtracting 0.1 from the object radius when filling the bbox for PIT_LineCheck(), would push the calculations for these corner cases towards the "safer" default, i.e. considering the object to be free.

I agree that honoring the original calculations would be a much solution, but this would require to convert the engine back to fixed point arithmetic. I don't know how much effort would be needed to do so.

#7 Updated by skyjake about 14 years ago

(originally posted by anonymous SF.net user)

Ugh, missing word. That should have been "honoring the original calculations would be a much better solution".

#8 Updated by danij about 14 years ago

Though such maps might not have been constructed that way intentionally, they certainly do rely on the old stuck calculation/behaviour.

I don't think its necessary to take such drastic action as to revert the whole map collision system to fixed point math. This would be my very last course of action.

A better solution would be a preprocessing step done during map conversion which actively looks for Things in this corner stuck situation. It would either flags them for special case handling or perhaps even move them out of the geometry they are stuck in.

#9 Updated by skyjake about 14 years ago

(originally posted by anonymous SF.net user)

I've done a little more research:

- Unlike I suspected the behavior of this particular map is not undeterministic in original Doom: If a point is exactly on a line the P_PointOnLineSide() function returns 1, meaning that the point is on the left side. Since most lines surrounding the moving pillar are defined counter-clockwise the left sides are on the inside of the sector and the enemies are considered to not touch the outer sector. If I flip any of the linedefs touched by an enemy the pillar is stuck using the original calculations, too.
It should be possible to reproduce the same effect using floating point calculations by comparing with a very small epsilon instead of zero in P_PointOnLineSide().

- prboom works around the issue by disregarding the height-clipping result when lowering floors. The original code is used only when the floor movement compatibility mode is enabled, e.g. for playing demos.

#10 Updated by skyjake about 14 years ago

(originally posted by anonymous SF.net user)

I've successfully tested my theory: I've changed the check in P_PointOnLineSide() to this:

return ((lY - y) * lDX - (lX - x) * lDY >= 0.000001);

Now, if a point is very close to the line it is considered to be on the left side. Using this change the pillar is free to move even in UV (four Sergeants).

#11 Updated by danij about 14 years ago

Good work, this is a much better solution as this test should use an epsilon in any case.

#12 Updated by danij about 14 years ago

However its not just this that uses P_PointOnLineSide so we'll need to check their behaviour isn't adversely affected.

#13 Updated by skyjake about 14 years ago

(originally posted by anonymous SF.net user)

BTW, my change does not fix the issue mentioned in Ronald's comment (E4M4): Those demons are clearly larger than the surrounding sector, so it's not surprising that they prevent the floor from lowering. What is surprising is that (a) the level works fine with the original engine and (b) deng treats the rightmost demon (the only one present in easy skill) different than the other two. Needs more investigation.

#14 Updated by danij about 14 years ago

Yes obviously that won't change but that is the desired outcome for that particular test.

#15 Updated by skyjake about 14 years ago

(originally posted by anonymous SF.net user)

I now found out why E4M4 works in the original engine while the floor is stuck in deng: The difference is caused by the order in which the lines are checked for collision with the map objects: The original code always iterates the lines in blockmap order. Linedef #280 (the solid wall behind the demons) is always checked before linedef #287 (the border to the moving sector). Since the demons are partially stuck in the back wall PIT_CheckLine() will return false and the iterator will stop before checking line #287, leaving tmfloorz unmodified.

Doomsday uses a different iterator implementation which checks #287 before #280 (except for the rightmost demon). Therefore tmFloorZ will be set to the height of the moving sector, reducing the available headroom to zero.

I hope I'm making sense. Should I file a separate bug report for this issue?

#16 Updated by danij about 14 years ago

Which branch/tag/version/revision of the source are you working with? I've recently (since the beta6.9 release) made changes to the tune of your findings when addressing a related issue in TNT.

#17 Updated by skyjake about 14 years ago

(originally posted by anonymous SF.net user)

I've been running all my tests with beta6.9. I now checked out the latest git version, and the behavior is exactly the same.
For reference, i.e. when I'm talking about the "original code", I'm using prboom 2.5.0 with floor motion compatibility enabled.

#18 Updated by danij about 14 years ago

It seems this is the change I was thinking of: http://deng.git.sourceforge.net/git/gitweb.cgi?p=deng/deng;a=commitdiff;h=23c1997664796699db5c8121d118a6e0047a3ff9

Clearly though thats not what we're looking at with this.

#19 Updated by skyjake about 14 years ago

The reason why the column doesn't lower is because the game thinks the mobjs on the raised floor are touching the walls they are next to. The edges of the mobj bounding boxes of the mobjs do indeed touch the walls (no intersection).

This was briefly fixed by the FRACEPSILON kludge in 1.9.7 unstable builds, but a better solution is needed.

#20 Updated by danij about 13 years ago

I have encountered this myself (only a couple of days previous in fact) however since then I have been unable to replicate the problem in subsequent play throughs.

#21 Updated by skyjake over 12 years ago

Raised to maximum priority as the issue has wider-ranging implications for playsim accuracy/compatibility.

#22 Updated by skyjake over 12 years ago

Offline comments from danij:

"It seems to me that you were on the right track with it being a precision issue, however I think its the blockmap generation algorithm which needs the epsilons.

Given that the algorithm is now logically the same as id's original yet the mobjs are getting stuck because their corner intercepts a linedef - it seems to me that the original algorithm placed said linedefs into blocks that wouldn't be touched due to the fixed point precision."

#23 Updated by vermil over 12 years ago

This won't be a technical comment, but on HeXen Death Kings, Map 35, there appears to be a similar case to the Doom E1M7 column, with an Ettin and a pillar that functions as a lift (sector 15 and thing 257).

The corner of the Ettin's hitbox slightly overlaps the lift, pretty much identically to the Sargeants on column in Doom. However he can move away freely, if alerted.

However, if the player tries to use the lift without alerting the Ettin, the Ettin suddenly jumps up to the lifts higher floor and the lift becomes stuck, as if Dday is confused about what sector the Ettin was in, when the player went to use the lift.

#24 Updated by skyjake over 12 years ago

Summarizing a little: these are the potential solutions to this issue:

1. Adjust blockmap so that the lines won't touch the mobjs in question (applying 16.16 precision), suggested by [/u/danij]; OR
2. Don't check for blocking mobjs when moving a plane downwards (as running out of space is impossible and crushing will never occur), suggested by [/u/inguin]. Needs a compatibility option?

#25 Updated by vermil about 12 years ago

Both options are needed.

1. For Vanilla compat

2. For Boom compat

Regarding 1.: I actually once made a simple Vanilla Heretic boss level that relied on the fact that the behavior was 1, to make a two stage boss battle involving Maulotaurs and then an on foot D'sparil.

#26 Updated by danij about 12 years ago

The logically correct solution to this problem is to use the original BLOCKMAP on game-side for collision testing.

#27 Updated by skyjake about 12 years ago

- assigned_to: Jaakko Keränen

#28 Updated by skyjake about 12 years ago

- status: open --> fixed
- milestone: v1.9.0-beta6 --> v1.9.10

#29 Updated by skyjake about 12 years ago

This has been addressed by applying fixed-point math to bounding box vs. line collision tests. It makes the behavior mimic that of the original DOOM, which used fixed-point math.

The blockmap iteration order had no effect on this particular issue. I examined this in the "vanilla-blockmap" branch: using the original blockmap data and iteration algorithm, the column remained stuck.

#30 Updated by vermil about 12 years ago

May I request this report be re-opened?

While the E1M7 Column in Doom1 and platform on Sump in HeXen DK have been fixed, this case I posted above on 14/5 hasn't been fixed:

'On HeXen Death Kings, Map 35, there appears to be a similar case to the Doom E1M7 column, with an Ettin and a pillar that functions as a lift (sector 15 and thing 257).

The corner of the Ettin's hitbox slightly overlaps the lift, pretty much identically to the Sargeants on column in Doom. However he can move away freely, if alerted.

However, if the player tries to use the lift without alerting the Ettin, the Ettin suddenly jumps up to the lifts higher floor and the lift becomes stuck, as if Dday is confused about what sector the Ettin was in, when the player went to use the lift'.

While this is on a deathmatch map (HeXen DK includes some DM specific maps), it's still indicative of an issue.

#31 Updated by skyjake almost 12 years ago

jumps up to the lift's higher floor

That sounds like a different issue. Please submit a new bug report, as this one is about the E1M7 stuck column.

Also available in: Atom PDF