Now that we've finished up development on Defendy Rocket (for those that haven't been keeping up, we're waiting on a UE4 Video Ads plug-in to turn up before we release the game), it's time to move onto a new project.
One of the big 'problems' with Defendy Rocket is that the game ended up being far bigger in scope than we ever expected. Bearing in mind, it was designed as a very small project that we originally set out to finish in 4-6 weeks, but it's taken us over four months to wrap it up. This wasn't due to under-estimating development work on our planned features but that - as a result of the game becoming more and more fun - we continued to expand on it and we just never really stopped working on it.
Defendy Rocket has a lot of great stuff in it (Multiple game modes, multiple difficulty levels, player upgrades, fully skin-able with cosmetic items, achievements, leaderboards, dynamic music etc) and we're extremely proud of it (we still play it ourselves from time-to-time, which is always a great sign) but we really wanted to return to the idea of making much smaller games in a much small time frame.
Discussing this, we identified the following: We would have to be a lot more careful about the next game we created (that is, it would have to be small in scope, not relying on a big meta game to support it and with a simple, yet powerful game mechanic at its heart) and we would need the tools to create it quickly.
We've already spent some time this week discussing the new project and we have a fairly good idea what that game is going to be. Next week we'll be prototyping some very rough ideas, nailing the design down and announcing it (as early as possible). But in preparing for making that game, we've been building a new project: The TriCat Template Game. And we wanted to share that with you...
What is the TriCat Template Game?
From working with UE4 on Defendy Rocket, we realised that it probably wasn't the best choice for the type of games we want to create. Defendy Rocket has three core technical pillars:
- 60 Frames per second.
- Playable on just about any device.
- Is relatively small to download.
Turns out that on mobile/cell devices, Unreal just doesn't do any of those very well. It's a really long drawn out series of thoughts about how we came to this conclusion, but to summarise it in a really simple way: A lot of the 'gains' you get in UE4 revolve around the idea that you pay a big initial overhead, but then pay almost nothing on any extra stuff you add to the game afterwards. On PC, this is fantastic and is re-enforced by some truly fantastic additions that can give you unbelievable performance in places. But these additions tend to perform badly on low end mobile devices (or don't exist at all a lot of the time).
One great example of this would be that we identified 'a large number of unique draw calls' to be a big issue in Defendy Rocket. UE4 has a static mesh instancing system built into it which completely removed the problem when we tried it on PC, but this system is emulated on mobile device, so the game run even worse on a lot of the lower end devices and we had to strip it. We spent over a day coming to that particular conclusion and it wasn't the only case where that happened... not by a long shot.
Another example involves trying to achieve the 60Hz pillar: On a low end device (we were testing on Dave's old phone, a Galaxy Nexus) getting the engine to even IDLE at 60hz was practically impossible. Bearing in mind that by that I mean that we had a black screen with a couple of sprites on it and NOTHING else going on (we'd striped the game out basically) and it would still stutter to around 56FPS occasionally.
And let's not forget that UE4 games tend to be about 35MB+ right out of the box, before you even add any content (not great when you're trying to encourage people to take a punt on your free game).
But putting all of these problems aside, over time we learnt to minimise a lot of them and circumvent the rest. Sure, there are things in Unreal that still annoy us (Defendy Rocket doesn't look as good as it could on high end devices because we had to globally disable the Mobile HDR - which gives us nice soft bloom on everything - otherwise all low end devices would run at ~5FPS), but we've managed to get a pretty decent set of results out of it eventually.
So rather than spend time experimenting with another engine (say, Unity), we've decided to stick with Unreal for now and just get on with making another game. But we also wanted to setup some ground work so that we could make these smaller games much faster. And that's where the Template Game comes in.
The Template Game is basically a pre-created game (built in UE4) that we can clone and use as a basis for all other games. It has a lot of our common functionality that we need to release a game built in (beyond what the engine has as standard) and deals with a lot of the cases that (originally) took us a lot of time to setup and get correct (notably deploying the game to Android and iOS test devices).
We put the final touches on the Template Game this morning and, from doing some experiments we can now get a fully working Android and iOS game running in approximately 7-8 minutes (excluding the time it takes to initially compile shaders and export).
Template Game Features
Below is a full list of all of the features we implemented in the Template Game:
Complete Game Loading Structure
Defendy Rocket uses the following loading sequence:
This is broken down into the following steps:
- The game is initialised; the splash screen animation is started.
- We initialise the game's core manager. The manager starts to load all of the other systems one by one.
- When there are no more systems left to initialise AND the splash screen is finished, we prompt the user for a sign in.
- When the sign in succeeds (or fails if they cancel it) we shut down the loading screen and transition to the main menu.
For the template game, we've reproduced this entire setup. This means we don't have to recreate the TriCat splash screen, the loading screen is already in place (we replaced the animated rockets with TriCats and this can be replaced again in minutes) and the Google play sign-in is setup. The template game simply hides the loading screen when this is done (unlike Defendy Rocket which loads the main menu), but it's easy to transition to a menu instead.
Core Game Setup
We've setup the Template project with all of the core classes needed to develop a game. This includes:
- Game Mode: The game mode acts as our manager class, dealing with loading the game and then holding onto references for all other systems. If any class needs access to any other system, it is available as long as they have a reference to the Game Mode.
- Player Controller: Handles player input. Pre-setup with debug hotkeys and the Camera Manager.
- Camera Manager: Pre-setup with a simple static camera and a switch for running a second, debug camera.
- HUD: Pre-setup with debug output messaging and hooks to the debug module.
- Save Game: Allows us to save the game state. Setup with some basic functionality and variables built it.
Modular Blueprint System
One of the things we discovered while working on Defendy Rocket was that it was really easy for systems to get tangled together too easily, making it difficulty to re-use the functionality again in the future. For the Template Game (and all ongoing projects in the future) we've designed a module system to help deal with that.
At the core of the system we have a base module class. There's nothing complex about this class, containing only some simply logic for activating and deactivating it. When a module is created, it is given a reference to the Game Mode class (allowing it access to the rest of the game).
When the game is loaded, the Game Mode class will go through and load each module it is asked to. If a module has the 'auto activate' boolean checked, it will also be activated immediately (this can then be easily expanded to allow modules to perform additional tasks). The steps to adding a new module are really simple:
1) Clone the Module class and name it.
2) Add a variable of 'New Module' type to the Game Mode class.
3) Add a class reference to the list of modules to be loaded at game launch.
4) Cast the result of 'Module Loaded' to the new class and assign it the original variable.
5) Done! Now any class that has access to the Game Mode has access to the new module too.
The Template Game comes with a few modules built into it and loaded. The idea though is to keep these modules reasonably bite-sized so that different games can re-use them without needing to ship an entire library of them with each and every game. It should also be noted that it is extremely easy to unhook a module from the game and get rid of it, so even if one of the built in modules isn't required, it can be removed within minutes, reducing the size of a game before shipping.
Debug Camera System
A simple debug camera system (controlled with a game pad) that allows us to work out issues with the camera or even try out new camera setups quickly. Has controls for moving the camera and adjusting the field of view. When the debug camera is activate, it outputs its location, rotation and FOV to the screen, allowing us to quickly diagnose issues.
This was missing in Defendy Rocket and there were times we really needed it.
IOS AND ANDROID support
The Template Game has a full iOS and Android setup built into it allowing us to instantly launch a new game on both sets of devices and test all common functionality (google play sign-in; banner ads etc). We also have a full set of icons and splash screens pre-setup so that we can make sure everything is working correctly (obviously these need to be replaced for shipped projects).
Save Game System
Our save game system has three core components: Keys, Stats and Currency.
All three of these systems are completely private within the save system and the variables themselves cannot be accessed from anywhere (this is to minimise the chance of exploits or hacks). We have getter/set functions for each type, but these are smart (where needed) to stop invalid data being passed through the system (for example, you can't have negative currency).
Save keys are a list of items that consist of a name and an integer value. You can ask the save system if a key with a particular name exists, or grab its current value. This allows you to create any type of information you like (e.g. you can ask if a key with the name 'TutorialComplete' exists and, if not, you know you need to show the player the tutorial - once complete, you can save the TutorialComplete key with a value of 1). Keys can also be written to IF the value is higher than the current value (e.g. for leaderboards scores).
Save stats are similar to keys but they can only have their value incremented, never set. This is useful for keeping track of the number of games played or the number of kills the player has achieved. Stats can't have their existence polled - if you ask for the value and it doesn't exist, it is automatically created and set to '0'.
Currency is simply a default currency value in case the game being created needs a currency system. The currency module uses it.
Actor Pooling System (Module + Base Actor)
Consists of a simple actor that can be spawned with an activated (visible and gets updated per frame) or deactivated (hidden and doesn't update) state. The actor pooling system can both spawn large numbers of these in a deactivated state, retrieve a de-activated actor from the pool (adding a new one automatically if the pool is too small) or shut down all actors when needed.
This functionality was essential to Defendy Rocket (especially in getting the performance to a high level), so having this available immediately is extremely useful.
Sound Manager (Module)
There are a few technical problems to overcome on Android devices when it comes to playing sounds. The biggest of these is that there are only 12 channels available at a time. If you simply spam sound requests (i.e. when a lot is happening on screen) an important sound effect can get missed in favour of lots of incidental ones.
For Defendy Rocket we fixed this by creating a system that could both prioritise sound effects and lock them out (so they didn't get repeated frequently - most sound effects do not need to be heard by the player multiple times for them to be effective, even if the event that caused them is happening a lot). We duplicated that system in the Template game, defining 10 audio components for sound effects and dedicating two for music (we often overlapped pieces of music in Defendy Rocket).
At the core of the system is a request system that takes the requested sound file (plus some data about its lock-out window and priority) and checks the system to see if there's a spare component to play it. If not, the system is capable of dropping a low priority sound to play the higher priority one requested. We also log dropped sounds, so we can see what's going wrong.
Templated UI Button
Simple touch screen compatible button with a click sound built in. Has a simply event system attached (needs to be initialised with a single function call) to allow us to create buttons very quickly. By default, you need to copy/paste buttons every where and this quickly leads to having many buttons to update (if you want to make changes). By templating the button, we can makes these changes in a single location.
Built in Font
We found a nice 'gamey' looking, slightly retro font that has a full character support for all standard characters as well as Russian and Greek and embedded it into the Template Game (This allows us to ship the game with that font in the majority of languages without any additional work). We also created a 256x256 texture map that includes all of the typical characters you would need to make a game HUD (presuming you were using icons instead of say, the word "Lives") in high resolution.
Localisation System (Module)
We used a custom localisation system for Defendy Rocket and we've duplicated that here. We slightly improved the system though to allow us to us place-holder strings (useful for Game Jams or prototype projects) and immediately switch to localised strings when needed (without skimming through the game for strings that need to be replaced).
Currency System (Module)
Simple module for handling how much currency the player has, if they can afford something of X price and writing the value to the save game. Also has pre-built in cheats for awarding currency mapped to hot keys on PC (1 = 1 Currency; 2 = 10 Currency; 3 = 100 Currency ... 7 = 1,000,000 Currency).
Game State System (Module)
Setup with all of the typical game states we use in a game ("Main Menu", "Gameplay", "Pause Screen", "Options" etc) and allows us to quickly switch between them. Also has typical Android Back button support for these default states so that the Android Back button works out of the box.
Game Speed Debugging
One thing that always comes up in development is being able to quickly manipulate the game speed. For that reason, the Template Game has hot keys built in for doing so on PC, built directly into the Player Controller class:
- NumPad 0 : Game speed = 0.001% (almost paused, but not quite).
- Numpad 1-9 : Game Speed = 10% - 90%
- Numpad / : Game Speed = 100%
- Numpad * : Game Speed = 150%
- Numpad - : Game speed = 200%
- Numpad + : Game Speed = 1000% (useful for skipping forward through the game REALLY quickly).