Welcome to the first Deep Loot coder diary. Deep Loot is our current work in progress and I’m the guy doing the coding for it while Dave does all the artwork and animation. This is a coder diary which means things are likely to get a bit techy. I’ll try to tone it down a bit so people with a general interest in game development can still get something out of it but I do want to get down to a fairly low level of how I’m going about things.
Dave and me said we wanted to do a development diary right from day one of this project and yet it’s taken us nearly two months to write the first entry! This means I’ve got a bit of a catch-up to do. I’m writing this having taken about three weeks off Deep Loot development to do some other projects and so I am using this blog post as an opportunity to get my head back into Deep Loot and prepare for a bit of a coding marathon over the next few weeks, so hopefully you guys will see some significant progress very soon! Anyway, on with the dev diary…
We started Deep Loot development with a bunch of design meetings. From there we wrote a game design doc, produced an estimate and a very rough schedule. This is fairly standard practice in some places but the first time Dave and me have worked like this since starting out on our own. We’ve already blown most of our planning out the water but at least from my point of view it was an exercise worth doing.
My next step was to do some groundwork on the technologies we’re going to use.
Since Deep Loot will be using the ‘freemium’ model we needed to find a way to get an AIR app to talk to Apple’s IAP system. At first I thought I might have to write my own Native Extension which I was not looking forward to. Luckily for me Dave found Milkman Games’ Native Extensions – these extensions are not free but they are much, much more cost effective than me trying to code something up. I evaluated the IAP extension and the Game Center extension and we will, more than likely, be using them both.
GPU mode performance tests
If you’ve read our post mortem on our previous two projects then you know about our experiences of using GPU mode in AIR. It’s pretty obvious that GPU mode is the way to go for AIR-based games on iOS and Android. We had an issue with Winter Walk where some bitmap assets were rendered blurry for some reason. I decided to do some rendering tests and I have managed to eliminate the blur effect. This post will get too long if I go into detail here but I promise instead I’ll dedicate a blog post to what I learned and publish it soon!
We also did some menu prototyping. For some reason it’s dead easy to underestimate the work required in a menu system. I even worked on a triple A project back in the day where we actually forgot to design the menu system at all! Luckily we spotted the omission in the design doc before too much development was done – but from my point of view that was a lesson hard learned. So now I like to make sure it’s something I tick off the list early on. We did two menu prototypes, one with placeholder artwork just to establish that the logical flow was approximately correct and we hadn’t missed any major areas and another prototype using some fully animated, more-or-less final assets as a performance test on iPod since we wanted to be sure we could have a fully vector-art menu system and still manage a decent framerate – with the latest version of AIR it turns out we can!
The next part I worked on represents the majority of the work I have done on the project to date and is still a way off being 100% complete. I’m talking about our infinitely explorable ocean system.
Deep Loot will use procedurally generated content. We wanted to do this because exploration and discovery is a large part of the appeal of our game. We want players to feel that they are the first and maybe only people to see what they’re seeing. This means making every dive a new and unique experience.
There are quite a few games that take this approach and we like them a lot but there were a couple of things we thought we could do differently and, of course, better.
For example we didn’t like that games with procedurally generated levels often sit there while the level is generating – 10%, 20%, 30% … this seems especially inappropriate in a mobile game where you might be snatching moments of gameplay at a bus stop or during a cigarette break or whatever. The level generation time is eating into fun time!
The other thing we don’t like is that in many of these games you can hit the edge of the world. If you decide to run, swim or mine straight down or all the way right or whatever, you hit an artificial wall which breaks the suspension of belief.
Generate content on-demand
So we designed a system to account for both of these issues. We decided to generate the level as the player explores it. Essentially we generate the new level content just off the edge of the screen, on demand. This means we spread the load of the level generation across the entire play session. And we also only generate parts of the level that the player actually goes to which saves memory and time.
This system does actually have quite a lot of drawbacks which is possibly why it’s quite an uncommon approach.
Some procedural content generators use multiple passes to improve the quality of the level designs, e.g. to guarantee that the user can’t get stuck in a dead end or that all the power-ups are accessible etc. If you’re generating as you go, you can’t alter the content that has already been created. For Deep Loot this shouldn’t be a problem given that mining is a core mechanic, the player will be able to dig their way out if they get stuck in a dead end.
The generating routines will have to be simple since they’re being executed during actual gameplay. Offline, ‘please wait’, type algorithms can take more time to decide what type of content to generate. Deep Loot will not be a hugely fast paced game (so the odd dropped frame wouldn’t be the end of the world) and we’ve gone for a simple retro look that should mean that a simple generator should be fine – i.e. the way we assemble tiles is not going to need a lot of processing to match tile edge types or any clever seguing between tile sets.
Because we only generate what the player explores, we will end up with an arbitrarily shaped level. Most similar games would use a two-dimensional array for simplicity. We will have to use a more complicated data structure. If we did use an array we’d have to make it big enough to hold the biggest area the player could ever explore or we’d have to grow rows/columns on demand, wasting memory for all the cells the player will never get to.
As I’ve already discovered, many other aspects of the content generation are more complicated too, but I’ll cover more of them as I outline my approach in the following sections.
Data structure – quad tree
I decided to use a quad tree as it’s a well-known data structure that can grow by an arbitrary amount in any direction. I don’t want to go into too much detail here as it’s a fairly standard approach that is easy to Google for if you want more info. The key element of a quad tree is that every tile in my world knows what/where its four neighbours are (i.e. north, east, south, west) which makes it nice for navigation.
When the game engine starts, I create a root node and then build the first screen’s worth of content. From there I add tiles as needed – i.e. just enough to cover the edge that appears when the screen scrolls.
Things get more complicated when the screen is scrolling back over areas that have already been partially generated. In these cases I have to detect gaps in the content and fill them in as appropriate.
On of the hardest problems I’ve had to solve so far is if the player goes round in a loop and manages to get back round to a part of the level they have already explored. In this case I need to stitch the newly generated tiles back to the existing ones creating a kind of seamless donut shape. I needed to come up with a way of testing newly created tiles against tiles that would potentially need stitching, preferably without testing against every tile in the map.
In the end I came up with a system where I keep a list of all the tiles that are on the edge of the map. This means I only need to check newly created tiles against this list of edge tiles. ActionScript 3 has a range of very powerful Array/Vector methods that make searching and cross-referencing nice and easy and they are generally faster than iterating the usual way.
I also realised a further optimisation was possible. I keep a separate list for each of the edge types; top edge, right edge, bottom edge and left edge – four lists. Because I know which direction I am growing the quad tree in I can generally limit the stitching tests to one type of edge or at most two edge types. I may find as I get further into development more optimisations will be needed, but for now the prototype is running adequately.
So at this point I have a quad tree that grows as I scroll the screen around. The next step is to start generating the different types of tile – sand, mud, rock etc.
Choosing suitable tile types
Tile types are all visually different and have different in-game properties. So choosing the tile types has to be partly about making the sea bed look right and partly about creating a satisfying feel/challenge to the exploration.
I’m in the early stages of this section. At the moment I’m using XML to set the parameters for choosing tiles based on a probability chance of generating a particular tile type at any given depth. The tile choice will also need to be influenced by neighbouring tiles that have already been generated as well as creating suitable spaces for spawning enemies. Though one step at a time eh?
Once I have a system that is generating fairly nice random tile layouts I will start to plan how we can integrate some authored content into the generator since Dave and me both agree that hand-crafted content is almost always superior to procedural content (at least with current technology). We will most likely use authored content to create interesting caverns and one-off ‘Easter egg’ locations such as crashed UFOs and sunken temples.
Anyway, that was a fairly rapid catch-up on the dev so far from my point of view. Hope it was interesting to you and keep an eye out for some more in-depth articles in the near future!
Thanks for reading!
ps Part 2 is here.