Fatal Attractions

2.5D Depth Compositing

Psst… wanna hear a secret? In an earlier incarnation of Fatal Attractions the game had a different name: It was known as Libera Me.
Libera Me never really got past the tech demo stage. But a key element of the game’s tech was its 2.5D compositing. The idea here is to have pre-rendered background images which contain information about each pixel’s depth. Through some clever shader tricks this allows us to perform several graphical feats that usually require full 3D scenes:

  • Depth compositing
  • 3D lighting
  • 3D shadows

This concept was used heavily in the earlier Resident Evil games.

I’ve decided to revive this technology for Fatal Attractions. The cool thing is that the entire background scene as well as the character are just billboard sprites; that makes for a whopping 4 (!) polygons being rendered in the clips below!
The 2.5D depth compositing is implemented via custom shaders and provides correct depth occlusion, as seen in this short clip when the character walks towards the background and ends up behind the tomb stones:

Traditionally this kind of depth compositing would require a fairly elaborate setup of masks and/or occluder geometry. Not so with 2.5D compositing where we get the occlusion for free without any extra effort.

But wait, there’s more! Here we can see a real-time directional light casting shadows from a 2D sprite onto a 2D background… and thanks to 2.5D depth compositing we get correct 3D shadows just like in a proper 3D scene:

Of course we’re not limited to static light sources – we can even move a light around. Here we have a dynamic point light moving around and lighting up just the appropriate region of the scene. Also note how the character sprite casts proper shadows onto the background geometry.

I plan to use the dynamic 2.5D lighting to allow the player to investigate using a flash light as well as other sources of light. Of course dynamic shadows will also have their place.

Unfortunately the video compression made a bit of a mess with the image quality, so here’s how the background render is meant to look:

The spooky cemetery

The Haunted Mansion

Working on the engine at the moment. That and the VHS Look post-processing shaders have been keeping me busy lately. It’s hard to find a good compromise there: On the one hand I want the game to have the authentic look of an old VHS tape that’s been watched too many times. But then again I’ve put so much work into the background art and this gets all but ruined by the VHS artifacts.

Today though inspiration struck and so I revisited an older scene that’d been sitting idly on my hard drive for a while. No creepy theme park is complete without a Haunted Mansion, so here’s a first look at what to expect:

The Haunted Mansion Entrance

Here I’m trying to recreate that somewhat over the top spookiness of Disney’s Haunted Mansion. Of course our heroes will have ample opportunity to explore the mansion and mingle with its inhabitants – whether they want to or not…

That VHS Look

When I started developing Fatal Attractions, the idea was to have the game be “authentically digital”. That is to say we’d have crisp, low-resolution pixel art. A palette of less than 256 carefully picked colors. Transparency would be an entirely binary matter. A purely digital soundtrack. Basically everything would be just like it was back in the day.

Sadly, as my pixel art skills turned out to be sorely lacking I eventually pivoted to the more-photorealistic-yet-still-thoroughly-retro style the game exhibits today. If I wasn’t going to capture the essence of early adventure games by mimicking their style, by Jove then at least I’d promote the spirit of the times by setting the game during the early 90s!

But… something was off. The sets and overall style were pretty retro. That couldn’t be it. The resolution of the artwork was retro but also a bit low-ish, which admittedly does turn some scenes into a pixelly mess.

So what could it be?

With the above in mind (and some extra computational power under my belt) I made a few stylistic adjustments and came up with this:

So what’s changed? For one, the artwork’s resolution has doubled. And you probably did not fail to notice that I’m experimenting with a faux VHS post effect to really sell that 90s look :)

Not sure I want to have the entire game running with this effect as it might get irritating after a while — in fact, it was fairly irritating to just mock it up. It’ll definitely need to be toned down a bit.
Though I suppose it could also be used for dramatic effect, similar to how Eternal Darkness messed with the player’s (in)sanity.

But I think the look captures the spirit of early 90s well enough now.

Thoughts on Game Engine Design

For a while I’ve been meaning to talk a bit about the engine design I’m using in Fatal Attractions. The astute reader may recall me mentioning previously that the game is built upon the LÖVE framework. One of the reasons I went with this lesser known framework instead of a full-fledged and commonly used engine such as Unity is that it offers me as the developer a lot of freedom; I can pretty much design the game exactly the way I want it. I’m not forced to follow anyone’s conventions or opinions — ‘cause that’s how I roll.

I’ve opted to go with an entity-component-system-based approach. Everything you see in the game (as well as a lot of stuff you don’t see) is considered an “entity”.
Of course an entity by itself is meaningless and devoid of function; it’s just an empty entry in a Lua table. Only by adding components we can fill entities with life. And depending on which combination of components we apply, an entity can become something entirely different. For example, you take a simple sprite, add a “follow mouse” component and voilà: You’ve created a mouse cursor!

Once you’ve come up with a reasonably sized library of components, you can mix and match them to combine all sorts of functionalities for your game. In Fatal Attractions a Player object gets initialized with the following set of components:

Player: -> 
  with Entity.new!
    \add Components.Actor
    \add Components.Animation
    \add Components.Color
    \add Components.Direction
    \add Components.Pathfinder
    \add Components.PersistentStorage
    \add Components.Pivot
    \add Components.Player
    \add Components.Render
    \add Components.Shader
    \add Components.Sprite
    \add Components.Transform

Now you must know that components are just containers. They’re pure data and do not provide any functionality of their own. An obvious example of this is the ‘Transform’ component I’m using above. Internally it looks like this:

  x: 0.0
  y: 0.0
  z: 0.0
  rotation: 0.0
  scale: 1.0

Now it would pretty neat if we could get these bundles of data to do something actually useful. That’s where the Systems come in. Each System defines a combination of components it can operate on. Here’s the header of my Sprite system:

class Sprite extends System

    Color: true
    Pivot: true
    Sprite: true
    Transform: true

An entity may have many more components. But as long as it has a Color, Pivot, Sprite and Transform component, it will be processed by the above-defined Sprite system. And as you’ve probably guessed, the sprite system is in charge of drawing sprites to the screen. Each system reads the data from its required components and does something with them. In this case, the Sprite system reads a texture from the Sprite component and draws it at the coordinates stored in the Transform component.


The drawing happens once every frame. But not every system can draw things. Some systems just want to do something every second frame. Or after a new stage was loaded. Or perhaps only when the mouse hovers over an object. Or when the player tried to talk to another actor…

These various cases are handled by an event queue. In fact the entire engine is based around this concept: Whenever something happens in the game, an event is fired. Any and all subscribers are then informed that this event has taken place. Depending on the event they may be provided some extra details — e.g. which character just moved, which stage was loaded or which object was picked up by the player.
Subscribing to events is super-easy inside a system. Simply define a method with the name of the event:

onMouseUp: (x, y, button) =>
  -- do something

onStageLoaded: (stage) =>
  -- do something

onExitStage: (stage) =>
  -- do something

The same idea also works for the game’s actors in the story description file. For example, say we have a dog on the screen and the player is supposed to be able to interact with said canine beast. Then in the story script I might add something like this:

Dog.onTalkTo: =>
  Player\say "Who’s a good boy?"
  Dog\say "Arf!"
  Player\say "That's right, you're a good boy!"
  await Dog\animate "Excited"
  Cat\say "Meh."
Bone.onPickUp: =>
  Dog\say "GRRRRR!"
Dog.onGive: (item) =>
  if item.name == "Snack"
    Dog\say "Arf! Arf"
    wait "1s"
    Dog\goto Bed
    Dog\say "GRRRR!"

Of course there are way more commands available to pick from in the actual story engine. But this should give you an idea of how complex interactions can be stringed together by using only simple commands.

The beauty of it is that the story script reads less like your typical programming language and almost like a movie script. This simplicity makes it really easy to prototype new ideas or just try something out to see if it works without having complex syntax get in the way.


You may be wondering what strange programming language I’ve shown above. All code examples are in a language called MoonScript. This is a dynamic scripting language that compiles into Lua. I don’t think I’ve ever come across a more concise yet easy to use language. It’s an absolute joy to develop games in.

Easter Update

First up: Gotta say, I’m terrible at this blogging thing. Really need to force myself to update on a more regular basis! Since my last post I’ve managed to find some time to create several new background scenes that I’d like to show here today.

The first one is an opening shot that shows the protagonist’s home somewhere in suburban America. I reckon I’ve captured that early 90s feel pretty well in this one:

The protagonist's home in suburban America

The next image is my first look into the actual “Screampark”. Still some visible grain and noise from the rendering, guess I’ll have to redo that. It’s not too bad seeing as the render times are fairly reasonable due to the very low resolution of the images. The composition and scenery could probably use some more polish. But I’m mostly experimenting with the color grading here to really capture that cheesy horror movie feel:

A first look at what the inside of the Screampark might look like...

Inventory Screen

This afternoon I was experimenting with the GUI for inventory a bit. Originally I’d planned to go with a Gameboy as the inventory screen, but unfortunately that didn’t work out too well due to its harsh constraints in color and resolution. The game itself is at such a low resolution that it clashed quite badly with the Gameboy’s even lower resolution. So instead I’ve opted for a custom hodgepodge of 90s computer interfaces: A bit of Windows 95 with a heavy dose of NeXTSTEP in there as well:

Experimenting with the Inventory screen

As for the engine, I haven’t been doing much on that front lately. My main focus was on prototyping graphical assets to make absolutely sure I can pull this off… nothing worse than having developed the perfect game engine only to realize that your assets just won’t be able to keep up with the images in your mind!