All Glitched Out

PostedSeptember 18, 2013
Reading Time @
Categories Game Development Games
Tags games game design flashpunk code actionscript
PreviousWe Have Facelift-off!
NextChartridge

NOTE: If you haven’t played Separation Anxiety yet, this post contains spoilers! Play the game first!

I would also like to take this time to acknowledge and recommend Lone Survivor, which has similar effects (albeit far more sophisticated). Lone Survivor was the initial inspiration for the effects of my game, and even if it wasn’t, you should play it anyway.

One of the coolest things about my game, Separation Anxiety, is the visual (and, to a lesser extent, auditory) effects. They also took up about half of the development time to get right1. In this post, I’ll break down how they work.


Visual Effects

Plain & Simple

Here’s what the game looks like without any effects applied:

Taste of Moonlight

Ugly, right? It only looks good with the effects applied. I’ll explain in more detail a little later.

Liquid Crystal-Clear

The first thing I’ll talk about is how I got it to look “pixellated,” like a low-quality screen or something.

The trick is to only let certain pixels shine through at their full opacity. This, in combination with other, more obvious effects, really sells the look.

Here’s that same screenshot, but with this “pixel filter” placed over it:

Taste of Moonlight

The trick here is to make a pattern where most pixels are drawn over, and the rest are the dots you see.

This is the pattern. It’s scaled up: in reality, it’s a 3x3 pixel pattern. The checkered background represents transparent pixels and I’ve added grid lines to make it easy to see exactly what it looks like.

Taste of Moonlight

On its own, this does nothing. But with a little code, we can get it to do what we want.

I created an Entity to place the filter. Here’s the code for that.

public class PixelFilter extends Entity
{
    [Embed(source = "assets/pixel_filter.png")] public static const PIXEL_FILTER:Class;

    public function PixelFilter():void
    {
        var data:BitmapData = new BitmapData(FP.width, FP.height, false, 0x353535);
        var g:Graphics = FP.sprite.graphics;
        g.clear();
        g.beginBitmapFill(new PIXEL_FILTER().bitmapData);
        g.drawRect(0, 0, FP.width, FP.height);
        data.draw(FP.sprite);
        var pixelFilter:Image = new Image(data);

        pixelFilter.blend = BlendMode.SUBTRACT;

        addGraphic(pixelFilter);
    }
}

The first important thing here are the color used for the BitmapData, #353535. If you use black instead, it won’t work. This color is arbitrary, but it got me the result I wanted. I wish I had a better explanation than that, but I just tried a bunch of colors until it looked good.

The other thing is the blend mode. BlendMode.SUBTRACT makes the one black pixel in the middle of the filter stand out. I think this is because it’s darker than #353535, but I honestly don’t understand blend modes very well.

The last important thing is how I add it to the world. It has to be on top of everything, otherwise sprites are just drawn over the filter and it doesn’t do its job.

Note: If you want only certain sprites to be filtered, then you can just put the unfiltered sprites on top. It’s that simple!

Here’s how I add it:

pixelFilter = new PixelFilter();
pixelFilter.layer = -999;
add(pixelFilter);

layer -999 draws it last because its layer is going to be less than anything else. Unless, of course, you make something with a layer value of -1000. I just never do that. :)

We’re still not there yet! It just looks like a messed up regular image. That’s where our good friend punk.fx comes in.

In Bloom

I wanted to make everything glow, like it really is shining through some sort of screen. I knew punk.fx could get me there, but I wasn’t quite sure how. My obvious first attempt was to use a GlowFX. However, GlowFX comes with a limitation: you can only have one color glowing out of a filtered object at any time.

At first, I thought this would be fine. Look at the top screenshot. All my graphics are basically solid colors anyway. I could just create a subclass of Entity that comes with a glowColor variable, and automatically glows with that color. Each Entity would get its own color and be fine. The blue square would glow blue, the pink square would glow pink, and it would all work out.

But then I realized that the level itself was one Entity, specifically a Tilemap.2 Sure, I could make it all glow white, but what about levels with red tiles at the edge?

So I wanted to find an effect that would allow me to “glow” multiple colors. BloomFX was the effect I wanted.

Here’s what that same screen looks like with BloomFX applied.

Taste of Moonlight

Side Note: PixelWorld

To get all these effects to work in harmony, I subclassed World and created PixelWorld (I’m terrible at naming things).

PixelWorld handles the effects themselves, applying them to the entire screen. It also allows me to change the intensity of the effects on the fly. I use this when you beat a level, for instance. This gives me the power to have a visual progression (regression?) as you play through the game.

It also handles non-punk.fx related effects, which I’ll talk about a bit later.

Every World in the game is a subclass of PixelWorld. The Preloader has to fake the effects without the help of FlashPunk.

So, this is looking pretty good, right? Wrong. It’s not there yet. Sure, the little filter looks better now that things are glowing, but everything is still really plain! Let’s change it up a little bit.

Every frame, I randomly increase or decrease the blur property (the intensity) of the BloomFX by a certain amount. This amount is determined by how intense I want the effects to be. The later you are in the game, the more intense the effects are. I also make sure it doesn’t go below a certain minimum or exceed a certain maximum, so the random factor doesn’t get out of control. Since blur continually goes up and down, it gives a pulsating effect that really makes the graphics look like they are glowing. I can’t really show how this affects the game in a screenshot, but it makes a big difference!

BloOMG

You have to be careful when using a bloom filter, though. Things can get out of control really easily, and you really have to experiment with things to make sure everything looks okay.

BloomFX strips the detail out of all the graphics you give it. For example, the “goal” and “hologram” tiles on my map gave me a lot of trouble because they would appear pure white! The filter would cause the white color to glow so much that the tile just looked solid white. That’s why, if you go back to the first screenshot, everything is an ugly gray color. It looks white under the filter, but it doesn’t glow so much as to suck the detail out of everything. (Also, the glow was a little too intense when it was pure white anyway.)

Glitch’d.

Next, I add a GlitchFX to the game. This causes the screen to go all wavy.

Taste of Moonlight

Much like the BloomFX, this increases in intensity as the game progresses. This effect looks animated right out of the box, so I don’t need to change the effect every frame like I did with BloomFX.

Making Noise

I also use a noise filter, via ScanLinesFX.

This one is barely noticeable, so I had to crank the intensity way up for this screenshot.

Taste of Moonlight

In combination with the subtractive filter, it looks really cool! This has a more drastic ramp-up than the other effects - you can barely see it at the beginning of the game, but it grows more and more intense as the game progresses.

Letting It Slide

A PBLineSlideFX filter is added but disabled most of the time. Every frame, there is a random chance that it might activate, and it does so instantaneously. The direction (left/right) it goes is also random.

The odds of it activating increase as you progress through the game.

Taste of Moonlight

This is also accompanied with an annoying “cartridge pulled while game was running” sound effect.

Pixelated Pause

The last effect I use is a PixelateFX for when the game is out of focus (not active).

When the game is paused, a few things happen:
1. The music gets quieter.
2. The GlitchFX gets more intense.
3. The ScanLinesFX activates and gets more intense.
4. The PixelateFX activates.
5. The shadow graphic (see below) gets more opaque.
6. All color is stripped from the screen.

All that stuff looks like this:

Taste of Moonlight

All of those steps are pretty straightforward, except for the last one. Honestly, I don’t even fully understand it, but it definitely works! This code is practically copy-pasted from here:

// yes, these are magic numbers. no, I don't know what they mean.
// something to do with luminosity.
private static const rLum:Number = 0.2125;
private static const gLum:Number = 0.7154;
private static const bLum:Number = 0.0721;
private static const grayscaleColorFilterMatrix:Array =
    [
        rLum, gLum, bLum, 0, 0,
        rLum, gLum, bLum, 0, 0,
        rLum, gLum, bLum, 0, 0,
        0, 0, 0, 1, 0
    ];

private var grayscaleFilter:ColorMatrixFilter =
        new ColorMatrixFilter(grayscaleColorFilterMatrix);

Then, in PixelWorld’s render():

if(paused){
    FP.buffer.applyFilter(FP.buffer, FP.buffer.rect, new Point(0, 0), grayscaleFilter);
}

More Subtle Effects

Catch a Flick

The screen randomly flickers. This was insanely easy to do. In PixelWorld’s render() function, I have this:

if(Math.random() < 0.001){ super.render(); }

So one in every thousand frames (theoretically) will result in a one-frame flicker (theoretically).

Superimposed

Once you get far enough in the game, a new type of screen glitching can occur. Part of the screen will be drawn elsewhere! This can happen multiple times. The superimposed drawing will only last a frame, so it flicks in and out of view before it really covers something important.

Taste of Moonlight

This is also pretty easy to do once you figure it out. In PixelWorld’s render function:

var x:uint = Math.random() * FP.width;
var y:uint = Math.random() * FP.height;
var w:uint = Math.random() * (FP.width - x);
var h:uint = Math.random() * (FP.height - y);

FP.buffer.merge(FP.buffer, new Rectangle(x, y, w, h), new Point(uint(Math.random() * FP.width), uint(Math.random() * FP.height)), 255, 255, 255, 255);

NOTE: This code is enclosed in a much more complex if statement and for loop that go beyond the scope of this post. Just know it won’t necessarily run every frame and it can run multiple times in a single frame.

Basically, this code builds a random rectangle at a random point on the screen, and then draws the screen’s contents in that rectangle at a random point on screen. If the random rectangle happens to be placed over the black background, it’s probably not going to be noticeable if it’s drawn over another part of the black background. It also won’t be noticeable if the rectangle is 1x1 pixel. Of course, neither of these are true in this screenshot.

Inner Shadows

A simple change that took about 10 second to implement but made a huge difference was the creation and use of a graphic that made the edges of the screen darker. That looks like this (the inside is transparent):

Taste of Moonlight

This is added with a really negative layer much like the PixelFilter. Its opacity increases as you progress through the game, but it gets nowhere near fully opaque.

Auditory Effects

Glitch Switch

Jacob created 2 versions of the gameplay theme: one of them has glitch sound effects rhythmically placed, the other does not.

As you play, the game starts and stops both these tracks simultaneously to keep them in sync. It plays the glitched version silently, but will randomly switch their volumes for short periods of time. As a result, you’ll occasionally hear a glitch sound on top of part of the music.

Just like all the other effects, the odds of this happening (and its duration) increase as you play.

Music Should Be Noisy, Right?

I also play a track of just white noise that gets louder (and drowns out the actual music) as you progress in the game. This was a compromise for the fact that I couldn’t find a reliable way to steadily decrease the quality of the music output as you play.

Panning for Gold Riches Glitches

Randomly, the panning of the music will change to a random number for a short duration. The idea here is that, as the screen fails, your “speakers” should also fail.

Once again, this gets more common and lasts longer as you play.

Questions?

I’ve left comments open on this post. If you have any questions or want me to clarify anything, I’d be happy to! Just ask. You can also contact me through other means if you don’t want to use my comment system for some reason.


  1. Really, this is a half-truth. It took about half of the real-world time before I was satisfied with the effect, but I was working on the game far less frequently until the effect worked. In terms of man-hours, it was far less than half the project. 

  2. In the end, I had to write some custom code to round the corners of the level, so I could have just applied a BlurFX on each tile anyway. I didn’t know that at the time, though. 

Have something to say?

Rampant robots make me require this. Click Tap this until it reaches 0:


Reply
Joseph
September 27, 2013 05:47 PM

This is really great write up, thanks so much for writing I'm gonna reread it tomorrow and try a bit of the stuff out :)

Reply
Mhar
October 07, 2013 07:24 AM

Thank you so much. Excellent work. The game itself is fantastic.