Managed to render another scene this weekend:
We visit this location early on in the game in the hopes of picking up a friend.
Managed to render another scene this weekend:
We visit this location early on in the game in the hopes of picking up a friend.
Sadly I didn’t have as much time to work on the game as I’d like in the past few weeks. Just life and work getting in the way.
But I did manage to squeeze in a couple new scenes and continued to improve the VHS look:
Stay tuned for more updates.
Today I’d like to show some of the character designs I’ve been working on lately. I’ve shown a lot of background art here already. Now it’s the characters’ turn. The designs are still very much work-in-progress but I feel they’re starting to come together finally.
On the right we have Emma – she’s a bit of a wallflower. The cool dude on the left is the oldest brother, Pete. He’s a huge metal fan.
Last but not least in the middle we have the youngest sibling, Mikey; he’s the playable character in this game.
And here is one of the more villainous characters. Because obviously no haunted theme park would be complete without a creepy evil clown lurking around the corner, right?
Finally there’s also a WIP background I’ve been working on for a while: We’re looking up at the boys’ treehouse in the woods. This is where the story unfolds when they discover an unexpected visitor.
That’s it for today!
As the kids try to make their way into the haunted theme park they realize they can’t just bust in through the main entrance. Looking for alternate ways to get inside, they come across a culvert that seems to lead straight where they’re heading.
And just like any self-respecting teenage horror movie
victims participants, they (of course!) decide to enter the darkness…
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:
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:
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:
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:
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…
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.
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:
Transform: 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 requires: 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 else 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.
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 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:
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:
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!
For the past couple years I’ve been working on and off on this point n’ click adventure game called Fatal Attractions. This is the first time I’m publicly showing my work on this project, but I feel it’s been incubating for long enough now and should start to finally see the light of day, for better or worse.
The game takes inspiration from ‘80s horror movies as well as classic 2D adventure games, two of my favourite things.
Fatal Attractions is set in the good old days of the early ‘90s in a small town in the US. We follow a couple teenage boys as they come across a curious looking girl lurking around their treehouse in the woods. She leads them to a seemingly abandoned theme park just outside of town. Once night falls, the boys quickly realise that the park is not as abandoned as they were led to believe…
The game plays very much like the classic adventure games from LucasArts and Sierra Online: You point the cursor at objects on the screen, choose an interaction method and see what happens. Throughout the game you get to explore mystic places, meet strange folk and solve puzzles along the way.
Originally I’d planned to make Fatal Attractions look a lot more like the games that inspired it: Clean pixel art with a limited VGA palette. Alas, it turned out I’m absolutely rubbish at this art style. Also, it wasn’t really jibing with the mood I had in mind for the game.
Thanks to my background in feature film animation I happen to know a thing or two about rendering in 3D. And so, after a lot of trial and error, I eventually settled on the style you see here. The pre-rendered 3D art gives me lots of artistic options to capture a nostalgic look reminiscent of ‘80s teen movies such as The Goonies or Fright Night. Moreover, the low resolution keeps the amount of time and work it takes to create and render the assets fairly reasonable.
Fatal Attractions is built on the lovely LÖVE game engine and written entirely in MoonScript. At one point I’d ported the whole thing to Unity, but eventually came to the conclusion that it’s just overkill for what I’m doing here.
At this point I have a working prototype of the game running:
These early screenshots are running in the game’s engine. Animations aren’t quite there yet, so just still images for now:
Hello and welcome (back) to my little development log. On these pages I’ll be talking about the continued and ongoing development of my point-and-click adventure game, Fatal Attractions. I’ll discuss game development ideas, techniques, issues I run into and I’ll talk you through the progress as the project comes along.
And this time for real, too! Must be the third or fourth time I’ve relaunched this devlog over the years. And every time it would fall into neglect shortly after. How is this time different, I hear you scoffing? For one (I hope!) I’ve finally come up with a style for the game that’s, well, “sustainable” for lack of a better word. You see, in previous iterations I had too lofty goals for this project; inevitably they’d eventually come crashing down on me. They were simply out of reach for a sole developer like myself who’s working on a game in what little spare time he has.
This time is different. I’m going for something with a more forgiving style. Something I can actually see myself completing in a reasonable time-frame. No more forever-projects. No more custom engine development. No more perfectionism. I need something to show for all the time I’ve invested into this game. And by God it’s been a lot! Too much!
Welcome aboard. And wish me luck.