So, we missed a week! In fact, we've been pretty quiet in general lately both here and on, say, Twitter. The reason for this is simply that we haven't had the time spare to sit down and write these posts up. They're fairly time consuming (That's before you take into account the time involved in keeping track of every thing we're doing between posts) and we've just been too busy trying to finish up the game.
If you read the previous development update, you'll know we had a really nasty spell a couple of weeks ago where we grabbed a version of the Unreal source code and compiled it all, only for it to fail unexplainably when building the Android code. The day after writing that previous post, I finally formatted my PC and started again. This, kind of annoyingly, fixed the problem.
We'd already started to port some of our key game logic to C++ and, having not delved into native programming for many years, took a while to get back up to speed. But as we started to move systems across, this caused a massive snowball effect. Need to move that piece of logic that drives rocket movement to native? Well, you can't, as it's using an enumeration that's only defined in blueprints. Thinking about moving the enumeration to native? Sure! But then you'd have to re-hook up a ton of other blueprints to use it. And it's not just that one enumeration. It's meshes. And particle systems. Data Structs and global values. And so on. And so on. And so on! It got to the point where we were looking at porting 95% of the game before it would even function correctly.
And there's other problems. As we mentioned in the last post, you can't build IOS code on a PC. You need a Mac. So now we have this recently purchased Mac, but that means we have another machine to setup; to make work as a build server remotely and... yeah: You get the idea. It gets complicated and time consuming very quickly.
So late last week we we decided that: Nope - it's not worth it. The final straw was some weird quirk in native - something related to templates - that just wasn't working the way it should have. At that point, we'd just used up too much time trying to get everything to work; we hadn't yet even tried compiling IOS code; the whole situation was starting to drag badly and was taking its toll; and we wanted to get on with, you know, making video games.
So we scrapped the native implementation. Entirely! We backed it up, reverted the project and re-hooked in the few bits of data changes we'd made (basically some updates to the music and sound effects that Dave had been working on while I'd been slamming my head on my desk over and over again with the Android issues). And we moved on.
The problem with native in this project is two fold:
- We started two late. If we'd have done this from the beginning, we would have been expanding native classes into blueprints, not retroactively trying to rebuild a very intricate blueprint system in native. In future projects, if we use native, it'll be from the start and used to define the game's key classes/layout. That way, native and/or blueprint implementations can be created without these sort of problems.
- We don't have a dedicated programmer. Defendy Rocket is being built by the two of us and, taking 20 days out to port everything over to native then get rid of all of the bugs (not to mention maintaining it), is too much of a drain on our resources. If we'd had a dedicated programmer who could focus entirely on this stuff, things would have likely been different, but instead we basically had to stop developing the game while we focused on switching.
So, more positively, we rolled out what we're calling 'BETA #1' to a very small group of people. And we were pretty happy with the results. But before anyone asks: No! It's not a 'beta' in the technical sense of the word; i.e. we haven't finished all of the game's systems/content yet. We're using 'beta' to mean 'play test' here.
The main goal of this was to test our new scoring system. The scoring system system is simple but interesting, and we sort of stumbled on it while trying to solve some of our design problems:
- Destroying chains of three or more rockets with a single one of your rockets generates stars (more enemies killed equals more stars).
- You collect stars for points. One star equals one point.
Simple enough, right? But we put a twist on this well established formula:
In Defendy Rocket, you can combo stars with enemy rockets to generate additional stars. This means you can kill three rockets with a single one of your own rockets and generate a single star, then collect the star with another one of your rockets for a single point. BUT, you can also leave that star in the world for a couple of seconds (although they only stick around for a short while before vanishing), waiting for the next chain of three enemies, and chain it together with them (i.e. four kills with a single rocket) to generate two more stars (three points in total).
We have a video which shows this in gameplay (this is from the actual gameplay we released for BETA #1!), which we originally intended to release two weeks ago but - you know - things didn't quite go to plan:
We were pretty happy with this system. This fixed our main gameplay concern, which was that all of our previous ideas about scoring and combos lead to huge numbers that eventually became meaningless. And it added a very significant risk/reward system to the game. We knew we were onto something great when we first played it on our test devices and couldn't put it down for two hours, desperately trying to outscore each other.
We'd come up with another twist that reinforced this concept even further: We were now collecting stars in the game, which are turned into points (one for one). But how were we going to convert this into a currency so that the player could purchase upgrades?
Simple answer: The stars ARE the game's currency. This means your ability to create combos and score highly now gives you a means to purchase upgrades. Purchasing upgrades gives you the ability to score more higher. We felt this a really compelling game loop for the game, and our initial internal tests showed this worked really well. The upgrades suddenly became extremely meaningful in the game.
BETA #1 basically became our way to answer the following question: Without being told what the system was, or how it worked, would people be able to generate stars, work out that they could even collect them and then that they could combo the stars together for more stars? The results were a mixed bag:
- Generally, yes, people worked out that defeating enemy rockets lead to stars, that you could collect stars and that, yes, stars were score.
- I don't think anyone really understood that chaining three rockets together equals one star, four rockets equals two etc.
- It seems nobody really got that you could chain the stars into your combos for more stars.
As a result, we've changed our design to the following:
- We now use a tutorial to teach how destroying groups of rockets generates stars as well as how to collect them. We make sure the player fully understands this before moving on. This does remove an element of mechanical exploration from the game, which we're kind of sad about, but we feel it's better for the player to understand what's happening and use that knowledge to discover better ways of playing the game, than risk them being completely in the dark and quitting in frustration.
- We've made the ability to combo the stars with the rockets a purchasable upgrade, so that the player is indirectly taught about it later in the game (without them getting overwhelmed initially).
- We never teach that 'longer chains equals more stars'. We leave this for the player to discover.
- We never teach any additional methods of generating stars (not discussed here), of which there are one or two.
Hopefully that will strike a nice balance between tutorialisation and exploration. We're going to run another BETA (cunningly named 'BETA #2' soon to see if these changes have paid off.
On a side note, we also rolled out a minor update to BETA #1 a few days ago, fixing a few key issues that people asked for (including supporting the 'back' button on Android phones and adding an 'upgrades' button to the game over screen).
HEADING TOWARDS BETA #2
So the last week or so we've been working really hard on BETA #2. I'm not going to go into huge amount of detail here (this is another blog post that's already getting too long), but this is some of the stuff we've changed / are in the middle of implementing:
- We completely scrapped the place-holder 'easy' difficulty we had in the game for BETA #1 and have replaced it with 'easy', 'medium', 'hard' and 'endless'. Each of the three core difficulties will have pre-determined enemy waves (the random nature of easy mode was a common piece of feedback we saw in BETA #1), but endless will be completely procedural. How complete each of these modes will be by the time we get to BETA #2, remains to be seen.
- We've slowed down 'easy' mode to 75% of the game's normal speed (tutorial is the same as easy) and sped up 'hard' to 125% ('endless' will be 'hard' mode difficulty). We've added turbo mode to each difficulty, boosting them up by an addition 25% each (i.e. 'hard' turbo runs at 150% speed).
- We've added a full blown dynamic tutorial which the player goes through the first time they play the game, teaching them the basics of the game mechanics and scoring.
- We've completely re-designed and rebuilt the upgrades screen from the ground up, adding new art and improving the usability.
- We've added a new cosmetics shop where the player can purchase (with stars) new meshes and colour schemes for almost every aspect of the game. We've added almost 100 cosmetic purchases to the game and a system to buy and equip them. Want purple player rockets? Sure!
- We've overhauled the game over system, making everything dramatically explode (including the ground) when an enemy rocket gets through.
- We've added more music, fine tuned some of the existing music and added more sound effects. We've added new music for the title screen and improved how the music loops.
- We've added a ton of optimisations to the game, slowly but surely moving towards a steady 60hz on even the crappest phones (the ones that can run UE4 at all, anyway).
- We've added an entirely new path drawing system (uses particle ribbons instead of a pool of static meshes). This is consistently a little faster, but also scalable, meaning we can make the paths look really nice on high end devices.
- We added dozens of bugs, fixed lots of them and then added lots more :)