Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
Never_Again

comp_floors voodoo

Recommended Posts

This is a split from the Can someone explain this to me? (Dummy-sector related) thread in Editing.

Here's the map of the problem area




S – switch action 71 "S1 Lower Floor to 8 Above Highest Floor", tagged to K and D1
R – room with yellow key (floor 2000, ceil 2128)
K – pedestal with yellow key (floor 2080, ceil 2128)
D1 – dummy sector, merged with K (D1 == K)
D2 - dummy sector (floor 2024, ceil 2128), model for D1
HK – Hell Knight (48x56) in closet (44x64, floor 2000, ceil 2128), facing east

There's is void around D1 and D2, and between R and HK.
Note that the closet is too narrow for the HK, whose bounding box overlaps 4 units into the closet door to the east.

The author's idea is that activating the switch S lowers the floor of the pedestal K with the yellow key to highest adjacent floor + 8. The highest adjacent floor is at 2024 (sector D2), as K and D1 have been merged into one sector.

However, the floor lowers as expected only in boom_compatibility_compatibility (-complevel 7) and higher. In -complevel 2, in Chocolate Doom and vanilla there's only a continuous sound of lowering floor.

The floor lowers as intended in vanilla compat if any of the following conditions are met:
a) -nomonsters
b) using the TNTEM (kill all monsters) cheat before or after activating S
c) opening the door of the HK closet
d) noclipping into the void between R and HK
e) replacing the HK with a monster with a more narrow bounding box (e.g. a Zombie or an Arch-Vile)
No, rebuilding the nodes with BSP or Zennode doesn't change anything.

As far as I can see, there's no connection whatsoever between the K/D1 and HK sectors to justify the correlation between the HK sticking through the door of the closet and the yellow key refusing to lower. And point d) throws another complication into the mystery.

I suspect some voodoo in p_floor.c causing undefined behavior when comp_floors is on:

  switch(floorOrCeiling)
  {
    case 0:
      // Moving a floor
      switch(direction)
      {
        case -1:
          // Moving a floor down
          if (sector->floorheight - speed < dest)
          {
            lastpos = sector->floorheight;
            sector->floorheight = dest;
            flag = P_CheckSector(sector,crush); //jff 3/19/98 use faster chk
            if (flag == true)
            {
              sector->floorheight =lastpos;
              P_CheckSector(sector,crush);      //jff 3/19/98 use faster chk
            }
            return pastdest;
          }
          else
          {
            lastpos = sector->floorheight;
            sector->floorheight -= speed;
            flag = P_CheckSector(sector,crush); //jff 3/19/98 use faster chk
      /* cph - make more compatible with original Doom, by
       *  reintroducing this code. This means floors can't lower
       *  if objects are stuck in the ceiling */
      if ((flag == true) && comp[comp_floors]) {
        sector->floorheight = lastpos;
        P_ChangeSector(sector,crush);
        return crushed;
      }
          }
          break;
Can anyone throw some light on this mystery?
Here's an edited version of the map, with the player start moved to the yellow-key room and the monsters there removed to help to focus on the problem at hand.

Share this post


Link to post
Never_Again said:

As far as I can see, there's no connection whatsoever between the K/D1 and HK sectors to justify the correlation between the HK sticking through the door of the closet and the yellow key refusing to lower.

Without even looking at the WAD, I can tell that the problem is not that the hell knight is stuck in the closet door, the problem is that the hell knight is stuck* inside sector D1. Remember that every point in the void is (as far as the BSP is concerned) still within one sector or another, and the void between R and D1 is evidently part of D1 (using a different nodebuilder may potentially affect this).

*Monsters and players stuck inside walls can still move freely, if they can move away from the wall in a single tic (which for a hell knight means less than 8 units).

(I was going to post this in the other thread a few days ago, except the problem was already solved and I figured the full explanation would be somewhat redundant.)

Share this post


Link to post

Thx Foxpup for explaining! I had a feeling that this has something to do with the void not being empty and now I can know for sure.

Share this post


Link to post
Memfis said:

Thx Foxpup for explaining! I had a feeling that this has something to do with the void not being empty and now I can know for sure.

I don't know if from the beginning you knew something about this that I didn't or are simply easy to please, but I wouldn't be comfortable saying I know something for sure without fully understanding it. Can you say you understand it fully now? If you do, maybe you could help Foxpup to explain all this to the old slow me.

Foxpup said:

Without even looking at the WAD, I can tell

Thank you for having a look at this problem. Now please bear with me for a page or two.
Perhaps you should have looked at the WAD closely, your explanation seems rather superficial as it stands. Maybe it's the wording or you didn't have the time or inclination to go into details, but I still don't understand it.

Foxpup said:

the problem is not that the hell knight is stuck in the closet door, the problem is that the hell knight is stuck* inside sector D1.

You may be on the right track here. The "floors can't lower if objects are stuck in the ceiling" comment in the code is the only instance of the issue being documented anywhere, AFAIK. Now it turns out that it's certainly not a complete description of the problem.

Foxpup said:

Monsters and players stuck inside walls can still move freely, if they can move away from the wall in a single tic (which for a hell knight means less than 8 units).

Now this is useful info, thank you. Using it as a jump-off point I found via making small test levels that a monster doesn't need to be too tall for the sector it's in to prevent the sector's floor from lowering. Having the monster's bounding box completely overlap the sector's boundaries in every direction also does the trick.
So "stuck in the ceiling" appears to be just a subset of the more general rule that could be worded as "the monster cannot move at all".
Perhaps this is all common knowledge among source port programmers — or at least those that are well-versed in the compatibility aspect of the code — but as long as it is not wikified in accessible form it is not general common knowledge. However, an informative forum post is a step in the right direction.

Foxpup said:

Remember that every point in the void is (as far as the BSP is concerned) still within one sector or another,

I can corroborate this. If you noclip outside a level and pass close to a secret sector, the game will award you a secret credit as if you actually entered that sector.

Foxpup said:

and the void between R and D1 is evidently part of D1 (using a different nodebuilder may potentially affect this).

This sounds more like a conjecture, albeit a plausible one. It's the "the hell knight is stuck inside sector D1" claim that I have a problem accepting. As I see it, it involves a leap of logic; yes, it explains why sector D1 won't lower, but it doesn't explain why the game thinks that the HK is in two sectors at once, as your reasoning appears to imply.

And then there's the complication of noclipping into the void magically allowing sector D1 to lower that you completely ignored in your explanation.

Foxpup said:

(I was going to post this in the other thread a few days ago, except the problem was already solved and I figured the full explanation would be somewhat redundant.)

I hope I succeeded in making it clear that is not. Certain links in your chain of reasoning are missing, these would need to be exposed for the explanation to be fully satisfactory.

edit: here's a seven-year-old thread that discussed a similar (same ?) problem and failed to provide a definitive answer:
Really odd bug in BARRACKS.WAD

The last paragraph of Vermil's post is of particular interest:

Vermil said:

Interestingly moving on top of the Sargeant in question without fixing the unused sidedefs/sectors moved him to ground level and caused the sector in question to lower normally. However when I moved away, the Sargeant jumped back up into the ceiling.

Share this post


Link to post

Something that's important to understand, and may be related here, is that not only are there various bugs and problems with the original P_ChangeSector routine in Doom (most of which Boom fixes), but also, it is *not* strictly based on what sector a monster is "in".

It checks all blockmap cells which partially contact the sector's blockbox, which is an area calculated from the furthest out of that sector's vertices in any X or Y positive and negative direction:

    // re-check heights for all things near the moving sector
    for (x=sector->blockbox[BOXLEFT] ; x<= sector->blockbox[BOXRIGHT] ; x++)
	for (y=sector->blockbox[BOXBOTTOM];y<= sector->blockbox[BOXTOP] ; y++)
	    P_BlockThingsIterator (x, y, PIT_ChangeSector);
In the case of a sector made up of two discrete disconnected areas, this may be checking and affecting objects which are nowhere near the moving sector.

Share this post


Link to post

Excellent! This is exactly the kind of explanation I was looking for — thank you, Quasar.
Only one issue remains unexplained: how the player noclipping into the void affects the problem sector. I suspect a debugger may be necessary to figure this one out.

Share this post


Link to post

Just for clarity, I made a pic:


The green box is the physical extent of the sector by its vertices; the red box is the area (composed of 128-grid-aligned blockmap cells) which is subject to movement checking, due to the green box being expanded into blockmap grid indices.

I can't really explain why noclipping into the void makes the sector move; I wouldn't normally expect that to improve the situation.

Share this post


Link to post
Quasar said:

In the case of a sector made up of two discrete disconnected areas, this may be checking and affecting objects which are nowhere near the moving sector.

Huh. I never thought of that. You just reminded me of the mystery of my concentric crushers, and I think you just solved it. Yup, it looks like things can be crushed by sectors they're not inside, if they're within the sector's bounding box.

Share this post


Link to post
Quasar said:

In the case of a sector made up of two discrete disconnected areas, this may be checking and affecting objects which are nowhere near the moving sector.

You know, the implications for this are enormous. For example, people now tend to join far away sectors for effects, sound relaying, etc. When id wanted sound to propagate, they would make "sound pipes" to carry the sound to other areas of the level. But, nowadays, it is commonly-taught wisdom to just join those separate rooms, which can make a HUGE bounding box.

I never really thought about it before. I wonder what careless sector joining can do to performance. I'm interested to know what other people think about this.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
×