Lazy Foo' Productions

SDL Forums external link SDL Tutorials 🐰SDL3 Tutorials🥚 Articles OpenGL Tutorials OpenGL Forums external link
Follow BlueSky Follow Facebook Follow Twitter Follow Threads
Donate
News FAQs Contact Bugs

Introduction

Last Updated: Nov 26th, 2024

Welcome to the third edition of Beginning Game Programming with SDL.

Why these tutorials exist

I was debating whether to even go through with this upgrade. Is it even necessary to make a game practically from scratch when engines like Unreal/Unity/Godot exist? Not really, but you do need to know how to do it.

I do realize that's a weird answer to that question, so let me explain.

Ever since in the post COVID tech/gaming industry layoffs, these tutorials have become more important. See, the gaming industry has always been super competitive and even before COVID it wasn't rare to see someone who managed to get into the game industry fall out after their first or second job. Layoffs were always looming around the corner and every industry veteran knew it was part of what they signed up for. However after 2022, it was a whole new ball game. Even for people who didn't fall out of the industry (and there were a lot of them), there were people who had over 15 years experience having to take entry level positions (which unfortunately also had entry level pay) after searching for 18 months.

However, there were people who did manage to do well even when the tech bubble popped because they had something a lot of the people who stuggled didn't: they had a strong understanding of lower level game programming. When I started out game programming, easily available engines like Unreal, Unity, and Godot weren't much of thing. In a way, it was a pain having to roll my own mesh rendering and physics engine code but it also meant I got a chance to learn how this stuff works. There's nothing wrong with using a ready made engine (if I were to self pubish a game, I would probably using an existing engine as opposed to rolling my own), but I have lost track of how many times I told students they need to understand the basics of how to make games without using a ready made engine only for them to shrug me off and now they are struggling in their careers. Because of the problem that so many students use ready made engines not as a tool in their wider game development toolkit but a crutch they're lost without, these tutorials have become more useful than ever.

Learning lower level game programming is like learning assembly. Much like you most likely won't encounter much assembly programming in the field (unless you're an engine programmer or build engineer in which case you are going to be using it on the regular), you still need to understand how it works because it is the foundation which everything is built on.

What I assume about you

I am basically going to assume you were I was at when I started working with SDL: just finished my intro to C++ course and wanted to make graphical games. You're going need to know math up to geometry (and if you want to be professional you'll need to know linear algebra at a minimum, I just wanted these tutorials to be accessible to high schoolers). You'll have to know the following C++ concepts:
  • Operators (+, -, *, /, ++, --, +=, -=, etc)
  • Controls (if, else, switch)
  • Loops (while, for)
  • Functions
  • Structs
  • Arrays
  • References
  • Pointers
  • Classes and Objects
  • How to use a template
  • Bitwise and/or
To make the code more beginner friendly, I may make some design choices that make code easier to understand but in a real world situation are probably not the best design choices. After some tutorials I will have addendums after the end for more advanced users to address any issues with sacrificing code quality for code readability. An advanced user is someone who has taken their operating system/computer architecture/compiler architecture courses and/or has experience with a pre-built engine and wants to get acquainted with lower level programming.

What are you going to learn here

If you're hoping these tutorials will teach you everything you need to get a job in the game industry, that is not going to happen here. That would take at least a thousand tutorials, and thousands of pages of content that is not specifically game programming related like operating system architecture and algorithm analysis. What this tutorial set will teach you is the basics on how to make your own game without a pre-built engine.

For 95%-97.5% of my game programming career, I have used some sort a pre-built engine. However, in the interviews I had to get through to get those jobs, I was never asked about how to use any specific engine. The reasons why were 1) anybody can go into the Unreal/Unity/Godot engine documentation and look things up if they need to 2) they care more that you know how they work than how to use them. One of the best ways to learn how to do engines work is by making games at a lower level. Some of you computer/electrical engineers are probably raising an eyebrow at the notion of C++ being considered low level, but when you can make games with Unreal Blueprint, rolling games with a low level API like SDL is considered relatively low level.

By stripping eveything out and leaving nothing but a thin wrapper API like SDL, you'll have to consider a lot of things the game engine handles for you. Once you learn how to roll your own game from scratch, you can then start looking into potentially rolling your own engine for a portfolio project. A custom rolled engine doesn't have to be in every portfolio, but a well desgined engine can be a strong centerpiece to a game programming portfolio. This tutorial set will hopefully get you off the ground so you can start on projects like these to help you stand out from dozens of portfolios that are just copying Unity/Unreal tutorials. You'd be surprised how many portfolios I reviewed that are copies of the same handful of engine tutorials.

By the end of these tutorials, you'll be able to make your Nasty Tetris Project.

What I mean by Nasty Tetris Project

Nobody wants to write bad code, but the fact is if you're learning you are going to have to write a lot of it in order to git gud. Rather than try to avoid making a disaster project that blows up in your face, I recommend to stop putting off the inevitable and go for a controlled explosion instead.

One of the biggest mistakes new game programmers is pick a project that is too large for their first game. They learn the basics of making graphical applications and then they go and try to make an RPG which is too big for a first project even if you're making a 8bit era RPG. Little by little the mistakes start piling up and by the time they realize that they have big problems with the fundamental architecture of their game, they have to throw everything out and start from scratch.

The only way to get good at software architecture is with experience and rather than trying to avoid the unavoidable fact that your code will be bad, you should lean into it and make a project you plan on throwing out. Tetris is as big a project you should go for before trying to make any project of size. Honestly, a simpler game like Tic Tac Toe or Black Jack would be a better first project but Tetris is definitely the ceiling for a 2nd or 3rd project. You're going to make your Nasty Tetris Project, you're going to hate the code base the moment you finish it, but you will have the experience you need to take on bigger projects.

Your goals for the Nasty Tetris Project are:
  • Get it done as quickly as possible. Your code is going to be bad, just get it done as fast as you can because you are going to throw it out anyway.
  • Get it done with as little code as possible. Overengineering is the destroyer of student projects. Don't try to do anything with 1000 lines of code when you could have done with with a 100.
  • Try to make it as bug free as possible. Just because the code is bad does not mean it should play bad. No matter where you are in your game development career, you should always be coding to get a good game in the players hands.
  • Don't bother trying to optimize it unless the slowness is somehow interfering with the user experience. You have to mess up pretty bad to get tetris to be slow on modern hardware. The fact is if you haven't made tetris yet, you don't know enough about game engine architecture to make informed decisions about optimization.
  • Remember: a game engine should always be as simple as possible. Yes, even complex behemoths like Unreal Engine do try to follow this to some degree.
This tutorial set is designed to get you to that hurdle of making a Nasty Tetris Project. Just accept the fact that the code is going to be garbage, don't worry about making your code as flexible or fast as possible, and just focus on getting it done.

Moving onto other engines

I generally recommend starting out with lower level game programming before using an engine like Unreal/Unity/Godot. It won't be the end of the world if you don't it's just that in my experience that when newbie developers use a pre-built engine first, they then try to rebuild all the class hierarchies when they roll their own engine which inevitably leads to over engineering (especially if they come from an opinionated engine like Unreal) when they should be focusing on getting their game done.

However, after you finish your Nasty Tetris Project with lower level game programming, I do recommend also making Nasty Tetris Projects in Unreal/Unity/Godot. I also recommending doing it in more than one engine, like once with an opinionated engine like Unreal and again with a less opinionated engine like Godot/Unity. This was you learn different ways you can potentially structure an engine. Oh and if you're wondering what I mean by an "opinionated engine", it means that Unreal tends to want to you to code things a specific way as opposed to Godot/Unity which is looser with how you interface with things. I wouldn't say one approach is better than the other but each approach makes certain things more difficult and certain things easier. By getting experience with both approaches, you can make better decisions on how to design your code.

After you're acquainted with lower level game programming, unopinionated engines, and opinionated engines you can really start diving into engine architecture (and hopefully by now you've taken your operating system and computer architecture courses). Then it becomes a matter of what you want to dive into. A lot of people dive back into lower level game programming so they can really learning how things work by rolling their own engine. Others start diving into existing engines to learn how they specifically work. It all comes down to what you are most interested in and what you think will help you most in your career.

On the importance of Cattle Projects

There's a saying in server programming: servers should be cattle not pets. When a pet gets sick, you take it to the vet. When cattle gets sick they uh... don't get taken to the vet (apologies to all the vegans out there). The reason they say this is because server failures are inevitable. Let's assume hard drive failures happen at a rate of 2% in the first year (it's probably higher than that). Imagine how many thousands of servers a company like Blizzard has. Let's assume they have 10,000 servers running. With a 2% failure rate, that means they will have 200 of those servers fail in the first year of deployment. That's not counting failure from bad power supplies, motherboards, RAM, etc.

Because your first few projects are going to be badly coded, you need to treat them like cattle. You'll want to crank out a Nasty Tic Tac Toe project or two, a Nasty Tetris Project in C++/SDL, a Nasty Tetris Project in an unopinionated engine like Unity or Godot, and a Nasty Tetris project in an opinionated engine like Unreal before getting to your pet project. I know this is hard because odds are you got into game development because you have a dream project you want to make, but you're going to be better off learning hard lessons on project you're going to throw out.

The problem I find is that in my many years in trying to help game programming students is that the number one thing game development students hate is learning. They just want to do and will look for any shortcut they can to avoid learning the boring stuff. Almost always it comes back to bite them in the butt like when they finally land an interview and don't make it past the phone screen because they can't do merge sort. Cattle projects are a good way to quickly get the boring stuff over with so you can move onto your pet projects.

Let's dive in

Now that you know what you expect to learn and the purpose of it within your larger game programming studies, let's get started.