Sunday, March 22, 2020

Fam Jam #1: Joe Johnson Gets Captured

I've been talking to my friend Ian Schreiber off and on for a long time about "fam jamming", or running a game jam with families. I've never actually done one; it always seemed like something else would come up. Now that everyone's stuck at home to stop the spread of COVID-19, it seemed like a great time to try it. Ian's primary advice was twofold: first, he advises to put a kid in charge of the vision while parents do what the kid says. This inverts the usual control structure, empowering the child and fruitfully humbling the parents. Second, he recognizes the different "superpowers" of the two classes: children are endlessly creative, and adults know how to get stuff done. Leverage these powers and use them for good.

Early yesterday morning, I surprised the family by saying we'd be doing a one-day family jam, and that #4 Son (who is five years old) would be in charge. Perhaps I shouldn't have surprised my wife with this; I had mentioned it to her in passing but she didn't know to plan on it for Saturday. However, once again we have the benefit of not really being able to go anywhere else. I encouraged #4 son to take a few minutes to sketch out some ideas, so he left to the crafting table and came back almost immediately with an idea about a mushroom and a turtle who are underwater and shoot at each other. The mushroom's attack shots are blocked by the turtle's block shots and vice versa. That more or less makes sense. Then he told us how after defeating the turtle, there is a crate you have to smash with a chainsaw in order to save Joe Johnson. Well now, this suddenly got much more interesting. I have no idea where Joe Johnson came from, but it was clear that we had to save him.

During this phase, I tried to ask some probing questions to understand what he was expressing. One of the other boys tried pushing toward something he wanted to make, so I jumped in and explained that #4 was the creative director: we could ask questions, but it was only to understand what he wanted us to do. This is a funny spin on Ian's advice for bigger families, since it's not like the other son lacks creativity or is particularly good at getting things done. However, he was very respectful and understood the exercise, and I think that itself was a small blessing from this project.

The original concept art for Joe Johnson Gets Captured
In the center of the image above is the original concept art for the game, showing a mushroom man who shoots circles and a turtle who shoots triangles. It was explained that they are in the water, standing on the ground, and the sky and sun are above them. The seahorse was added later. Around that original rectangle, you can see some of the other pieces that were added as the discussion went forward. On the left center is Joe Johnson, who is wearing a pink dress. In my work, I tended to refer to her as Jo Johnson because of the dress, but the rest seemed happy to have him be Joe Johnson. Fine by me, as the important thing is saving him. In the upper left, you see a "chainsaw", which the careful observer will notice is actually a hacksaw. I wonder if this was inspired by peering over my shoulder as I've been exploring One Finger Death Punch 2. (Wholesome family entertainment.) Across the top right are the original drawings of the triangular turtle bullets and the round player bullets, with an annotation about which button on the controller would fire them.

We talked briefly about platforms and tools. I am most productive with Unreal Engine 4, and my oldest son has some experience with it (such as at Global Game Jam). However, it is tuned for native delivery, and Epic recently removed the capacity for HTML5 export, which means that the artifacts are harder to share with distant family and friends. One can rebuild the engine from source to support HTML5 export, but that was definitely out of scope for a one-day jam. My two older sons have built some lightweight games using the free version of Construct 2, which is great for letting them explore ideas. I have relatively little experience with it, however, and honestly I don't have a lot of incentive to learn it. On the other hand, I have been increasingly curious about Godot Engine and I can see a lot of benefit to learning it. Games from Scratch has been singing its praises (although I know this more from reading the titles of videos than watching them), and I recently talked to Mike Sellers about how it is used in IU's Game Design courses. The whole engine is released under the MIT License, which is also very attractive. In preparation for the fam jam, I had built a very small tech demo the previous day in Godot Engine, before only ever having tinkered with it once to work through one of the stock tutorials with my oldest son. The tech demo was enough to get my head around some of the core ideas and validate how easy the HTML5 export was. I could see that this would probably be enough to go in mostly-blind to build a one-day project designed by a five-year-old. This established, we settled on Godot.

So as not to bury the lede (maybe it's too late for that...), you can play the game online or check out the source code via GitHub. It was a few hours in that we asked the lead designer what to call the game, and he offhandedly came up with Joe Johnson Gets Captured. It's catchy. The result, well, it looks like it was designed by a five-year old, but we're all pretty happy with it.

What I'd like to do next in the blog is provide a few vignettes about the day, rather than continue in a chronological fashion.

Title Screen

Production

One of the major challenges I faced was trying to fulfill the role of a producer on a five-person team with such varying levels of skills. At the beginning of the day, #3 son asked what to work on, and I suggested storyboards... which of course he had never heard of, so I had to provide some guidance. This poor guy was caught in between ages, not being quite advanced enough to do some of the technical work, and not being the youngest one who was sharing vision and giving feedback. My oldest son and I did the technical and integration work from my upstairs home office, while my wife worked in her downstairs home office. Even just this small physical separation kept us out of sync, where we didn't know where things were, and she didn't know what integrated work looked like. #1 son and I used git to share our work, but oh how I miss the asset locking that's so easy in UE4 with Perforce. Also, there seems to be known troubles with working across Linux and Windows machines in Godot because of line ending problems. Seriously, in 2020, in release 3.x of a popular game engine, this is still a problem. Still, between GitHub and Google Drive, spread out across three rooms and four computers of the house, we were able to bring everything together before 9PM.

I'm not entirely sure what I would do differently next time. It would be nice if we could all work together in one room, but I am sure neither my wife nor I want to give up our dual-monitor setups. I think we could get #2 Son at least more actively into Godot Engine in a future project, especially in the post-project exploration I've done of some of the tools as discussed below. I also need to remember to look carefully at that link I shared above to make sure I'm taking the best possible precautions against the silly line-ending problem, which caused us a lot of unnecessary headaches yesterday.

Music

A few weeks ago, I came across this video about using LMMS to make music for games, and my second son happened to watch it with me. He became interested, so we installed it onto the family laptop and he tinkered around a bit. For this fam jam, we put him in charge of the soundtrack. The truth, though, is that he doesn't have the musical knowledge to quite know how to structure a song: common rhythms, intervals, chords, etc. His first original composition is actually used in the loss screen of the game: it's actually a perfect fit for this part of the game, though musically, it's pretty clearly the result of kind of aimless messing around with LMMS.

Our lead designer said that he wanted the game to sound like Istanbul (Not Constantinople), which is a family favorite. I had written out a simple arrangement of that song, and I encouraged #2 son to transcribe the bassline into LMMS as a starting point. He wasn't really sure about this either, in part because I don't think he sees the isomorphism between staff and piano roll representations. I laid down the 1-1-1-5 bassline for him, and then I showed how I would approach the rhythm, setting up separate tracks for a bass drum on the downbeats and a high hat on the upbeats. He got that it sounded good, but maybe still doesn't quite know what to do with that knowledge. We found a lead tone (flute), and I showed how I'd layer a melody on top of these other ones by laying down a simple two-bar line. My son took the next little while to play with adding and removing the tracks, making some modifications to the melody. At one point, he accidentally copied the bass drum line to the highhat; this actually gave a good variation where all the rhythm was on the downbeat, though he didn't actually recognize that he did it. In our last session together, we got rid of the grating flute sound and replaced it with a synth. He had a spot where the drums dropped out, which was a good variation in tone, and I added in a kind of silly furious highhat tapping to bring the drums back in, which is still my favorite part of the song. The result is a fine little loop that runs through most of the game. For the title screen music, I once again laid down a few simple lines that he rearranged into a short loop that sets the tone for the game.

Maybe that's more detail about the music than you cared to hear about. There are very few things I've been doing longer than I've been programming, but playing and writing music is one of them. I'm hoping that perhaps this experience can be a good hook to encourage my son (and perhaps the others) to think some more about how music works and to try to start copying some of those ideas and playing with them. I am reminded of all the hours I spent as a kid copying songs from my piano lessons book or from my imagination into the C64 Music Maker software. I like to think that time wasn't just wasted!

Sound Effects

Fairly late in the project, as we had the core functionality in place, I sat down with the three younger boys to show them how to record sound effects on the family laptop using Audacity. I was surprised how quickly they caught on, not only to the recording, but also how to deal with multiple takes, exporting the selected audio tracks, and uploading them to Drive so we could put them into the game. I told them that this was how I made all the sounds for Kaiju Kaboom, and how pitch shifting could be used for very simple transformations. They put together a suite of sound effects which, truly, are not at all what I had in mind, but which certainly add to the aesthetics of the game.

Spoiler: When you win the game, there is a bit of spoken dialog that is tricky to catch. It's a combination of young kids talking into a laptop microphone and also adopting funny voices. The actual spoken words are: "You saved me, man." "No problemo."

The Mushroom Man and the Turtle in Action

Godot Engine

Let me start with my criticisms. Programming in Godot Engine reminds me in many ways of the things I hated most about programming in Unity ten years ago. The reliance on strings as signals, as method names, as node paths, and as resource paths strikes me as inexcusably fragile. Refactoring anything in Godot is an exercise in frustration. While it's true that one should minimize dependencies, one of the few truisms in programming is that code always changes. Tools without built-in refactoring support make me feel like we lost all the gains the agile software development movement made to modern IDEs. Worse, the reliance on literal strings throughout the architecture inculcates programmers into the idea that this is a good idea. That's really dangerous when compared to tools and processes which encourage constant improvement and refactoring. There's a rule of thumb: if refactoring is hard, people won't do it. On the positive side, this criticism makes me think about potential research opportunities for how to measure or change the environment to promote best practices. 

Another criticism, which should go without saying, is that whitespace should not be significant in a programming language. You cannot see it, so it should not be meaningful. Now, if you're really good, you'll appreciate the irony that this goes without saying. Why should it go without saying? Well, show me your whitespace. Also, if you cannot deal with line break characters properly, maybe you should not rely on whitespace for meaning. 

The node system has grown on me. I am glad I took the time the previous day to understand the relationship between areas, collision shapes, and their shapes, because that did not click for me right away. Now, I have a better appreciation for what I believe is the intended mental model. 

One of the most powerful notions in Godot Engine is instancing scenes. The nomenclature is terrible, however, since a "scene" is actually a class, in the object-oriented programming sense. The documentation even points this out. A "scene" in English has a connotation that is not at all implemented in Godot Engine, but if you think "class of objects" or "blueprint" instead, you get a better understanding. Ignoring the nomenclature for now, the idea that you can instance a scene into another is a powerful way to think about composition: while other parts of the engine encourage bad behavior, this one gives you a way to think about decomposing functionality and responsibilities in a very nice way.

Toward the end of the project, we ran into the classic problem where we wanted one song to play throughout multiple scenes.  The classic problem has a documented solution that we were able to incorporate before shipping: using autoloaded singleton scenes to manage shared state. With a few changes to where we put our songs and responsibilities, we were able to get the music behavior properly. (Well, except for a bug I noticed late last night on mobile, where, depending on where you first tap the screen, you can end up with two songs playing at once.) There is a problem again here though, and it also is mentioned in the documentation: these aren't singletons. The primary point of the design patterns movement was to introduce vocabulary to describe common solution strategies to categories of problems. It's not clear to me why the Godot Engine documentation writers would chose to use the term "singleton" for something that is not a singleton, not when one could just as well use a different word. Still, it's good technique to know, reminiscent of using GameInstance in UE4 to manage information that persists between levels.

We didn't use many advanced feature of Godot Engine. My son and I talked about it this morning, how the first time you use a tool like this, you sort of meander around, building and testing mental models. It's not until after you've built something that you can then really understand some of the other pieces, because then you understand not just the terminology but also the rationale for them. This morning and late last night, I did some reading that revealed some great features that I suppose we could have used, but now I see them as fun and powerful ideas to explore in future projects. These include the Tween node, the animation player, and cutout animation. The first two of those represent things I know how to do readily in UE4—things that add juice that our one-day build is clearly lacking. The cutout animation feature though is really special. I'm already thinking about it enables some of the ideas that have been kicking around to perhaps become more attainable. That is, rather than just seeing how to apply what I know from one tool to another, it's showing me a new way to do new things.

A Story of Code Quality

I'll take a brief aside to share a story that illustrates one of my points above and one of my son's reflections below. My eldest son was responsible for the cooldown timer on the player's mushroom man. Keep in mind that the player can shoot either attack or defense shots, and that these share a cooldown timer. His original implementation looked a bit like this:
 # Shooting attack bullet    
 if cooldown==false:  
   ....
   cooldown = true  
   yield(get_tree().create_timer(.5), 'timeout')  
   cooldown = false  
 # Shooting defense bullet  
 if cooldown==false:  
   ...
   cooldown = true  
   yield(get_tree().create_timer(.5), 'timeout')  
   cooldown = false  

This is the approach encouraged by the tutorial I mentioned earlier that we had worked through. I told him it's not the approach I would have taken, but we left it in. I did ask him, if we wanted to change the cooldown duration, how many places he would have to change it; he recognized that problem and then he replaced the literal 0.5 with a variable.

Originally, we just had input via the keyboard, but later we added the on-screen buttons. We wanted to make the game playable on mobile web browsers without keyboards or gamepads, so he worked on this feature, too. His original implementation, then, simply copied both of those blocks of text into the scripts attached to the buttons. However, the buttons were not connected to the player but to a separate UI, and so they had their own cooldown variable. The result was that, when using keyboard input, the experience was fine, or when using the buttons, the experience was fine, but when mixing the two, one could fire faster than we wanted to allow.

He understood the problem, and I suggested that a simple solution would be to have the buttons watch the player and, each tick, check if shooting is enabled. Their enabled state then could be matched to the player's shooting ability. He acknowledged this but said he had a different approach. His solution was to use signals: the player would emit signals when its shooting ability was enabled or disabled, and the buttons would listen for those signals to update their own state. Did you get that? He deployed the Observer design pattern. Proud Dad moment.

Family Reflection

I made omelettes for lunch today, and as I was preparing them, I told the family that I would ask everyone to share something they learned from yesterday's jam. I've written enough about what I learned, so let's hear what they wanted to share. For simplicity, I'll list the kids by age instead of ordinally.

5-year-old: The way he put it was, "I learned how to draw a computer." Digging more carefully into it, he meant that he learned to draw concept art—to draw something as he would like it to appear on a screen. He didn't have much else to offer besides what we tried to prompt from him, but you know, he's five. He clearly had a great time.

7-year-old: He mentioned storyboarding and recording audio in Audacity. He could not remember the terms for either, but he has brought up both multiple times, so clearly this was impactful. As I mentioned above, he's the one who I think got a bit shorted by the production plan, but he also clearly had a great time.

10-year-old: He also mentioned using Audacity, but he added that he learned how to share the files with the rest of us. My wife was a bit surprised at this, but that's because that whole process was physically and technically hidden from her: I clarified that he had not only recorded the audio, but also exported it and uploaded it to Drive for me to incorporate into the game. This gave me a good opportunity to talk about how a more mature process would be for everyone to have access to Godot Engine so that they could integrate and test their own work, but that I didn't think we would be able to recoup the overhead of that within a one-day jam. It would have required getting at least my wife and the 10-year-old into the engine and, more importantly, acclimated to using git from the command-line (which, incidentally, the 13-year-old did really well with after a brief tutorial).

This son also mentioned that he learned something about the division of windows in LMMS, but we had a hard time sorting it out: it had to do with the relationship between the song editor, the track editor, and the piano roll, but when I tried to assemble these things to see if I understood him, I kept getting it wrong. I need to sit with him and LMMS to see what it really ways. He also interrupted my wife's responses to throw in, "I learned that we should do family game jams more often!"

13-year-old: He learned about how collision handling works in Godot Engine, which was something that was dogging him on a side project. I asked him if he also learned anything about code quality, and emphatically affirmed that he had. In particular, he said that he learned that, to make a change in the behavior, you shouldn't have to change it in many different places. I explained that this was the essence of the DRY principle.

Wife (age withheld): The first thing she mentioned was that it's important to choose a palette at the start of a project. She had attempted a lot of color correction and postprocessing on the boys' hand-drawn images, and she realized that establishing a palette would have made this a lot easier. She also learned how to better use tools like Inkscape. In fact, she was working on processing images and layouts well past when we were done yesterday, and she spent several more hours working on pieces this morning. Later, I may go in and add her revisions and see if I can trap that aforementioned audio bug. Finally, she also noticed how important communication was and how difficult it was, even though we were all in the same building. Better communication would have meant an improved product and less confusion.

Concluding Thoughts

The family was all very excited, and while there were some tense times (mostly when people were asking me for things while I was trying to track down an elusive bug), it was a great day. Everyone is proud of our work, and they should be: together, we went from an idea in the morning to a playable, complete game in the evening. The only thing that we couldn't incorporate was a midday feature request that, when you save Joe, it becomes nighttime. During the day, #3 Son asked if we would do at again soon (I think he wanted to do it today) and if we would be going up in age order as lead designer. All the other boys agreed that they would love to do it again. The older two already spent time this morning tweaking some of their old projects based on what they learned or were excited by in Saturday's jam.

For me, it was a good break from a stressful time at work. In addition to all the stresses brought about by the coronavirus, I also have a major writing project that is due on Wednesday, and I'm not feeling confident about it. Rather than fret about it over the weekend, we took Saturday to make, and that's just about the best thing to do. 

Thanks for reading. I think you'll be hearing about Fam Jam #2 before too long, and I wish you the best in your own game-making adventures.

No comments:

Post a Comment