# Wolf 3D

Wolfenstein 3D (shortened as *Wolf3D*, dubbed the "grandfather of 3D shooters") is an acclaimed and celebrated [first man shooter](fps.md) video [game](game.md) created by Id Software in [1992](90s.md) (released for MS [DOS](dos.md), as [shareware](shareware.md)), the game credited for pioneering 3D shooters and overall helping video games reach [mainstream](mainstream.md) popularity. For its portrayal or violence and [Nazism](nazism.md) (albeit in the role of the enemy) the game was surrounded by numerous controversies, and still it may be yet more noteworthy for its at the time incredible [raycasted](raycasting.md) graphics redered from the protagonist's point of view, featuring fully [textured](texturing.md) walls and animated [sprites](sprite.md). At the beginning of the 90s this was deemed unprecedented realism, and it came from the hands of the brilliant programmer [John Carmack](john_carmack.md). Despite the game achieving considerable success on its own, in retrospect it's remembered more and more as the first of many legendary games to come, mainly for having paved the way for its direct successor that was none other than [Doom](doom.md), the most influential game of all time. Wolfenstein foreshadowed the coming of a new era, it set the scene and brought us the FPS formula, even if in a rather primitive form. While yes, Doom undeniably turned out to shine as the true masterpiece, deservedly earned all the glory and stayed a timeless classic still actively played to this day, Wolfenstein became a little forgotten in this regard, being a much simpler and humble game, and yet it's the game to whom Doom owes everything.

{ Some good resources on the technical aspects of the game are the book *Game Engine Black Book: Wolfenstein 3D* and the ECWolf wiki at https://maniacsvault.net/ecwolf/wiki/Main_Page. ~drummyfish }

It will surprise no one that **wolf 3D is [proprietary](proprietary.md)**, but like with other Id Software games the engine's source code at least was later on (1995) publicly released, firstly under "[non-commercial](nc.md) use only" terms, and then allegedly under [GPL](gpl.md), i.e. [free as in freedom](free_software.md). Information about this is scarce and SUS, apparently Carmack one day proclaimed "yeah, consider the code GPL", and god only knows if this is legit. At any rate based on this code there was a modernized port created, called *ECWolf*. But it may not even matter than much as almost no one actually plays the game unironically anymore, Wolfenstein's legacy is more in its [historical](history.md) significance, in its influence and [cultural](culture.md) impact.

It's fair to note that the game was neither the first shooter, nor the first game with such amazing graphics, Catacombs 3D for instance had practically the same graphics and game mechanics. Wolfenstein was ONE of the first and its legacy mainly lies in the execution of the idea, its success and influence.

The game was met with hilarious [censorship](censorship.md) as there are swastikas everywhere and one boss is literally [Hitler](hitler.md). Germany and Nintendon't understandably couldn't allow kids to see Hitler, so they replaced everything, blood became sweat, [dogs](dog.md) turned into mutant rats etc. That should save the poor little children souls, best if we make them think Hitler never existed. It's also [funny](fun.md) that some guys made mods that replace the Nazis with [Jews](jew.md) :D Quite ironic is also the fact that the Wolfenstein engine was subsequently licensed for games of completely different nature, for example *Super 3D Noah's Ark*, a 100% peaceful Christian game where the player throws food at animals to make them sleep.

**Storyline**: what? What storyline? Ah, yeah, you're basically a guy trying to escape from a castle full of Nazis, you encounter guns and hallways and you must kill everyone, there are also occasionally mutants and big guys AKA bosses. That should probably do.

## Code/Engine

The game is written in [C89](c.md) (with some bits in [assembly](assembly.md)) and consists of 70 files that count roughly 30000 [lines of code](loc.md) (depending on how we count). Formatting and [comments](comment.md) look like garbage, tabs are mixed with spaces and stuff, a bunch of empty lines suddenly appear for no reasons, inconsistencies (sometimes a function is called like `f ()`, sometimes `f()`), also great many ifdefs everywhere etc. Yep, there are [gotos](goto.md) too.

System requirements were 528 KB [RAM](ram.md), 3 MB of disk space and 286 CPU (8 MHz).

Compared with Doom, Wolfenstein's code shows considerable [shittiness](shitty.md), for example in that the engine **isn't [deterministic](determinism.md)** and literally **uses [floating point](float.md)** (although it looks like float is only used to precompute tables and that actual real time logic then uses [fixed point](fixed_point.md) arithmetic, but still the [dependency](dependency.md) is there). Apparently there are slips and fails such as the pseudorandom number table not containing certain values, item pickups being part of rendering code (so items can't be picked up moving backwards), or a hardcoded FPS for demos due to the fact that with variable FPS the game isn't deterministic.

Wolfenstein's **rendering** is arguably the most commonly discussed part of the engine, and possibly the most substantial one. It uses 1 dimensional [raycasting](raycasting.md) (see also [raycastlib](raycastlib.md)). Textured walls, sliding door and movable walls were implemented; floors and ceilings were not textured. It goes without saying everything was rendered [purely in software](sw_rendering.md), [GPUs](gpu.md) as known today didn't exist yet. The levels were represented as a 2 dimensional [array](array.md) of cells against which rays were cast from the player's position -- every screen column would have one ray cast per rendered frame. The ray was then traced with the [DDA](dda.md) line drawing [algorithm](algorithm.md) to find intersection with the closest wall. The intersection then determined how tall the wall would appear in the corresponding screen column (based on the [distance](distance.md) and perspective), as well as which part of the texture should be used for the column etc. Each wall texture had two versions: lighter and darker, each of which was used for different wall angles to create a primitive but [effective](good_enough.md) illusion of lighting. Level geometry was naturally limited by the square grid: only 90 degree walls could be placed, there weren't any stairs, walls of different heights etc.

The game used a [256](256.md) [color](color.md) [palette](palette.md). This allowed quick fades of the screen by simply modifying the palette.

A lesser known piece of trivia is that the [SNES](snes.md) port of Wolfenstein actually used [BSP](bsp.md) rendering instead of raycasting (source: *Black Book: Doom*), i.e. the technique subsequently used in Doom -- this was due to poor performance of the DDA algorithm, and the fact that BSP worked so well is actually why Carmack went on to use it in Doom.

[Sprites](sprite.md) were additionally rendered on top of the environment to represent enemies, items, decorations such as tables etc. Only sprites in the squares visited by the raycaster were drawn, from the furthest to nearest. The sprite's on-screen size was given by its distance from the player, as per [perspective](persepctive.md). The sprite was then drawn by columns and visibility was ingeniously solved by comparing the sprite's scaled height with the height of the wall in the same column (as the wall's height effective encodes its distance, so this is basically a 1D [z buffer](z_buffer.md)).

To quickly scale sprites and wall textures a clever [optimization](optimization.md) was used, called *scalers*. A scaler was essentially compiled code that would take an image and draw its scaled version without any parameters, branching or condition checking; the point is there was a scaler for every possible "stretch", so this is a kind of precomputation sacrificing memory to win speed. Precomputation is after all a theme present in the whole engine, just like in Doom -- there is a precomputed [sine](sin.md) table, table of [pseudorandom](pseudorandomness.md) numbers etc.

[AI](ai.md) is based on [finite state machine](fsm.md). Enemies always occupy a single square -- when changing square the motion is [interpolated](interpolation.md) to create an illusion of smooth motion. Thinking actors are represented by `objtype` struct. There is one remarkably advanced feature to the AI system: sound propagation. Enemies can be awoken when they hear a noise and this takes into account separate rooms and closed/open doors. This was again made possible by a precomputed table that marks parts of the map as "acoustically connected".

**[Interesting](interesting.md) places in code**: `ID_US_A.ASM:19`: pseudorandom number table; `WL_MAIN.C:1586`: the C main function; `WL_GAME.C: 1233`: game loop; `WL_PLAY.C:1368`: play loop (funnily there is a hint of some kind of [virtual reality](vr.md) support? See the variable `virtualreality`); `WL_DRAW.C:1336`: the raycasting function.

## See Also

- [Doom](doom.md)
- [Anarch](anarch.md)
- [raycasting](raycasting.md)
- [raycastlib](raycastlib.md)
- [Duke 3D](duke3d.md)