This week we both hit the point where we’re now looking at Defendy Rocket so often, that it’s starting to feel like our changes aren’t actually improving it any more. But when comparing the current build to last week’s end-of-week video, the differences between the two are not only obvious, but we’re actually really happy with the way the game’s shaping up.
So firstly, here’s a look at the game as it stands right now:
There are a LOT of changes that have gone into the game this week (so many that this blog has turned out far too long - we're going to have to start posting these more frequently in the future) which we’re going to talk about in detail below.
But before that: While trying to get the game onto an older Android phone, in order to test out banner adverts, we accidentally stumbled onto an old build created back in February (around the time when the game first started to take form). We managed to capture some footage using another phone (sorry about the quality; we have no way to capture it from that mobile device) before we had to overwrite it with the current build:
Man, the differences between that version and what we have now! It’s not even close! Everything feels like it’s moving through treacle, the game is incredibly static and the interaction between the player’s rocket and the enemy’s is dire. Was a nice motivational boost to see how much things have improved since then.
So onto this week’s changes:
MAJOR CHANGES THIS WEEK
Epic released a new major version of Unreal (4.8) a few days ago . We decided to take the plunge and upgrade Defendy Rocket now rather than wait until later. We backed up the latest version of the game (although this isn’t really necessary, we have numerous redundant back-ups if something went wrong) and grabbed the latest engine.
Normally I’d expect a bunch of minor issues when switching to a new build like this but there was nothing. It literally updated the project file and that was that. The new version seemed stable enough, so we ran with it.
Annoyingly, we took this time to clean up a bunch of directories, remove some old, redundant files and tidy up the content browser. Along the way a bunch of assets broke and it took us an hour or so to get everything working again.
Unreal 4.8 seems sweet enough. We’re noticing an increased number of crashes, but nothing significant so far (between the two of us the average went up from about 3-5 a day to about 4-7).
One other, rather annoying problem is that something has changed in the way the game gets rendered on PC. It’s extremely hard to spot and we’re not 100% what’s causing it (we have some ideas), but there seems to be a dynamic film-grain filter over the top of everything. While this doesn’t sound like a huge problem, we’ve had significant trouble capturing gifs at a reasonable size other the last couple of days, so posting to twitter has been difficult).
The image below shows what a single frame of our gifs looked like in Unreal 4.7.6 on the left, and what a similar gif looks like in 4.8 on the right, when displaying the differences from one frame to the next.
With the image on the right, every single frame of the gif is completely unique to the previous frame, which has bloated the size of our gifs from 2-3MB average, to 12-20MB. Twitter only allows gifs of 3MB or less, so this has become a serious problem and, after a couple of hours of looking around the engine for possible causes, we're still no closer to solving it.
TESTING ON MOBILE
We've now managed to set up all of the prerequisite SDKs that we need in order to get the game running on a few different devices. At the moment we have in running on:
An iPhone 4S running the iOS build. This runs the game reasonably well, but automatically disables a bunch of graphical improvements (like emissive glow).
A Samsung Galaxy Nexus running the Android build. This things runs the game atrociously, even with the lack of fancy graphical options.
An LG G3 running the Android build. As a very modern phone, this runs the game extremely well with a ton of nice graphical touches, and at 1440p.
The Samsung (which we consider to be within our target audience) has highlighted that we need to add some graphics customisation options to the game. We’re going to look into this soon (maybe next week, more likely the week after) and put an option in for the player to reduce the graphics down to a “medium” or even “low” setting in order to maintain a solid 60FPS whenever possible.
Time Dilation System Completed
We finished off the time dilation system that we’d been working on at the end of last week. This meant slightly re-working the logic that spawns the particle explosions when an enemy rocket dies. Previously they would spawn as a one-shot particle system and we’d forget about them. Now we’re caching the pointer to the particle system in an array and iterating through them all, updating their delta times whenever the slow motion effect is engaged. This particle system components in this array also get re-used between explosions.
New Rocket Types Implemented
We have designed four rocket types to go into the game:
- Small rockets
- Large rockets
- Splitter rockets
- Mega rockets
Previously the game only had support for the small rockets and none of our logic easily supported adding the other types.
It would have been easy enough to go through and duplicate the small rocket functionality several times, hacking together new rockets as we went, but it would be better in the long run to do this properly.
So we spent about half a day creating a bunch of new systems. We now have a new rocket class which simply handles a rocket’s mesh/collision, movement and rotation. That base class is then derived into both a player and enemy rocket subclass. Finally the enemy rocket class is derived into small/large/splitter/mega classes.
Unfortunately, along the way, I ran into three different problems that all wound together to cause some serious grief that would take me the next 16 hours to solve properly:
When I re-wrote the rotation code, I bumped into a bunch of gimbal-lock issues. This meant that the rockets were rotating in very unpredictable ways for a while.
I stumbled into a bug with Unreal where the rotation of an object will occasionally change from (-90, 0, 0) to (90, 180, 180), or something like that (I didn’t stick around long enough to find out exactly what was happening).
Because the game’s running at a high frame rate the game’s delta is reasonably small (0.016 at 60hz). When the game’s slow motion kicks in it reduces this by up to 95% (0.0008). When the rockets were making tiny rotations they occasionally would rotate almost no distance at all (say 3 degrees per second) and combined with the slowed delta, could generate numbers as small as 0.000026. Or zero, as it turns out, as the float precision wouldn’t cover the value and it would round to zero.
On their own, none of these issues would be a huge problem and I solved each one individually (although I still have some checks to add to the game later for the third issue), but I was having all three of them show their face up at once. I ended up rewriting one piece of code that I thought was broken, to find one of the other problems was actually responsible. It took a long time to iron everything out and get things working reliably, and I ended up writing the entire movement system twice along the way.
Eventually, though, we ended up with each of the four rockets spawnable in the game. Dave created a new set of meshes for each one. He then decided to have the rocket’s design be a strong outline shape and, after some testing we went with it. Dave generated a new mesh for each of the enemy rockets:
Dave also spent a reasonable amount of time doing scale tests. This mostly involved making sure that things in Blender were the correct size so that we didn’t have to second-guess how it would look in Unreal. We used this time to get a better approximation of how big each of the rockets should be but, of course, this is an ongoing design process.
At this point we needed a way to spawn these rockets in the game (so that we could test them quickly). This lead to the creation of a new debug menu:
This new menu has an option to switch the spawning from the default (using the game’s wave setup) to only using small rockets, large rockets, splitters or mega rockets. Each of these settings replaces the first rocket in each standard wave with a single instance of that particular rocket.
Later I returned to this menu and added a ‘Spawn: NONE’ option so that we could test other systems (like the music) without having to worry about gameplay.
The large rockets and the mega rockets, although they can be be spawned currently, don’t do anything useful (i.e. they fly straight down and kill you).
Splitter Rockets Implemented
The next task was to do an initial implementation of one of the other rockets. We started with the Splitter rockets.
The design with the Splitters was simple: You’d shoot them down and they would break into multiple other rockets. This took some reworking of the rocket spawning systems to allow the split rockets to spawn without immediately dying (initial tests had the same player rocket that killed the Splitter kill its offspring too, in the same frame). But after a few hours we had the Splitter in game:
We’re pretty happy with how they’ve turned out, though we’ll probably come back and tune them later once the other rockets make it into the game. We also need some way to differentiate the recently spawned split rockets with the standard small rockets (so that the player’s not confused as to why they’re briefly invincible). Our current plan is to try making them a dull grey color while they're moving into position.
This week Dave implemented a dynamic music system. Its main purpose is to mix up the music you're hearing as you play the game, and give a sense of progression when you survive for a decent length of time. We ran into issues with Unreal when it came to playing two pieces of music in sequence with no gap between them. Turns out this is surprisingly difficult to do, due to the way you can't really run commands between frames! At the moment there's still a variation in the timing between pieces, but hopefully it's minor enough that it's not noticeable. The music is also a bit more placeholder-y than it was last week, for the purpose of getting the music system working. With any luck, we'll write a blog post about the process of creating the music, and the specifics of the music system, once it's all a bit more final.
After upgrading to Unreal 4.8 and during our clean-up, some of the menu screens lost their reference to the font they were using. At this point, it made more sense for us to choose an actual font we were going to use in the game and implement it, than fix up the placeholder assets.
We chose Expansiva Bold (http://www.1001fonts.com/expansiva-font.html) which is a font which can be used commercially, for free. We generated some new font pages for the font and implemented it across the game.
One gameplay mechanic that had been on our mind for a while now was a method of informing the player which enemies were coming up next. With the recently increased enemy rocket speed, it was becoming more and more important that we addressed this.
Originally we had a system in mind where the rockets would introduce an icon at the top of the screen a couple of seconds before they emerged, which we think may have worked OK (at least until there were a lot of rockets coming down) but I had another idea earlier in the week that we wanted to try first.
Rather than spawning the rockets directly, the game now spawns an ‘anticipation’ rocket (this is just the name we’ve been using internally and, to be honest, I can’t think of a better one). These rockets represent the rocket that the player will later destroy. They fly in the from the back of the game world towards the top of the screen and when they hit the top, they proceed to drop in as normal.
We weren’t sure how well this would work, but it actually turned out extremely well. It basically triples the size of the playing field for the player and allows them to set up some pretty interesting combos. The downside was that we had to remove the red particles from the explosions as they looked like enemy rockets coming in.
Currently the anticipation system only works with the small rockets (we had a huge gameplay problem to solve this morning as a result of this and I’ll be talking about this issue and its solution next week), but early next week we should have it working with all rocket types.
We also noted that the outline version of the rockets doesn’t work for the anticipation system, so we’re having to use the solid-colour version of the rockets right now. We will probably end up using both versions in the final game.
Over the week we’ve continued to make numerous improvements to the game’s graphics:
Dave had an idea about the ground plane being a physical box floor in the game world (that the death plane sat on) a few weeks back and he implemented a prototype earlier this week. Originally, I had been extremely skeptical about this idea, but I wanted to see it in game before dismissing it completely. Turns out it worked extremely well. With some tweaking (including making it into a cylinder and Dave adding a really nice grid texture to it) we’re now really happy with it and feel that it adds a lot to the game. Dave also added a nice ground effect to the cylinder which helped the player identify where the enemy rockets would crash (and where the player’s rocket would spawn).
This change made us wonder if the stars should be travelling towards you and Dave pointed out that it didn’t make much sense that they were travelling sideways in the first place (not that it really makes any difference in a game like this). So we did a test and flipped the star field around, with the stars come towards you.
It kind of worked, but it was a bit odd that the stars were crashing into the ground in front of you. We tweaked it a little, making the stars shoot diagonally upwards and over the ground plane (but never hitting it). We also tweaked the speed, density and size of the stars for a while, making everything feel a little better. In the end, this worked out extremely well.
Dave had the idea of rotating the ground plane towards the player. Since then we’ve been back and forth on this for a while now and are still not 100% sure if we should keep it in the game. Right now, it feels correct for it to be in there, but we still have some tweaks to make yet. It is also currently unaffected by time dilation, which looks a bit odd.
We’ve also been tweaking the explosion particles a lot this week. They’re in a constant state of flux though and will probably be one of the last things we finalise. As a result of rewriting some of the rocket spawn / dying systems, we also lost the ripple effect that spawns in the background. I aim to get this back into the game in a week or so (and place it properly as it used to spawn in the wrong place).
We finally got around to creating a TriCat Games Ad Mob account and setting up some test banner ads for the Android version of the game. This took a bit of time, but didn’t really cause us any grief and the Android version now displays banners on the frontend menu / game over screen.
At some point next week we also have to setup the IOS adverts. We’ve also started looking into the IOS and Android leaderboards/achievement integration.
For next week, we’re hoping to tackle the following:
Finish the anticipation system and allow spawning of all rocket types. We have a new wave spawning system design in mind (we’ll be discussing this early next week).
Implement the large and mega rockets.
We’ve got a new gameplay mechanic that we think will make the mega rocket interesting to destroy. We’re going to prototype this shortly.
Continue iterating and improving the player rocket, enemy rockets and background imagery.
We’re going to start looking at implementing a proper frontend / game over screen.
Finalise the system that handles playing music.
- Continue looking into IOS/Android integration.