Recreating DOOM in Python: Episode 4 – Walls

Welcome back to another episode of “Recreating DOOM in Python”! In this episode, we will delve into the fascinating world of walls in DOOM and figure out how to render them. But before we get started, let’s quickly recap what we know so far.

In DOOM, there are two types of walls: solid walls and portal walls. Solid walls are your regular walls, while portal walls are special walls that serve as windows and openings. To understand how walls work in DOOM, we need to understand two key concepts: line defs and sectors.

Line defs are formed by two vertices, and the segments we render correspond to parts of these lines. Each line def can have a front and backside depth which determines the textures for the walls. Speaking of textures, there are three types of textures in DOOM: middle textures for solid walls, upper and lower textures for portal walls, and cases where all three textures are applied.

On the other hand, sectors define the height of the floor and ceiling, as well as their textures. Sectors can be concave and are crucial for determining the rendering of walls. With all this background information in mind, let’s dive into the rendering process.

Recreating DOOM in Python: Episode 4 - Walls
Recreating DOOM in Python: Episode 4 – Walls

Rendering Solid Walls

To render solid walls, we’ll first need to define classes for side defs and sectors based on their structures from the DOOM Wiki. Additionally, we’ll add appropriate attributes for the segment and line def classes for convenience. We’ll also define methods in the wad reader class to read the necessary data for these lumps.

Further reading:  Test Automation: Enhancing Game Engine Programming with Unit Tests

Once we have all the instances of side defs and sectors, it’s important to update the data for each line def correctly. This involves determining the presence of front and backside depths based on the line def’s identifier. Keep in mind that segments have a direction, so side defs can be swapped, and we’ll need this information to determine the appropriate front sector for the segment. If the line def is two-sided, the segment will also have a back sector.

To work with walls, we’ll need two classes: a view renderer class and a segment handler class. The view renderer class will have methods for getting a random color and drawing a vertical line using the gfx module. The segment handler class, on the other hand, will keep track of the current segment and the angle to the first vertex of that segment.

We’ll pass the segments that are in the player’s field of view to the segment classification method of the segment handler class in the bsp (Binary Space Partitioning) class. This method helps us determine the type of segments we’re dealing with. We start with segments that don’t have a back sector, meaning they are solid walls. We’ll use the data from these segments in the method for clipping solid walls.

Clipping solid walls involves tracking the horizontal screen space filled by the nearest segments’ widths. Once the screen is completely filled with solid walls, we discard the remaining segments. This task falls under the range merging category, and you’re encouraged to explore various methods or develop your own algorithm to achieve this.

Further reading:  Instrumentation in Game Engine Development

Rendering Portal Walls

Portal walls, as mentioned earlier, are transparent and require special handling. In the segment classification method, we process segments that have a height difference for the ceiling and floor first. Then, we discard segments that serve as utility triggers in special events. Finally, we process empty walls that have a change in the level of light in their floor or ceiling textures.

When clipping portal walls, we use a similar algorithm to the one used for solid walls. However, in this case, we don’t affect the set of screen coordinates since we can’t draw anything on top of solid walls. When rendering portal walls, we render the upper and lower parts of the wall using the same method as solid walls.

Portal walls require us to draw what’s behind them, and we do this by rendering everything from near to far. To handle this, we use two screen height clipping lists that keep track of every y-height for every x-height on the screen. We consider a column completely opaque if the height values of the clipping lists are equal. Portal fragments only update the occlusion columns with what they cover in screen space.

With all this rendering magic, we can now partially render DOOM game levels in a peculiar, cartoonish coloring. We still need to implement additional functionalities, such as finding the height of the sector in which the player is located, to enable climbing up and down stairs. But as you can see, a lot of progress has been made in rendering the walls of DOOM.

Further reading:  An Introduction to PCF and Slope-Scaling in Hardware 3D

Conclusion

In this episode, we explored the world of walls in DOOM and learned how to render both solid walls and portal walls. We delved into the concepts of line defs and sectors, and we saw how important they are in determining the textures and heights of walls. With the right algorithms and techniques, we were able to render DOOM game levels, giving us a glimpse into the early days of game development.

Join us in the next episode as we continue our journey of recreating DOOM in Python and explore the loading of assets and texturing in DOOM. Stay tuned for more exciting and insightful content from the Techal brand!

FAQs

Coming soon…

References:

YouTube video
Recreating DOOM in Python: Episode 4 – Walls