Nicholas Junkas
Nowhere, Here, Then, And Now
ㅤㅤㅤㅤ
Platform:
Windows PC, Mac
Engine:
Unity
Language:
C#
Duration:
June 2023
Team Size: 2
Role:
Programmer, Game Designer, Sound Designer
Overview:
Nowhere, here, then, and now is a survival horror game where you play as an individual trapped within a series of liminal-inspired spaces. The player must manage their hunger, thirst, and sanity while traversing a seemingly infinite space in hopes of finding an exit.
This game was a summer project and a submission to Liminal Game Jam 2023.
Responsibilites:
Map Generation:
- Developed and utilized a maze algorithm as a basis for the liminal space procedural generation
- Created a room generation system for randomized internal structure of maze rooms
- Created a system for balancing item, prop, and exit point spawning
- Created level transitions
- Managed game optimizations for map generation and traversal
- Implemented player movement and control scheme
Sound Design:
- Designed and implemented all sound effects in the game
Map Generation:
For Nowhere, Here, Then and Now, I undertook the intricate and complex task of creating the map generation system. During the first week of the jam, I dedicated my time to researching and conceptualizing various methods to replicate an environment akin to a liminal space. Initially, I explored room-based dungeon generation algorithms, inspired by games like Binding Of Isaac. However, I found that these solutions didn’t quite capture the labyrinthine nature I envisioned, with dead-ends, hallways, and random paths. This is when I realized, what I was looking for was reflective of a maze, and therefore looked into maze algorithms. To add a layer of customization to the maze interior, I merged the concept of incorporating rooms into the generation process, ultimately working with a room-based maze generator. The rooms within the maze essentially act a node within the maze algorithm.
Top-view of a small procedurally generated map:
In the maze generation process, the algorithm selects two different types of rooms: premade rooms and randomly generated rooms. These rooms are chosen randomly from a list, but some are specifically designed in advance to invoke a sense of familiarity and cohesion throughout different sections of the map. However, while each room may vary in layout and features, all rooms share common elements such as a floor, ceiling, and walls to maintain a consistent visual and navigational experience.
An example of a premade room:
One method used to create rooms with random elements was creating a list of points to spawn room parts in:
I developed a total of three procedurally generated areas using the maze system. These areas encompass an office inspired by the Backrooms, an eerie arcade, and a representation of a vast and endless pool. Each area is designed to be highly customizable, allowing for easy creation by configuring a set of values. I invested extra effort into creating a menu to ensure that adding new areas to the game in the future would be straightforward and efficient.
Menu for creating or customizing a new liminal area to be added:
Game Optimizations:
Being well-versed in the graphical fidelity triangle (frame rate, resolution, detail), I understood that without map optimizations, a large instance of the maze could cause a significant drop in frame rate. To address this, I implemented a system around the player that only renders nearby rooms, thereby optimizing the number of rendered objects in the scene. Furthermore, to maintain immersion and prevent rooms from abruptly appearing and disappearing, I incorporated a dark fog around the player. The fog not only added an extra layer of mystery to the areas but also seamlessly masked the rendering transitions, ensuring a smoother gameplay experience.
A significant challenge I encountered with the maze system was achieving seamless transitions between levels. One potential optimization method was preloading maps into memory, but I hesitated due to concerns about overwhelming the user’s memory with thousands of preallocated objects. While I did preload one maze to mitigate performance issues like garbage collection, I sought a more creative solution for level transitions.
My approach centered on utilizing the exit objects I created for going between levels. When an exit object is triggered, it will play an animation that effectively conceals the previous map while loading the new one, creating a nearly seamless transition. Although loading the new map could result in frame drops, the transition animation masked any lag, as the player remained engaged during the process. This method ensured a smoother transition between levels without overburdening the user’s memory.
Player Movement And Interactions:
In Nowhere, Here, Then, and Now, player movement is kept simple, focusing on walking, running, jumping, and camera control. However, as the game jam progressed, I took the opportunity to fine-tune the movement system with some added polish. This involved introducing a subtle camera zoom effect when transitioning from walking to running, as well as fine-tuning acceleration to ensure a smoother transition between the two movement speeds.
Moreover, I decided to remove the sprint limitation mechanic. Constantly waiting for the sprint bar to recharge was slowing down the pace of the game. Instead, I introduced a trade-off: while running, the player’s thirst and hunger bars deplete faster, adding strategic depth to the gameplay experience.
Finally, I integrated an interaction animation for actions like picking up items from the floor, enhancing the immersion and fluidity of player interactions within the game world.