cotton.org.uk

AboutContributionsDownloadsMy GitHub

3D Game Engine

Short clip of walking through a corridor in the engine

For my university dissertation, I wrote a Raycasting First-Person 3D (or 2.5D) Game Engine in Java. The style is based on classic games of the genre, such as Wolfenstein 3D and DOOM. The project was initially based on a tutorial on Instructables, which I built upon and added several features to. My main objective was to produce a viable engine, designed for a hypothetical developer to create their own game from.

I explicitly targeted the engine side of game development, because I was interested more in the nitty-gritty of how a game works behind the scenes, as opposed to more surface-level aspects like level design. My Engine handles drawing pixels to the screen, based on a variety of Objects that can exist. For example, when the camera is facing a wall, it knows what texture that wall has, and writes appropriate colour codes to a 2D array based on the distance from the wall, as well as the angle. The end result is a believable world that you can explore and interact with.

Maps are generated by three simple text files, which represent where textures should be loaded. One file is for ceilings, another for floors, and another for walls. An extremely basic room with a dividing wall would look like this:

Walls FloorsCeilings
1,1,1,1,1
1,0,2,0,1
1,0,2,0,1
1,0,0,0,1
1,1,1,1,1
3,3,3,3,3
3,3,3,4,3
3,3,3,4,3
3,3,3,4,3
3,3,3,3,3
5,5,5,5,5
5,5,5,5,5
5,5,5,5,5
5,5,5,5,5
5,5,5,5,5

In the walls array, the entire room is enclosed with Texture 1, and there is a wall of Texture 2 protruding from the North side, with a space on the South side to walk through. Zeroes represent empty space, so the player (and enemies) may walk through this area.

The floors array mostly uses Texture 3 across the whole room, but the East side uses Texture 4.

The ceilings are simply a single texture throughout the whole room.

To explain textures a bit further: they are loaded by the developer at the start of their game and retain the load order, so the developer can identify which texture corresponds to each number.

Additional features I developed for the Engine include simple movement mechanics, such as jumping, crouching, and looking up/down. There is also weaponry, that can be used to fight enemies. Functional damage types are melee and hitscan. Hitscan damage works similarly to the way that the raycasting system does, in that a "ray" is calculated from the centre of the player's view, towards whatever is in front of them. If the ray collides with an enemy, then damage processing will take place, and if the enemy loses enough HP then they will die.

Despite my pride at receiving a 1st Class Hons grade for the dissertation of this project, there were several features & mechanics that I am dissapointed I never managed to finish. Part of the reason why I couldn't finish the features were time constraints and partly due to my other obligations at university, such as studying for my other modules. I wanted to render a viewmodel of the player's held item/weapon, as well as other HUD elements, like a minimap. There was also supposed to be a third type of weapon, which fires projectiles and would be used for weapons such as rocket or grenade launchers. There is no way to complete objectives and actually play the game, so it very much just feels like a sandbox. In theory, these features could be implemented by the developer themselves – but the point of the Engine is to streamline development of those aspects of the game, so it's a shame it couldn't be done in time.

This is a project that I may return to one day if the motivation arises. I would like to finish off the aforementioned features, fix some of the bugs and even develop some more features on top of that, should inspiration strike. It would be good to rewrite the project in a C-based language, such as C# or C++ – Java isn't really ideal for this sort of use. I would probably also release the code under Open Source, so that it's actually usable and modifiable by game developers.