Monthly Archives: January 2017

Jetboard Joust Devlog #56 – Pointing Out The Obvious

Whoa – 100 days of development under my belt!

Kind of a brief entry this one – I thought I was done with adding extra gameplay stuff for the alpha but watching my son play the game I realised there were a few things that were a little unclear.

The main one was the location of ammo stashes. It’s really annoying when you run out of ammo (I’m still not 100% sure that I shouldn’t give the base weapon unlimited ammo) and sometimes, in the heat of battle, it’s hard to locate the nearest ammo cache onscreen or on the scanner. This is even more of an issue since I added enemy bones which clutter up the battlefield.

So I’ve added two new features to make it easier to locate ammo, shields and rocket pickups – I call these ‘pickup detectors’ and ‘pickup indicators’.

A ‘pickup indicator’ simply indicates the location of the nearest onscreen stash – they don’t appear if the user’s ammo, rockets or shields are maxxed out. Implementing these was fairly straightforward, though I did have a few issues getting the indicator to move nicely between two different stashes. In the end I settled on having the indicator ‘pop out’ and then ‘pop in’ again when the location of the nearest stash changes. In my libraries I have a method that allows one to set a ‘timed event’ on a particular sprite, this is an event that doesn’t get triggered until a certain amount of frames later. This functionality has proved extremely useful for this type of thing.

A ‘pickup detector’ shows the closest route to the nearest stash if it is not onscreen. I settled on a simple arrow at the edges of the screen for this – not subtle but it works. As these would be annoying if they hung around all the time they only appear when the user’s shields or ammo are critically low. The rocket detector appears whenever a rocket pickup is present as these are pretty rare and you don’t want to miss them when they do appear.

The ‘pickup detector’ was also pretty straightforward to implement – the most fiddly bit was getting the arrows to centre correctly depending on how many of them there are, even that wasn’t that much hassle though.

I think these features make the game considerably more playable – plus I just love the look of that tiny pixel text!

Dev Time: 0.5 days
Total Dev Time: approx 100 days(!)

previous


Pickup Indicators In Action


Showing The Pop In / Pop Out As The Closest Stash Changes

mockup_3x
Please Sir – Where’s The Nearest Ammo Stash?

Jetboard Joust Devlog #55 – The Bubblewrap Effect

Everyone loves popping bubblewrap, yet no-one really knows why. For some reason the combination of the sound and tactile response makes it incredibly satisfying despite being utterly pointless. I had a friend who use to refer to this type of action as being ‘urgey’ – once you’ve done it you have the urge to do it again, and again, and again…

I’ve always thought we should aspire to this ‘bubblewrap effect’ when designing games. Most games, even the supposed AAA ones, comprise a fairly limited set of repetitive actions. If you can make those actions an enjoyable experience in and of themselves, regardless of gameplay, then you are onto a winner because no matter how good the player is at playing your game they will be having fun and come back for more.

Recently I’ve seen this loosely referred to as ‘juice’ or ‘game feel’ but these terms are rather vague and are often used to refer to all sorts of things. I’m talking about something pretty specific here – make all your repetitive actions as ‘urgey’ as popping bubblewrap. Usually this is a combination of both visuals and audio.

Now I’d already spent a lot of time on this stuff in Jetboard Joust but, whilst surfing GDC talks on YouTube, I came across this excellent talk by Jan Willem Nijman of Vlambeer on adding these types of elements to your game. I’d already implemented many of the techniques he talks about (camera shake, gun recoil, enemy and player knockback etc) but he made me rethink some aspects and put a bit more effort in to areas that were somewhat lacking.

So – here’s what I’ve been working on as the result of @jwaaaap‘s talk.

1. Bigger Bullets
To be honest a) this would never have occurred to me and b)I never would have thought it would work if it did. I was using little pixel squares for bullets as 1) they seemed appropriate for the size of gun and 2) this worked in Defender so why fix what ain’t broke? But I thought – ‘what the hell?’ and gave it a go. I started increasing the size of the bullets a little and was amazed how much better this felt, so I increased them what I would have thought was a ridiculous amount and it felt even better! It makes no visual sense whatsoever but the pistol (and particularly) the gatling gun are so much more satisfying to shoot now. I haven’t tried playing with the accuracy yet but should really do that too…

2. Camera Knockback
I already have some pretty hefty recoil on weapons but @jwaaaap suggests also recoiling the camera a certain amount when a weapon is fired. This didn’t make a massive difference in Jetboard Joust, probably because the camera is generally moving pretty fast anyway, but it is noticeable under some circumstances so I left it in.

3. Explosion Delay
Adding a very slight delay when an enemy is destroyed adds to the ‘jolt’ effect and makes destroying enemies much more satisfying. It’s subtle but it works. I’m using a delay of 32ms. I had to be careful here to not implement the delay until the next frame (ensuring the first frame of the explosion is drawn before the delay occurs) and also to clamp the delay time so that destroying a bunch of enemies at the same time didn’t result in a massive delay. I also improved the first ‘flash’ frame of the explosion by adding a ‘threshold invert’ to my collision shader and making the circles that briefly appear larger, brighter and less pixelated. Enemies really look like they’re getting nuked now!

4. Permanence
I had been wanting to do something to make battles seem more ‘permanent’ for some time and @jwaaaap‘s talk was the kick up the arse I needed. I talk about adding smoke in my previous post but that’s still not really permanent so I also added bones that fall from enemies when they’re destroyed and collect on the ground as a permanent record of the carnage that’s ocurred there.

Adding the bones was easy, the trouble started when I decided that they were too static and should react if the player hit the ground near them or crashed into a building that they were resting on. I didn’t want to run collision checking on every bone (there can be tons of them by the end of a level) so worked out a system whereby the world is divided into a series of overlapping ‘bone zones’. When a bone is static it is added to a zone and an entire zone can easily be discarded from the collision detection process in one go. I’ve used this approach before and it works well but I got myself into a bit of a flap with it here, plus it took a long time tweaking the various parameters so that the bones seemed to get disturbed by the correct amount. It still looks a little odd sometimes but its much better than having them totally static.

I’d really like to add some permanent damage to the buildings but I haven’t yet figured out a way to do this that would be a) be cpu/memory efficient and b) not involve creating a load more pixel art. I will continue to give this some thought – it could be that I’m underestimating the memory available on modern devices as a spent so long developing for J2ME feature phones!

So I hope that was all worth it and makes my game feel a little more like popping bubblewrap. I’d like to say these were the last gameplay tweaks before I release the alpha but watching my son play it has led me to implement just a couple more things…

Dev Time: 2 days
Total Dev Time: approx 99.5 days

previous|next

mockup_3x
My… What Big Bullets You Have!

mockup_3x
These Bullets Are Ridiculous – But Somehow They Work!

mockup_3x
Explosion Delay (Exaggerated), Smoke, And Improved ‘Flash Frame’

mockup_3x
A Battle Amidst The Bones Of Fallen Enemies

mockup_3x
Bone Bashing – A Stupid Detail That Caused Me Much Grief!

Jetboard Joust Devlog #54 – Smoke & Mirrors

For the past few days I’ve been working on adding some more ‘juice’ to Jetboard Joust – the sort of small details that don’t really add anything to gameplay per se but, when combined, add an awful lot to game feel (hopefully).

I’ll go over most of these in a separate post but one element seemed to deserve a post of it’s own – smoke.

I wanted to add smoke as a way of increasing a sense of ‘permanence’ to the combat. Explosions are over and done in less than a second but smoke could hang around for ten seconds or so and build up depending on how much destruction is going on.

I wasn’t after a ‘realistic’ smoke effect but something more stylised to fit in with the rest of the game art. It seemed logical to use circles as the base for the effect but I felt pretty sure I’d want these circles to increase in size over time, maybe quite dramatically, so I didn’t want to rely on scaling sprites for this. I decided to use custom shaders instead as this should give me much more control.

So the first step was to use a custom shader to draw a simple filled circle. Initially I thought the geometry behind this would be quite complex but, in fact, it’s just simple pythagoras. Here’s the approach in pseudo code…

// get coordinates relative to centre of circle
float x = 0.5-coords.x;
float y = 0.5-coords.y;

// fill the entire space
float radius = 0.5;

if ( x*x + y*y <= radius*radius )
{
// return a color
}
else
{
// discard
}

…I’d be lying if I said I got to this stage quickly though! Though it didn’t take me long to figure out the maths, I spent far too long passing the shader a region of a texture to draw rather than the entire texture and getting confused as to why my results were all off (forgetting that coords.x and coords.y are relative to the entire texture to be drawn, not the region). When I started passing a simple 2×2 image to the texture everything clicked into place.

Once I’d successfully drawn a filled circle it was pretty easy to expand that technique to draw concentric rings and the like, and to animate these by basing their radii on parameters that are passed to the shader and change each frame.

Next step was to find a way of applying motion to these circles that looked suitably smoke-like. I started by simple applying a uniform velocity to several circles distributed across a certain range, e.g. -60d to +60d, as well as increasing the circles size over time.

When I finally got this to work the way I intended it didn’t look too bad as a starting point so I added a couple more parameters to make things more interesting – a ‘deceleration’ parameter (so that the velocity of the circles decayed over time), and a ‘buoyancy’ parameter (so that the circles gradually floated upwards over time). I also decreased the opacity of the circles over time so that they gradually faded out.

This looked much better but the results were still far too uniform, forming very obvious geometric patterns as the circles intersected. To stop this I added a certain amount of randomisation to both the circles initial velocity and their ‘buoyancy’ – this produced a much more smoke-like effect – still stylised but not overly ‘geometric’.

I was almost there now but felt that the smoke cloud was dissipating too quickly and lacked some kind of ‘weight’ to it’s centre. I fixed this by adding additional batches of circles with a decreasing initial spread and velocity with the final one staying pretty much in the same place. This looked a lot better.

Lastly I experimented with adding pixelation to the shader so that the circles were drawn at the ‘game’ pixel resolution rather than the ‘screen’ pixel resolution. Unfortunately I felt this looked pretty crappy – one of those things that ‘should’ have worked but didn’t! So I left things as they were but I did add a gradually increasing amount of pixelation over time so that when the circles have pretty much faded out they kind of ‘dissolve’ out rather than just disappearing.

Actually I couldn’t stop there – I thought the centre of the smoke cloud looked too ‘solid’ to start with so added a small particle effect to imitate ash or something. It’s subtle but it just breaks things up a little.

I’m pretty happy with the final result – watch this space for a mini-tutorial on using shaders to draw geometric shapes. I think I might end up using that technique again in this game…

Dev Time: 1.5 days
Total Dev Time: approx 97.5 days

previous | next

mockup_3x
Successfully Drawing Circles With HLSL

mockup_3x
First Attempt At Multiple Circles – An Interesting Fail!

mockup_3x
Starting To Look More Smoke-Like But Still Too Geometric

mockup_3x
Adding Some Randomisation For A More Natural Effect

mockup_3x
The Final Shader With Pixel Dissolve

mockup_3x
The Final Smoke Effect In Game

Jetboard Joust Devlog #53 – Camera Obscura

In the unlikely event that you’ve been reading this blog from the beginning you might remember that the camera in Jetboard Joust has always been something of a bugbear for me.

Way back in the early stages of development I wasted countless hours trying to get a camera action that I was happy with but, after failing miserably (once I started to add enemies the camera tracking solution I described in the blog post above proved woefully inadequate), decided to go for the simplest solution of locking the camera to the player centre-screen and leaving it at that.

Thing is – this kind of worked. Maybe because the camera is horizontal-only and the player’s horizontal motion smoothly accelerates and decelerates with no sudden changes? The game was perfectly playable and there were no sudden camera movements that looked out of place or anything.

But… it was just a bit boring and I always thought I could make it better, so as I’m nearing ‘playable alpha’ stage I decide once more to revisit. I set up a separate ‘Camera’ class (rather than putting all the camera code in the main game class as I had before) and attempted to approach things a bit more methodically.

Though it probably seems blindingly obvious I had a bit of an epiphany on realising that camera motion is really comprised of two separate elements, the camera target (ie what you want to be the centre of attention) and the way the camera moves to that target.

I decided to tackle the camera motion itself first. Many online articles talk about Lerp smoothing as the de-facto way to deal with this so this seemed a good place to start. Rather than working with Lerp smoothing on the camera right away I tried applying it to some sprite motion so it was much easier to see what was going on. The results of this really require a separate post so I’ve explained the process in a small tutorial with some example code here. The net result was an extended Lerp class that moves an object smoothly towards a target no matter how often (and by how much) the target position changes.

Now I had a way of making the camera track smoothly I set about working on the camera target (what the camera is moving towards). This was a lot harder! My thought process here had three key stages…

1. Player Velocity
One of my main concerns about the camera being centred all the time was that, if the player was moving quickly, lookahead was limited to half the screen width. In ‘Defender’ (the main inspiration for Jetboard Joust) the camera seems to be focussed something like 25% of the screen width if front of the player so I started with similar approach. I took a maximum lookahead value, worked out the player’s current velocity relative to the maximum possible velocity, and then placed the camera target the same proportion of the maximum lookahead value in front of the player.

The end result was OK but, as it doesn’t take long for the player to accelerate to top speed, the camera was moving far too quickly to its farthest position. Jetboard Joust plays differently to Defender in that there is more ‘dogfighting’ style gameplay when dealing with enemies (rather than hurtling in one direction as fast as possible) and somehow the camera movement needed to reflect this. So I tried a different approach…

2. Directional Duration
For my second attempt I set up a variable that gradually increased/decreased in value depending on how long the player was travelling in a particular direction. So, from stationary, if the player was travelling left it would take approx five seconds for the value to reach -1.0 (the minimum possible) and the inverse for travelling right. I then multiplied the maximum lookahead value by this variable and set the camera target appropriately. If the player changes direction I set the variable to zero for a quick turnaround.

This worked much better than my first attempt – the camera seemed to track fairly naturally with a long lookahead distance if the player was travelling any distance left and right and not switching erratically in the midst of battle. There were a couple of problems with this approach though, I didn’t like the obvious lag as the camera tried to ‘catch up’ with the player when accelerating from stationary and too often I’d end up forced to do battle at the edges of the screen.

3. Enemy Location
For my third attempt I adopted an entirely different tactic. I totally ignored player movement and instead positioned the camera entirely based on the location of nearby enemies (limiting this at a maximum value to ensure the player remains onscreen). I tried two approaches here:

3a. Enemy Position
Firstly I tried positioning based on how many enemies were to the left or right of the player. So I’d start by dividing 1.0 by the number of enemies within range and then adding or subtracting this number to a variable based on whether each enemy was to the left or right of the player. The result was a number between -1.0 and 1.0 which gave an indication of where the action was relative to the player – this number was multiplied by the max lookahead value to give the camera target position.

This strategy had some interesting results in the way the camera swung towards the action but overall it was too unreliable, I’d often find my attention was on a particular enemy and the camera would suddenly swing away as there were more enemies behind me or something. So I tried something simpler…

3b. Closest Enemy
This time, based on the logic that 99% of the time the closest enemy would be the one the player was concentrating on in a dogfight I simply targeted the camera at the closest enemy to the player (whilst ensuring the player remained onscreen).

The result of this was strangely compelling! Although the camera lurched left and right far too much it made the gameplay seem more intense, dynamic, and somehow just more ‘fun’. I was really surprised about how much the gameplay was enhanced by this simple approach – I just needed to find a way to tone it down a bit.

4. All Of The Above
So what I did next was use all of the above approaches and apply a weighting to each of them, hoping that this would provide some kind of ‘happy medium’. Fortunately, with a bit of tweaking, it did!

I still felt I could improve things further though so I made this weighting dynamic. I fixed the weighting based on player velocity at 25% and based the remaining 75% on either the closest enemy (if any enemies are within range) or the directional duration.

Another tweak I made was to slightly bias the ‘closest enemy’ calculation based on the direction the player is facing so that enemies in front of the player are considered ‘closer’ (I reduce the distance by 75%) than those behind. This makes the camera more likely to stick on enemy the player is currently engaged with.

The result is a camera that doesn’t lag, gives a long lookahead if the player is covering a lot of distance (and no enemies are present), and pans to the centre of the action when a dogfight is in place. I think it works pretty well.

I’m particularly pleased with the way the camera snaps to the closest enemy. I don’t know if it’s still too motion-sickness-inducing (maybe) but it feels much more visceral, seems to help with gameplay, makes it easier to get combos, and, in certain situations, just makes the player feel like a complete badass! So I think I’m going to park the camera now and wait for user feedback before I go tweaking it further…

Dev Time: 2.5 days
Total Dev Time: approx 96 days

previous|next

mockup_3x
Camera Motion Based On Player Velocity

mockup_3x
Camera Motion Based On Duration Of Movement

mockup_3x
Camera Motion Based On Closest Enemy

mockup_3x
Camera Motion Based On All Of The Above #1

mockup_3x
Camera Motion Based On All Of The Above #2

Jetboard Joust Devlog #52 – Go Logo!!

Been really ill over Christmas with a very heavy cold/flu and it hasn’t got any better this year as it appears to have developed into sinusitis. Now at least I know why I can barely walk up the stairs without feeling like my head’s going to split open.

So it’s been tough trying to work this week – but I’ve managed to get some done! It was quite a relief not to have to dive right into coding but to start with a fairly significant art task instead – the design of the game logo.

I had an idea of the type of thing I wanted but, as with all art projects, I started by gathering reference material and trying to whittle down ‘stuff I like’ into ‘stuff I like but might have a vague hope of achieving with my limited skills in a reasonable amount of time’.

I eventually settled on four key reference logos…

1. National Petrol
The ‘National’ brand is long-since defunct but I have fond memories of it from my childhood as National petrol stations were the only place in the UK that you could buy Smurfs! I really the the dynamism and simplicity of the main pictogram which has an almost Soviet constructivist feel.

2. Go Jetters – CBeebies
I’d never heard of this TV show (my kids are too old) but I was looking after my niece and nephew over the holiday and they had an activity book from the series. The ‘jet’ reference is obviously relevant and again I like the simplicity. The oblique effect on the type is subtle but adds a lot of dynamics.

3. Trans Am – Ultimate Play The Game
OK so this one’s kind of horrible but cool at the same time. As a kid the ‘Ultimate’ games were like the holy grail of Spectrum gaming. I originally looked at the ‘Jet Pac’ logo for obvious reasons but thought it too heavy and overworked. There’s more of a sense of motion to the ‘Trans Am’ logo and I like the ‘silver dream machine’ feel to it – even if that 70s airbrushed effect is something I’d normally avoid like the plague. It works in context.

4. Asteroids – Atari
I’m a massive fan of the Atari arcade service manual art but the trouble with it as reference is that it’s very intricate and would take more time and skill than I have at my disposal to pull off effectively. The nice thing about the ‘Asteroids’ logo is that it uses a very straightforward typeface in a pretty straightforward manner yet still works extremely well.

I decided to start working in Illustrator rather than Photoshop and to restrict myself to pure black and white. Restrictions are good – and I knew that if I had something that looked good in a single colour it would be easy to add colour later whereas trying to retrofit a colour logo into black and white can be a nightmare. It’s a similar approach to the one I’m taking with the actual game art.

Once I had my reference in place I began experimenting with different typefaces*. Initially I thought I needed something that looked a bit ‘sci-fi’ but, despite finding some nice fonts, everything I tried looked either incorrectly proportioned or too gimmicky. The only typeface that seemed to hit the spot was Helvetica Neue Black Oblique which is very similar to the font used in the Asteroids logo. I rotated the letters anti-clockwise so that the uprights sat directly vertical, spaced the letters very tightly (so much so that some of them joined together) and finally felt like I had something I could work with. I also sheared the logo slightly so that it sat at an exact 25% gradient in order to make it easier to convert to pixel art.

Next step was to add something to make the logo seem more unique and give it more of a feeling of motion. I started by add some ‘wings’ to the tops of the ‘J’ characters based on the ‘winged helmet’ of the National logo. This worked right away! I tried some more curvaceous and illustrative alternatives as well but these all seemed too flouncy so the hard-edged brutalist approach won out ( a good job really as it would be a whole lot easier to realise as low-res pixel art). I also added similar ‘wings’ to the right side of the logo which seemed to balance better.

I then tried to increase the motion effect by adding Dyno-Rod style arrow-type shapes at the top-left of letters where there was a lot of negative space. As well as making the lettering seem more dynamic this also had the benefit of filling in the negative space, thus making the letters seems as if they were spaced more evenly.

Lastly I felt the logo needed something to kind of tie it all together a bit more so I experimented with various ‘underline’ effects and illustrative elements, eventually settling for a simple ‘double underline’ consistent with the National-style ‘wings’ on the letters. It doesn’t look like it but the little angled section on the right of the underline took a long time to get right!

Once this was in place I noticed that the ‘wings’ gave the type an almost 3D effect – I liked this (for some reason it reminded me a bit of the 20th Century Fox logo) so I tweaked the angles and lengths to exaggerate the effect.

At this point I was pretty happy with the vector version so I moved on to converting it to low-res pixel art. I began working at a resolution of 256 pixels wide as this seemed to scale nicely for the title screen.

The most time-consuming stage of creating the pixel art version was tidying up the original, rasterized, black and white version so that it looked as good as possible. I realigned all the angled lines so that any that run parallel ‘step up’ at the same time and also changed the angle at the end of the ‘wings’ so that this ran at 45 degrees which looked a lot tidier and didn’t really seem to affect the overall feel.

After this it was a matter of playing around with outlines, drop-shadows and highlights in Photoshop until I found something I liked then tidying it up manually. The final stage was to add some ‘shine’ to the letters (a bit like the ‘Trans Am’ logo) and a final bit of texture by manually dithering the edges of the ‘shine’ and adding some rivets.

I’m pretty pleased with the end result – it looks clear, dynamic, and has a kind of accidental retro/art-deco sci-fi quality that I like. Reminds me of ‘Flash Gordon’ or some of the work by French comic artist Moebius, neither of which are reference points to be ashamed of. The pixel art version could still do with more texture (possibly) but it was hard to do this with the limited palette I’d set myself, and these things can always be better so maybe I’ll revisit at some stage – for now though it’s time to get it integrated into the game!

* Whilst doing this I came across this really useful tool – it’s like Shazam for fonts and actually works (did for me anyway)!

Dev Time: 2 days
Total Dev Time: approx 93.5 days

previous | next

mockup_3x
Gathering Reference Material

mockup_3x
Unsuccessfully Experimenting With Typefaces

mockup_3x
The Final Flat Vector Version

mockup_3x
The Final Pixel Art Version (Click To See 2:1)


Two Day’s Work In Ten Seconds