Making a 3d game in assembly, introduction
This blog will cover the development of a game I’m making in x86_64 assembly.
In this post I will explain the game idea and why I choose to make it in assembly.
The game idea is based on Cities Skylines and Tycoon games. It came from my realisation when playing Cities Skylines that I spend most of my time optimizing the traffic flow in the city, since that is the most interesting part for me. So then I thought, why not make a game that focus more on that part and less on the other parts. It had the benefit of being a bit smaller in scope than a complete city builder which is important since I would create the game on my own in my free time at least to begin with.
With that introduction here comes the game idea explained on a high level. It will be a bit similar to a city builder, but simpler. You build a mall or entertainment centre. It could be made of some different shops or restaurants as well as clubs or cinemas and perhaps some hotels. Then you have to connect these to cities that are located outside the map of the game and then try to get as many people as possible to your facilities. The more places you have to visit the more people want to visit which leads to more traffic that your road network will have to support. The main challenge will be to build a good road network that can take enough visitors to keep your business afloat.
At first I considered using Unity for this project. Even though I did not want to use a garbage collected language having had enough of that in previous project Unity did sort of solve that issue with the new Dots architecture. But that was still new at that time and in the earliest previews still. This was at the start of the Summer 2019. So it felt quite uncertain if Dots would be done anytime soon and there were also rumours about Unity going public which made their future business model an uncertainty as well. In addition I did not really like the idea of using a general purpose engine since it often has overly complicated solutions for things since it has to work to create as many things as possible. While a custom engine for a game can take all the shortcuts to just solve things that is needed for this particular game.
I then thought, what if I go a bit extreme and use assembly. Is it even possible still? Why is no one doing it any more? These were questions I asked myself. I remember that Chris Sawyer used assembly to make his games transport tycoon and roller coaster tycoon. So I made some research on the subject while on a sunny vacation in Croatia. I came across the following series of articles on code project:
DirectX and Pure Assembly Language: Doing What Can’t be Done
So I read this series and was convinced that it was worth trying to make the game in assembly. So I spent the rest of the summer implementing Tetris in assembly and DirectX 11. It was a bit tricky at first especially since it took me some time to find a debugger to use and I never really got it working fully during the Tetris project. I did however get a good opportunity to learn about SIMD operations which is the key to good performance on a modern CPU. You can se a short video of the result in the video below.
After that exercise I felt that assembly was a tool that could be suitable to make a full game in and it would be a fun challenge as well.
The main benefit of using assembly would be that it is much more transparent around memory use and branching than compiled languages. These two things are what accounts for most of the time spend by a cpu usually in a program and should me minimized. Also the use of SIMD instructions is more clear in assembly than in compiled language as you can’t be sure if the compiler is smart enough to use SIMD instructions for your code without reading the assembly it outputs.
Now since I am a solo developer on this project and currently are working on it in my free time I needed to set some heavy limitations if I want the game to ever be done. Firstly I have chosen to go with a low poly art style. This is both much quicker to get going than a more realistic textured look, as well as easier to create. This means it will take much less time if I make the 3d models myself, or if I were to outsource it, it will be much cheaper than a more realistic look would be.
Secondly the game will be windows only. Mostly because of assembly and DirectX being my tools of choice, which means quite a lot of work would be required to port it to any other platform. But also because it is a reasonable limitation to set if you develop a game for PC, since it is where most of the users are. More platforms would increase the test space as well and most likely not worth the effort. The only other platform than Windows PC that would be worth considering given my choices and limitations would be Xbox, since that is basically a Windows PC when it comes to games from what I can gather so it should not be much of an issue to make that port.
A third limitation I have chosen is the game will only use static memory. First of all this helps the performance, since dynamically allocating memory during runtime is quite costly. And since this game is centred around performance this seems like a natural decision to make. It also has the benefit of making memory management much easier. Which is very welcome since there is not much at all that helps with that in assembly. With only static memory I don’t have to worry about null pointers or memory leaks. All my memory is pre planned and all there when the application is started. This does of course come with its own limitations and problems as with everything. Everything will have to have hard limits that are set during the build of the game which could make it a bit trickier to cater to different hardware requirements. The game will most likely use the same amount of memory no matter what graphics settings you use for example, unless I have different binaries for different settings or something, will need to do some thinking about some clever solutions for that issue in the future.
This has been the introduction of this game dev journey. In the next post I will start the recap of what has been done so far on the game since I started the project, autumn 2019.
For more frequent updates follow me on twitter or subscribe to our YouTube channel