One of our Minion Studios team members stumbled across a game jam called the Asylum Jam. It takes place over Halloween and is themed around horror settings which do not involve negative mental health or medical stereotypes.
Mostly because it sounded fun, and slightly because all of us were a little burned out on our Skurvy project, we decided to take a break and enter the jam. We had a fantastic time working on Minimalist Horror Story, our first game and game jam participation, so working on another horror adventure in such a short time seemed like a great diversion.
We kept the concept very loose and simple. There was no real story revealed to the player, though we had decided amongst ourselves that the player’s character had been at a party where someone had summoned some sort of Lovecraftian horror into the house. All the other party members had been killed or injured. The player wakes up alone in the mansion, and has to explore the darkness to survive. This end goal turned into a fetch quest for pages of a mystical tome that could banish the creature and allow the player to escape.
Most of these details ended up on the cutting floor due to time constraints for the jam, but we have developed the game quite a lot further after the jam was over to add many of them back in. In the final jam entry, you could explore the mansion, finding keys to unlock doors, restoring power to the electrical system, and finding pages to the book. Once you took the completed book to the library where the ritual began, you could reverse the ritual and end the game.
While exploring, you are threatened by the horror as it manifested as 3 different entities. I’m not sure who came up with this idea, but each of the entities has a different attack method, patrol route, and behavior. The original intention is that each of these would spawn and de-spawn randomly around the house, so you weren’t sure what you what you would be dealing with all the time.
The player was to have gameplay options for avoiding the entities, including crouching to sneak and a hold-breath mechanic when hiding. We wanted to add hiding-in-object mechanics similar to games like Amnesia or Alien: Isolation, but did not have time to complete this.
Because of the loose rules of the jam, we decided to take advantage of a large library of assets we had created for a previous project we had abandoned. Eric still had to clean these assets up quite a bit, but it did save a lot of time for putting the mansion together. He did a fantastic job of producing new assets at an insane rate as well.
Sonny took care of all of the AI for the game, including tackling a lot of problems with how they move up and down the 3 different staircases. He used the RAIN Unity asset to create the behavior trees and pathfinding. Damon handled the player movement, 1/2 of the environment interaction, and setting up the player object.
I set up all of the game menus, created the other half of the environment interactions, and did a lot of work on the level, such as occlusion culling baking, after Eric populated the mansion with his assets. I’m going to restrict most of the of rest of this post to the the work I did.
You can play the game here:
A Small Glimpse
How much fun is walking through a scary mansion that you can’t interact with? None at all. This was going to be my largest contribution to the project, but I still had to build the menus as well as all the test/completed builds of the game(I am the only one of us with a Pro Unity license). So, I tried to build something that would be extensible but also simple to up and running quickly.
We knew we wanted most of these interactions to make our jam deadline:
- Open/Close doors
- Key/Page/Item pickups
- Unlockable doors
- Light switches
- Fuse box switch
- Summoning Circle
Damon and I have worked these two sides of the interactive coin before. First with The Brass Bastards, then later with “Multi-Horror”, then aforementioned abandoned project. Each time we had settled on a class type that the player script would look for in order to interact with an object.
Basically, one of our player scripts would raycast from the camera forward into world space. If the raycast hit an object with an Interact tag, then the script would check for input from the player. If the player clicks, then the script checks for the Interactor component on the hit game object. If found, it then calls the prescribed DoAction method on that object.
We like this method for simple projects like this. It keeps the work of the two systems separate, and it’s easy to communicate where the systems will intersect and how that will be implemented. Even though we use Git for source control, in most situations we prefer not to step on each other’s toes, especially during jams when code, levels, and assets change so quickly.
A major downside to this is that it’s difficult to test completely. Until he has a player he can share and I have an “Interactor”, we can’t really test a lot of the gameplay until late in the jam. This is compounded by the varying schedules most of the team members keep during the jams. Some of us stay up late at night, while others are more day people. Finding good times to integrate and test code and other assets presents a challenge.
This isn’t probably the best way to do this or the easiest, but it works for us on these quick projects.
For this game, we had an added problem of inventory. The player should be able to pick up different keys and multiple pages. In The Brass Bastards, you could only really pick up a single cog “key” at a time, so the design stayed simple. To address this issue, we decided that the player would maintain a list of items that he was carrying, and would pass this list to the DoAction systems every time interaction occurred. We also split the system into to parts, Items and Interactors. Items were anything you could pick up, and they had their own tag, classes, and method call. Interactors were everything else, including doors, light switches, and the fuse box.
When you pick up a page or a key, the player script stores a reference to the item in its inventory list, then calls the PickUp method on the item. Depending on the item, different things occur in this method. Some send messages to the UI, such as “You still need to find 4 more pages.”; others may trigger sounds and/or animations. All of them disable the renderer of the item so it no longer appears on the floor or table or wherever you found it.
The most important part of this system is that besides adding the item to the player’s inventory, the player script doesn’t care what the item does with itself. This is even more important for Interactors, because they do so many more things.
Interactors are called by through the DoAction method from the hit game object in the player script. After processing the action, the DoAction method returns an ActionResult, which handles things like error messages or flag if an item was consumed with use. The player object passes a list of Items that represent the inventory the player is currently carrying. Some Interactors, such as a light switch or unlocked door, don’t care about what you are carrying. Locked doors and Summoning Circles do.
For those that do, the first thing many of them did is search through the list of items for the necessary carrying requirements, such as a particular key or all of pages of the Tome. It then carries out the action, which usually involves playing sounds and animations, then returns the ActionResult.
All of the Interactors in the game extended this base abstract class:
As we continued to work on the game, I think I can actually remove two of the DoAction declarations. Damon actually always passes an inventory list to the DoAction method, whether it’s empty or not. I can’t really think of any use cases with our current system where we would need to call these without an inventory list or with just a single item.
For the most part, this is very simple stuff. Of course, because I wrote so much of the system before properly testing it with the actual player code, there were a myriad of bugs, though most of it were in the UI systems we pieced together last minute. Still, if we do another jam like this, my goal would be to get a lot of this core gameplay code written and integrated in the first 12 hours. This leaves the other 36 to test and polish.
Overall, the environment work I did turned out pretty well, and I’ve continued to improve the code and functionality over the last two months.
- We released the game, albeit a bit late.
- Most of the systems came together easily without a lot of bugs. Monsters eat you and doors open.
- The visuals are impressive and atmospheric.
- Occlusion culling seemed to work great for this level. It reduced draw calls and improved performance. Eric has since optimized a lot of meshes, so the payoff isn’t as great, but still it was a simple system to get up and running during the jam and helped us shave some corners.
- Real life interfered on some level for all of us. It’s frustrating, but I don’t see how you can change this. We are adults with busy lives, and it’s hard to commit a full 48 hours to a single event like this.
- Communication breakdowns occurred frequently. Mismatched schedules, sickness, family…all of these made it difficult to coordinate the project.
- No early build. We keep talking about doing earlier builds that we can test and play, but it seems like gameplay gets finalized as the game entry is being submitted. This has to happen much sooner.
- Builds that supported low quality settings made it into the wild. There’s a fantastic video of the game running without proper lighting/shadows. Looks terrible.
- Too many gameplay features hit the cutting floor, including hiding, true sneaking, and breathing mechanics.
- Jump scares and a lot of atmosphere didn’t make it into the game.
Here’s the gameplay video on low quality settings:
While our ambitions fell short, we still made a good start on a game that we will continue to develop into the near future. Our hopes are to release a new version with Physically Based Shading and a large amount of added content. We have been working on a lot of these improvements and hope to bring them out soon. I will be working on a follow up article about the new power grid system that I wrote for the new release.