Now that we have a good handle of some game development concepts, we can start to create our game. Let's talk about the libraries we're going to use and the game development philosophy we'll try to keep in mind throughout.
Here is an overview of some of the libraries/crates we'll use as we make our game:
||rendering, window management, events|
||random number generation1|
||data parallelism library2|
Important: Installing SDL2, SDL2_Image, and SDL2_ttf
To use the Rust
sdl2crate, you need to have SDL2 and its related libraries installed on your computer. Since we use the
ttffeatures of the
sdl2crate, you need to have SDL2_Image, and SDL2_ttf installed as well.
A summary for some common operating systems:
brew install sdl2 sdl2_image sdl2_ttf
# Add to ~/.bash_profile if not already present
# Ubuntu (note the -dev suffix)
sudo apt-get install libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev
If you run into any trouble or your operating system is not listed here, check out the links above for the complete steps.
By using separate libraries like this and having to combine them together, you'll learn quite a bit about game development that you wouldn't learn using a crate that has already done that work for you. These libraries are also quite stable and well tested. That means fewer bugs than the bigger Rust game engines that are still in development. A downside is that these libraries are a bit "lower-level", so you'll have to write a lot of your own abstractions. We'll go through the process of doing that, but it will require a little more coding than if we were using a full Rust game engine/framework.
Bigger frameworks like
ggez are essentially higher-level
abstractions over these kinds of libraries. The
amethyst crate in particular
is even designed as a set of libraries (called "bundles") that are composed
together similar to how we're going to compose libraries in this tutorial.
That means that you'll be able to transfer a lot of the knowledge you gain by doing this tutorial to those bigger frameworks if you decide to go learn one of them afterwards.
Game Development Philosophy
One of the most important things you should remember from this tutorial is:
Build your game in small increments or "milestones" so you stay motivated and don't set your expectations too unrealistically.
In other words, don't expect to output a complete AAA title in one hour. There is a reason that many really big games have hundreds or even thousands of people working on them. It's important to plan out your work in small steps so you don't get discouraged if you don't finish everything very quickly.
Another way to put this is:
- Go one step at a time.
- Work your way up to the vision you have.
- Don't try to build every part of your game all at once.
Some of this advice might sound really simple or obvious, but it is actually very easy to completely forget about it and try to do too much at once in your game. Especially when you are starting out, you do not want to end up in a situation where you have no idea what to do next because your code or your vision for your game has become completely unmanageable. Breaking things down into steps helps avoid this problem and makes developing your game easier.
We're going to follow this advice as best we can as we build our game.
Here are some of our milestones as we get started:
- get a window for our game to exist in
- get an image rendering in that window
- get a single sprite rendering from a spritesheet
- simple movement
- play an animation while moving
- scale to an ECS so adding more entities is just a matter of adding another entity (instead of duplicating code)
- get back to the same point we were just at using just the ECS (way more code, but also scalable)
- add a bunch of enemies (should be easy now)
- add movement to the enemies
- add the ability for the game to end when the character collides with an enemy
- add items so the game actually has a goal
- ...and so on...
This is a lot of steps, but each of them is relatively small. As we go through them, we'll build up into a complete game.
It's okay to have an initial list and then adjust it afterwards as you need to. What's important is understanding that your game is going to progress step by step. It's not going to look exactly as you imagined at first and that is okay. Keep working at it and taking small steps towards what you want to create.
Random number generation is actually an incredibly rich and complicated topic so Rust doesn't include an implementation in its standard library ↩
This crate will not be used initially, but it is really good to know about it because it makes parallelism very easy and that is incredibly important for games ↩