I thought I was going to be a game developer growing up. It always sounded like the best job. Getting to make amazing worlds and work on different interesting problems every day. Little did I know, I would be 10 years into my career before I would find game development fascinating and find myself jumping in.
This isnāt the first time Iāve tried making games. Iāve attended summer classes at DigiPen, messed around with Unity in college design class, downloaded the Unreal Engine a number of times, and even made a web-based game called Our Story. None of these pulled me in and I found myself spending more time coding websites for large companies than building games.
What repulsed me was the game engine. When you try to learn game development the first thing people try to do is give you a box of tools and tell you to make something simple. The tools are all context specific and require a deeper understanding to use. You end up spending a lot of time trying to figure out the nuance of each tool, how it works in this system, and come away with understanding of only how this specific engine works. I found this endlessly frustrating.
It was overwhelming having to learn an entire system manual to start making anything and who even knew if I was learning the right engine. With Unity and Unreal changing over the years, something you learned how to do last year might have gone out of date with the latest changes. I couldnāt find the reason to invest in these systems because that investment always felt short lived.
But something changed recently, a friend asked me to work together on a game from scratch in C++.
Iām not a huge lover of C++ or Object Oriented programming and thereās hesitancy there. But I loved C and have been programming in JavaScript for so long that itās been a nice change to be working in a more powerful language. C++ has changed a lot over the years and Iām enjoying the more modern syntax Iām used to seeing. Lastly, I love working with people and the idea of trying to work to make the game we wanted to create when we were kids sounded like a fun challenge.
Getting Started Again
I jumped in and started poking around with C++. I recently cleared out my bookmarks that I had made from college and came across a few bookmarks for SDL including a tutorial series by Lazy Fooā. That looked like a good enough place to start.
So I jumped in and started figuring things out as I went through he tutorials. Early on I had about a dayās worth of struggle trying to get CMAKE to work after fighting against the Frameworks files on the command line. Eventually, after much Googling I arrived at a place where everything was building inside of CLion.
Once I made it through a number of the early tutorials about how to pull in textures, render textures from sprite sheets, and basic keyboard event handling I wanted to see what I could do with these learned skills. Our game is going to be an isometric style game where the camera is tilted at an angle. I found a very cool asset pack on itch.io by Exuin and started playing with things to try to get the display working.
As I started bringing in the different assets from the sprite sheet, I realized that I was having to write a lot of the same commands over and over again. Custom adding all these details in C++ was painful and I knew I didnāt want to make changes to C++ code every time I wanted to make a change. So I created a CSV file and created the configuration there.
Writing a parser for the CSV file was painful since many of the solutions were involved or required libraries but eventually I found a simple solution that worked well for me. Eventually Iāll optimize it but for now it works for my needs.
Iāve learned that over-optimization is the enemy and youāll likely not need the speed except in a few cases. When it becomes a problem, Iāll circle back. And the best thing about a simple solution is that no-one feels bad when you throw it away for a better, faster, or even a simpler one.
The other thing I realized is that C++ had taught me a lesson. CSV or TXT files are better for configurations of data. This pretty true and the thing is, JavaScript makes it too easy for you to nest all those configurations in your code. Once itās in the code itās sticky and it becomes hard to change how the file is used. You become attached to the way things work and it stops being configuration. It just becomes code.
After writing the CSV file for the tiles that go into the map I wanted to make something move. I decided I wanted to light a block on fire and have it animated. Once I downloaded the files, by Sanctum Pixel, I saw that many animations were done with a number of individual PNGs. I didnāt want to have to load each one of them as an individual texture in C++ and so I started looking for a way to build them into a sprite sheet.
Iād poked at Aseprite and had that bookmarked from an earlier exploration of game design. Once I downloaded and played with it I knew Iād be using it a lot on this project and bought a copy. This helped me get this cool fire animation working on the page.
Learning More
At this point I felt like Iād gotten pretty far along what Iād learned and I circled back to the tutorials. After learning about handling mouse click events I used those to update tiles on the map when I clicked on them. The math for this took a while as I needed to map my coordinates from screen points to map points. Getting that locked in was one of the most satisfying feelings Iāve had on this project.
Recently I worked to get a character to walk around this space Iād created. For this I needed to get back to my trigonometry and linear algebra days of mathematics. A heavy reliance on math concepts is essential when youāre coding an engine from scratch. I eventually got a character to walk from one point to another although there were fun times when my equations were off that Iām too embarrassed to discuss further.
After getting the character walking in a straight line I wanted to be able to move them wherever I wanted on the map. This took way more work to do. I needed to load up new sprite sheets for each direction that the character could move and I needed to switch sheets depending on which way they were walking.
To do this I introduced another CSV to store all the different directions and texture sheets for the character. I wrote a function to determine the direction that the character should be facing and update a variable that could be read at the time when I rendered their sprite. It took a while to refactor and get the math right but Iām super satisfied with the way things turned out.
A Brief Review
Iāve barely touched on everything that I want to try out. Iām having a blast building things and have many ideas that I want to make into something cool. Itās still funny to me that having fewer tools makes me feel more creative. Iām having a great time building things and Iām excited to keep learning and improving.
Eventually I do see myself converging on the games industry best practices around entity systems. I know I havenāt built things in the best way but the way Iāve built them have helped me learn and see the details of how things work. Itāll glean light on why the best way is the best. Thatās what small projects are for: Learning. And learning is whatās fun!
If youāre interested in seeing the progress or trying out the code Iāve put together you can try that out here on my Github repo. I hope it inspires you to give old C++ a try or find a new way to learn something youāve always wanted to try out.