From some research, learning about build tools and graphics libraries is beneficial for my future roles in the games industry. This was a University assignment.
Published on December 18, 2022 by Amy Elliott
C++ Programming SFML CMake Project-Based Learning
26 min READ
With the time I’ve spent working in the Games Industry and building my career, I’ve learnt a lot, and I still am learning new things every day, and my experience has just made me much more aware and prepared to realise where my weaknesses are at.
Because I was at Jagex (Gower & Gower, 2000) for 3 months, I only briefly used C++ (Stroustrup, 1985) with Unreal Engine 4 (Unreal Engine, 2019), and C++ with a Proprietary Engine for Old School Runescape (Jagex, 2007), - I learnt a lot at Jagex, but I never got to the point like at Sumo Digital (Dunn & Woods, 2003) and Altered Gene (Gayle, 2013) where I’ve been there much longer so I got very used to the tools I am using.
Because of all of this, I feel I’m at a disadvantage now, because I’ve grown too comfortable with the tools I’ve been using at Sumo Digital and Altered Gene.
I was considering doing something in Unreal Engine, but I wasn’t really keen on that because I already knew how to use Unreal Engine, so I would rather push myself a bit more and do something else which didn’t include an engine.
So, before I began doing further research, my initial idea was to use a graphics library called ‘RayLib’ (Santamaria & Contributors, 2013), to recreate one of my older games, ‘Blocky Road’ (Elliott, 2020) (See figure 1), when I’ve been learning new engines, like Godot (Linietsky & Manzur, 2014) and Unreal Engine, I always like recreating this game, it is like my own ‘Hello World’ when I come to learn new game engines. Doing this also means I don’t get distracted by designing anything for the game, as that has already been done!
Figure 1: Blocky Road Screenshot
I did further research into RayLib by looking through the example code on their website, and I contacted a professional friend of mine to get her opinion on RayLib.
From my research, I figured that I should review my goals for this module again, as RayLib is quite high-level, which means ‘it will include all of the bells and whistles which would make things much too easy for this project’ (A. Smith, personal communication, 2022a), and I wouldn’t be challenging myself enough.
From here on out, I decided, as I was challenging myself more, I will change the project, instead of recreating Blocky Road, I will create something that can be made in 2D, with a lower-level graphics library. So, I wrote up a few game briefs.
I already decided that I wasn’t going to be using RayLib, so the other graphics libraries that I had in mind were SFML (Gomila & SFML Team, 2007) and SDL (Lantinga & Valve Corporation, 1998).
I found out about SDL through a YouTuber called PolyMars (Wismar, 2017), and two of his videos titled ‘Learning SDL2 in 48 Hours’ (PolyMars, 2020) and ‘Making a Game With C++ and SDL2’ (PolyMars, 2021).
I plan to make a 2D version of Gobblet Gobblers (Denoual, 2003) - Which is a board game, a bit like Tic-Tac-Toe (Tic-Tac-Toe, n.d.) with a twist, and that is that you have 3 sizes of gobblets and they can gobble up your opponent’s pieces if they’re larger than the one placed down.
My 2nd idea is I will be remaking a 2D game inspired by ‘Blocky Road’, with some of the same concepts but adjusted to work well in 2D with some more challenging puzzles, the downside to this is that it would require more design which isn’t what I want to focus on for this module.
My 3rd idea is making a puzzle game where the player needs to navigate an area to get to the end point without going over the same grid block again, there was a minigame I remember on Club Penguin (Club Penguin, 2005) called ‘Thin Ice’ which I was inspired by.
The idea I have chosen out of the three game briefs is Gobblet Gobblers, because I recently threw together a really small prototype of this game in Unity during a 3 hour game jam, I could go back to this code to break it down so I have a reference on one way of how I can design my systems, I also think this game is quite fun, and not too design-heavy, so I can focus all my time on my goals.
When it comes to picking the graphics library, there is never a perfect tool for the job. ‘None of them are better than the others, and they can all achieve the same things, but they do have their differences’ (A. Smith, personal communication, 2022b). But with this in mind, I shouldn’t be picking an API just because it’s a ‘favorite’, it’s important to be impartial and admit when something isn’t suitable for the job at hand, much like I did with RayLib.
I decided SFML would be the best for my project, and the reason for this is that upon googling ‘SFML or SDL’ there are A LOT of posts from people in my exact position not knowing which one to use, and reading through the many forums, this reddit comment goes into more detail:
One of the top comments explained that SFML is ‘More beginner friendly’, and ‘Has everything you need to make a simple 2D game.’ (Giacomand, 2020) Additionally, I have the book titled ‘SFML Game Development By Example’ (Pupius, 2015), and I’m enjoying studying from this book.
Whereas SDL is ‘not beginner friendly’ and ‘is used widely in the industry’ (Giacomand, 2020) On the official SDL website, there is a list of professional games produced with SDL, it’s well known in the industry, and also used for engines like Unity (See figure 2). So, it still is a graphics library that I really would like to learn more about.
Figure 2: SDL in the Unity Git Repository
Looking at my goals, I just want to focus on improving my C++ skill and confidence, so if I were to pick SDL, I would be going too low-level, unnecessarily so.
I will of course be playing around with both libraries, as they both interest me, but my focus for this project will be on SFML.
I decided it would also be a good idea to ask my mentor Kerry and my friend Ashley about their opinions on this.
I’ve been really inspired by the colour schemes in Dinosaur Polo Club’s (Dinosaur Polo Club, 2013) games Mini Metro (Dinosaur Polo Club, 2014) and Mini Motorways (Dinosaur Polo Club, 2019), I will be designing my games with their artstyle as a main inspiration.
Figure 3: Mini Metro Screenshot
In the end, I have chosen to use the SFML graphics library to make a 2D board game based on Gobblets Gobblers because this project would be the best project to reach my goals.
Beginning my work was the complicated part. There was quite a bit of setup involved.
I’ve worked with libraries before, so I knew how I can get SFML set up for development, but I wanted to go the extra mile and get this project working with CMake (Kitware, 2000), so I can control the games’ compilation process, and it also means that there is only ‘one configuration that works for many environments.’ (leinaD_natipaC, 2014) - Making things easier in the long run.
One of the reasons I decided to use CMake is because it’s relevant in the Games Industry, as demonstrated here on this Senior Games Systems Engineer role advertised (Jagex - Senior Game Systems Engineer, 2022) (See figure 4) - And if you search ‘CMake’ in the Unreal Engine git repository (Epic Games, 2022), you also get a bunch of CMake-relevant files! (See figure 5). I’ve seen first-hand variants of build tools used in a professional setting when I worked on Old School Runescape (Jagex, 2007), so, hopefully learning more about using CMake can help me when I apply to similar roles in the future.
Figure 4: Senior Systems Engineer Job Listing
Figure 5: CMake files’ in Unreal Engine
It took quite some time to learn about CMake, and get everything compiling with the SFML library linked up as there really isn’t too much documentation or forums on CMake.
I used a template CMake build file and changed it to suit my project. I will probably keep using this same file over and over again if I were to use CMake with another project, as my friend Ashley stated: ‘CMake is something that you write once and forget.’ (A. Smith, personal communication, 8 October 2022).
Setting up the CMake generation with the SFML project went smoothly though! It was mostly straightforward, as SFML has a tutorial on how to compile SFML with CMake! (SFML Team, 2015).
Using SFML in general was great fun, it reminded me of using PICO-8!
I was able to dive right into development, and my idea was I would start with a gamejam, so I can learn more about SFML first before diving into my final project - My focus for this was on SFML and not making clean code.
I decided to make a connect-4 game, and learnt a lot through that, like different parts of this code I can reuse, and refactor for my final project. Through reading extracts from the SFML Game Development By Example book and using the SFML Official Discord (eXpl0it3r, 2018) to ask questions when I came across issues, I eventually was able to make something that resembles a Connect-4 game (See figure 6) - And this YouTube Video (Amy Elliott, 2022).
Figure 6: Connect 4 Gamejam
From here, I decided to take the gamejam and strip it down into its core parts, making a template that I can use for each SFML game I make going forward.
I called this library ‘Inception Engine’, and learnt about how to make it a template on GitHub, so I can use it as such, and through using this tutorial on the GitHub docs (Creating a Template Repository, 2022), I was able to do that (See figure 7).
Figure 7: Game Engine Library Template in GitHub
When it came to making the final project, I was unfortunately not able to complete it within time, I had spent too much time on the Connect-4 gamejam, Inception Engine, and spent too much time making a start on the Gobblet Gobblers game, optimising and cleaning up my code as much as possible.
I am quite happy with what I have, even though it’s not a complete Gobblet Gobblers game, but I was able to produce:
I am happy with what I’ve got at this point with the Gobblet Gobblers game, as the code I have written is very optimised, and clean, which is contrary to the Connect 4 game, which had messy unoptimized code, due to it being a gamejam.
In my proposal, I stated I wanted to get more confident with C++, and writing clean code helps me reach that goal, as it allows me to explore the language!
The clean, and optimised code took me a while to write, whereas if I took the same approach to the project as I did with the connect 4 game, I’d have messy code which would be difficult to expand upon, and not have learnt as much, this is an important point which is made within the Clean Code book (C. Martin, 2008), I could take hundreds of quotes from this and them to be relevant here, but the ones that sticks out are ‘The clearer the author can make the code, the less time others will have to spend understanding it. This will reduce defects and shrink the cost of maintenance.’ and ‘the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …[Therefore,] making it easy to read makes it easier to write.’ (C. Martin, 2008) - Clean code is really important, so when starting this project, that was my goal.
I’ve not encountered too many problems that I thought were worth writing about, I’ve gotten used to doing lots of problem-solving, and fixing errors and bugs quickly without a second thought, so below are issues that have stuck out to me.
I decided to practice how CMake works, so I could get more confident using it, as it was an important skillset to have if I wanted to become a Senior Software Engineer one day, and one of the main problems I had was that I got this error (See figure 8) when trying to generate project files for an SDL test project:
Module path: C:/Users/amyel/Documents/_University/Year2/PRAPI/SDL_Project/cmake-modules/
CMake Error at CMakeLists.txt:17 (find_package):
By not providing "FindSDL2.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "SDL2", but
CMake did not find one.
Could not find a package configuration file provided by "SDL2" with any of
the following names:
SDL2Config.cmake
sdl2-config.cmake
Add the installation prefix of "SDL2" to CMAKE_PREFIX_PATH or set
"SDL2_DIR" to a directory containing one of the above files. If "SDL2"
provides a separate development package or SDK, be sure it has been
installed.
Figure 8: CMake errors
I used the same setup as I had used with SFML, so I wasn’t sure why it wasn’t working for SDL. I spent a while googling, everything was set up how it was supposed to be. Renaming the SDL2Config.cmake file so it can be used generated a different error (See figure 9):
Figure 9: CMake errors (2)
I was talking to my friend to ask if she had any ideas, and she made a few suggestions, but in the end, this was a rabbit hole, and it was wasting too much time fixing at this point, so I didn’t resolve it at the time. When looking back at this issue, I found a few forum posts where people have had similar issues, and a solution that I propose is that it could be the CMAKE file itself, something written in there incorrectly, specifically something to do with packages. I think line 17 isn’t written correctly, I thought of this because this forum titled ‘How to Solve this Parse error’ mentions “You cannot use Makefile syntax in CMake.” (Boeckel, 2022) - To debug, I would change this line, if this is unsuccessful, I’d look at another CMakeLists.txt file specifically for SDL to see how that’s written. Unfortunately, I don’t have the time to test this for submission.
When initially setting up the project, I had a small, and really silly mistake when linking SFML! I downloaded the wrong SFML library (A source library), which lead to issues when setting up the project with CMake. I fixed this by going to the SFML website and downloading another version of the library, thinking I just had a fault with mine, but then noticing the contents of the files looked different, upon trying out the new version, all the problems fixed themselves.
Had I not made the Connect-4 Gamejam game, or the Inception Engine library, I may have made more progress with the Gobblet project, but I feel it would’ve been much more complicated, as I wouldn’t have the confidence of using SFML from the gamejam, or a template to work on top of.
Additionally, I feel throughout this project, I could’ve managed my time better. At first, I worked well, I had a milestone plan for the project, as well as sprints, and that went well for a few weeks, but nearing the end of the module, I began feeling burnt out and was producing work of a lower quality than my standards. To combat this, I booked time off work closer to submission and brought a few self-help books to put me in the right mindset for work, these books titled: Hyperfocus (Bailey, 2018) and Deep Work (Newport, 2016). This helped me, but it was all quite last minute, had I noticed my burnout a bit sooner, I may have been able to produce more work.
At first, I worked well, I had a milestone plan for the project, as well as sprints, and that went well for a few weeks, but nearing the end of the module, I began feeling burnt out and was producing work of a lower quality than my standards. To combat this, I booked time off work closer to submission and brought a few self-help books to put me in the right mindset for work, these books titled: Hyperfocus (Bailey, 2018) and Deep Work (Newport, 2016). This helped me, but it was all quite last minute, had I noticed my burnout a bit sooner, I may have been able to produce more work.
To become more confident with programming in C++, I need to make sure I’m constantly getting feedback from myself and my peers on my work.
An example of this happening during development is during my first code review for Connect 4 when I implemented a destructor as soon as I read up about it, and when I looked at my code a few days later, I was confused. (See figure 10) I then had to look up what it meant again, but the whole process of learning, forgetting, and then learning again helped me solidify that knowledge.
Figure 10: Self-Code-Review
During my final code review, Ashley mentioned that I used a lot of ‘summaries’ everywhere (XML Comments) when documenting my code (See figure 11). We talked about how I shouldn’t have to use these, and I would do just fine using the normal comments. I didn’t know ‘Why’ until I looked further, and found out that XML Comments are used to ‘build API documentation which is readable by external tools.’ (TypeIA, 2014) - This is useful to know for future projects.
Figure 11: XML Comments vs Normal Comments
Ashley gave me a lot of useful tips on documenting my code, for example, in some places, I have some very redundant comments, and I should really spend some more time looking at other people’s documentation on their code, to learn some better practices to bring into my own code.
In general, a lot of my problems are solved by looking over my code, reading it aloud, and talking my problems through to my fish, and that makes me sound crazy, but sometimes, I have a lightbulb moment, where I figure out a solution because I’ve explained it aloud.
This doesn’t work all the time though, and the approaches mentioned below have been additional help, finding help by collaborating with other people.
During the workshops, we had standups every week, where we talked about our progress, any issues we have, and our plans for the coming weeks. During these standups, I learnt about other people’s projects, and I was able to help a few people with issues they have had, like:
These standups also helped me figure out whether I was on pace with my own project. Unfortunately, it didn’t really help past that, because the majority of my peers in the workshop were working on Unreal projects, meaning it was harder for me to collaborate with them.
I used the SFML official discord quite frequently when I needed help finding documentation, or figuring out how to implement certain functionality. The community is very active and has been a great help, it has also been a great way to network with other users of SFML.
An example of where Discord was useful was when I had an issue with my events, generating an error, and through chatting with a member on discord, I realised that I accidentally included something I shouldn’t have.
I wanted to have good code reviews for this project, because my goal was to improve my C++.
Throughout my jobs in the industry, I’ve done many code reviews, and have had my own code reviewed, and it really has helped me improve my own coding skills over the years. As I want to improve my confidence in C++, code reviews are the best way I can do that as well, as a good skill in the industry is to take constructive criticism on your own work.
When I completed my Connect-4 SFML project, I asked Ashley if she could give me a code review, and from that code review, I learnt a lot and reflected upon that within the Connect-4, whilst also taking some of those comments into consideration on Inception Engine and Gobblet Gobblers.
I even gave myself a code review, adding comments on things I’ve missed, and also things to learn more about, and reflect on. Unfortunately, I can’t contain the entire code review here as there is too much to talk about, but here are some important points which I took away from my first code review:
‘Take a look at the return type of loadFromFile - it actually returns a bool. One challenge you’ll have to handle going forward is error handling - what should happen if the loading for the file actually fails? There’s no right answer for this, but simply wrapping your initialisation logic with an if statement and logging errors is a good starting point.’ (A. Smith, personal communication, 6 November 2022)
From this feedback, I made sure I ran checks, and logged errors each time I ran loadFromFile, or any function that acts similarly.
‘Try to use const wherever possible - sf::Vector2u size can be const.’ (A. Smith, personal communication, 9 November 2022a)
As you may see throughout the rest of the projects, I ended up using more constants, as I realized many places which can use them
I shouldn’t have used Inline, and the reason why I had to use it was because I was including a .cpp file which I shouldn’t have. When removing that, I didn’t need to use inline anymore (A. Smith, personal communication, 9 November 2022b)
Taking all my code review feedback, I reflected upon it on my Connect 4 game. I asked Ashley for another code review once I had made my final changes to Gobblet Gobblers.
Again, there was a lot to reflect on, unfortunately, I didn’t have time to make all the changes she mentioned in the code review though, but this is all still very useful, as reading through her reviews made me realise many more ways I can improve and get stronger with C++.
I also have been able to demonstrate that I can adapt quickly, through learning about CMake and SFML in a short amount of time.
Bailey, C. (2018). Hyperfocus.
Martin, R. (2008). Clean Code.
Club Penguin. (2005).
Dinosaur Polo Club. (2013, May 1). https://dinopoloclub.com/
Dinosaur Polo Club. (2014). Mini Metro. https://dinopoloclub.com/games/mini-metro/
Dinosaur Polo Club. (2019). Mini Motorways. https://dinopoloclub.com/games/mini-motorways/
Dunn, G., & Woods, J. (2003). Sumo Digital. https://www.sumo-digital.com/
Elliott, A. (2020). Blocky Road. https://amy-elliott.itch.io/blockyroads
eXpl0it3r. (2018, April 19). Discord server. https://en.sfml-dev.org/forums/index.php?topic=23925.0
Gayle, D. (2013, September 14). Altered Gene. Altered Gene. https://www.alteredgene.co.uk
Gomila, L. & SFML Team. (2007). SFML. https://www.sfml-dev.org/
Gower, A., & Gower, P. (2000, April 28). Jagex. https://www.jagex.com/en-GB/
Jagex. (2007). Old School Runescape. Jagex. https://oldschool.runescape.com/
Kitware. (2000). CMake. https://cmake.org/
Lantinga, S. & Valve Corporation. (1998). SDL. https://www.libsdl.org/
Linietsky, J., & Manzur, A. (2014). Godot. https://godotengine.org/
Newport, C. (2016). Deep Work.
Pupius, R. (2015). SFML Game Development By Example.
Rev Rooms. (n.d.). Rev Rooms. Retrieved 13 December 2022, from https://www.revrooms.co.uk
Santamaria, R. & Contributors. (2013). RayLib. https://www.raylib.com/
Smith, A. (2022a). It will include all of the bells and whistles which would make things much too easy for this project, and I wouldn't be challenging myself enough [Personal Communication].
Smith, A. (2022b). None of them are better than the others, and they can all achieve the same things, but they do have their differences [Personal Communication].
Smith, A. (2022c). SDL doesn't handle graphics too well, so it would be much better for my purpose of just learning C++ to use SFML [Personal Communication].
Smith, A. (2022, October 8). No one understand cmake fully, we just use it. Cmake is something that you write once and forget, since its only done at the start of the project. Everyone just goes online and rips something and adapts it, never start from scratch [Personal communication].
Smith, A. (2022, November 6). Ashley Code Review: LoadFromFile [Code Review].
Smith, A. (2022a, November 9). Ashley Code Review: Consts [Code Review].
Smith, A. (2022b, November 9). Ashley Code Review: Inline [Personal communication].
Stroustrup, B. (1985). C++.
Turner, K. (2022). SFML is perfect for me as it's the middle ground of RayLib (Too simple, lots of bells and whistles) and SDL (Too low level, I'd be too bogged down doing graphics programming instead of just C++) [Personal Communication].
Unreal Engine. (2019). Epic Games. https://www.unrealengine.com
Wismar, J. (2017, December 22). PolyMars. YouTube. https://www.youtube.com/c/PolyMars