Jetboard Joust DevLog #110 – Making New Enemies pt 2

…and on and on it goes. Please wishlist Jetboard Joust on Steam here.

In the last devlog entry I talked about how I felt there wasn’t enough variety in the earlier levels of Jetboard Joust and that more enemies were needed. The two covered in this post are the more elaborate additions to the pack, in fact they kind of morphed into three – or two and a half at least!

1. The Watcher
I’d always wanted to add an enemy based on a giant floating eyeball. That and a brain in a jar, but I haven’t got to the brain in the jar (yet).

My fascination with giant eyeballs comes from two things. Firstly, the art of Rick Griffin. Rick Griffin was an American counter-culture psychedelic comic/poster artist who helped define the look of the period. Giant, often winged, eyeballs feature throughout his work alongside all sorts of other weird shit. I love it.

Secondly – The Residents. The Residents are an avant-garde rock band formed in the early 1970s who have released a mountain of weird and wonderful work over the past 50 odd years. Their ‘Duck Stab/Buster and Glen’ set is one of my favourite LPs of all time – it sounds like it’s landed from another planet. They were one of the first bands to experiment with multimedia and (weirdly) appeared in Apple’s original demos for Quicktime. The Residents famously used giant eyeballs and top hats to mask their identity throughout their career.

Designing the eyeball itself wasn’t too difficult with such great inspiration to work from. It didn’t really work just as a floating eyeball though, and I thought adding Rick Griffin style ‘wings’ would be too time consuming and complex to animate, so I decided to add some slightly Lovecraftian tentacles which are in fact part tentacles and part severed optic nerve (nice)!

Of course I had to make the eyeball track the player! I also added a laser attack (with recoil) and a background shader effect which is also a nod to Rick Griffin psychedelics. The enemy’s movement is based on the ‘swarmer’ logic from the previous post in that there’s a ‘controller’ for each group of eyeballs so they attempt to circle the player rather than attack the player directly. I also use a ‘baton’ approach for the firing so that only a certain number of the group can ever be firing at one time. In the end I was really pleased with the way this enemy worked out.

2. The Swimmer
The next enemy actually started with an idea for its movement before I had any idea what it would look like. I wanted something that would rotate and attack in short ninety degree ‘bursts’ as there aren’t really many enemies in the game that follow this type of strictly horizontal/vertical movement pattern. Coding the movement was pretty easy but I became a bit stuck as to what the enemy should actually look like. I didn’t want to have anything abstract like a rocket or missile (everything has to have personality) and anything I thought of would have looked weird rotating in this way.

Then, whilst emptying the week’s food waste into my compost heap, I happened to see a bunch of woodlice crawling around. It occurred to me (as it has many times before) that these creatures look very similar to prehistoric trilobites and I though – bingo! That would work! A trilobite enemy would work with that movement pattern and fit within the aquatic/Lovecraftian feel of much of the art. I was amazed when looking at reference material just how many types of trilobite existed, and just how creepy some of them were!

So I got to work on animating a trilobite. This wasn’t as hard as I thought it might be, luckily just using a chequered pattern to infer some kind of skeletal structure worked rather than literally attempting to draw every single bone (which would have been impossible in so few pixels). The hardest thing to get right was the head which I found difficult to make look like something that was seen top-down and facing forward rather than some kind of face looking at you straight on. It actually looked better when seen in the context of the enemy’s movement rather than when worked on in isolation.

I felt that these guys should have more of an attack than just ramrodding the player so I blessed them with the ability to shoot exploding egg sacks out of their arse (aren’t they lucky)! Also, these are the only enemy that interact with each other in that they bounce off each other as well as off the environment. I felt this made the movement patterns more interesting.

I was pleased with this enemy but when I tested it in-game their size meant they were much too hard for the level at which they needed to appear. Being such a large enemy it looked silly if I reduced their health so much that the player could just one-shot them with a weak weapon. They’d have to appear later in the game, which left yet another gap earlier on!

So, I decided to work on a ‘baby’ version. I edited down the graphics, removed the exploding egg sacks, and slowed down the movement. This made for a much more appropriate enemy for the earlier levels – almost two enemies for the price of one!

Dev Time: 5 days
Total Dev Time: approx 325 days

previous

mockup_3x
Eyeball Inspiration – Rick Griffin & The Residents

mockup_3x
The Finished ‘Watcher’ Enemy In Isolation

mockup_3x
The Trilobite-Inspired ‘Swimmer’ Enemy

mockup_3x
…and Its Baby Brother

Jetboard Joust DevLog #109 – Making New Enemies pt 1

Check out Jetboard Joust on Steam here. View the full trailer here.

During my recent intensive playtesting sessions playtesting I’ve become a bit concerned that there’s not enough variety in the earlier levels of Jetboard Joust.

Originally I’d paced things so that either a new weapon or a new enemy is introduced at least every other level. This is fine once you’ve made a bit of progress through the game (as it has all the weapons/enemies from the previous levels to draw on for variety) but earlier on it just felt like I was facing the same old enemies too much, even if they were armed with new weapons.

So I’ve decided to bite the bullet and create a new enemy per level for at least every level until you meet the first boss. As these enemies appear early on in the game they don’t need to be too elaborate, but as engagement in the first stages is key I thought it was worth the extra effort.

This means a total of five new enemies, I’ll cover the three simplest ones in this post as the two slightly more complex ones in the next devlog.

The first two are both jetboarding enemies. Jetboarding enemies are the easiest to add as they all work from basically the same AI, I just have to tweak certain values and maybe add a couple of specialist behaviours for variety. I wanted these ones to have a ‘gang’ type behaviour so I designate one enemy from each group as a ‘leader’ and have the others position themselves around the leader until they get within a certain distance of the player (in which case it’s pretty much every man for himself). Both enemies follow this pattern, though one type will abduct/mutate whereas the other attacks more aggressively.

The enemy on the left is supposed to be wearing a kind of gas mask / backpack type arrangement. This was bloody hard to get right in so few pixels and I’m still not convinced to be honest. Someone on r/pixelart said it looked like a racoon and now I can’t unsee that! It looks better in some palettes.

The other enemy I’ve christened the ‘swarmer’. As you can guess from the name, it attacks in large batches! For the attack pattern I generate a virtual circle around the player and set an ideal position for each enemy on a point on that circle. The enemy tracks to this ideal position rather than directly onto the player, as I rotate each ideal position this means that the enemies circle the player when they get close enough.

The swarmer also has a more aggressive ‘ram attack’ where it propels itself towards the player at high velocity. To make sure that not too many swarmers are doing this at once I maintain a virtual ‘baton’ which is passed from one enemy to another, only the enemy that possesses this ‘baton’ can carry out the attack. I can vary the amount of batons per group to increase difficulty.

Whilst testing on large groups of this enemy I found that gameplay tended to get a bit unbalanced, with all enemies lumped on one side of the player. To avoid this I’ve implemented a ‘split’ AI whereby, if things do get too ‘one sided’, a bunch of enemies will split off in the ‘wrong’ direction to wrap round the game world and attack the player from the other side in a pincer movement! You can see this in action in the video. This mechanic seems to work well so I’ve applied it to a few of the other ‘swarm’ type enemies as well.

Dev Time: 4 days
Total Dev Time: approx 320 days

previous

mockup_3x
The New Jetboarding Enemies

mockup_3x
Close-Up of the Swarmer Enemy

Jetboard Joust DevLog #108 – Spit And Polish

The last couple of weeks have been taken up with what seems like an endless round of playtesting, bugfixing, and making minor improvements. It’s the first time I’ve really played the game through from scratch, gradually upgrading a character and progressing through the various worlds in an attempt to see how much time, and how difficult it is, to complete the game.

I made it to just before the second-to-last boss before realising I had to implement major changes to the cost/benefit ratio of the weapon upgrade system in order to get things to scale properly across the game. So now it’s back to square one for another go (groan). It took me around 11.5hrs of gameplay to get this far so I reckon there’s at least 15hrs worth in the game in total.

Every time I come across a bug (no matter how minor), or something that I just find frustrating in the overall experience, I log it in Trello to fix later. There’s been too many minor improvements to list here so I’ll just go over some of the key ones…

Abduction Warnings
There is now an indicator to show where the closest abduction is relative to the player. What became clear to me during playtesting is how vital it is to unlock teleports at the end of each level in order to enable free travel throughout the various worlds. As you unlock teleports by completing a level without having had any of your babies abducted, warnings as to when and where abductions are occurring are key. I may also add some kind of audio indicator as well, like a siren or something.

Map Improvements
Rather than show every upgradeable item with the same icon the map now differentiates between new weapons, weapon upgrades and (valuable) jetboard/jetsuit upgrades. This make it less likely that the player will get frustrated chasing items that are less important. The map now also shows the location of the jetsuit (akin to the bloodstain in Dark Souls) which makes it easier for them to retrieve any cash they may have lost on their previous game.

Weapon Warnings
It was too annoying when enemies armed with powerful weapons such as the RPG or grenade launcher ‘one shotted’ the player pretty much as soon as they appeared onscreen so I’ve implemented a configurable delay for certain weapon types. The first time an enemy appear on screen there’s a delay set before they can fire so the player has adequate warning that that weapon is ‘in play’. A separate (shorter) delay time can also be set for each subsequent time the same weapon appears on screen.

Explosive Weapon Limits
I have limited the player to one explosive weapon per level, some levels offered up multiple explosive weapons which pretty much made the player invincible. The was fun, but didn’t really do much for the gameplay.

Rocket Recharge Limits
I have stopped the meter that indicates when a new rocket will be awarded (for the jetboard attack) from filling up if the player’s rockets are maxxed out. It seemed a bit too easy that a new rocket pickup would get dropped almost as soon as the player used the jetboard attack.

Combo Restrictions
I have limited the cash ‘combo’ multiplier at x5 as it was ratcheting up massive combos which could dish out a huge amount of cash and throw off the upgrades system.

Upgrade Tweaks
I have implemented an algorithmic system for allocating weapon upgrade costs that takes into account the maximum amount of cash that can be earned on the level when the weapon is unlocked, and the estimated amount of levels before the weapon is maxxed out. For weapons that are unlocked earlier on in the game I have allocated more upgrade levels so that they can be upgraded regularly early on but also continue to be upgraded throughout the game and dish out enough to damage to be effective in the later levels. This is proving to be one of the hardest things to balance.

Restrict Level Exit
It was too annoying to accidentally teleport out of a level when you were in the middle of a boss fight. Consequently I’ve made it so that, once a treasure chamber has been activated, you can’t exit the level until either the boss(es) have been defeated and the treasure retrieved, or you’ve lost a life.

There have been numerous bugfixes as well, and other minor improvements. I’ve also made some very significant improvements to the way I calculate explosive damage but that’s going to be the subject of a post in its own right…

Dev Time: 8 days
Total Dev Time: approx 316 days

previous

mockup_3x
The Antimatter Gun Was Too Overpowered, So I Added Some Recoil

mockup_3x
Sticky Explosives Now Attach Properly To Rotating Enemies

mockup_3x
There’s Now An Indicator For Alien Abductions

Jetboard Joust DevLog #107 – A Day For Saving

The final major thing I wanted to do before releasing the beta (other than going back to the PC port) was implement multiple save ‘slots’ per game. It’s surprising how few games bother with this now but for me, it’s essential. Not only does it provide a loving nod back to the days of 8bit consoles, it allows the player to mess around with different upgrade paths and/or multiple members of the same family to maintain their own save state.

It’s not really a technical challenge either. What’s time consuming, as with most functionality of this nature, is designing and implementing the UI.

Fortunately I was able to cheat by recycling 90% of the UI for the upgrades screen (which I’d implemented in a pretty flexible manner to allow for different numbers of stats per weapon). This saved me a ton of time and allowed me to romp through this task pretty quickly.

The only real change I made from a UI perspective was the positioning of the ‘jetsuit’ and ‘jetboard’ icons. I also though the jetsuit looked a little static without any kind of animation so I implemented a few simple idle anims to bring things to life a bit.

On MacOS I have shifted location of the save files to ~/Library/Application Support rather than the default C# IsolatedStorage directory. This makes more sense and, crucially, means save files are preserved between builds (I wouldn’t be able to test it otherwise). As I’m using JSON for the save data I’ve also implemented a very simple encryption algorithm to obfuscate the files, it’s now now longer a trivial business for users to edit the file to change upgrade levels etc!

The game saves at the end of every level and at other key points, such as losing a life and upgrading a weapon – not every time the user picks up a coin or something. Consequently progress will be lost if the user quits in the middle of a level but I don’t think this matters – the end of the level is effectively the ‘save point’.

Testing seems to have gone relatively smoothly so far but I’m continuing to test as I do my final round of pre-beta playtesting.

Wishlist Jetboard Joust here, and view the trailer here, sign up for the beta here.

Dev Time: 2 days
Total Dev Time: approx 308 days

previous

mockup_3x
Close Up of the Jetsuit Idle Animation

mockup_3x
The ‘Save Slots’ UI

Jetboard Joust DevLog #106 – Full Steam Ahead

Yes, Jetboard Joust can now be wishlisted on Steam here. Your support is much appreciated, even if you don’t end up buying it each wishlist helps!

I’m getting rather behind on this devlog again and wanted to write something about the process of getting the Steam page up. Even if it’s not strictly ‘development’ per se, it’s an important part of the process and took me some time.

I started off by reading this excellent Reddit post on how to create a kick-ass Steam page. Lots of useful info there and I kept referring back to this throughout the process. I also spent quite some time looking at the pages of other games, especially those that are also in the same general genre (fast-paced pixelart SHMUP) such as Nuclear Throne and Enter The Gungeon.

The bulk of the work, of course, is creating image assets. I decided to do this using the in-game art rather than trying to illustrate the game in some other fashion. This was a decision largely borne out of necessity (it would have taken me ages to produce quality vector illustrations), but I also felt a pixel art approach would more accurately convey the spirit of the game. If I couldn’t get it to work with pixel art I’d try another method, maybe even commission someone else.

I started off working on rough layouts using art cut-and-pasted from the trailer just to see if what I wanted to do was going to be achievable. I knew I’d need to use at least one of the boss sprites as they were the only ones likely to have the necessary impact without being blown up a ridiculous amount. I settled on the ‘stinger’ boss as it seemed to work well within the proportions of the various steam ‘capsules’, the other bosses actually proved to be too large and complex.

When I had a layout I was happy with I built a much cleaner final version using art taken from the original sprite sheets.

A huge part of the game’s personality though is the particle and shader effects and without these my capsule images were looking rather static and boring. As these are all semi-transparent in-game and overlap other elements it was impossible to cut-and-paste them from gameplay footage and would have been extremely laborious to recreate them ‘manually’ in Photoshop. Consequently I was a bit stuck as to how to convey these in a static context.

After much head-scratching I came up with the idea of doing a pure black-and white palette for the game. I could then make only the particle and shader fx visible, capture these as gameplay footage, import them in to Photoshop as an alpha channel, position where I saw fit and apply colors and blending. This method, with a bit of post-editing, worked really well and, I think, enabled me to communicate the feel of the game pretty well in a static context without a lot of laborious Photoshop work. It was also extremely useful when it came to mocking up / embellishing screenshots. For the screenshots I also used a ‘green-screening’ technique whereby everything but key sprites are rendered in green making cut-and-paste from gameplay footage extremely easy.

Annoyingly the ‘angled’ logo I use in-game just didn’t work within the proportions of the Steam Capsule images, particularly the smaller ones, and its proportions meant it was either too big or too small when blown up in the exact multiples necessary to maintain the pixel integrity. Consequently I had to recreate a purely horizontal version of the logo which I did in illustrator and pasted into Photoshop as vectors. I think a ‘pure’ pixelart version would possibly have looked better but I’m not sure it would have justified the amount of time needed to do it, particularly given the differing size requirements.

Then there was also the text to write, a myriad of forms to fill in, emails to write to try and generate some publicity, tags to add and a press page to create. I was pretty much losing the will to live by the end of it (not the first time I’ve said that on this project) but it’s done now. Check out the final result here.

Dev Time: 6 days (including other marketing)
Total Dev Time: approx 306 days

previous | next

mockup_3x
Steam Main Capsule Image (click to enlarge)

mockup_3x
Steam Library Capsule Image (click to enlarge)


Blacked Out Gameplay Footage For Photoshop Alpha Channels

‘Green-Screening’ Makes Composing Screenshots Easier

Lerp Camera Motion Smoothing Tutorial and Example Code

Recently I’ve been revisiting at the way the camera works in Jetboard Joust (wishlist on Steam here!) something that has been a continual thorn in my side throughout the project.

When researching how to make the camera movement better I came across many references to Lerp smoothing but I found few, if any, detailed explanations as to how this works in practice and (particularly) ways to get around its significant limitations. Cue this post, by the end of which we’ll have a class that’ll move an object smoothly towards a target point and ‘brake’ so it reaches it exactly no matter how often and by how much the target is changed.

I’m just concentrating on one axis of movement here for simplicity but this approach can easily be applied to 2D or 3D vectors. For those of you with short attention spans you can just download the final class here.

So… Lerp is a quasi-acronym for ‘linear interpolation’ and used to create smooth movement between two points. It’s often used to smooth out camera movement but can equally be applied to sprites or anything else in 2D or 3D space. The basic equation for Lerp is very simple, it takes a position and target, works out the difference between them and then returns a value a specified amount along that path. Only values >0 and <1 are generally meaningful.

public static float Lerp(float position, float target, float amount)
{
     float d = (value2 - value1) * amount;
     return value1 + d;
}

If you are using this equation to move an object and each frame call it with the object’s current position (keeping the other values the same) the object will move a smaller distance each frame which results in a ‘slowing down’ effect as the objects reaches its target. Here’s an example of this type of motion applied to a sprite. In this case the sprite is moving approx 480 pixels at a frame rate of 60fps with a Lerp value of 0.025.


Basic Lerp Smoothing

Now this looks pretty good already but, as you’ve probably figured out, there are issues. The first one is that using this approach the object will never actually reach its destination – this can result in a slightly jerky looking motion as it reaches the end of its trajectory as well as presenting potential issues if you want to do something when the destination is reached.

One way of resolving this is to implement a minimum amount of movement per frame. This can be anything you want but for many applications it makes sense for this to be one pixel.

Here’s a simple ‘Lerper’ class that implements this – each frame the amount of movement (LerpVelocity) is calculated and, if the absolute value of this is less the minimum velocity we clamp it at the minimum velocity. Of course this means that the object might now be in danger of moving beyond its target point so we check for this at well and make sure it doesn’t.

public static float Lerp(float position, float target, float amount)
public class Lerper
{
    public Lerper()
    {
        Amount = 0.025f;
    }

    // Returns the amount of movement at this stage of the lerp
    private float LerpVelocity(float position, float target)
    {
        return (target - position) * Amount;
    }

    public float Lerp(float position, float target)
    {
        float v = LerpVelocity(position, target);

	// If this is less than the minimum velocity then
        // clamp at minimum velocity
        if ( Math.Abs(v) 0) ? MinVelocity : 0 - MinVelocity;

	position += v;
	// Now account for potential overshoot and clamp to target if necessary
        if ( (v= target))
        {
            position = target;
        }
        return position;
    }

    public float Amount
    {
        get;
        set;
    }

    public float MinVelocity
    {
	get;
	set;
    }
}

Here’s an example of this in action. As you can see it looks much better…


Lerp With Minimum Velocity Applied

Still we have limitations though if we’re looking for really smooth movement. The next glaringly obvious one is that Lerp is ‘ease out’ only, the object will be moving fastest at the start of the sequence which makes it look like it’s being fired from a slingshot rather than smoothly accelerating from rest.

To resolve this I’m going to apply an ‘Acceleration’ property to my Lerper class. This ensures that, if the object is increasing in speed, the increase doesn’t exceed a specified amount. This requires a variable to store the amount of movement each frame.

public class Lerper
{
    private float previous_velocity;

    public Lerper()
    {
        Amount = 0.025f;
        Acceleration = float.MaxValue;
    }

    // Returns the amount of movement at this staget of the lerp
    private float LerpVelocity(float position, float target)
    {
        return (target - position) * Amount;
    }

    // Returns the next position with lerp smoothing
    public float Lerp(float position, float target)
    {
        // get the amount to move
        float v = LerpVelocity(position, target);
        // don't allow increases in velocity beyond the specifed acceleration
        if ( v>0 && previous_velocity>=0 && v-previous_velocity>Acceleration )
        {
            v = previous_velocity + Acceleration;
        }
        else if (v < 0 && previous_velocity  Acceleration)
        {
            v = previous_velocity - Acceleration;
        }
        // If this is less than the minimum velocity then
        // clamp at minimum velocity
        if ( Math.Abs(v) 0) ? MinVelocity : 0 - MinVelocity;
        }
        // Remember the previous velocity
        previous_velocity = v;

        // Adjust the position based on the new velocity
        position += v;
        // Now account for potential overshoot
        if ( (v= target))
        {
            position = target;
        }
        return position;
    }

    public float Amount
    {
        get;
        set;
    }

    public float MinVelocity
    {
        get;
        set;
    }

    public float Acceleration
    {
        get;
        set;
    }
}

Here’s an example of this in action – now we have a nice ‘ease in’ to our Lerp motion. Here I’m using an acceleration value of 0.25f.


Lerp With Maximum Acceleration ‘Ease In’ Applied

There’s one other problem I’m going to address though. This ‘ease in’ effect works nicely if the object is initially at rest or moving in the same direction but if the object had previously been moving in the opposite direction we’re still going to get a nasty jolt. Here’s an example where I’m changing the destination to the opposite side before the previous Lerp has reached the end of its trajectory.


Sudden Changes In Direction Result in A Nasty Jolt

So we’re going to check for this in the code and again apply a maximum amount by which the velocity can change each frame. Remember that because we’re changing direction the absolute value of the current velocity at the point of change is the sum of the absolute value of both the current and previous velocities, ie a change in direction from 10 to -10 would result in a new velocity of -20.

A side-effect of this is that the object will probably end up moving away from the target until it’s gathered enough momentum to change direction. As the code that clamps to the target position assumes we are moving towards the target we have to max out the target value if this happens.

We also have a special case check for our minimum velocity here as we need to make sure that if the minimum velocity is applied its applied in the direction that moves towards the target (otherwise the object could get stuck moving in the wrong direction).

public class Lerper
{
    private float previous_velocity;

    public Lerper()
    {
        Amount = 0.025f;
        Acceleration = float.MaxValue;
        MinVelocity = 0;
    }

    // Returns the amount of movement at this staget of the lerp
    private float LerpVelocity(float position, float target)
    {
        return (target - position) * Amount;
    }

    // Returns the next position with lerp smoothing
    public float Lerp(float position, float target)
    {
        // get the amount to move
        float v = LerpVelocity(position, target);
        // don't allow increases in velocity beyond the specifed acceleration (ease in)
        if ( v>0 && previous_velocity>=0 && v-previous_velocity>Acceleration )
        {
            v = previous_velocity + Acceleration;
        }
        else if  (v  Acceleration )
        {
            v = previous_velocity - Acceleration;
            // we might actually end up moving away from the target
            // here in which case we adjust the target so we don't get
            // clamped to it later
            if (v  0 && previous_velocity  Acceleration )
        {
            v = previous_velocity + Acceleration;
            // we might actually end up moving away from the target
            // here in which case we adjust the target so we don't get
            // clamped to it later
            if (v > 0-MinVelocity)
                v = MinVelocity;
            else
                target = float.MinValue;
        }

        // If this is less than the minimum velocity then
        // clamp at minimum velocity
        if ( Math.Abs(v) 0) ? MinVelocity : 0 - MinVelocity;
        }
        // Remember the previous velocity
        previous_velocity = v;

        // Adjust the position based on the new velocity
        position += v;
        // Now account for potential overshoot and clamp to target if necessary
        if ( (v= target))
        {
            position = target;
        }
        return position;
    }

    public virtual void OnTarget(){}

    public float Amount
    {
        get;
        set;
    }

    public float MinVelocity
    {
        get;
        set;
    }

    public float Acceleration
    {
        get;
        set;
    }
}

Here’s what happens when you suddenly change the Lerp target with this code applied – as you can see we now have a nice smooth movement no matter how often we change the target value.


Lerp With Maximum Acceleration ‘Ease In’ Applied

And that’s pretty much it. You can download the final class file here – in the final version I’ve also added a MaxVelocity property, a delegate to be called when the object reaches its destination, and tidied up the code so its not quite so verbose.

If you are in the process of coding a camera for a 2D game I highly recommend you check out this excellent article.

If you are looking for something to move smoothly between two points over a specified number of frames then you’re probably better off using some kind of tweening rather than Lerp. Check out Robert Penner’s excellent tweening/easing functions or the ‘smoothstep’ algorithm approaches described here.


These articles take a lot of time and effort to put together. If you found this useful and would like to help me create more content like this like you can support me below – I really appreciate it!

Buy Me a Coffee at ko-fi.com

Granny Bait – The Making Of “Skateboard Joust”

Granny Bait: A term used back in the day to describe a game that had virtually no redeeming features but, because it had something ostensibly ‘youth’ in the title (and was cheap), would be bought in droves by clueless older folk as gifts for their disappointed grandchildren.

A while ago I wrote a post about ‘Subterranean Nightmare‘, my first commercial release for the ZX Spectrum. Whereas ‘Subterranean Nightmare‘ was something of a labour of love and represented a genuine attempt to create a decent game, my next title (I am somewhat ashamed to admit) was executed in a rather more mercenary manner. I can’t remember exactly what age I was when I started work on ‘Skateboard Joust’ but I was heading into my late teens. I was losing interest in videogames and starting to become far more interested in guitars, girls and beer. Guitars, girls and beer cost money though – and the best way I knew of to make a quick buck was to churn out another budget Spectrum title.

I never had the slightest interest in skateboarding but tying the game in with something that was relatively fashionable seemed like a good idea. I’d also never played ‘Joust‘, but I’d seen screenshots and knew it was made by the some people that made ‘Defender‘ (which I still rate as one of the finest videogames of all time) so it was bound to be pretty cool.

The central mechanic of the game involves destroying enemies with your skateboard which you can only do if you are mid-jump (not actually riding the board) and I still think this is a pretty sound gameplay concept. It’s not executed very well however and is extremely difficult to get the hang of (‘totally unplayable’ might be a better description). Then there’s the fact that, aside from a few pretty unimaginative powerups, this central mechanic is pretty much all there is to the game making it a fairly tedious experience.

The worst thing about the game though is that what appear to be the level backgrounds are actually in the foreground and serve no purpose other than to obstruct your view of a game that’s hard enough to play as it is. Making gameplay harder by simply obscuring what’s going on must surely be one of the most laughably bad game design ideas ever!

I remember borrowing chunks of code from my brother Tim (of I-Ball fame) who was always a much better coder than me, and recycling some of the graphics from ‘Subterranean Nightmare‘. I also added some of the most embarrassingly ‘wrong’ skate slang between the levels. Not my finest hour but I was paid a £2.5k advance by Silverbird which paid for a lot of beer.

The game was justifiably slated by Crash Magazine at the time, though in recent years some people have been rather kinder to it, notably the vg-junk blog. There’s also some drunk guy on YouTube who plays the game for around five minutes without realising that you can jump off your skateboard!

Bizarrely though the game had some devoted fans despite its awfulness – in the comments for this video there’s someone who seems to take great offence when people suggest that it might be a tad shit! I also ‘met’ the person who did the C64 version in this thread, turns out they got paid considerably more than I did for writing the original!

And no, I have no idea what I was thinking of when I designed those ‘extra’ life icons! They do look like some kind of demented frog!

World Of Spectrum entry here.

30 years later I’m now working on a sequel, ‘Jetboard Joust’, in order to balance out my karma for forcing such a terrible game onto the unsuspecting public. ‘Jetboard Joust’ builds on the central ‘Jetboard of Death’ mechanic and adds a whole lot more besides – you can wishlist it on Steam here and read about the development here.

30 years Later – The Sequel…
Read the instructions you fool!


The C64 Version (With At Least One Devoted Fan)!

cornflower
Recycled Graphics on Skateboards

cornflower
Yes, All That Shit Just Gets In The Way!

cornflower
Attack of The Roast Chickens

Jetboard Joust Devlog #105 – Trailer Trash pt 2

Please wishlist Jetboard Joust on Steam here.

Well, the trailer’s finally done – thank God! As with the last instalment I ran into a few issues along the way and got distracted by (necessary) bugfixes. Here’s a brief summary of how things panned out…

1. Oh, Bugger!
The thing about doing a trailer is that it makes you capture and scrutinize a shedload of gameplay footage AND deviate from your ‘learned’ methods of playing your own game. The consequence of both these things is that you uncover new bugs.

I ran into a few new bugs when working on this section of the trailer, most of them related to trying out different weapon types on the bosses. The most significant of these was that there were major deficiencies in the raycasting algorithm I was using to work out damage caused by explosive weapons. Turned out I was only calculating collisions based on axis-aligned bounding boxes (fine for smaller enemies, not fine for the more complex outlines of some bosses). So I had to redo the algorithm to work properly with convex polygons.

There were also issues in the way damage was distributed via ‘proxies’ (e.g. different parts of the same boss) which had to be looked at and problems with the ‘particle storm‘ weapon which were very fiddly to debug.

2. Enemies and Weapons
The next twenty-ish second chunk of the trailer aims to give an overview of the variety of weapons and enemies in the game. I split the into eight 2.5ish edits, taking the timings from the ‘Enter The Gungeon’ gameplay trailer which seemed to pace the edits about as fast as you can get whilst still making sense of what’s going on. Managed to squeeze a brief glimpse of the weapon upgrade process in here too – I wanted to convey visually that there’s upgrade paths available for the weapons.

The edits were made by grabbing a shedload of footage and then whittling it down to the ‘best’ short segment. This was a time-consuming process. I set up levels artificially so I was only dealing with one enemy at a time – ‘real’ gameplay footage proved too confusing as there was just too much going on most of the time.

3. Bosses
The next twenty seconds or so provide a five second ‘reveal’ of the first four bosses. That’s only enough time to sneak a look at the first attack phase of each but I think that’s enough – I’m bit worried about giving too much away as it is. As with the previous stage, I had to grab a ton of footage and then whittle it down to the ‘best’ edits. I also had to bear in mind the transitions between the edits whilst grabbing the footage, i.e. make sure the player was positioned onscreen at a point where a smooth transition would be possible so the viewer’s eye never has to make a disconcerting jump. I found this was particularly important when dealing with very short cuts. I had to re-shoot a couple of edits in both this section and the last in order to get these transitions smooth.

4. Out With A Bang
Initially this section was simply a glimpse at the final boss fight but I felt that just cutting to titles after this seemed rather lame. Consequently I worked on a more ‘scripted’ take where the player flies over the final boss and then takes it out with an R.P.G. It’s not possible to do this in the actual game (the fight has about five stages) but it acts as a significantly more punchy ending to the trailer.

I had to do multiple takes of this to get it right as I needed to fly over the boss, shoot it accurately, and then position the player accurately in the middle of the screen all without doing anything visually unappealing like crash into the edges of the screen or flipping left/right too much. there were plenty of bloopers – including some where I fired the R.P.G. in completely the wrong direction.

5. Outro Titles
I ended up doing these in code and positioning them over the last section in After Effects using chromakeying. Initially I thought I’d animate them in After Effects but I just found this far too fiddly. Fortunately I was able to use the in-game logo ‘entrance’ without having to change anything much so it was mainly about animating the subheadings with the release date etc. I like the way the smoke is still dissipating in the background as the titles appear!

6. Back To The Beginning
Lastly, I went back to the start of the trailer. I was every-so-slightly over 1:30 seconds so I edited the initial titles down a bit. As some people had commented that the player appeared to come ‘out of nowhere’ a bit (I kind of agreed with this) I tried panning across to the player before going back to the alien babies/abductions. This seemed to work. I also made the player blink in this cut to bring him to life a bit (done in After Effects) and added ‘abduction’ and ‘mutation’ text with pans and zooms with the rest of the action.

Now I think we’re finally there. Next task – Steam page and assets!

Dev Time: 8 days
Total Dev Time: approx 300 days

previous | next

The Final Trailer In All Its Glory

mockup_3x
Raycasting Now Works Correctly With Convex Collision Polygons

mockup_3x
Fixing ‘Proxy’ Collision Detection Bugs

Jetboard Joust Devlog #104 – Trailer Trash pt 1

Decided to split this devlog in two as making a videogame trailer is a fairly long process, particularly when you don’t know what the hell you’re doing! Plus there’s been a couple of other things that needed attending to before I felt I could really progress as I’d like.

1. Audio FX
Firstly I had to do some more work on the in-game audio. There were a number of actions I felt required fx that didn’t have any (some pretty important such as unlocking weapons and worlds) and a couple I wasn’t happy with. I spent a couple of days on this. There are now around 270 individual effects files in the game, and that’s not including background music and loops! I think the audio is a pretty distinctive part of the game due to the fact it’s all produced from scratch on analogue gear – no stock samples here, folks!

2. Performance Optimisations
Secondly, as I was recording a bunch of action footage I began to notice frame-rate drop at a few points where there was really intense action on screen. This was exclusively at places where enemies that release a bunch of ‘offspring’ are destroyed by a weapon that kills the enemy and all it’s offspring in one fell swoop (e.g. the jetboard attack). The resulting explosion-and-bonus-fest was just a bit too much.

So, I worked on some optimisations for the above. This included adding object pooling for every object that’s generated when an enemy is destroyed, combining multiple smaller explosions and/or smoke clouds that are very close together (and instantiated in the same frame) into one larger one, and pre-caching of the terrain elements that pickups might hit as they fall (rather than calculating this every frame). I’ve also let some offspring ‘escape’ in the above scenario as I didn’t like it when absolutely everything got destroyed. I no longer see any frame rate drop now, even when there’s a shitload of fireworks going on, and I’m running a Mac from 2008!

3. Start The Trailer
Before starting the trailer I read through a number of very helpful blogs on the subject by Kert Gartner and M. Joshua. Here is a particularly good one.

3.1 Choose The Tools
One of the most useful practical tips I picked up from these was a pointer to an app called Screenflow that will grab 1080 game footage at 60fps even on my ancient Mac. I’ve been through a bunch of these screen capture applications (Snapz Pro, Capto, Screenium) but Screenflow is the only one that will do this. Capto is cheap and neat (this is what I’ve used for most of my animated GIFs and devlog posts) but will sometimes compress really heavily for no apparent reason, Screenium is almost as good as Screenflow (and cheaper), will let you record a set area AND remembers this rea (really useful) but it still compresses a bit even at the highest settings (plus I found it’s editing tools a tad clumsy and prone to crashing). For the purposes of recording gameplay footage for trailers Screenflow definitely comes out tops.

3.2 Intro
Probably the hardest part of the trailer to get right is the first 15 seconds. You don’t want to lose the user’s interest and you have to attempt to communicate the core mechanics of your game in as short a time as possible (without being overly didactic). I’m still not sure I’m 100% there but I think what I’ve come up with does a reasonable job of communicating abductions, mutations, the jetboard attack and the general carnage of the game in that timeframe. To get this footage I used a combination of scripted events (i.e. faking things through coding) and playing through a set sequence over and over again until I managed to one-shot all the enemies in a way that looked effortless and ‘readable’ enough.

3.3 Shock & Awe
After this initial intro section comes just under another 15 seconds of what I’m referring to as ‘shock and awe’. This is a high-octane segment that focusses mainly on the destruction wrought by the jetboard attack but also features a couple of other weapons. This is all ‘real’ gameplay footage, I just recorded a load of stuff to get a variety of enemies and palettes. I deliberately try and move the action from one side of the screen to the other here.

3.4 Breathing Space
Lastly comes just over 10 seconds of ‘breathing space’. A longer cut in which we see the destruction of a boss, the opening of a treasure chamber and the discovery of a new weapon. This section has a certain amount of scripting (reducing the bosses health and getting rid of some onscreen distractions) but is largely the result of playthrough after playthrough to get things looking slick and pulled off in as short a time as possible.

I’ve tried to keep the player’s position onscreen consistent between cuts so that the viewer’s eyes can easily track what’s going on. I’m also zooming/panning across the action where appropriate in order to avoid ‘dead’ areas of screenspace and create variety. I thought this might be overly distracting but it doesn’t seem to be.

So now we have just under 45 seconds of trailer done which is approximately half of it. Next step, around 20 seconds on enemies and weapons, 20 seconds on bosses, and a five second closer!

Dev Time: 10 days (inc 2 days audio and 2.5 days performance optimisations)
Total Dev Time: approx 292 days

previous | next

Jetboard Joust Devlog #103 – A Broader Palette

Well, I reckon this has been the longest break between devlog updates so far. I’ve had two contract jobs on, one of which turned into a bit of a never-ending spiral with the client refusing to pay me unless I kept adding additional functionality (for free). Shame, as it was kind of a nice project otherwise. I have a bit of a rule about not working for startups which I broke for that one as I knew the person involved and was interested in the concept.

I’ve also had a lot to do at a rental property I own which needed considerable TLC between tenants and which was built to a very shoddy standard. Grinding out and re-doing grouting between floor tiles in the bathroom was a horrendous job – hope I never have to do that again!

Anyway, you don’t want to hear about that shit. The bulk of the work on Jetboard Joust has been in finalising the main palettes for each of the five ‘worlds’ that comprise the game. I’m going to have four main palettes per world, plus a bunch of ‘bonus’ palettes that can be unlocked by completing specific levels.

I probably should have coded a tool to make this process easier but I just couldn’t face it when the time I had available was very piecemeal, generally half a day here and there between contract work and property maintenance! Consequently my working process was pretty inefficient, basically editing a big PNG of all the palettes in Photoshop before recompiling and running the game to see how things looked.

There are ten colours per palette in the game and the following items can all have a different palette applied (though in practice many share the same palette)

– Player
– Enemies (three types)
– Bosses
– Pickups
– Terrain
– Floor
– Background parallax (both layers)

To design the palettes I used a combination of reference material and inspiration from messing around with colour association using coolors.co and a simple colour ramp generator.

The actual palettes themselves I’ll list below and detail the specific inspiration where appropriate. These are all in the order they appear in the vids.

World One
I wanted to start the game with earthy, muted colours and then progress to more vibrant colours as the user moves through the worlds, as well as slowly introducing different palettes for different sprites. The first palette is the slightly gameboy-ish one I’ve been using from day one and I gradually add more subtle hues to this as we move on. There’s no specific inspiration for the palettes in this world though I was looking a bit at army camouflage designs for the third palette here which is currently named ‘Going Commando’.

World Two
Each of these palettes had a different inspiration, only two of them particularly related.

1. No Space To Scream
A good ‘segue’ palette from the muted colours of world one. This is inspired by the colour scheme for the branding of the original Alien movie.

2. Deep Dive
Inspired by photographs of coral reefs. As the boss in this world is a giant alien robot-fish this seemed appropriate somehow.

3. Neon Flux
Inspired by neon-heavy nighttime shots of cities, particularly Tokyo. Visually it has the feel of being a much more saturated version of the previous palette.

4. Aliens on Acid
Originally inspired by the ‘Alien’ colour scheme as was the first palette, only with colours so saturated it almost has an early arcade / ZX Spectrum feel.

World Three
We go back to a slightly more ‘muted’ feel for these palettes, all of which have their inspiration from vintage designs.

1. Stan and Jack
Inspired by the cheaply printed colours of early comic books, particularly the Marvel stuff.

2. Dead Red Revolution
Partly inspired by poster art from ‘Grindhouse’ style movies (I have a large poster for ‘Death Proof’ on the wall of my studio) and partly by the artwork for Red Dead Redemption which has a similar ‘vintage’ feel.

3. Forbidden Fruit
Inspired by a poster for the 50s sci-fi classic ‘Forbidden Planet’ – I’m really pleased with this one.

4. Retro Apocalypse
Inspired by some cover art for a 50s or 60s pulp sci-fi novel. I am not convinced by this one. It kind of works but some of the sprites just don’t. Needs more work!

World Four
All inspired by various ‘horror’ related themes! We move back to some pretty saturated colours for these ones.

1. Dead Evil
Inspired by the original posters for Sam Raimi’s ‘Evil Dead’ movie.

2. House of Hammers
Inspired by the poster art for various low-rent Hammer horror films. This is another one I’m particularly pleased with.

3. Toil and Trouble
I went for deliberately clichéd ‘Halloween’ style colours for this one. Very saturated and ‘in your face’ but I think it works.

4. Black Mass
Inspired by various different, more modern, horror film posters – as well as the artwork for the ‘American Horror Story’ TV series (which I thought was terrible and never made it past the first series).

World Five
These were mainly inspired by the manual artwork for early Atari arcade cabinets. I absolutely love that stuff and it also adorns the walls of my studio (alongside the aforementioned Death Proof poster and paintings by Basquiat and Tapies).

1. Rayguns at Dawn
Inspired by the ‘Space Duel’ manual art.

2. Planet X
I forget what inspired this specifically (oops) but I’m pretty sure it was the cover art for another vintage pulp sci-fi novel.

3. Gravity’s Rainbow
Inspired by the ‘Gravitar’ manual art. This is one of my favourite palettes in the game.

4. Prospero’s Cabinet
Inspired by the ‘Tempest’ manual art.

There’s still the bonus palettes to be finalised, I’ve done quite a few of them and there’s a lot of nods in there to 8bit home computers and consoles. That’ll be the subject of another post though! Hopefully things will move a little quicker over the next few weeks, next task is to fill in a few gaps in the audio then do a pretty much final teaser vid and get my Steam page up (I probably should have done the latter months ago).

Dev Time: 10 days (pretty broad estimate)!
Total Dev Time: approx 292 days

previous

World Two Palettes – Aliens and Oceanography

World Five Palettes – Atari Arcade Manual Art

mockup_3x
Awesome Atari Arcade Manual Art

mockup_3x
The Forbidden Planet Poster That Inspired One Of My Favourite Palettes