Alone, Not Lonely

 

The Game

Alone, Not Lonely is a mixed 2D and 3D exploration and puzzle RPG that follows a young child that’s home alone; who begins chasing after a figure that they suddenly see, in an effort to escape their growing feeling of loneliness. The child’s journey involves them going through the halls and rooms of the house, and maneuvering through obstacles set by the figure and (mentally) by themselves, in order to continue progressing.

My Role

As lead programmer, I designed and implemented a majority of the systems in the game while also assigning tasks and determining task priority for the other programmer on the team. I also supported our level designer as he implemented the levels, making sure that all of the scripts I wrote were usable from the inspector for someone that doesn’t come from a programming background so that he could implement our levels with minimal intervention from the programming team. As a technical artist who comes from a programming background, I really enjoyed getting to make shaders and work out the art pipeline for this incredibly visually unique game.


System Breakdown

Monster AI - Almost all monsters billboard to face the player, raise the player’s anxiety level when the player is within a certain radius, and play audio clips to indicate that the player is too close to the monster, but there are a few distinct types of monsters throughout the game

StaticMonsters.gif

Static Monsters

These monsters stay in place, fading in and out of existence based on the player’s distance to them

portalMonster.gif

Portal Monsters

These monsters work off of a base system comprised of an agent that moves between a set of patrol points, but with the added complication of having the agent pass through portals that change their location and certain portals that change the direction in which they are moving.

elevatorMonster.gif

Elevator Monsters

These monsters move the object that they are holding up and down, from ground level to a height set by the level designer. The animations of this sprite line up with the movement of the held object, so it looks like the monster is pushing the object up with its head. The player can interact with this held object normally, climbing on top of it or picking it up and moving it.

smashMonster.gif

Smash Monster

There is only one of these in the game, but he is key to solving several of the room’s puzzles. The player places an object underneath the smash monster and the smash monster squishes it, turning it into a compressed version of the original object which the player now carries above their head, allowing them to place it on top of taller obstacles. The squish mechanic is a simple prefab swap, where the original object is swapped with it’s squashed variant on contact with the monster, and after a set amount of time the object swaps back to a prefab of its original, unsquashed variant.

SwitchingMonsters.gif

Switching Monsters

This set of static monsters swaps between on and off based on a timer, where half of the monsters are “group A” that start active, and the other half of the monsters are “group B” that start inactive. When the timer hits zero, group B becomes active, group A becomes inactive, and the timer resets.


Grabbing System - In the above monster breakdowns you can see the the portal monsters and the elevator monsters can pick up and move the grabbable physics objects in the levels. The player can also pick up and move these objects - this system is the way that the player interacts with the monsters to solve the puzzles. To implement this system, I wrote a general “Grabber” class that controls how all agents interact with the “grabbable” physics objects. This controls the picking up and releasing of objects, as well as the passing of objects between two different Grabber agents. Each of the unique agents then extends this class for their own specific implementations - handling how the object should move and collide with its environment based on which Grabber is holding it, as well as handling animations, audio, and movement restrictions in the case of the player.

A UML of the system from fairly early in development - at this point, the patrol points controller (later to become the portal monster controller) was the most fleshed out. In the end, we moved UI handling to its own system and ended up having the Grabber class contain an actual implementation instead of being an abstract class.

A UML of the system from fairly early in development - at this point, the patrol points controller (later to become the portal monster controller) was the most fleshed out. In the end, we moved UI handling to its own system and ended up having the Grabber class contain an actual implementation instead of being an abstract class.


Progression (Puzzle Pieces) - The way that you beat the game is by collecting all of the puzzle pieces hidden around the house and assembling them on the coffee table at the end of the game to reveal the end cutscene. This method of game progression presented some unique challenges.

  1. The player needed to be able to return to any levels where they may have missed a puzzle piece. This required that

    • The player can move backwards through levels

    • If they’ve already visited a room, any keys that they’ve picked up, doors that they’ve opened, or creatures they’ve defeated must remain the way that they remember leaving them

    • Levels need to load with only the puzzle pieces that the player does not have yet, i.e. puzzle pieces that have already been picked up need to not be there

  2. The player needed to be able to put the puzzle pieces onto the coffee table

    • If the player leaves and returns, the puzzle pieces need to still be on the table

    • If the player is missing specific puzzle pieces, only the pieces they have picked up should be on the table

  3. The player needed to understand how important puzzle pieces are before reaching the end of the game

    • When the player picks up a puzzle piece, we need them to take a moment to look at them and know that the piece has gone into their inventory

Issue #1 was handled by some complex scene persistence handling. When the player loads into a level, all of the objects that could potentially be in the players inventory check the player, and if they are already in the player’s inventory, they destroy themselves. The same goes for monsters and other two dimensional, imaginary entities; we track if the player has defeated a level, and if they have, all of the imaginary entities in the level destroy themselves on load.

Issue #2 was handled by assigning all of the puzzle pieces their own unique ID’s, allowing for a similar check for specific puzzle pieces.

Issue #3 was handled with an interaction system that allows the player to inspect the puzzle piece in 3D before putting it into their inventory, rotating and turning it before the counter in the corner ticks up and the piece is added to the inventory. This interaction system handles the deactivation of puzzle piece containers when a piece has been picked up, the animations of the boxes containing puzzle pieces, and the switching of the control scheme between the regular movement mode and “object inspection mode”, where the player can only look at and rotate the object until they decide to put it down.

The player assembling the puzzle on the coffee table after getting all of the pieces.

The player assembling the puzzle on the coffee table after getting all of the pieces.

The introductory sequence of the game, where the player encounters their first puzzle piece.

The introductory sequence of the game, where the player encounters their first puzzle piece.


Shaders, Effects, and Lighting - An important thing for this project was establishing a distinct visual style, inspired by illustrated children’s books while still providing a tense and spooky atmosphere. I discuss my process for developing the shaders used throughout the game as well as the custom render pass for the outline effect in this blogpost as well as this follow-up post. I was also responsible for the particle effect shown above that indicates where to find puzzle pieces. Another effect that I created was a fake volumetric light sprite, which rotates around the direction that the light is being cast and adds a subtle effect of physicality to the space.

Below, you can see the living room television without volumetric lighting on the left, and the living room television with volumetric lighting on the right.