Ghost Party ~ WGD ‘Spooky (2016)’ Three-Week Competition

It’s been a while since I’ve properly sat down and made a game, apart from the Zero Hour Game Jam, which I entered with an entirely broken game about shooting ghosts with a flashlight. Today, after having three weeks to work on a game, I decided to start one the day it was due to be shown.

3dspooky5me

My Zero Hour Game Jam entry, the lesser of my two games about flashing ghosts.

I decided that my Zero Hour Game Jam entry had a few flaws, the main one being that you magically die after about 30 seconds every time without being visibly hit by anything. You hit ghosts by aiming straight at them; unfortunately, this means you have to aim the centre of the screen at them as the game uses a raycast, but there is no crosshair so it’s almost impossible to tell if you’re hitting the mark except that the ghosts turn red.

I did like the idea of hitting ghosts with a flashlight though, so I kept it and made a brand new game today with a different art style: crayons. You might think I’m crazy, but when you’re time-constrained, it always helps to think of quick hacks to make things easy. I could have just as easily used normal coloured pencil to draw everything, but a bad artist (or in this case, a rushed one, although I’m not exactly Picasso to start with) will always make coloured pencil look crap. On the contrary, when someone thinks of wax crayons, you think of a 5-year-old’s drawing tacked onto the fridge. Essentially, wax crayons have a very low skill ceiling and I exploited the heck out of that. It made for a very consistent style and I actually really like it! It’s similar to the style I used for Tappy Dev, but I think it’s possibly better.

screenshot_01

Yellow ghost is far too happy.

The general idea is that ghosts spawn from left and right, and it’s your job to shoot them down with your flashlight by clicking on them. It’s better than 3DSpooky5Me (my 0h game jam game), in that you can see the mouse cursor to indicate where you’re aiming. The ghosts are also much cuter.

Given more time, I’d go back and make sure the proportions of all the objects in the game were consistent. As you can see, the ground’s outline is very thick compared to that of the ghosts, despite being drawn using the same crayons. I’d also change the design of the gravestones and the large tombstones, since my friend said they look like printers. While the thought of a haunted Konica Minolta fills me with glee, I might save that idea for when I’m in a real jam.

I also need to change the mechanics a bit. Similar to the 0h Game Jam, I didn’t make the flashlight affect an area, but stuck with a raycast; having the flashlight hit all ghosts in its range when flashed would open up the possibility of combos and make the mechanic feel more satisfying when you line up 5 ghosts in the same flash. Currently, the score increments by a strange formula I devised based on the speed, sine-waviness and z-distance of the ghosts, but I feel this should be better communicated to the player, as it’s difficult to even notice how many points you got for hitting one. Furthermore, one thing the game lacks entirely is a lose condition, which I was minutes away from getting in the game, but was hindered at the last moment by having to go to the WGD event in which I showed the game.

But the biggest and funniest problem in this build is the unintentional and bewilderingly fast escalation in difficulty. Above was a screenshot from about 30 seconds in, but the following one is from a couple minutes in:

screenshot_02

Points for spotting the cameo appearance.

At the start, the difficulty increases in a linear fashion. Every 5 seconds (although I’d planned to change it to every 20 or 30 seconds and forgot), the time interval between ghost spawns goes down by a fixed amount. It does this 10 times, then it starts going down in a geometric progression. You can see where this is going. Every 5 seconds, the time between spawns is divided by 1.2. Then you end up with a ghost party. It’s a classic example of “oh I’m sure this arbitrarily-picked number will be fine”.

At the early stages of development (read: while zoning out in a lecture this morning, thinking about spooky ghosts), I considered adding some element of a rhythm game into this, but as you’ll find out there is no sound whatsoever. It’s somewhat inspired by the Sneaky Spirits game from Rhythm Paradise (or Rhythm Heaven, for you Americans). I wanted each ghost type to have their own behaviour, but this didn’t come to fruition and they instead all follow sine waves of varying frequency and magnitude.

I wanted the spiky green ones to zig-zag, the puffy white ones to flutter upwards and fall back down a bit constantly, and the blue ones were going to have Pacman-style grid movement. The pale ones were going to have an animated tail that wiggled around and the rare Drifloon (please don’t sue me, Nintendo) would’ve occasionally grabbed a headstone with its tassels and flown off with it. Maybe next build!

All things considered, the most important lesson I’ve learned today is that I should drawn with crayons more often. It’s really easy and looks pretty nice, especially with the Paper Mario-style aesthetic. It’s also not really apt to keep referencing ‘today’, but I’m not a clock so it’s fine. You can download the game here.

Advertisements

I’m Making a Game Engine

It’s sure been a while since I last posted, well, anything. Part of that was me getting reacquainted with uni life, part of it was me adjusting to a real-person sleep cycle and part of it was me thinking about the game engine this post will be about. But most of it was just me being lazy because my last post was in early July, about three months ago. That’s my longest disappearance yet. Oops.

However, since I was last here, a lot has happened! As part of my third year at uni (I’m already halfway through, where does the time go?!), I have to do a big project about something to do with computer science; I’ve decided to make a game engine, which has resulted in some people thinking I’m a tad insane. I’m inclined to disagree – doing it will make me insane. Without further ado, introducing my concept: the Honeycomb Game Engine!

honeycomb_logo

At some point I will vectorise this image.

The basic idea is that Honeycomb will be geared towards people who don’t have all that much experience in game design or programming (or both!). The way I will achieve that is by turning the idea of a game engine on its head. Some game engines try to give the developer tons of tools for any imaginable situation, but I think this is overwhelming for a new user – that’s how I felt way back when I started using Unity, anyway. Instead of following in those footsteps, I’m going to try and condense my game engine down to easy-to-use key features and avoid adding anything that’s unnecessary. Essentially it will lie somewhere between Unity and Game Maker.

In my opinion, a beginner-friendly game engine should have most of the following features:

  • A clean interface with easy-to-understand buttons and menus for common tasks;
  • A way to add behaviour to game objects that is intuitive and doesn’t require writing tons of boilerplate code (a simple scripting language, for example);
  • A room-building tool that lets you add game objects to a room and snap them to a grid easily;
  • Support for common 3D modelling packages, such as Blender or Maya. I think supporting .fbx files is sufficient for this;
  • A big, red button in the corner of the editor that donates an energy drink to an exhausted game engine developer somewhere in the world;
  • One-button exports to the platforms the engine supports. Users shouldn’t have to sift through mile-long lists of options for their exports;
  • A UI designer toolkit that lets users place buttons, text elements and sliders on a virtual ‘screen’ that then gets overlaid onto the running game;
  • A ‘play’ button that lets users run their game directly in the editor, or at least build the game quickly and provide debugging feedback to the user. This is one of the most difficult things I will try to implement (it’s a stretch goal);
  • A material editor that lets users plug in values and textures for various parameters. Then users can drag those materials onto models in their game;
  • An animation toolkit that lets users control how models are animated and how different animations work together;
  • Coroutines. Holy hell, they are so useful in Unity while writing behaviour.
  • Many many more things that I’ve inevitably missed out!

Some of these features obviously require more work than others. For example, I plan to create a scripting language (called Honeycode, because I’m an awful person) that will get compiled to C++. The advantage of creating my own scripting language is that I can abstract some of the less beginner-friendly features of C++ and ignore some less useful ones entirely, while making assumptions about what Honeycomb provides. This way, I can bake engine integration directly into the language, similar to how the Unity API augments C# to provide Unity’s features.

Essentially, my motivation for the engine is to create something that new users can just pick up and start making things with, without having to spend hours with setup and tutorials. A user should be able to drag in a default character controller and immediately have working character input and movement, the whole shebang. They should then be able to easily add behaviour to objects in the scene in a way that feels natural – telling a sheep to jump 17 feet in the air when the player approaches should be a simple line or two of code. Obviously sheep don’t jump that high though, it’d be terrifying if they did. Or baaaaad.

So that’s my approach. I’m going to add in the absolute basic features that a new user will want or need and let them build everything else on top of that framework. To aid that, I’ll also try and write a bunch of tutorials and sample code to guide users into writing the more complex and weird stuff that I don’t think needs to be baked into the engine itself. That way, it’s not as if I completely neglect the existence of the more useful features, but I don’t just provide them for the sake of making my engine do your tax returns and make toast for you while you’re working.

One of the more exciting things about my project is that I’m going to try and use Vulkan, the shiny new graphics API by the Khronos Group. It’s sorta like OpenGL++, but not really. Khronos basically took the remnants of AMD’s Mantle API and created a cross-platform graphics API for the modern age, which allowed them to make different design decisions to the ones made during OpenGL’s development. As a result, the API provides much lower-level access to hardware, but this makes everything so much more verbose; it’ll be a challenge to implement Vulkan support, but I’m confident I can get it working with a little elbow grease. By that, I mean a lot of coding all-nighters. And hey, if it doesn’t work, I can always fall back to OpenGL.

I’ll be returning to this blog every now and then to document my progress, and when the time comes, upload working downloads for people to try out the engine. That’s a very far way off currently though! I hope this whirlwind tour of my plans make sense, although I’ve probably missed some stuff out, so let me know if something doesn’t make sense. It’d actually be hugely useful for me to know what people’s most requested features or major gripes about their choice of game engine or development tool are, so feel free to bellyache and rant in the comments section about something your game engine does that you think could be improved!

ShaderLab Programming #1 – Sepia Blend Shader

Now that exams are over, I’ve had time to actually breathe and, more importantly, do game dev stuff. I’ve rarely touched computer graphics in the past, but it’s an area I’ve always wanted to explore in detail. This summer, I plan to mostly spend my time learning the intricacies of computer graphics, and that’s partially where Unity’s ShaderLab steps in.

ShaderLab is a graphics language in its own right, but it also encompasses Cg, a high-level shader language by Nvidia, and HLSL, a Microsoft shader language for use with DirectX, both of which were developed together. We don’t need to know too much about the structure of ShaderLab programs for what we’re doing, so I’m largely going to ignore it for now. I needed to create a post-processing effect similar to Unity’s built-in Sepia Tone, which is an on/off effect, with a tweak that allows it to fade in and out instead. It’s for a game I’m working on in which you can turn back time – more on that in the coming days when I’ve put together something a bit more concrete hopefully! Let’s deconstruct this super-simple program and explore what a sepia effect actually is. Unfortunately, Unity’s Sepia Tone shader seems to use some sort of maths wizardry for its fragment shader that I don’t understand, so I’ll also be writing mine mostly from scratch. Here’s the number bullshit right here:

fixed4 frag (v2f_img i) : SV_Target
{ 
    fixed4 original = tex2D(_MainTex, i.uv);
 
    // get intensity value (Y part of YIQ color space)
    fixed Y = dot (fixed3(0.299, 0.587, 0.114), original.rgb);

    // Convert to Sepia Tone by adding constant
    fixed4 sepiaConvert = float4 (0.191, -0.054, -0.221, 0.0);
    fixed4 output = sepiaConvert + Y;
    output.a = original.a;
 
    return output;
}

The infinite wisdom of the Internet tells us that to convert a source image to a sepia-tone version, we just define a function of the input colours as follows:

new red = min(in red * 0.393 + in green * 0.769 + in blue * 0.189, 255)
new green = min(in red * 0.349 + in green * 0.686 + in blue * 0.168, 255)
new blue = min(in red * 0.272 + in green * 0.534 + in blue * 0.131, 255)

This formula represents 100% sepia; that is, the source image completely turned into a sepia tone. But we don’t always want a completely sepia image – we need to incorporate some sort of progress measure. Using this formula, we can just interpolate between the input colour and the full sepia tone and use a separate script to control the ‘progress’ of the interpolation. I’ve talked about interpolation before, so if this really big word is confusing, it just means we’re picking a colour on an imaginary line between ‘original colour’ and ‘sepia colour’, with a parameter between 0 and 1. We can now create another function to get our final ‘blended’ sepia colour:

out red = parameter * new red + (1 - parameter) * in red
out green = parameter * new green + (1 - parameter) * in green
out blue = parameter * new blue + (1 - parameter) * blue

With the theory out of the way, we can now create the shader and the script that will control it. We’ll be utilising the post-processing effects provided by Unity, so make sure you import them from the Standard Assets using Assets->Import Package->Effects from the menu bar. We’ll start with the controller script.

There are two main ways to keep track of the progress, so I’ll cover both. The first way is to define a method such that another script can just pass in a float to act as the parameter.

using UnityEngine;

namespace UnityStandardAssets.ImageEffects
{
    [ExecuteInEditMode]
    [AddComponentMenu("Image Effects/Color Adjustments/Sepia Blend")]
    public class SepiaBlend : ImageEffectBase
    {
        private float progress = 0f;
        private bool active = false;

        private void SetProgress(float progress)
        {
            this.progress = progress;
            active = (progress == 0f);
        }

        // Called by camera to apply image effect.
        void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            if(active)
            {
                material.SetFloat("_Progress", progress);
                Graphics.Blit(source, destination, material);
            }
        }
    }
}

OnRenderImage() is the method called when we want to render a post-processing image. We set the ‘progress’ parameter of the material attached to this project – we’ll see how this works with that material’s shader shortly – and use Graphics.Blit() to apply the texture created by the shader to the screen. The second way to control the progress parameter is to allow external scripts to set the ‘active’ boolean and use a time-based interpolation to decide what the progress should be. The guts of the program will look more like this:

private float progress = 0f;
private bool active = false;

private void SetActive(bool active)
{
    this.active = active;
}

private void Update()
{
    progress = Mathf.Lerp(progress, active ? 1f : 0f, Time.deltaTime
        * 5f);
}

// Called by camera to apply image effect.
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
    material.SetFloat("_Progress", progress);
    Graphics.Blit(source, destination, material);
}

Now for the actual shader! I’ll explain very quickly what the fragment shader is doing and ignore the vertex shader since it’s doing nothing in this example; I may do another post in the future explaining the details of how the shader is constructed, but I’m glossing over a lot for now. Don’t even worry about it yet.

Shader "Hidden/SepiaBlendEffect"
{
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Progress ("Progress", Float) = 0
    }
    SubShader
    {
        Pass
        {
            ZTest Always Cull Off ZWrite Off

            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
 
            #include "UnityCG.cginc"

            uniform sampler2D _MainTex;
            uniform float _Progress;

            fixed4 frag(v2f_img i) : SV_Target
            {
                fixed4 original = tex2D(_MainTex, i.uv);
 
                half3x3 vals = half3x3
                (
                    0.393, 0.349, 0.272, // Values for input red.
                    0.769, 0.686, 0.534, // Values for input green.
                    0.189, 0.168, 0.131  // Values for input blue.
                );

                half3 input = half3(original.rgb);

                half progress = half(_Progress);

                half3 intermed = (progress * mul(input, vals)) + 
                    ((1 - progress) * input);

                fixed4 output = half4(intermed, original.a);

                return output;
            }
            ENDCG
        }
    }
    Fallback Off
}

We’re interested in the stuff between ‘CGPROGRAM’ and ‘ENDCG’ – this is written in Nvidia’s Cg. All we need to know about the structure of shaders for now is that the fragment shader is run on every pixel of a processed image. I’ll also ignore all the types of variables for now and cover those in another post at a later date. Jumping straight to the frag() method, which constitutes the fragment shader, we’ll see a 3×3 table of numbers, vals, that looks strikingly like the one defined for our first function; the table is the transpose of a matrix formed by those functions’s numbers. Our shader performs a matrix multiplication on a vector made of the original rgb values, input, and our magical sepia number matrix vals (which is why it had to be transposed), then we do our interpolation to get intermed. Afterwards, we put together the final output by adding the original colour’s alpha onto intermed, and boom! We have our Sepia Blend shader. Now all that remains is to attach the SepiaBlend script to the main camera and assign the SepiaBlendEffect shader to the script, then we’re good to go.

I hope this has been a helpful introduction to the world of computer graphics. I’ve uploaded the three scripts to avoid you having to copy everything out (both variants of SepiaBlend.cs are included; pick your preferred version). Let me know if everything turns into a bugfest when you attempt to run any of the examples and I’ll try to diagnose the problem.

Shifting Dungeons ~ Post-LD35 Update 1

One thing I’ve become exceedingly bad at is updating games once I’ve thrown them onto the Internet for the first time. The last time I did such a thing was probably over a year ago. But, starting today, I am a changed man! For I have vowed to complete Shifting Dungeons to a standard that I’m happy to put my name to and watch it run off into the wider world, playable and somewhat consistent. Ahh, games, they grow up so fast. I’ve been very preoccupied lately with ruining my sleep schedule by doing coursework right up until deadlines (and beyond…), but that didn’t stop me tweaking Shifting Dungeons a bit.

Without further ado, it’s time to list what’s changed! That’s what change-lists are for, after all.

giphy

Character Customisation

There’s a handful of new character customisation options, bringing the total of skin and clothing colours available to 8 each. That may increase in the future, but for now I’ve stuck with 16 total options because the UI feels clean and not overwhelming with choice, while providing a relatively broad number of outfit combinations.
The whole character customisation scene has a background too – I’ve decided to make it look like the player is getting changed in their bedroom. It’s woefully incomplete currently, but it’s a start.

promo-dev-06

Options Menu

The bare basics of an options menu are also now in the game. Most importantly, this menu has an exit button – something I’m very good at forgetting to add. Now you don’t have to Alt+F4 out of the game or use Task Manager! There are sliders for adjusting music and SFX volume and for changing text speed, but they don’t do anything right now (especially since there’s no music and next to no text). However, the sliders’ values are accurately stored, so it’s a start! I’ll probably have them fully implemented by next update.

promo-dev-04

Intro Cutscene

I’ve also started work on a cutscene for the start of the game. It’ll be rather short and serve only to introduce the concepts and backstory of the game in a better way than the Ludum Dare entry version handled it – a wall of text. Instead, short sentences accompanied by pretty pixel art will probably work better. Similar cutscenes will appear during major story arcs, but since there’s no story right now, this is the only cutscene implemented.

promo-dev-05

Controller Support

Any controller that supports X-Input should work with the game. I say should; I’ve been testing the game using a Wii U pro controller and an adapter that allows it to mimic an Xbox 360 controller (which uses X-Input), so hopefully it also works with other X-Input devices, although I can’t promise anything will work perfectly. The controls are fairly simple and you shouldn’t have any trouble getting to grips with them. However, there are no in-game instructions for controllers, so here is an image detailing how the controls work (which I probably could have just included in the game anyway):

promo-dev-02

Enemy Lock-on

To make it easier to take down baddies, you can now lock onto them. On a controller, aim in the general direction of the enemy and press the left button; using a mouse, press the right mouse button. It’s the same button to de-lock (lock off?), but make sure you’re not aiming at an enemy when you do it or it’ll just lock onto the new enemy. Unless that’s what you wanted to do, then great, that’s how you do that. When locked onto an enemy, their health will appear next to them and decrease in realtime, plus your bullets will fire straight at them, so you can see why it’s a handy feature. Plus, when you kill a locked-on enemy, it’ll automatically lock onto any nearby enemies. To aid your aiming, there’s a second cursor – the orange one is for locking on while the white one is the mouse’s actual position. I’ve yet to implement the white cursor for controller input, but it’ll be in the next update for sure. Oh, and the cursor sprite and animation is a lot fancier, too.

promo-dev-03

Mechanical Changes

The biggest gameplay change is possibly the addition of the Energy bar. There is a distinction between powerup energy and general energy, hence there two energy bars; the leftmost one, with the thunderbolt icon, will decrease when you fire bullets or slow down time and replenish when you move. The one on the right, with the arrow icon, starts off full when you pick up a powerup (try saying that five times fast), then slowly falls as you move until it reaches zero and the powerup expires. Health replenishes as you move as before, but at a slower rate, plus the UI is more reactive; being hit makes the health bar shake, and having low energy makes the energy bar shake more, the lower energy you have. Staying stationary also no longer stops time completely, but it slows it down a lot.

Shooting mechanics have had a bit of a mix-up too. Your bullets and enemy bullets don’t collide any more, as it provided an easy way to get rid of enemy attacks and there was no incentive to use the time-slowing mechanic to dodge bullets. However, you can now hold down the shoot button to start a hailstorm of bullets and wipe enemies off the map without me being liable for loads of repetitive strain injury lawsuits! To balance the increased shooting speed and the ability to lock on to enemies, your bullets do half as much damage, although in the next update I hope to add some system such as different bullet types that’ll let the player (and enemies) do more damage.

A few other changes are there, namely that rooms are much larger and the camera is zoomed out so the player can see further. It makes it slightly less confusing when you can hear you’re being shot at, since you can more easily see where it’s coming from by virtue of the threat actually being on-screen or only just off-screen, not a million miles away.

giphy1

Yay low-quality GIFs! My computer is just bad at everything…

Bug Fixes

You know that game-breaking bug I wrote about in the last blog post? The one that means you couldn’t get past the first dungeon because you’re unable to move on its final floor? That’s been squished. There were also a couple oversights where the game would sometimes skip to the final floor when there was supposed to be another standard floor before it, but now the floors act like they should.

Bugs Implemented

There’s only one that I’ve actually found and can remember, and it’s not hugely important: on the character select screen, the player’s face appears blank. That’s because technically he’s looking upwards, and due the the fact the player’s at an angle in 3D space, the game doesn’t recognise the mouse position correctly and doesn’t face it. If you press the right stick on a controller, the player will face the correct way, but unfortunately the right stick’s rest position has the player looking upwards anyway… Swings and roundabouts, huh?

promo-dev-07

Meet the very introverted and shy hero of the game.

Next Update’s Priorities

Most of all, I hope to implement more enemy types. Right now, there’s only one type, and they share the same sprites as one of the character customisation options. They all share the same terrible AI too, so I’m going to at least attempt to work on pathfinding and give some enemies different attacking styles. I’ll also try to make more dungeon types and give more variety to the dungeons themselves – different sizes, shapes and maybe obstacles inside the rooms. Plus, I’ll try to finish the powerups that were originally planned for the Ludum Dare version and implement new ones – the ‘shapeshifting’ aspect of the game is a little bare currently. Finally, I still need to balance the floors’ difficulties and spawning rates of enemies and powerups, since it’s still very imbalanced.

ld35_u1_download_banner

Shifting Dungeons ~ Ludum Dare 35 (Shapeshift)

This weekend was the thrice-annual Ludum Dare game jam. The rules for the competition are simple: working alone, you must create all game assets yourself and come up with a complete game in 48 hours to abide by a predetermined theme. There’s also a more relaxed ‘jam’ version, with a 72-hour time limit, in which you may work in teams and use assets from online, but because I must be a masochist I entered the competition version for the fifth time in a row. These game jams are a bit of a habit now!

The theme is voted on by the community beforehand in several phases (and is almost always terrible), so this time we got stuck with ‘Shapeshift’. Immediately the idea of shape-shifting dungeons came into my head, because I’ve been hanging out with people obsessed with making Mystery Dungeon-like games for far too long (James, I blame you. Unless you’re a different James, then carry on with your day). I’ve basically made a dungeon crawler-meets-my Ludum Dare 32 entry, but it has a twist!

press-02

I tried making the art look pretty. I think it worked?

In some tile-based dungeon crawlers, such as Pokemon Mystery Dungeon, players and enemies move simultaneously each turn. However, to avoid having to create a tile-based turn system, I’ve allowed players and enemies full 360-degree movement. To keep things somewhat ‘simultaneous’, enemy and bullet speeds are tied to the player speed. Think 2D SUPERHOT. This allows the player to stop for a moment and think: do I shoot the enemy’s bullet down before it hits me, or move to the side and shoot them directly? It’s the closest analogue to a turn system I could think of in a continuous game other than each character moving in turns of, say, five seconds each. Which would have sucked.

press-03

I also added a couple of powerups for the player, and had planned more that got cut due to time constraints. Currently, there’s the axe powerup, which turns the player into a massive slab of metal on a stick that ups attacking power massively and increases defense. There’s also a slime powerup that turns you into an amorphous blob (in the style of Dragon Quest’s slimes) and lets you shoot bullets that slow enemies (or, well, they would if they weren’t bugged in the release version). That brings me to the next feature: bugs!

promo-post-01

The second dungeon, Glacial Rift. Shame that a bug prevented reaching it.

In the release version of the game, there were three dungeons. However, because of a wonderful bug on the lowest floor of the first dungeon, you can’t access the other two – the player won’t move once you reach that floor. It’s a bug that took 5 seconds to find, one line to correct and was stupidly introduced right before submission – I immediately knew what I did wrong but hadn’t thought to check whether the stuff I added would have any negative consequences. In short, I’m an idiot when I’m sleep-deprived. Above is a screenshot from the second dungeon, Glacial Rift, albeit taken after submission (I’ve been working on the game a bit since the deadline). There are a few smaller bugs related to combat, but they’ve mostly been figured out and weren’t too disastrous.

press-01

The character select screen was one of the first things I fully implemented.

I had to abandon a couple of planned features, too. Originally, there were set to be more powerups – the Drill, American Footballer and Super Magician. The drill powerup would have let you tunnel through walls, while the footballer would have granted you a powerful charge attack that lets you vault through enemies at high speed. Transforming into the super magician would have given you a cape and made your magic attacks stronger, faster and larger. I also didn’t get time to implement all the little flourishes I wished to put into the game – there are no particles (a disgrace, I know!) or death animations for either the player or enemies. The screenshake is also a bit weak in places – I’ll probably increase the strength when enemies die. On the graphical side, I wanted to have a few more character customisation options, but at least that system was working entirely. I’d also planned a couple more varieties of dungeon theme, like City, Forest or Volcano, but I’m happy with the two that made it through (Temple and Ice).

I’ve already got a ton of notes written down for how I’d improve this game, and that’s just what I’m in the process of doing. I’ll have an updated version up soon! In the meantime, you can play the game on the Ludum Dare website! Just clicky da box below. Voting is still taking place, so if you also made a game for Ludum Dare 35, I’d really appreciate it if you voted for my game and left feedback!

ld35_download_banner

Tappy Dev ~ WGD ‘Fuck This’ 48-Hour Jam

Well this post is certainly overdue. This jam happened from the 26-28th February, so my apologies for taking quite so long writing this one up; the end of term was, as always, filled to the brim with horrible, terrible coursework.

The idea behind the ‘Fuck This’ jam is that participants make a game in a tool, language or engine that they’ve never used or hate using, or that they make a game in a genre they don’t like. That way, you can learn a new skill or add your own spin to a genre that’s never been tried before. Since learning a new tool would’ve taken too long, I opted for a bad genre. That genre was idle games. Since I’ve never really focused much on mobile development, I made Android my sole target platform. Sorry iPhone people and Windows Phone fans (both of you), but I didn’t have either of those at hand for testing.

My idea for a terrible idle game was a game in which you tap the screen in order to make games. Every time you tap the screen, you get a point, and every 1000 points will ‘make a game’. Those games are all jokes or tropes on the games industry, as seen in the example below.

Screenshot_20160324-191950

The counter gets incremented once every time you tap on the screen. That counts for multiple taps at the same time, so the pro strats for getting as many points as possible are to just mash the screen with your fingertips. Not sure if that counts as mashing, but I don’t care, just do it. Gotta get 1000 points to see my hilarious references, after all.

The art style was literally just me drawing badly on some paper using some coloured pencils. I made sure I coloured out of the lines, for good measure. I did this mostly because it was something different from pixel art, but it was also something I knew I could quickly and easily draw. Personally, I think it worked out remarkably well, considering the fact I didn’t spend all that long on it.

As you tap (or, well, ‘type’), the on-screen screen will fill up with text. It’s nothing special, just a measure of progress. And also an insult!

Screenshot_20160325-134436

If you want to try it out, you’ll need to find some way of installing non-Play Store apps on your phone. I’ve also built the game for Android 5.0+, so it (probably) won’t work on versions lower than that. I hope it works on your phone! Just click the banner below to download the game.

tappy_dev_header.png

Game Design Tips #16 – [Unity + C#] Linear Interpolation

It’s been an awfully long time since my last post – blame coursework! I have a few weeks to get a couple of posts in before I have more coursework and then exams, so enjoy me while I’m here.

If you’ve coded at all with Unity, you’ve probably noticed its API has a lot of methods called ‘lerp’. Mathf.Lerp(), Vector3.Lerp(), Color.Lerp(); all of these are very helpful methods. But what exactly do they do, and how should we be using them properly? First of all, I’m gonna go ahead and show you how they’re meant to be used, then I’m gonna break them horribly to show you cheap ways of doing cool stuff.

How to use Lerp without being hacky

‘Linear Interpolation’ is a lot of syllables to get your head around, so first of all, let me explain what it means. Let’s say we have a thing. We want the thing to change into another thing at a constant (linear) rate. This is what linear interpolation does – it takes a vector, colour, float, you name it, and changes it into a new one.

tip-16_img01

This is the lerp method for Vector3. We pass in startPos, endPos (both Vector3s) and a float parameter; this parameter should be between 0.0 and 1.0. When time = 0.0, the object’s position will be 100% at startPos and 0% at endPos, and when time = 1.0, it will be placed at 0% startPos and 100% endPos. It’s easiest to demonstrate what lerp is doing when talking about Color.Lerp(), so we can use a pretty diagram:

tip-16_img02

Here, the square represents the RGB colour scale found in Unity’s colour picker (well, flipped horizontally). When we use Color.Lerp() in this way, when the third parameter is 0, the method returns a red colour (#ff0000 in hexadecimal RGB colour representation) and when the parameter is 1, we get full white (#ffffff). At any point in between, we blend between the two linearly – at 0.5, we’ll get a pink-ish colour exactly halfway between red and white on the RGB scale (#ff7f7f roughly) and at 0.75, we get something mostly white but retaining a tiny bit of red (about #ffbfbf).

Once we understand what lerp is doing when we pass in certain numbers, we can pull everything together cleanly into a coroutine.

tip-16_img03

We pass in the sprite renderer whose colour will change, the colour it will change to and how long it will take to change. The coroutine automatically works out all of the needed variables for the user, so we don’t need to pass in the start colour. Every frame, we set the new colour of the renderer based on what percentage the current time is between the start and end times. Simple! The final step is to ensure the colour gets set to the end colour exactly, since the loop might have exited only 99.9% through the lerp (it’s never going to be noticeable to the human eye, but I’m doing this for the sake of completeness and to avoid triggering anyone’s OCD).

How to use Lerp badly

Now that we know how to use lerp properly, it’s time to be a terrible person! I’ll show you one popular way of using lerp badly. Assume, for the following example, that the ‘speed’ variable is set to 0.1f.

tip-16_img04

tip-16_img05

I’ve tried to illustrate what happens on each frame here. At the start (on the first time interval), the sprite colour is at its original colour. At the second time interval (0.1s after starting), we have moved 10% from the original position towards the final position. This is easy to understand – we move 10% of the way between full red and full white (assuming the original colour was red and targetCol is white). On the next interval, we have travelled another 10%. However, the starting point was not the original red – it was 10% towards white. This means the current colour is 10% between the last colour and full white; it is now 19% towards full white. This process continues; rather than moving linearly between red and white, the end result is a curve.

The reason this works is because the time parameter we pass in is always a fraction between 0 and 1, but the start colour is always changing too. It’s not exact, but roughly every 0.1s, the colour will change 10%. The numbers above won’t be precise since the lerp is running every frame, not every 0.1s, but hopefully this gives you an idea of how this blasphemy is working behind the scenes. This isn’t how lerp is intended to be used, but it is a cheap way of moving between vectors, colours or floats on a curve. It’s disgustingly amazing – dismazing, if you will.

It’s also worth noting that if the parameter passed to lerp is set to below 0 or above 1, it will snap up or down to those boundary values. Now you should be a certified lerp expert! I’ve put both versions of the linear interpolation script online for you to download if you’re too lazy to copy them (which is only a problem because I’m too lazy to make them look nice without resorting to taking screenshots. My bad).