Hitscan attacks hit invisible barriers in large open areas

From DoomWiki.org

Spider Mastermind's attacks are blocked by an invisible barrier

Sometimes hitscans may hit an invisible barrier. This is caused by the fact that Doom has some difficulty handling the collision of bullets against very long walls. Projectiles will not be blocked by this invisible barrier, but it does block autoaim, potentially making projectile shots miss.

As a rule of thumb, a good habit for map developers is to break long walls into linedefs shorter than 2048 units long, which will also reduce the visibility of the long wall error at the same time.

Technical explanation[edit]

The bug is caused by fixed point overflow during arithmetic on large distances.

When a bullet is fired, its path is checked for nearby linedefs. This is done via the blockmap wherein each block has a blocklist, a list of linedefs inside that block. Each block in the bullet's path each have their linedefs checked for intersection with the bullet path, using the function P_PointOnDivlineSide that treats both lines as if they were infinite in length, meaning even walls behind the player may be checked.

The distances between the bullet's path and a linedef's vertices are used in the function P_InterceptVector in p_maputl.c for calculating a relative distance from the player (the start of the bullet's path) to the point the bullet hit on the linedef. The relative distance numbers are sorted from lowest to highest, and the wall with the lowest is what the bullet hit.

There are two kinds of linedefs that lead to overflow when a bullet is shot in their direction:

  • Linedefs that are exceptionally long, such as the south hallway of NGS1.WAD, will cause arithmetic overflow when the player shoots in blockmap tiles containing these linedefs. They consistently have overflowing relative distance calculations, meaning that shooting them leads to bullets passing through them or hitting the air in front of them, making it possible to hit targets on the other side (or miss targets in front). This anomaly is local to the blockmap tiles containing such linedefs.
  • Linedefs that are exceptionally far away but are checked for some reason anyway, such as on E3M6, can cause arithmetic overflow, especially if they are very long. They may behave normally when the player is close, but linedef length combined with a bullet shot far away can lead to overflow and bullets being blocked in the air. This is typically due to the linedef 0 problem, detailed in the Linedef 0 section, in which case it is an anomaly global to the map regardless of blockmap tiles.

Linedefs with relative distances calculated to be behind the player are discarded, but due to overflow they may instead be calculated to be ahead of the player, meaning aiming in the opposite direction of the linedef can also risk hitting it. This can be seen in E3M6, where both sides of the invisible barrier can be shot, as long as the bullet path line extended infinitely in both directions intersects the overflowing wall.

Since the invisible barrier is the overflowing linedef itself, it also has this linedef's properties; if it is a shootable switch, it can be activated by shooting the invisible barrier, and if it is pressable, it can be activated by pressing the invisible barrier. Because shooting and pressing have different ranges, they overflow with different relative distances that require each their own positioning. The chainsaw has mostly the same range as the use action and may be helpful in locating pressable invisible barriers due to it creating smoke when hitting walls.

Linedef 0[edit]

Most blockmap-building tools (an exception being ZokumBSP) used for map creation, including those used for building the official maps, pointlessly include the first defined linedef, linedef 0, in each blocklist, meaning maps built with these tools have this linedef always checked in some capacity even if it is very far away from a bullet's path.

If the player shoots in the direction of this linedef from anywhere on the map, its relative distance will be calculated and an overflow will likely occur if the linedef is long due to the combined large distances from the bullet's path and the distance between the linedef's vertices.

Demo files[edit]