Jetboard Joust Devlog #30 – Crossed Platforms

Porting From Mobile To PC with MonoGame
This week I was supposed to have started on the initial gameplay testing for Jetboard Joust but I came up against a rather nasty snag.I develop using Xamarin Studio on a Mac and had been using the GenyMotion Android emulator for my main testing platform. This probably seems strange given that my main target platform is PC, but GenyMotion generally runs extremely well and I don’t want to have to buy another machine just for development purposes. Unfortunately I discovered a problem with GenyMotion in that it seems to just ‘miss’ some keyup/keydown events. The problem is intermittent but bad enough to make serious gameplay testing on the platform impossible – no response from their support either.

That means I need another platform for testing. The iOS simulators are hopeless for graphics performance (and don’t respond to keyboard control as far as I’m aware), Google’s stock Android emulators take an age to launch/install builds and the Xamarin Android Player, though fast, is still pretty flaky. That left Xamarin.Mac as the only ‘native’ Mac option but there’s a hefty additional licence charge for that (or at least there used to be – I couldn’t quite work out what’s going on with Xamarin.Mac since the Microsoft buyout).

As a result of this tragic state of affairs (remember when Apple used to take x-platform development seriously in the initial OSX days?) I decided the only option would be to ditch Mac native and move to running Windows under VMWare Fusion (at least for any development that requires serious gameplay testing). Quite a change. I’ve done this before for ‘Attack Of Giant Jumping Man’ though so was optimistic that it should be a workable solution, plus I’d have to do the PC port anyway at some point – may as well get on with it.

So I started with a brand new Windows 8.1 VM and a fresh installation of Visual Studio 2015. I’ve been using MonoGame 3.2 up to this point but this was as good a time as any to update to 3.5. Installation of the various components was a breeze. I chose the DesktopGL target as it was most similar to the target I’d worked on for ‘Attack Of Giant Jumping Man’ (so hopefully the few bits of platform-specifc code I’d had to write could be re-used) and it didn’t take too long to get my project to compile. The only problem I ran into was that references to the Microsoft.Xna.Framework.GamerServices namespace couldn’t be resolved. For some reason the reference to the assembly that contains these wasn’t included in the MonoGame template project and had to be added manually (Add Reference->Extensions and then choose the appropriate MonoGame.Framework.Net assembly for the platform you are targeting, its a bit confusing as all the assemblies are named the same in the list so you have to click on each one to see more info).

I’m using the ‘shared folder’ feature of VMWare Fusion to share my source code directory between Mac and Windows – if I import the source files as links then both my Xamarin Studio projects on MacOS and my Visual Studio projects on windows both remain perfectly in sync – nice!

Next step is to import all the content – unfortunately I can’t figure out a way to keep all these files in sync as importing a file as a link from a shared folder doesn’t seem to work in the MonoGame pipeline tool. This is a bit of a bummer but not to much of an issue at the moment – hopefully I can figure something out eventually.

Only issue with the content was that I was getting an error when compiling my custom shader files due to a missing DirectX component (‘d3dcompiler_43.dll’) despite having DirectX 11 installed. I followed the instructions to fix this here (using the second method, not the full install) and all was fine.

So now everything would compile and run. Imagine my joy when, on launching, all I got was the garbage you can see in the GIF on the right. Complete gobbledegook. Spirits totally crushed. What. The. Hell.

I had absolutely no idea what was going on here and no idea where to start debugging. Nothing I thought of initially had any effect. Jetboard Joust runs on MEAT, my own (originally Java-based) 2D gaming platform that has been over ten years in development. MEAT is another layer of abstraction above MonoGame and fairly complex making it difficult to strip things down to MonoGame basics and do a few simple tests but this is clearly what I needed to do.

I decided to run a few simple MEAT tests first and see if I could get anything up and running…

1. Load image and draw sprite
2. Load image and draw sprite with clipping (as if from sprite sheet)
3. Load image and draw sprite with crop (MonoGame ScissorRectangle)
4. Load image, render to offscreen buffer (RenderTarget2D) and then to screen.

…all of these worked fine which was encouraging to an extent but didn’t get me any closer to a solution. However the next test produced some very strange results.

One of the MEAT classes is a graphical font class – a bitmap font and associated metrics data are stored in a single file which can be used to easily render bitmap text to screen. When I tried a test render using one of these graphical fonts the text would appear OK and then mysteriously disappear after around 30 seconds on screen. Bizarre. This mysterious disappearance only happened when my game template code (that handles all the main menus and stuff) had been executed at startup, ie at least 30 seconds before the problem occurred.

So all I could do was to comment out chunks of the game template code, launch the app, and then run a timer for approx 45 seconds to see if the font disappeared – an incredibly tedious process reminiscent of debugging on J2ME handsets. Eventually I narrowed it down to the line of code that was causing the problem – I was reassigning the property originally assigned to the graphical font that was drawn to screen to a different graphical font. Even though this was a mistake on my part there is absolutely nothing ‘wrong’ with this and it wasn’t causing a problem on any other platform. I had to test and retest several times to convince myself that this line of code was the problem but it was – as soon as I didn’t reallocate the property once the font was drawn to screen the test font didn’t disappear and the entire game ran perfectly!

All I can think of is this had something to do with garbage collection of graphics memory. Reallocating the property meant that the garbage collector (incorrectly) thought the memory should be freed which resulted in some kind of graphics meltdown. This would explain why it took around 30 seconds for the problem to appear – it only happened when the garbage collector kicked in. I create the font images using Texture2D.FromStream() rather than the Content.Load() methods in MonoGame which is slightly weird and could be something to do with it as well – I doubt this is as well tested as the Content.Load() methods.

Anyway, one can’t really blame the MonoGame team for missing such an obscure issue and even with the amount of time I wasted over this it was still a pretty fast cross-platform port so kudos to them. Android/iOS to PC in around a day with about 99% of the codebase consistent – not to be sniffed at! Nice to see the issues with the XBox controller fixed in MonoGame 3.5 too!

Dev Time: 1 days
Total Dev Time: approx 32.5 days

previous | next

mockup_3x
Where On Earth Do You Start To Debug This Shit?

Got There In The End – PC, Full Screen, XBox Controller

Jetboard Joust Devlog #29 – To Do’s Are Done

I hate ‘to do’ lists so usually I decide I can’t be arsed ‘to do’ them. There’s something about them that makes me feel like I’m working for ‘the man’ even though I’m sitting in my home office surrounded by synths and guitars with King Gizzard & The Lizard Wizard cranked up to an antisocial volume.

They are useful sometimes though so I do resort to them when I’ve got a lot of boring, fiddly stuff to finish and am having motivation issues. There is something mildly satisfying about crossing items off one by one which is why I always do them on paper – digital ‘to do’ lists are even worse.

So anyway, here’s what’s been on my ‘to do’ list and is now ‘done’. It’s pretty dull but then game development is a lot of the time I’m afraid (sorry to burst your bubble kids, Santa isn’t real either).

Add ‘Brake’ Functionality To Enemy AI
The jetboarding enemies were still kamikaze-ing into the player too often as I was relying on air friction to slow them down which just wasn’t slowing them down quick enough. I’ve given them the ability to air-brake – it’s a bit of a cheat as the player can’t do this without turning round but it looks a lot better.

Make Enemies Drop Ammo
I’m pretty sure it’s going to be too easy to run out of ammo so I’ve added the ability for enemies to drop a small ammo cache when destroyed. Unlike the larger ammo pickup (which completely recharges the current weapon) this one just adds one ‘clip’ of ammo.

Add Pickups And Warp Gates To Scanner
Self explanatory – needed to be done and involved a bit of messing around with class hierarchies.

Improve Rider vs Board Collisions
I felt the way this was working was inconsistent so I’ve added a separate collision check for the rider and the board. A Rider vs rider collision won’t cause any damage the bulk of the time, health is mainly lost when a rider collides with an opposing jetboard.

Add ‘Teleport In’ Effect For Enemies
I was presuming all enemies would be there at the start of each level but after playing ‘Defender’ some more I’ve decided I’m going to need batches of enemies that appear as a level progresses which means I’m going to need some kind of ‘teleport in’ effect. I’m using the same effect I used for the player and wanted to duplicate as little code as possible so, again, needed to mess with the class hierarchies a fair bit to get this to work.

Remove Permanent Enemy Health Displays
I thought this looked a bit dumb when there were lots on enemies on screen so now the enemy health bars automatically show/hide as they take damage. Thankfully this code was already shared with the player and it was just a matter of turning the ‘auto-hide’ feature on.

Add Scanner To HUD
In the code scanner and HUD they were separate which resulted in some stupid duplication of code when switching shaders for the level teleport effect. This is structured much better now.

Fix Scanner Wrap Bugs
Items on the scanner were getting cropped when they crossed the wrap point of the game world. Fixed this by drawing them twice in this scenario at both the left and right of the offscreen image.

Tidy Up Scanner
Changed the way the ‘screen marker’ is positioned as this was overlapping some scanner elements and also fixed an int rounding issue which meant that scanner items with an odd number of pixels in width weren’t getting aligned correctly.

Fix Board Flashing After Player Death
You can see this in some of the previous GIFs – the player’s jetboard was rendering with the ‘collision’ shader when the player continued to get pummeled by bullets after he’d died. I’ve changed this so the jetboard only does this if the player is riding it.

Can’t Collect Pickups After Warp Gates Appear
Dumb bug – fixed!

Carry Last Weapon Over Between Lives
Rather than starting with the default weapon each life.

Weapon Crate Icon Not Showing After New Level
Dumb bug – fixed!

Some Enemy Bullet Trails never Disappear
Dumb bug – fixed! This one was quite a hard one to track down.

And that’s the list all crossed off (for now). Looking forward to actually starting to refine the gameplay!

Dev Time: 1 day
Total Dev Time: approx 31.5 days

previous

mockup_3x
The Improved AI With Braking

mockup_3x
Enemies Now Drop A Small Ammo Cache

mockup_3x
Gameplay Viewed On The Improved Scanner

Jetboard Joust Devlog #28 – Bounty Hunter

So, with those annoying bugs out the way it’s time to start on what will probably be the last pickup – cash!

I want to have some kind of in-game currency for upgrading weapons and the like and I can’t see any point in getting too clever about it so I’m just going to stick with cold, hard cash. Plus I like the retro feel of having big spinning coins that get scattered all over the place – having an enemy dissolve into spinning coins is something of a videogame archetype after all.

The spinning coin wasn’t too hard too get right (at least compared to the spinning crate) but still took me a good couple of hours tweaking. I may well have different sizes of coin so this one, at 12px square, will either be the small or medium. I’m pretty pleased with it though I’m in two minds about whether the way some of the middle pixels flash a bit looks like light reflecting or just looks crap!

Once the coin was done the rest was pretty straightforward implementational stuff – the thing that took the longest was tweaking the particles etc for the ‘got coin’ effect. I also had to add a ‘cash’ element to the HUD.

So now I think I have all core gameplay elements in place really – now I need to start adding some enemies properly and get working on a first playable level. This is also the point where I need to decide if I’m going to do my main gameplay testing on mobile/touchscreen or PC/controller. Or both!

Dev Time: 1 day
Total Dev Time: approx 30.5 days

previous | next

mockup_3x
The Spinning Coin

mockup_3x
Bounty Hunting

mockup_3x
More Bounty Hunting

Jetboard Joust Devlog #27 – Bang Go Some Bugs

Bit of a ‘clearing the decks’ session today as I get rid of a few bugs that have been irritating me. There were problems with the teleport sequence that I needed to fix (the jetboard weapon attachment not getting displayed correctly), the ‘lost the jetboard’ sequence was annoying me (as the main character carried on waving his arm all gung-ho even when it was obvious he was heading for certain death) and I needed some kind of explosion/disintegration effect for a destroyed jetboard.

None of these proved particularly heinous to sort thankfully so I could move on pretty quickly to tweaking the enemy explosions which I wasn’t entirely happy with. I wanted something a bit more dramatic but not too OTT and think I got there in the end – though my first attempts were way to extreme. Took a fair bit of tweaking though.

I tried adding a velocity deviation to the particles in the enemy explosion but I think I prefer it with the particles moving at a more uniform velocity. It’s not ‘realistic’ but it seems to fit with the visual feel to me, slightly more glitchy and geometric in quality.

Dev Time: 0.5 days
Total Dev Time: approx 29.5 days

previous | next

mockup_3x
Improved ‘Lost Jetboard’ – Not So Gung-Ho Now!

mockup_3x
Too Much ‘Shock And Awe’ For George W Bush Even?

mockup_3x
Toned Down – Almost There

mockup_3x
Final(!?) Explosion – More Uniform Particles

Jetboard Joust Devlog #26 – Pistols At Dawn

So – with the AI now looking respectable it’s time to get the first basic weapon in there!

I should add that before doing this I did improve the AI a bit since the last post – instead of just charging ‘through’ the player when moving to a safe distance it now makes an attempt to fly over or under instead. This looks a lot better, particularly when going ‘face to face’ on the ground and between obstacles.

The most basic weapon, other than the jetboard jump, is the pistol (has to be). Implementing a simple pistol shot should be easy but it took me rather a long time as, as ever, I started obsessing over the details. I started with a simple two pixel square as the bullet (that’s all the room I have to play with really) but wasn’t very happy with it so began using a simple particle effect to create a type of trail instead. This looked much better but when the entire trail disappeared at the end of the bullet’s range it looked rather odd so I had to implement a way to have the trail carry on moving and disappear at the same place as the ‘main’ bullet. Doing this in an efficient manner (ie not by creating loads of separate sprite objects) was a bit of a pain in the arse – I also had to think about what would happen when the bullet collided with an obstacle too.

Got there in the end though – and added a simple particle effect for when the bullet disappears or explodes. When everything slotted together it looked quite satisfying – like fireworks.

I also added a bunch of generic parameters that will apply to every weapon and affect the speed at which a weapon can be fired – these are:

Automatic
Whether the weapon auto-fires when FIRE is held.

Repeat Rate
The quickest speed at which a weapon can be fired in succession.

Clip Size
The amount of ammo that can be fired before the weapon needs reloading.

Reload Time
The time the weapon takes to reload (doh)!

I think that should give me enough configurations to play with – reloading will happen automatically if enough time is left between shots.

Once all this was sorted getting the enemy AI to fire was pretty straightforward as all the board/weapon code is the same for both player and enemies. At the moment it just pumps FIRE when within a certain range of the player so I need to add some kind of reaction time parameters but it’s pretty effective.

Maybe rather too effective – an unexpected accident was the way the enemy keeps pumping the player full of bullets even after they’re dead ‘just to make sure’. I actually think this is pretty funny so will probably leave it in there – makes the enemies seem ultra vindictive and evil!

I need to tweak this a bit and iron out some other bugs that are annoying me next – then it’ll be on to creating ‘cash’ pickups when enemies are destroyed.

Dev Time: 1.5 days
Total Dev Time: approx 29 days

previous | next

mockup_3x
Improved AI To Circumnavigate Player More Effectively

mockup_3x
Shock And Awe? The Final Bullet Anim


A Very Vindictive AI – I’ve Created A Monster!!

mockup_3x
Pistols At Dawn – Proof That Violence Solves Nothing

Jetboard Joust Devlog #25 – A Fine Line Between Stupid And Clever

Now I have my basic jetboarding enemies in place it’s time to start turning them into something that actually constitutes opposition – that means AI.

Fortunately we’re not talking neural networks here. To quote Spinal Tap (again) ‘It’s such a fine line between stupid and… clever’ and we just need something that operates well enough to track the player reliably and reasonably realistically.

So I started with a basic premise – at preset intervals (call it ‘reaction time’) the enemy would make a decision as to whether to operate their horizontal and/or vertical thrusters based on what the player was doing. There would be a configurable horizontal and vertical reaction time for different enemy types, as well as a configurable ‘aggro distance’ outside of which the enemy would just idle rather than attempting to attack.

The first and most basic decision making I tried was extremely simple, just move in the direction of the player and hope for the best. I tried this with a reaction time of 1/10th of a second and it actually worked surprisingly well. There were a few key problems however.

1. The Kamikaze Effect
A result of this super-simple decision making is that the enemy just charges headlong into the player. This might be appropriate for certain enemies but most should really hang back at a reasonably safe distance. In order to resolve this I added a ‘range’ parameter to the jetboard weapon attachment – now if the enemy is within weapon range of the player they don’t attempt to move any closer.

2. World Wrap Confusion (He’s Behind You)!
Dealing with a wrapping scrolling world can be a pain at the point the world wraps. Say my world is 1000 units wide, player is at x location 950 and the enemy is at x location 50 – onscreen this appears as if the player is to the enemy’s left though as far as the coordinates are concerned he’s way off to the right! The solution here is to offset everything by the player’s x location (ie treat player x as zero) and then ‘wrap’ the resulting enemy x location (if it is less than world.width/2 add world.width, if greater than world.width/2 subtract world width).

3. Getting Over It
This one’s a slightly trickier problem. Making the enemy fly over obstacles instead of getting blocked by them is straightforward (if the path is blocked, activate vertical thrusters – job done) but the issue is complicated when also trying to maintain a safe distance (weapon range) from the player. Maintaining a safe distance is pointless if we do not have a clear line of sight to the player in order to fire a weapon. The solution here is to draw a rectangle between the enemy and the player – if this rectangle intersects any obstacles that are higher than the player then we need to get past them (activate horizontal thrusters), if these obstacles are higher than the current enemy position we also need to get over them (activate vertical thrusters).

By this point the AI was performing pretty well – enemies would chase the player down (even across the world wrap), not get stuck on obstacles and (most of the time) maintain a reasonably safe distance from the player from which they would be able to fire weapons. There were a couple of things still niggling me though…

4. Not So Fast!
Up to this point I had been treating the use of the horizontal thrusters as pretty binary, ie just on or off depending on the position of the player and obstacles. Whilst this worked most of the time it meant enemies had a tendency to accelerate extremely rapidly and then not have enough time to slow down, therefore overshooting or colliding into the player. I have tweaked this so that enemies only accelerate when close to the player if below a certain speed or if the player is moving away from them. This results in much better tracking and also and apparent ‘feathering’ of the thrusters which looks more realistic.

5. Getting Away From It
Even with the all the above there were still instances in which the enemy would end up aligned with the player on the horizontal axis and, unless the player moved away, just attempt to collide with him. I needed to extend my concept of a ‘safe zone’ so that, not only did the enemy stop moving towards the player when it entered the safe zone, it actively moved towards the edges of the safe zone when too close to the player. I implemented this with the additional constraint that, when too close to the player, the enemy moves away from the player in the direction of the furthest obstacle from the player. This seems to work fine.

No doubt I will refine aspects of the above but for now I think I have a pretty convincing AI controlled jetboarder. Next step is to create the first basic weapon..

Dev Time: 1.5 days
Total Dev Time: approx 27.5 days

previous | next

mockup_3x
First Attempt – The Kamikaze Effect

mockup_3x
Confusion At The World Wrap Point

mockup_3x
Get Over It, Stupid!

mockup_3x
Learning To Circumnavigate Obstacles

mockup_3x
From Stupid To (Relatively) Clever

Animated GIFs of Gameplay Footage for Twitter on Mac OSX

I’ve been asked how I do this a few times on Twitter so thought I’d write a post about it. Haven’t done a ‘tutorial’ style post in a while. My bad.

Posting animated GIF images on Twitter is a very good way to get retweets and likes and build awareness of your game, but if you’re using a Mac there aren’t that many tools out there for the job. Most people seem to use GifCam on PC but there doesn’t seem to be a Mac equivalent.

In a nutshell I use Apple’s Quicktime Player to screen capture followed by a process in Photoshop to crop and convert to animated GIF. I tried a bunch of different tools and processes before deciding on this as by far the best way.

Make your GIFs 506 pixels wide by less than or equal to 506 pixels tall so that Twitter doesn’t resize them and make them all blurry (especially important for pixel art).

Photoshop has a stupid 500 frame limit for animated GIFs but you’ll probably hit Twitter’s 5mb size limit before this becomes a problem. It is, unfortunately, a problem sometimes though.

So, in detail…

1. Decide On An Emulator
I’m developing cross platform with Xamarin/MonoGame and have found by far the best emulator to use is GenyMotion for the Android platform. I use this for general development and for all screen capture. The iOS emulators are way to slow and grabbing video direct from iOS device is also too flakey and produces too many compression artefacts. The GenyMotion emulator is very fast and can be reliably run at 1:1 ration for pixel art – only downside is that the 1:1 function requires a ‘paid for’ licence.

Xamarin’s free Android Player is pretty good but at the time of writing there are bugs in the handling of key events which means I can’t use it for my purposes.

2. Capture
I use Apple’s Quicktime Player for this. I was using Snapz Pro but it only seems to capture up to 30fps. To screen capture from Quicktime Player just click ‘done’ on the first dialog that pops up then go to File->New Screen Recording. From there it’s self-explanatory.

3. Edit
This step is optional as you can do it in Photoshop. I find it much easier to crop the video to the section I want using Apple’s outdated but incredibly useful QuickTime Player 7 Pro. This is another paid app I’m afraid but it really makes the process a lot less painful.

4. Import Into Photoshop
Open your video in Photoshop and crop it to size. You can ‘scale up’ later when saving as a GIF so you could crop to 50% of your final size (or even less). This can look good for pixel art. Then I do the following procedure…

5. Adjust Colour Profile
– Edit->Assign Profile->Generic RGB Profile
Your mileage may vary on this but I find that screen captures from Quicktime always seem too dark when importing into Photoshop. This alleviates that issue to an extent.

6. Create Layers
Open the animation window (Window->Animation) and in the menu at the top rioght of the animation window select ‘Flatten Frames Into Layers’. This may take some time. Once this is done select the original movie layer (it will be the bottom layer in the layers palette) and delete it.

7. Create Frames
Back to the animation window menu now – this time select ‘Make Frames From Layers’.

8. Save As GIF
You are now ready to export your animation. For some reason I’ve found that Photoshop often does something weird with the first frame, like it’s assigned a different colour profile or something. You can check this by moving the timeline marker in the animation window and seeing if everything looks OK. If it doesn’t you can more the ‘start’ marker to just beyond the problem frame (you can also use these start/end markers to crop the timeline if you didn’t edit your video as described in step 3).

Use ‘Save For Web’ to export and you will have to mess around with the colour settings to get your animation under 5mb. Even if your image contains no transparency keep ‘transparency’ checked as without it file size jumps up dramatically (maybe photoshop uses this to only update areas of each frame that change). Note that you can scale up your image at this point – be sure to select ‘Nearest Neighbour’ scaling for pixel art.

I’ve found that the ‘loop’ setting keeps getting set back to ‘once’ when other parameters are changed so make this the last thing that you do. Changing colour options and the like can result in a lengthy ‘beachball of death’ depending on the size of your GIF so when you see this don’t panic just wait it out.

It’s easy to set up a Photoshop Action to cover steps 5 through 7.

That’s it. Any questions or comments please contact me here or on Twitter.

Jetboard Joust Devlog #24 – It’s All About Class

I want to have enemies on jetboards.

I didn’t really think about this at first – I thought that the enemies would be your usual SHMUP fare, different types of robots/spaceships and the like. But as the game’s called ‘Jetboard Joust’ it makes more sense to have at least some of the enemies riding jetboards like the player.

I’d also been thinking about the rpg-lite elements to the game. There’s going to be different ways to arm your jetboard and a weapon upgrade system – if I treated the enemies and jetboards differently I’d end up with far more combinations of opponent which would make things much more interesting. I guess its been Dark Souls (again) making me mull over this – the way the same basic enemy can present a very different challenge depending what weapon they’re armed with and what armour they’re wearing.

So I’ve been pulling apart my class structure to get something that’s much more flexible. First step was to create a generic ‘Board’ and ‘Rider’ class that represent, at the most basic level, a board and something that rides it. I then created the (somewhat randomly named) Surfer class which defines a Rider that animates in a similar way to the main player character (based on a 3×3 grid as described here). I split out a separate Jetboard class which extends Board – this contains the code for the ‘jetboard as weapon’ functionality which will probably only be available to the main character (as I think having enemies jumping off their jetboards will become too visually complex and confusing). There’s also a separate Weapon class which represents the base level weapon attachment for a board.

The fly in the ointment was with the enemy classes. There’s a bunch of generic ‘enemy’ code that deals with things like player collisions and collisions with projectiles. I couldn’t find a way to share this between enemies that were subclasses of Surfer and those that weren’t (ie won’t be riding jetboards) so I’ve had to (annoyingly) duplicate some of this in the EnemySurfer and GenericEnemy classes. There’s an IEnemy interface that allows both of these to be treated generically by various methods. Not having multiple inheritance is both a blessing and a curse sometimes.

Oh yeah, the base level Character class defines something that has health and can collide with the player and/or projectiles.

This all took some time – I hate retrofitting class hierarchies – but I took it slowly and carefully and once I was all done everything (amazingly) worked fine apart from one minor bug which was fairly easily quashed.

I’ve also designed my first jetboarding enemy – calling him ‘Skullhead’ for now.

Next step will be to add some basic enemy AI and get weapon attachments working.

Dev Time: 1.5 days
Total Dev Time: approx 26 days

previous | next

mockup_3x
The New Class Hierarchy

mockup_3x
Very Basic Jetboarding Enemy In Action

Jetboard Joust Devlog #23 – Spinning Crate Gate

Finally got the spinning crate sorted thanks to some pointers from very helpful Twitter user @grayhaze.

Seems obvious when you think about it but really the cube should get wider whilst it spins, not narrower as I had it (unless the perspective was ridiculously exaggerated). Another good tip from @grayhaze was to try drawing things from the top when approaching problems like this – if I’d have done that in the first place I wouldn’t have wasted anything like as much time.

So with that in mind I was able to create a ‘flat on’ spinning crate without having to add any perspective – and it doesn’t look like a page turning!

Next task was to actually make the weapon swap happen which, whilst pretty straightforward, involved a lot of setting up of additional classes and code restructuring so was fairly time consuming – note the way the weapon attachment on the jetboard changes in the GIF on the right.

I’m glad this has been put to bed now. Now I need to do some proper work on the enemies which is going to involve even more code restructuring (groan) so you may well not hear from me for a while…

Dev Time: 1 day
Total Dev Time: approx 24.5 days

previous | next

mockup_3x
It Should Get Wider, Stupid!!


Weapon Exchange Sequence Finally Done

Jetboard Joust Devlog #22 – Spin Doctor

Don’t you just hate it when something that you thought would take a couple of hours takes pretty much all day – and then you’re still not entirely happy with it?

Witness the spinning crate. A bit of a repeat of the floor tile episode this one – and another indicator of just how inexperienced I am with pixel art.

I needed something for a ‘weapon swap’ pickup. As it’s a swap (ie your original weapon gets left behind and a new one picked up) I needed a kind of ‘permanent’ storage system rather than something that gets destroyed on pickup like the bubble I’m using for extra health.

A crate seemed the obvious choice. Far from original I know, but it seemed as though it worked work and there’s something quite iconic about the pickup crate. I thought the crate could spin when you activated it and the crate icon change to show the weapon you’d just deposited.

Designing the crate itself was pretty easy. Getting it to spin wasn’t. Firstly I made the schoolboy error of drawing every frame of the animation before prototyping it. Each frame looked great on its own but when I tested the animation I was gutted to discover I’d failed miserably. The crate didn’t really look like it was spinning – it looked like the pages of a book turning or something. Everything I’d done ‘should’ have worked (to my mind) and I was somewhat stuck to figure out what I’d done wrong.

So I did what I should have done in the first place if I’d have had half a brain – I went back to the drawing board and sketched out some simple prototypes. This (and studying a few classic ‘spinning cube’ demos) enabled me to see where the problem was. My art style is fully 2D which means that, really, there should be no perspective. However it turns out that without perspective it’s very difficult to judge what is ‘3D’ and what’s not (hence the ‘page turn’ effect). I tried adding some shading and this helped but the only way I could get the crate to look like a cube was to add some simple perspective. I think, really, this shouldn’t fit with the art style but it does seem to kind of work to me. I could only add perspective to the top of the crate though, otherwise it didn’t sit right on the ground!

Another issue which compounds the difficulty is trying to work with a strict eight colour palette (this makes gradually altering the brightness of things very difficult) and working in a ‘blown up’ pixel style. In most instances every pixel I use will be represented by at least three pixels on screen so a one pixel shift in the artwork actually represents quite a visual ‘jump’. In the (for now) final animation I only use a one pixel shift for the perspective and it almost seems too much (that’s right, ‘too much f-ing perspective’ to quote spinal tap).

In the animated GIF on the right you can see some rough prototypes followed by the ‘final’ animation as it stands at the moment.

1. The first approach – looks like a ‘page turn’
2. Adding shading – slightly better but still looks like a page turn.
3. Adding perspective – starting to look like a cube now.

Anyway – what doesn’t kill you makes you stronger and all that. The moral of today’s story kids is simple prototypes first!

Maybe I should have titled this post ‘Spinning Crate Gate’.

Dev Time: 0.75 days
Total Dev Time: approx 23.5 days

previous | next

mockup_3x
The Static Crate Design – This Is The Easy Part

mockup_3x
Getting Things In Persepective