Monthly Archives: July 2016

Jetboard Joust Devlog #38 – 2D Or Not 2D?

It’s funny how this stuff works. You design sprite A and are perfectly happy with it, then you add sprite B which you feel is even better and sprite A now seems rather lacklustre in comparison. So you go back and tweak sprite A – which is great, only sprite B now seems to have lost its sheen a bit and needs a bit more work. And on and on it goes…

Looking back on this Devlog I’ve been through this process a few times and this week I’ve been bitten by the bug yet again. Even though I know this is a 2D game I was feeling that the buildings that make up the terrain just felt a little too 2D (22D?) and needed something to give them a bit more depth.

I remembered how @PVBroadz had been through similar a process when we were working on Attack Of Giant Jumping Man (he blogged about it here) and I felt a similar solution would work for Jetboard Joust.

So I started redrawing the buildings – keeping the same ‘space aztec’ feel but this time imagining that they were viewed from a kind of flattened ‘side on’ perspective, a bit like Zelda’s ‘top down’ 2D only from the side. As I’m restricting myself to an 8 colour monochrome palette it was tough to get the shading right (really I think the side section should be darker but then I run out of dark tones) but I think the result looks pretty good.

Trouble is, these versions, whilst they certainly looked more solid, seemed too heavy and ‘brick like’ in-game. I attempted to counter this by designing a bunch of more ‘open’ tiles and making sure there was at least one ‘open’ tile between each ‘solid’ tile. The more ‘open’ tiles were a lot harder to get right and I spent a long time fiddling about with the way the shadows worked.

The ‘open’ tiles seemed to work but I didn’t think the arched tiles I had designed (even though I was pleased with them individually) fitted in with the overall, more geometric look of the game. Consequently I decided to bin these (always difficult when you’ve spent some time on something) and create a bunch more based on more geometric forms instead. I also added a subtle one-pixel indent between the ‘solid’ tiles which also seemed to break up the regularity a bit.

I’m pleased with the end result now and think the buildings look much better than they did. There is still room for improvement (isn’t there always) and I think with a bit of effort I could get some really interesting Escher-style connections going on – for now it’s time to park it though!

Dev Time: 1.5 days
Total Dev Time: approx 45.5 days

previous | next

First Attempt – Solid, But Too ‘Brick-Like’

More Open But The Arches Don’t Work

I Think This Is It – For Now!

Scrolling Through…

Jetboard Joust Devlog #37 – Shake, Rattle & Roll!

I’d been thinking for a while that I needed a slightly more visceral feel to the collisions in Jetboard Joust, particularly when the main character crashes into the terrain but also when he’s taking damage from enemies.

So I’ve spent the last couple of days working on this by applying three different effects, the amount of each effect applied depends on the strength of impact (ie the speed the player is travelling or amount of damage taken) and is tweened back to zero over a short period of time, roughly 0.25 seconds. The three effects are as follows…

1. Scanner Distortion
It didn’t make sense to me that the scanner display should remain pristine when you’re taking a pummeling. Though the scanner is part of the HUD I imagine it as being embedded in the player’s helmet or something so it should appear to suffer as the player does whilst still maintaining enough legibility to make the game playable. I’ve achieved this by applying a ‘pixelator’ type shader that is based on my ‘teleport’ shader with a few changes. As well as changing the amount of pixelation based on the strength of impact I also add a small amount of brightness and noise which gives the impression of old-school CRT interference.

2. Camera Shake
This effect has become so much a staple of indie games that it’s almost a cliché by now but, what the hell – it looks good! Applying the effect was a bit more complex than I thought as it needs the appearance of randomness without being genuinely random (because a genuinely random shake can appear to stick at times). My final approach was to take a {1,0} vector, rotate pseudo-randomly, and then multiply the camera offset by the strength of impact on the x and y axis. For the pseudo-random rotation I always rotate by at least 90deg from the last ‘shake’ and then add another random amount between 0 and 180deg, this gives the appearance of randomness but always ensures there’s a ‘whole lot of shaking going on’. I also keep track of the ‘static’ camera position so that the ‘shaken’ position is always offset from the ‘static’ position and you don’t get a ‘brownian motion’ type effect with the camera movement which would upset the standard camera taking of the player.

3. Impact Shader
This was the effect that took the longest to get right. In my head I wanted an effect applied to the terrain that was kind of a cross between ‘double vision’ and the ‘vibration lines’ you might see on static illustrations to give the impression of movement. I also wanted the effect to look a bit glitchy.

First step was, whilst the effect was in progress, render the entire terrain to an offscreen image rather than rendering directly to screen. The shader could then be applied to the entire terrain rather than each individual component of it which would be both inefficient and cause visual issues.

I then started by applying a shader that simply rendered the whole terrain in a flat colour with some scaling distortion applied, the scaling varying according to strength of impact. I found I had to apply this shader three times in order to get the ‘double vision’ effect on the top, left and right of each building.

I then tried applying some raster lines to the effect and found this looked best if I applied horizontal raster lines when the shader was distorting vertically and vice versa. This gave a ‘vibration line’ effect around the buildings.

Next I tried randomizing the amount of scaling every x pixels – so there would be more distortion at certain, regular, points. This gave a ‘spiky’ effect to the shader that I thought looked pretty cool.

Lastly I varied the amount of scaling distortion on each axis based on the direction of the player’s travel and also added a certain amount of pixelation, again dependent on the direction of travel. I’m pretty pleased with the effect now though it has taken a hell of a lot of tweaking to get this far. No doubt I won’t be able to resist tweaking it some more either!

Dev Time: 1.5 days
Total Dev Time: approx 44 days

previous | next

One Of The First Impact Shader Attempts

Something A Little More Subtle

Adding Raster Lines For A ‘Shake’ Effect

Adding Scaling Spikes

Final (No Chance!) Impact Shader, Scanner Distortion & Camera Shake

Jetboard Joust Devlog #36 – What A Performance!

It’s been a while since the last devlog but I haven’t been idle, I decided that before I could start tweaking gameplay again (now that we have abductions and mutations) I should make sure that everything was running as fast and as smooth as possible.

The main performance tweaks involved a bunch of changes to the particle engine which pretty much necessitated a complete refactoring of this part of the game code. This took several days and, whilst I know I have further optimisations to do, the result is an architecture that’s much more flexible and seems to run very well to boot. It could still be improved though. As this was kind of a generic topic I wrote a separate post on it here.

Other performance tweaks involved various memory optimisations, particularly implementing object pooling for commonly used objects. Again, as this was a pretty generic topic I wrote a separate post on it here.

The last thing to be optimised was collision detection and for the record I’ll list the main optimisations I made below. Though these are pretty specific to the way the gameplay and game physics work in Jetboard Joust they could be applied to a bunch of 2D games.

1. Ignore The Real World
Jetboard Joust implements a pretty simple physics model but it is still a physics model – therefore anything that exists in the game world is treated as being constantly under the influence of gravity (ie always falling) unless ‘pushed’ up by another object. This means that a collision check has to be run each frame for each object against any other object that might get in its way. Even though I use a segmented approach for the terrain this can still prove expensive.

When I ran my first diagnostic tests I was shocked to see that around 8.5% of the CPU time in my update loop was taken up by collision detection on the ‘pickup’ items (there are a lot of these created in the game and they can hang around a long time). As these pickup items are stationary most of the time this was clearly a complete waste of cycles!

So what I did was effectively disable the physics on the pickup items once they have come to rest. I can get away with this because I know that once they have come to rest the object on which they rest won’t be removed at any point – all that can happen to them is that they get picked up by the player or disappear if they hang around too long.

This simple optimisation took the CPU useage for this section of the code down to around 0.23% – a pretty hefty saving!

2. Apply Basic Logic, Stupid!
The next chunk of cycles were eaten up by collision detection on the enemies against the terrain. There were a couple of simple optimisations I could make here. Firstly I now keep a record of the highest point the terrain reaches when the level is constructed, if an enemy is higher than this point (as they often are) I know I don’t need to bother checking against the terrain at all. Similarly, if an enemy is travelling right I know I don’t need to bother checking against the right side of terrain objects and the same for the other directions.

3. Cache Me If You Can
I have my own Rectangle class that I use in my code and there were quite a few key places where I was using Rectangle.Width/2, Rectangle.Height/2. I replaced these with a HalfWidth and HalfHeight property that is cached and only updated when the Width or Height of the Rectangle is set – this has potentially saved me many thousands of division calculations per frame.

The game seems to be maintaining close to a 60fps framerate now in most situations though the fact I’m testing on a virtual PC running on a seven-year-old Mac Pro makes it kind of hard to tell for sure. I get occasional juddering but I think this is due to running on an emulated OS.

Oh yeah, I also decided that having the enemy mutations happen offscreen was kind of a cop out (as well as being annoying gameplay-wise) so we now have onscreen mutations!

Dev Time: 5 days
Total Dev Time: approx 42.5 days

previous | next

Enemy Mutations Now Happen Onscreen

Badly Filmed – But Gives And Idea Of How Smooth Things Feel