XaiJu
castpixel
castpixel

patreon


GHOSTVAC post-mortem - masterclass in fakery and illusion

This is a post-mortem/ behind the scenes of my game GHOSTVAC. Made in 3 days for the Ludum Dare 46 jam, in Construct 2, a 2D engine.

THEME

First things first, I did let the theme get lost in development. The game was initially about feeding balls to a creature via the hatches, to keep it alive. The gameplay has stayed exactly the same, you still have to feed the hatches before time runs out, but arcade games live and die on how easy they are to pick up. I thought the metaphor of busting ghosts was more apt. So the story the game tells isn’t about “keeping it alive”, but I’m ok with it. I prioritized gameplay over metaphor.

Re: people who ask whether I copied an existing machine: I would swear that there’s nothing like this game in any amusement hall, BUT, searching through my reference folder this week, I found:



 https://youtu.be/Yo7mBHUHnV4 


It’s a two player game where you score goals on each other using 2 blowers! It’s even ghost themed, and it’s obvious to me that I totally stole those flat-bottomed ghosts that are part ball and part air hockey puck!

I was obsessively researching electromechanical games a few months ago, and it obviously stuck with me subconsciously!! That said, my game is significantly more sophisticated and gameplay is very different, so no, nothing like this exists anywhere, to my knowledge.

Game Design breakdown:

A sort of pinball-ish, sort of shooter-y, sort of tractor-beam type arcade physics gameplay. I wanted to realize the fantasy of busting ghosts like Ghostbusters or Danny Phantom. I felt it would be fun to make it a two step process: get the ghost, then a trap opens, then you have a limited time window to shoot your ghost in there. Two peaks of pleasure: successfully sucking and trapping a ghost, and then managing to exterminate it by successfully aiming it into a trap.

The ghosts would have to move around a bunch, to provide a moving target. If I had time (I did!) I wanted to implement a boss with a higher difficulty obviously, but also a slightly different mechanic: this time hatches open up and close automatically and randomly. Those same hatches that used to be ghost traps, now represent vulnerable spots of the boss.

Concept art: 


Suction is an illusion!

I went about implementing a “suck” behavior. Now, real-world vacuums do not suck that far! My solution was to “engineer” one blower fan that blows uniformly through 20 small holes arranged in a half circle opposite the player. Each of those holes opens via a circuit, depending on the angle of the ghost vacuum. Probably a potentiometer, or maybe even more primitive, through 20 distinct contacts on the rotating vacuum side. The effect looks like sucking ghosts, even though it’s actually ghosts being blown towards the player.

The same blower fan also periodically diverts some air to blow away from the player, so that the ghosts move around on the playfield.

But the illusion of sucking doesn’t stop there: When a ghost is near the vacuum, it really does suck it in (I emulated a suction force, by making it dependent on the inverse square of the distance - i.e. it gets weak at even tiny distances from the source).

When a ball is close enough, a sensor triggers a magnet at the tip of the vacuum, so the ghost is locked. Then, in order to shoot the ghost fast, a kicker is activated that sends it flying. Just blowing it away wouldn’t be half as snappy or consistent or satisfying. So that called for more fakery.

Also to keep the balls from flying into the hatches on their own, I implemented a bump/ ridge in front of the hatches - i.e. a barrier for most balls, unless they’re moving fast enough to overcome the bump.

To keep the balls from spilling out of their traps, the back half of the playfield is a platform that’s angled back: I apply a small force toward the top of the playfield on any captured ball. When the game resets, the platform is raised, and the slope is enough to send the balls toward the player and out of the traps.

It looks extremely simple, but it would probably be expensive to manufacture: there are sensors for the balls going in and out (so that the game knows when to score or reset). To stay realistic and keep “costs” down I didn’t implement flashing lights on the playfield or other gimmicks. Those games usually rely on cheap segmented monitors (already a Dot Matrix Display is luxury), and one core mechanical gimmick (the blower).

I think it’s a fascinating field of game design, and I pride myself for thinking things through and implementing real-life mechanics.

3D is also an illusion!

Then there’s the fake 3D using sprites. That was a lot of work to figure out, especially since I made this in a 2D engine. The source code gives it away, you can have a look. But it’s basically projection math. Dividing by Z to convert “flat world” coordinates to “projected” coordinates. Then the flat world can be used to design a playfield in 3D

2D playfield for designing and testing:

3D playfield built on the 2D playfield. For displaying the game at a more immersive angle:

2D physics on the right, sprites on the left:

The one and only sprite used for the ghosts. They get Z-sorted, based on the ghosts’ Y coordinate, and also scaled depending on Z.

The combined shadow and reflection sprite, that follows the ghosts around, on a separate layer (i.e. canvas) with universal 50% layer opacity:

The ghostvac plastic nozzle is a prerendered 60-frame animation. Each of those 60 frames corresponds to one of 60 degrees that the ghostvac is constrained to.

The prerendered plastic border was sliced and placed on top or behind the ghost balls, accordingly:


 

The Dot Matrix Display

Electromechanical games, including pinball machines, often rely on DMDs to give out player feedback. It was surprisingly easy to get this one to work:

The reflection is just the same sprite, set to 50% opacity, flipped vertically and blurred. It doesn’t even need the grille overlay, it looks fine as is.

I also made a numeric sprite font, for the time (and maybe in future for scores):


Known Bugs

thanks to all the feedback from players, I’m now aware of a timer bug. It doesn’t always trigger, and seems to only trigger on slower systems or browsers. I did however track it down, and it’s completely because of my sloppy spaghetti code: I’m not setting the enum state of the game properly. And because of that I had to use lots of if-statements, which is exactly the sort of thing the state machine design pattern is there to avoid. I’m still debugging this. In any case, don’t emulate my mistakes!

Further Development

The things to add to this game are definitely: score and a survival mode-type gameplay. Maybe a bonus mode where you freely shoot hatches. Nothing that requires more mechanical gimmicks! It’s the limitations that make this kind of machine attractive to design for.

Also an operator’s settings menu, including highscore reset and timer difficulty adjustments, which also double as accessibility options. Disabled players love arcade challenges too, and giving a leeway of a few extra seconds to make the game beatable by everyone is high on my list.

Thank you for playing!

 GHOSTVAC 

Comments

omg thank you! And can't wait to see what you do with it!!!!

This is really great, thanks for sharing -- the blowing mechanism sure lit a lightbulb in my head haha! DING!


More Creators