RECAP: GGJ 2018
January 31, 2018
I made a game with some folks (and the rest of the world) over the weekend for Global Game Jam. These are some words about it.
I'm so tired. Which is weird, because I'm also very energized. Game jams are like that when they're good, and this past weekend was very very good. I originally started writing this post on Monday, but as you can see it didn't quite get done by the end of the day. Assume I was more tired than I thought, hence the delay.
For those unfamiliar with it, Global Game Jam is an annual event where participants all over the world make games based on a theme announced at 5pm on Friday, and they have until 5pm Sunday to complete... something (or not, that's cool too!). Like all game jams, the games made are, well, jammy. And that's pretty cool. Also, since it's worldwide, it means there's a lot of really jammy games appearing all at once online made by folks all over, which is also really cool.
It's fun to be a part of that. This weekend I was lucky enough to work with some very talented folks on a two-player puzzle game we titled Co-op Knights. It's sort of a walking sim with two variations on a single map (a day version and night version), with the conceit being the puzzles in the day map require hints provided in the night map, and vice versa. You can download and play the latest build from the game's page on the Global Game Jam site.
Making a puzzle game was definitely an interesting experience. The most educational bit out of the whole process was "playtest early, playtest often," which I only learned because we did neither of those things. Having said that, the puzzles still played out pretty well when we demoed it. The problem was our puzzles were either too easy or too abstract. Two of the five were brute-forced when demoed live, and one required guidance from the audience of attendees and the development team. That's a pretty wide spectrum, and if we'd actually had people try it out before the end of the event we probably would've been able to at least bring the puzzles all closer to the middle ground. Having said that, for a jam game I think we made some pretty clever design choices with the tools we had available.
The most recent build of the game has a total of 5 puzzles in it, each fairly different from the last. One involves pressing a set of buttons in the correct sequence. Another involves navigating an invisible maze of tiles without missing a step. Yet another involves visually matching a series of tones to a grid of buttons. While the presentation and senses used to convey these puzzles and their hints varied a good deal, the actual implementation of them behind the scenes was identical. They all were basically just event triggers. The button sequence puzzle and the musical tones were technically the same puzzle. What separated them was the presentation: one used an animated sequence to imply the order in which they were to be clicked, and the other used musical notes played in a specific, repeated order. But both were simply collections of GameObjects that contained a generic "Click"able method that invoked a UnityEvent. I made a couple components that subscribed to these UnityEvents, most of which were really just stopgaps that contained their own UnityEvent that just linked to a Door controller component that opened the in-game gates. It was the use of UnityEvents that really made the game technically possible, since the level of decoupling they provide allowed for the use (and reuse) of lots and lots of little pieces (aka Modules) that could easily communicate with each other.
I think one of the best things about the game we made were the assets used. I worked with Shannon Zagst in creating the 3D model set used to populate the game (which, fun fact, only uses something like 15 unique models). Katherine Spitler developed the 2D textures on the assets, as well as the in-game UI graphics and game logo. Kevin Brown wrote the music (some of which unfortunately went unused) and provided the sound effects for the various puzzle and game elements. All in all, I think it's one of the better looking and sounding games I've created for a game jam.
I want to go back to the unique models point for a minute. Something really important about game jams as a whole is doing more with less. This mostly has to do with the fact that you have zero time to make a game, so cutting corners as creatively as possible is almost always guaranteed to pay off. Case in point, asset reuse. The levels created for Co-op Knights are built with
- Four different wall models
- One column model
- One gate model
- One door model
- Two button column models (one of which is just a single-use variant of the other)
- One floor panel model
- A fountain model
- A broken barrel model
- A torch model
- A treasure chest model
- Three rock models
Now, I might be a bit biased since I made it and I'm happy with how it turned out, but I think the whole thing turned out looking way better than those numbers might imply. A little creative reuse of models (rotate this a bit here, crop that out there) made for an environment that was interesting to look at and explore without being overly monotonous.
Last thing I want to write about making this game: event systems are amazing. I got into this a little already talking about modularity, but I still feel like designing with delegates/UnityEvents is straight-up magical. But before I go into excited raving mode, a brief explanation.
When you're coding interactivity between elements there's a lot of different ways to do it, but one of the better things you can do is avoid coupling things when you can. The general rule is if you can design something with it knowing nothing about the other items it's interacting with, do it. Providing a component with too much understanding or reliance on how another one works leads to inflexibility in your design very quickly. For example, say you're designing a room with a ceiling lamp and a light switch. If you explicitly tell the light switch that it has to connect to Ceiling Fan A2, enable connectivity between the light bulb and it's socket, and turn the brightness of the light bulb up to 11, you'll have a very specific implementation of a switch you can only use with that ceiling fan. BUT, if you design your system so that the light switch can send a message that says "turn on" and give the ceiling fan enough rules to know what to do with that message, then you can reuse the light switch anywhere else you want to have "turn on" do something.
Effectively this is how the buttons in Co-op Knights work. Every button in the game is exactly the same. They inherit the IClickable interface, which requires them to implement method "Click", which, in this specific implementation, invokes the UnityEvent "ClickAction". ClickAction then has methods subscribed to it that are called when "Click" is called on the button. What this means is the buttons tied to the doors are exactly the same as the buttons tied to the torches or the sequence puzzle. They don't care how any of those things work, they just know that, when clicked, they have to call a bunch of methods that subscribed to it at some point.
Where this gets even cooler is with UnityEvents (and this is also where I go into the aforementioned "excited raving mode"). UnityEvents allow you to subscribe methods to a caller, but unlike delegates (which are native to C#) they provide editing access from inside the Unity Editor. This means if I want to add a new method to a button that gets called when it's clicked, all I have to do is drop a GameObject onto it in the inspector, select the component and method I want to Invoke from a dropdown, and provide any data that might be needed by the event in the autogenerated fields. This is AWESOME, and it's how all the doors and button puzzles are set up in Co-op Knights. If you're a Unity dev and not using UnityEvents, I highly recommend you check them out and start playing with them.
Well, I think I've rambled on long enough. Again, big thanks to Shannon Zagst, Katherine Spitler and Kevin Brown for their work at GGJ '18. If you're interested in playing Co-op Knights you can get it at the BGS Global Game Jam site, along with all the other cool games that were made this past weekend. You can also peruse the source code for Co-op Knights on GitLab.
Doing a little cleanup in my overflowing collection of unsaved text files in Notepad++ revealed my initial brainstorming notes for the game. Figured I'd post them here for posterity (and so I don't need to save the text file)
Co-op maze navigation -Puzzles- -Map to maze -Riddles -Cut the right wire -Next in the order -Simon -Pressure plate pattern -Slider puzzle -Logic puzzles -Warmer/colder -Tone matching -One player sees three doors (Bird/Dog/Human), the other sees a room full of feathers -Theme/Aesthetic- -Night/day -Post apolcalypse - SCOPE CREEEEEEEP