Justin Time: Man of the Hour Postmortem

Justin Time Main Menu.png

Hey all,

Our team usually hops on after a jam to do a postmortem of how what worked and what didn't for us, but we usually don't share it. This game felt like it went particularly well for us though, and we've been seeing the other postmortems being posted, so we wanted to make a post about why it felt so good to make, and what we thought we could still improve on.

Some context:

About the game:

Our game, Justin Time: Man of the Hour is a rogue-like deck builder that uses a 10 second timer as your mana pool. Each of your cards costs time, so you need to think on your feet if you want to have enough time to play all the cards you want to in a turn. Once you run out of time, your turn ends and the enemies get a turn. On each enemy turn, waves of Clockwork Automata from the Nation of Procrasti (Get it? Procrasti-Nation? hehehe) will try to close in on you, and if they get close enough, they'll start to attack.

About us:

We're three developers, though we've sort of settled into roles of Producer/programmer, artist/programmer, and lead programmer. FplatfoThis is our 6th jam together as a team, and 4 of them have been platformers (and one didn't make it). If you want to see how we've been progressing as a team, feel free to check out our itch games :smile: It's been fun tracking our progress as we've improved.

Game Concept: Brainstorming and Selection

We always start our jams with a brainstorming session where we put a few minutes on the clock and we each start writing out word-clouds with whatever comes to mind when thinking about the theme. Sometimes they're game pitches, sometimes they're genres, sometimes they're mechanics, and they're just words or feelings we'd like to capture. Then we come back together, go around offering one or two at a time, then we try to draw out each idea to its logical conclusion, mixing and matching where we can.

I personally wanted to make a game based on the combat from Mega Man: Battle Network. I thought that 10 second rounds of real-time combat with a break to select new cards feels like great pacing and very on-theme.

Here's my brainstorming page for this project: Justin Time Brainstorm Yoni.jpg

As I mentioned, I'm a big Mega Man Battle Network fan...

What we wound up making was really designed out loud though, which brings me to the first big thing that went well:

We designed this game out loud. (Good!)

This wasn't anyone's idea, it was all of ours. In a way we lucked into it, but I think this is the first time we did a jam where I can't actually point to who came up with this game. Aspects of it, sure, but we all really own this idea. I don't think this game actually appears on any of our brainstorming sheets, but aspects of it appeared on all of ours.

We took our time (Good!)

Usually with 48-hour jams, we're itching to get started. This was our first 72-hour jam, and we took an extra couple of hours on design, cracking jokes, and ideating. Not only was it fun and less stressful, but a lot of that extra content really shaped the final outcome of our game.

We couldn't use the software we wanted to (Bad!)

I think we had card games on the mind already when we started brainstorming because we'd recently bought the Humble Software Bundle: Unity Tools, which included a license to use CCG Kit, an out-of-the-box card game asset pack. It became immediately clear once we started working on the game that CCGKit was too complex to learn as you go. It seems awesome and really extensible, but it's also really complicated and without easy tutorials. In hindsight, I'm glad that we didn't know that going in, because we probably wouldn't have tried such an ambitious game if we thought we'd have to do it all from scratch, but by the time we realized we couldn't use it we'd already spent a few hours designing this game. We like using jams to learn new skills and software, but now we know to look ahead into whether something can be picked up as you go or requires playing around with ahead of time.

Development and Distribution of Tasks

Separating out work (Good!)

I can't express enough how useful it was to have someone in the group step into the producer role. One of our team members managed our taskboard and distributed work whenever one of us was idling. There's always so much to do and keeping the big picture in mind is hard. Having someone who's keeping an eye on that, who can say what we're on track to do and what we're not, or just keep the project organized, is such a big help. That's not all our producer did, she also coded and worked on a lot of the infrastructure of the game, but the only reason that our development of this game flowed as smoothly as it did was because we had her to keep us on track. We also used Monday.com as our task tracker app for the first time, and it seemed to work better for us than other ones we've used before.

This also may seem silly and obvious to some, but it's the first time we've tried it: We each made our own playground scenes to mess around with. Up until now, we've all been working in one kitchen sink scene for work in progress, then building up a new scene that's the "release" version. That leads to conflicts, breaking each other's work, etc. Just having separate scenes and pulling aspects of each other's work as needed made early prototyping much faster.

Extensible systems (Good!)

Card generation

We invested early in making systems that would allow us to make new cards with little or no code. I'll have a more detailed post on how we did that a little later, but for now, here's a little glimpse into how it worked.

The card prefab itself didn't do anything. It was a collection of TextMeshPros and images, with a single script that would initialize the card, handle being dragged, and activate the card's affect when released (though what that affect would be was unspecified). Then, we made a ScriptableObject called a CardDescriptor, which would contain all of the information a card might need. For those of you who are unfamiliar with Unity's Scriptable Object system, I highly recommend checking it out. They're basically fancy data stores, and they're great for making many different kinds of the same thing (among a long list of other uses). We used them for individual cards, groups of cards (like a deck), groups of enemies, individual enemies, and our event system. Here's how it worked with the cards:

Each card would get a CardDescriptor ScriptableObject. You could make a new CardDescriptor through Unity's UI, then fill it in with all the information you needed through the inspector:

Justin Time CardCreate.png

Justin Time Card Inspector.png

The card effects would select some effect from a static enum, and a static function would take a value from that enum and call the function associated with that effect:

Justin Time Card Effect Enum.png

Once a new card was made, adding it to the game was just a matter of including it in the CardList (also a scriptable object) of cards included in the game. That would ensure that it can show up in the shop between rounds. If we wanted to add it to the starting deck, we could just add the card to the CardList for the starting deck:

Justin Time Card Effect Enum2.png

This made the design process of the game extremely simple. Once we had cards working, we just had to think of a handful of interactions that we enjoyed that we wanted to show off in the game.

Enemy Widgets

We knew we wanted some aspect of randomly generated enemies to fill out the roguelike genre, but we only had 3 enemies, and randomly selecting when to spawn them felt too stochastic and unconstrained. We wanted and randomly generated but well-designed experience; something that felt more intentional. We wound up doing a widget system, inspired by roguelike dungeoncrawlers that use pre-designed tiles that are shuffled randomly, so each tile is a crafted experience, and the game always feels well designed.

Our levels were built out of "widgets", where each widget described a set of enemies, where they spawn relative to each other, how many turns it takes before they spawn, and how many turns after this widget begins the game should wait before beginning to spawn the next widget.

Here's an example:

Justin Time Widgets.jpg.png

Here we have a widget that spawns 3 enemies, 1 ranged and 2 melee (Clockwork Mike was our name for the little round guy). The first two spawn immediately when the widget is activated, and the last melee guy waits one turn, then spawns. The "Wait Time" field at the bottom specifies how many turns the game should wait before activating another widget. This one isn't a very hard widget to beat, so it only waits 1 turn before beginning the next widget, but our widgets that use the Big Boy give you a few turns to deal with the new threat before sending in another wave of enemies. These widgets are categorized by difficulty 1-5, and at the start of each level, a few widgets are randomly chosen at various difficulties to make the experience we want for the player. For example, level 5 would have 5 level 1 widgets, 3 level 2 widgets, 2 level 3 widgets, 1 level 4 widget, and 1 level 5.

In the end, we did all of our level designing in about an hour. The last hour. But that's all we needed to throw together a really solid experience. Sadly, that does lead to our next thing-we-could-have-done-better.

Priorities

We didn't test it (Bad!)

We didn't have time to test the game. At the time, it was something we wanted to do once the game was ready, but we only submitted it right before the deadline. It seemed natural at the time, but I think that if we had prioritized getting testers (just friends in the neighborhood) to come play the game from the start, we would have made us factor that into our plans and we'd be better off for it. Most of the constructive feedback we got in our comments were simple to resolve, if only we had people tell us about them before release. One big thing that would've taken seconds to fix is that we were way too stingy with sending out Big Boys, when actually they would've kept the game feeling fresh for longer. Also getting outside opinions on UI and HUD would've saved our players some grief!

Cutting corners (Good!)

It sounds bad when I say it like that, but it's pretty accurate. In the past we've liked to have a settings menu that controls things like volume or sound effects or whatever is adjustable in this game. This time we just... didn't. Saved one of us a couple hours of work, including not needing to design the buttons or layout. We used a puppet-style (just transforming the limbs and body and recording it in the animator) animation instead of full sprite-based animation style. Saved us a ton of time on animations, and looks pretty good I think, especially because we really leaned into it. From now on we're going to pay more attention to what we can cut out to save time.

Reusing Code (Good!)

We've done a few jams now, and we've started to notice what infrastructural code we keep rewriting in mostly the same way. We've been trying to reuse more code from old jams that can be easily transferred (a lot of managers, mostly). I think this was the first time we saw real dividends from doing that. Saved us probably several hours of work, even though we've never done a card game before.

We didn't have a tutorial (Bad!)

Not having an interactive explanation for how the game worked really shot us in the foot. The game isn't actually that complicated, but it does throw a bunch of information at you. Most people who left reviews didn't have a problem, but we know the game experience would have vastly improved if we had a tutorial. It's something we kept saying we needed, but no one took it up until it was too late to make a good one. We could have prioritized better, but also we could've just used more time.

No ending (Bad!)

We didn't think we'd have time to fully craft a few strong levels and a satisfying ending, so we opted to go for an unending game. We also didn't have much enemy variation. I think that the game suffers a bit from being aimless at the end. There comes a point where you've mastered the game, but the game has stopped scaling with you, and it becomes a little monotonous. Aside from more enemy variation, I think we could have used more of the Big Boy, as we called him. He was tougher and more exciting, and I think we were too stingy with using him.

I think having an ending -- something to work towards -- would be a great motivator for people not only to continue playing our game, but also to come back to it if they were to lose.

Remembering that this is a jam (Good!)

We usually try to imagine a fully formed game and try to translate that directly into the game we're making. This time, we imagined a fully realized game, but during the actual design steps when we were deciding what cards to include in the game and what pacing to have for certain things, we tried to think of how to best convey our vision to the player, rather than trying to fully realize it all at once. We picked a starting deck full of interactions that we wanted to guarantee the player would experience (rather than balance it for a long game), and make sure that they get the full experience of playing the game even if they only play for 5-10 minutes. I think the result was that players could see the potential in the game, if it just got built out a little and had more content. Considering that this is a game jam and how players tend to interact with game jam games helped us keep perspective on what was important and craft an experience more geared to who our actual users were.


That about sums it up. Overall, I think we did really well with this one. We learned a lot of lessons for what works well for us, and a few about what doesn't and what we should try prioritizing in the future. If you haven't tried our game, please go check it out, we're really proud of how it turned out!