Recently I have wanted to address three goals that I set for myself for game side projects that I work on:
- More rapidly create my own small games and prototypes.
- Develop a custom framework to use instead of any existing third party game engines.
- Write more about projects that I work on.
I thought about how these could be combined into a single overall plan. This resulted in the decision to start making small game prototypes that I will build in a custom game framework and to blog about progress on a regular basis.
Racket is a simple game that I have been building the initial framework around
Using my own game framework for these games allows me to keep full control and understanding over the technology used to create them, with the ability to completely change how parts work when required.
Using a custom framework gives quite a few benefits including being able to port the games to any platform I wish in the future (pending the time taken to do the porting work), and being able to change how the simulation or rendering is handled directly in the framework depending on the needs of the game idea and any unique requirements it might have.
There are also downsides to building your own framework such as potentially falling into the trap of attempting to build a general purpose game engine instead of working on the games themselves. The necessary time required to build the new framework features required for each game in addition to game specific code also requires more time.
To help ensure things go well I am going to only build the features and tools that each game requires when the need arises. The evolving framework will also be used more as a starting boilerplate with each project rather than something that is directly shared by each game. This should reduces the potential for complex dependencies between a single framework codebase and multiple game projects which would require maintenance on each game when a framework feature changes. I will also blog/release on a fairly regular schedule to keep myself on track.
Framework language and third party libraries
I have decided that the framework should be written in C++. C++ is very well supported on all platforms relevant to games with C/C++ toolchains as standard. The language provides more direct access to hardware if/when required, yet is still a high level language with recent updates to the language providing many of the modern features and syntactic sugar you get in more high level scripting languages.
Since I want to have the framework be flexible and without too many dependencies I intend to sparingly use third party libraries.
SDL 2.0 and the SDL libraries/projects SDL_image, SDL_mixer, and SDL_ttf are the only current third party components being used by the framework. These handle the platform specific window setup, provide a basic 2D rendering API, load images, play back audio, and render font.
While I am also using the SDL 2.0 provided 2D rendering API at present, this will be one of the first things that will be replaced soon after some initial 2D projects. I intend to replace this with an OpenGL renderer since that will work for all the current platforms I want to support.
Investigating Vulkan as a better alternative cross platform graphics API to OpenGL is also something I’m interested in trying at some point in the future.
Initial platforms I want to support for the framework will be Windows, Linux, macOS, and to work on the web with modern desktop web browsers.
The web is not typically thought of as a particularly good platform for deploying games to, yet it is by far the easiest for end users to access. For small games and prototypes being able to run directly in a web page is a huge advantage to getting people to try them.
I find the Emscripten compiler/project and the general idea of compiling C/C++ to work in web browsers as a very interesting one. It opens lots of possibilities for complex games that can run on the web, in addition to fully native versions using a shared codebase.
Current features of the framework
When running with debug mode turn on entity bounding boxes are displayed, paths that objects will move in are traced, and statistics about the current simulation and render frame times are displayed.
Currently the framework has the basic features required to get Racket (the simple game shown in the screenshots throughout this post) working:
- Entities which can be rendered as rectangles, images or text, and provide various settings such as colour.
- Simulation of entity collision and movement using a fixed step, currently 60 steps a second.
- Rendering running at monitor refresh rate using VSync, e.g. 60 FPS on a 60hz monitor.
- Input from keyboard and game controllers - only tested with an Xbox controller so far.
- Image sprite rendering using PNG images.
- Sound effects playback using WAV audio files.
- Text rendering using TrueType fonts.
- Frame performance information displayed in debug mode.
- Viewing entity bounding boxes and movement paths in debug mode.
- A debug message logging system that can be viewed in debug mode.
Racket is a simple game in which a ball is returned between two rackets (or paddles) with points awarded when a player gets the ball past the other.
Racket main menu
The original purpose of Racket was to be a simple target game to build the functionality of the framework around. It requires basic features like collision detection, entity movement, input using keyboard or game controllers, and audio playback. The game currently requires 2 players to play.
Now that the game is working I’m going to put some extra work into getting it into a releasable state. Among the additional work I am going to do is make some better assets for the entities, menus and backgrounds, and add a single player mode that lets a human play against a computer controlled player with varying levels of difficulty.
I will continue to document the development of these games and the framework.
My next post will be after the polishing work on Racket is done and the game can be played.
EDIT (27/07/2017): The next post is now available: Game framework, Part 2