No More Levels Map Files

Engine Design

The NML engine is a small, compact raycasting engine that has been under development for some weeks now with the soul purpose of being a usable retro game maker. The engine was modeled after the Wolfenstein 3D engine in the methods and algorithms it uses to calculate the graphics, but takes a more modern approach when it comes to object handling and scripting. Using a basic 2D map file, and some lua scripting, the game generates everything it needs to run on the fly. No 3D models, no shaders, just a few basic scripts and a map file and the game will run.

Making Mapfiles

The map files in the NML engine are a slightly updated map file from a 2D engine I programmed several years ago. This eliminates the need to completely rewrite a file parser and map editor. After some light tweaking, the level creator and loader base was ready.

The current tile editor for NML Engine

With this tweaked map file and editor, I could create levels as easy as drawing in Paint, and the Raycasting engine would do the rest of the work turning it into a 3D environment.

An island map in the NML engine

 

As a programmer I am often worried about how things like the map file or parser look. Is it easy to tweak if needed? Is it easy to read? Well yes. Yes it is! The map file is written in chunks. It starts by writing the header data. After that, the locations of the textures. The rest of the map file is a 2D array of integers defining what tiles go where on the map.

A snip of the NML level file.

Limitations of the Map File

In an effort to preserve usability and simplicity, this engine has a few hard-coded limitations. Effects are one of the main limitations. Because shaders are not quite possible when Raycasting, every effect must be hard-coded directly into the rendering routine. Therefore, any effects that are needed require a change to the engine itself.  Currently there are several effects already in the engine that can be selected by applying an effect number to tiles in the map editor. These effects include reflections, water ripple, or corruption.

Another limitation is the lack of hard-coded collisions for non-wall objects. Because the walls are drawn based on whether a tile has collisions or not, if an object is to be drawn as a sprite, floor, or ceiling tile, it cannot have collisions hard-coded through the raycasting routine. There are simple work-arounds such as programming the collisions into a game script, but this is slightly inefficient. I have been working on modifying this aspect of the level file, but in it’s current state, that limitation will stay.

 

All About Raycasters

What is a raycaster?

A raycaster, or raycasting engine, is a method of creating a 3D perspective image without using any actual 3D polygons. Raycast engines typically use a 2D map to generate their 3D worlds. This is done in real-time and uses very few resources. This makes it an, albeit crude, but very fast method for showing basic 3D graphics. Games such as Wolfenstein 3D, and to an extent, Doom used raycasting engines to create their definitive style.

Raycasting works by checking lines for every X coordinate on the screen for how far away the nearest obstacle is. Then, depending on the distance, we draw a vertical line at the current X coordinate on the screen at a height relative to the distance from the camera.

What are the benefits of a raycaster?

Well, the short answer is that there aren’t any anymore. Raycasters were developed in a time when computers didn’t have powerful graphics cards and almost all graphics calculations were done on CPU. This makes the raycaster a very CPU intensive program. This means less power is able to be devoted to AI logic, player logic, and game scripting. The programmer has to be very careful with what he adds to a game because every new line of code beyond the raycaster itself will drop the framerate of the game.

If there are no benefits, why do they still exist?

Honestly, raycasters exist as more of an experiment or programming challenge these days. I personally enjoy working with raycasters because of the unique way that they work and the specific challenges they pose. Experimenting with visual effects is rather different when manipulating every individual pixel is possible BEFORE it’s drawn. To someone who’s used to GLSL or HLSL, raw raycasters are a beast of a different color.

No More Levels Raycaster Reflection Demo

For example, above is a raycaster I have been working with for a bit of time now. It is currently demonstrating it’s reflective capabilities. If you are familiar with other graphics programming, you might understand how most real time reflections work. Either by ray-tracing¬†or by render targets. This demonstration uses neither. Instead, it draws the walls first. left to right, top to bottom. However, for every pixel it draws, it draws a duplicate offset by a set value on the Y axis. This essentially creates a 2-unit high wall with the lower half below the floor level. Next is drawn the ceiling. No special effects here, just some perspective projections. Then comes the floor. This is drawn the same way as the ceiling, but with a set opacity level to allow the lower half of the walls to show through.

Epilogue

Although raycasters are outdated and clunky, they still manage to enthrall myself and many other programmers alike with their challenging simplicity. Further into the future I hope to be posting more about my exploits with the No More Levels raycaster and how it works.

If you’re looking to do more reading on how Raycasters work, please check out the site that I used to study the workings of raycasters.

http://lodev.org/cgtutor/raycasting.html