Saturday, December 24, 2022

Flutter, Godot, Plans, and Regrets

A conversation last summer put a bug in my head for a game design. It's been flitting around for months, and I feel like the idea could be fun for a niche audience. In fact, it's the same idea I wrote about last July, when I tried some exercises from Justin Gary's book. Two or three weeks ago, I got out my paper prototyping supplies and whipped up a minimally playable version. Although the paper version was anemic, it showed that the core ideas could be fun. My intention though had always been for it to be a digital experience, and I knew that a lot of the experimenting would require trying different content and interactions in digital form. 

This led to me to explore two different options for digital prototyping. My first option was Flutter, which I continue to be fascinated by. I have used it for several side projects and a few classes, and I am particularly interested in the elegance of Dart and the separation of UI and model-layer concerns. My other option is, of course, Godot Engine, which I have used for most of my game development the past several years. A significant benefit of Godot Engine over Flutter is that I just have a lot of it in my head right now, so I don't have to spend as much time scouring documentation for just the right thing.

The game design itself is, fundamentally, a single-player card game. At this point, I've made several different prototypes in both Flutter and Godot Engine. Indeed, I've made so many, with enough variations on their directory names, that I've had to set up a separate directory just for abandoned prototypes. What I've come to realize just recently, though, is that I have spent a lot of time on the wrong things. To be honest, it's not clear if these things are wrong since I did learn what I wanted to learn from them, but on the other hand, they are wrong because, six months and many hours of labor later, I don't have a version of the game that I can send to my friends to playtest.

In particular, I've been having serial headaches with a fundamental card game interaction problem: I want to drag cards from one area (e.g. a hand of cards) to another. I want this to feel good to the player, so the cards should animate nicely into position. If they are over an area where they make sense to play, the player should get some feedback. If they are dropped in an illegal area, they should go back to where they came from. 

Note that none of these issues are core mechanisms: they are UI design problems. They are important UI design problems indeed, and one of my concerns going into the project was that, if I was going to sink personal time into it, I wanted to invest in the right tool stack so I would have to do minimal re-engineering. However, reading Lemarchand's A Playful Production Process—which I am doing in preparation to teach CS390 next semester (blog post coming soon)—got me thinking that I am trying to solve a production problem while I should be focusing on preproduction problems. That is, my goal right now should be to determine if the game should be pursued at all, not whether it should feel good. This means making a toy, a playful artifact, rather than a vertical slice.

Rather than regale you with the chronological narrative of my discoveries, I will summarize some of what I found for each of my engine options.

Flutter:

  • The dev tool support here is incredible, with easy refactoring and convenient language constructs.
  • The Draggable and DropTarget widgets are really nice for most drag-and-drop purposes, but not for my case. When dragging a widget, a separate element is made for the version that is following the mouse, and it is irrevocably lost on release. This makes it impossible (or at least impracticable) for handling my case where a card animates smoothly into position or returns to the player's hand. 
  • A custom drag-and-drop system can be built out of Stack, using Positioned widgets. That is, rather than nesting widgets in the normal Flutter way, one can get complete control over an entire canvas of widgets. AnimatedPositioned makes animating these into position a breeze. Indeed, I was pleasantly surprised at how easy this was to express things like, "Keep all my cards in my hand evenly distributed across this widget." The problem is that, when recognizing the drag gesture, the mouse position is consumed by the widget on top: one cannot get mouse entry/exit events for the widgets underneath. 
  • It seems like, at this point, I'm just building my own UI framework and may as well just be using Flame. The trouble is that then there's yet another piece that I don't know, and development is slow and awkward for me.
As always, if any of you readers knows more about Flutter than I do, please feel free to correct any of these misconceptions.

Now, Godot Engine:
  • Of course, Godot Engine has the benefit of its visual editor for building scenes, including composing them. This makes it very easy to break up a project into pieces that are individually, but manually, tested.
  • Godot Control nodes do have drag-and-drop support, which I had not come across before. Like Flutter, you make a separate view node that is visible just while dragging. It would be great for normal drag-and-drop interfaces, but not for something like a card game. 
  • Which controls receive mouse focus is again a problem, but it's solved by keeping track of all the geometries in a "tableau" class. It watches for the mouse and, at the level of the table, keeps track of where the mouse is, which areas should be highlighted, when cards should be animated, and so on.
  • One of the things I built in a Godot prototype was an EventQueue to manage some of the in-game events, such as waiting to start a round until an animation was finished. That was something I found particularly awkward to do in Flutter. None of my past projects used an EventQueue, and I suspect that if I finish this project, it will need something like that. 
  • Refactoring in Godot Engine is a huge hassle. It is easy to build a thing. It is almost impossible to rebuild a thing differently.
How much of this really matters right now? I'm not sure. It's Christmas Eve, and I want to spend most of the next several days with family and friends. I'll have some time to dive into code if I want to. I still have significant prep to do for this new class I'm teaching in Spring, and of my other two classes, one is almost ready to go, and the other needs maybe a half day more of work. If I do dive into code, I think I will have to make yet another new project though, and I will have to hold myself accountable to making something simply playable. I need to stop myself from getting distracted by these interesting problems of software architecture and player experience so that I can determine better whether this game is fundamentally worth pursuing or not. I suspect this means I will turn back to Flutter, where I can easily refactor and whip up UIs that respond to model-level changes.

Merry Christmas!

Thursday, December 22, 2022

Reflecting on CS215 Game Design, Fall 2022 Edition

I do enjoy teaching my introduction to game design class, and partnering with Minnetrista through the Immersive Learning program is always a treat. I want to capture a few thoughts here before the Fall semester disappears in a haze of planning for Spring.

Three things that went well

I still like following Schreiber's online Game Design Concepts book. Despite its age, which means that it doesn't have examples that resonate with the students nor touch on more modern phenomena like MOBAs, the fundamental ideas in it are good. You also can't beat the price. I have two new books here that I will flip through soon, but I continue to be impressed by how well Schreiber's online massive teaching experiment has held up.

The transition to a larger class size was not as bad as I feared. I love to teach the class in a manner that has everyone putting posters up on the wall for discussion, but there were too many students for that. The exercises had to move to other formats. I don't think it was as good, honestly, but it was also not so bad.

Having students track their time in their final project using labor logging was much smoother this year than last. Regular readers may recall that, last year, I tried to combine design logs and labor logs, and this confused the students at both the logistical and the epistemological level. This year, it was much clearer whether students were putting in the time being asked of them for the final project. As usual, the projects were graded on process rather than product, and putting effort in is an important part of the process (he says, as he writes his blog post rather than working on his side project).

Three things that could be improved

I am sure I have said this before, but I need to find ways to help students better integrate the first half of the semester into the projects of their second half. The final exam asks the students to connect some of the dots, and it's obvious from their answers that they are doing post hoc reasoning: they talk about these final projects using terms from the reading that never came up in their design logs or presentations. Put another way, I think it's fair to say that most of the student projects would be exactly the same with or without the studies from the first half of the semester. I need to get them reflecting about these ideas in a more structured way, perhaps by adding some additional writing or discussion assignments.

Compounding the issue above is an observation that shocked me early this semester: I don't think I've ever had a class with worse reading comprehension skills. The students and I talked about this more than once during the semester, how they did not understand simple reading assignments. This runs into a fundamental problem with being a university professor: it's almost impossible to distinguish between cannot and won't. That is, if they can read for comprehension but are choosing not to, then that is their problem, but if they cannot read for comprehension, then I have a responsibility to them to scaffold this better. Seeing how poor college students' reading skills are, it makes me wonder if I need to design some interventions here. For example, in my draft Spring CS222 course plans, I am requiring students to take notes while reading and then write summaries of those notes; I think the very notion of taking notes while reading is foreign to them, but I am hopeful that this will bear fruit.

Given the confusion around the tasks in the first half of the semester, it's also possible that allowing resubmission would help. Many students got fundamental things wrong around the basic theories, but very few students are motivated to actually correct these misunderstandings, opting instead to charge forward with muck in their eyes. I'd rather not have an exponential increase in the number of things I have to grade, but on the other hand, I also want them to understand these theories so that they can apply them in their own work and in looking at their classmates' work.

Tuesday, December 13, 2022

Reflecting on CS315 Game Programming, Fall 2022 Edition

Following up on my previous post, here is another short reflection on one of the courses I regularly teach: Game Programming, also known as CS315. My students are taking the final exam right now, so it seems a good time to record some of my own thoughts about the class.

I did not make any major changes to this class, and it continues to be one of my favorite classes to teach. Godot Engine is just the right level of abstraction for junior-level CS students who are just getting into game development: they can make things reasonably good-looking and fast while still getting into some serious details of game programming. Checklist-based evaluation means that the work is fairly easy to grade and the students by and large understand what is expected of them. Yes, there are always some hiccups here, but there's not enough to warrant radical change.

The class involves several sessions where I am demonstrating concepts and students are thinking about how the pieces fit together. They did a good job with that this year, and they asked better questions than I remember past students asking. Of course, some of the questions could just be answered with, "Try it and let us know," but still, I didn't want to prevent their asking questions. The flip side of this, however, is that they were terrible at taking notes. The fallacy that they will remember lectures is strong with them. I am not sure how I can use the class to help fight against this ridiculous misconception that plagues so many students.

There were a few sessions that I expected to finish in one class period that ended up taking more than two. For example, I put together an interactive lesson on shaders, and for some reason, it filled up a lot more time than I expected. I'm simply noting this here so that I can keep that in mind for the future.

There are some bolts yet to be tightened on the course. The final project has too many checklist items that are easy to cheese. For example, given an item like "Add pop to your UI using AnimationPlayer," some students do a lame fly-in and call it done. I am not quite sure how to invert this. That is, what I want is for them to do something they are motivated to do, and I give it course credit. One of the downsides of checklist-based grading is that some will do the minimum required and present this as if it demonstrates mastery. It's not obvious to me where the dividing line is between those two, especially in the absence of a game design prerequisite. That is, for this course, they can want to make something pretty dumb, and it's hard to distinguish then between whether what they wanted was dumb or whether they were bad at making something better.

I look forward to continuing to teach this course as a generation of students comes up through the Game Design & Development concentration. I am hopeful that we are bringing students who are even more excited to excel at these ideas rather than just barely pass the bar. I expect I will continue to use Godot Engine, and I am hopeful that next year, it will be Godot 4. Indeed, right now I am evaluating whether I want to build a prototype in Flutter or in Godot, and a large part of it is because Dart is just such a nicer language to express ideas than GDScript 1.0.

Reflecting on CS222 Advanced Programming, Fall 2022 edition

My students have not yet taken their final exam in CS222, but I feel like I am in a good position to share a few thoughts about the course. 

Three things that went well

Using Dart and Flutter was a success. I did not get the impression that the students were any more lost using Dart and Flutter than they traditionally have been with Java and JavaFX. There is so much good documentation around Flutter that I suspect it was actually much easier for them to deal with it. I plan to keep this change to the course next semester, when I will be teaching CS222 once again.

Around the middle of the semester, I presented a series of two workshops comparing Java and Dart. I had hoped for more students to come, but the fact is that preparing and executing the workshops helped me better understand where the students were. I plan to bring this experience into next semester's class, potentially rearranging some of the first-week material to give these workshops in class. I have been inspired by Robert Talbert's latest blog post about 12-week plans for 15-week courses: while his target audience is not teachers like me, it still got me thinking about how the first week of CS222 might be structured as more of a review of past material.

Incorporating the mob programming game got my students thinking and talking about mobbing, and adding the achievement gave my students something to pursue. I look forward to using my classroom mob programming game next semester.

Three things that require consideration

I think I had less participation in the resubmission and achievement system this semester than usual, or if it wasn't actually less, it was still disappointingly low. I have had some conversations with others who use similar methods, and I wonder if the students would be better served by having a handful of concrete deadlines rather than rolling weekly ones. Undergraduates are notoriously bad at time management, and so maybe it is a double whammy for them to have to deal with both managing resubmissions/achievements and remembering weekly submissions.

I use a simple grading scheme that, despite my efforts, students do not understand. On one hand, I do not blame them but rather the school system that has damaged their thinking around learning. Again inspired by some of Talbert's other writings, as well as some recent conversations with colleagues, I have been wondering how much of my class I can get away with not grading. This would be an uphill battle since students are trained to be anxious about grades. 

In the final iteration of the final project, some teams included fundamental errors, such as not having passing tests or naming classes as verbs. I have already provided checklists to help with such things, but nobody uses these. I could ask students to turn in more artifacts such as checklists and CRC cards, but this runs counter to the previous point. I wish I had a better view into the students' behavior and how it is that a team of four smart students can run multiple code reviews and not see simple, fundamental Clean Code violations such as naming problems.

Something like conclusions

That's all I have for today. I need to do significant work during the winter break to pull together changes to this course. I hope to be able to share some thoughts about it in under three weeks. Ack, this is a short break.

Friday, December 9, 2022

What we learned in CS222 (Fall 2022 edition)

Regular readers will know what time it is: it's time for the next installment of What We Learned in CS222. As has been my recent custom, I moved this exercise from the final exam timeslot into the penultimate day of class, the final day of class being reserved for students' final presentations. We only had seven students in class this morning, which is less than half the enrollment but not far from what I've been getting the last several weeks.

I had them start by quickly making mind maps on the theme of programming. I only gave them three minutes to sketch them out, telling them afterward that it would be a great study exercise to compare your current map to the one made on the first day of class. The exercise was really to just prime the pump for them to answer the question, "What did you learn this semester?"

Here are the 71 responses, sorted by the number of votes earned at the end of the process. Each student had four votes, but either someone misunderstood the instruction or I lost a sticker in transit.

  • Clean Code (7)
  • TDD (6)
  • GitHub (3)
  • Code Review (3)
  • Agile fundamentals (1)
  • Version control (1)
  • User stories (1)
  • Model-View Separation (1)
  • Flutter + Dart (1)
  • Naming (1)
  • Requirements analysis (1)
  • Software architecture (1)
  • SRP
  • Acceptance testing
  • CRC cards
  • CI/CD
  • Pair programming
  • Mob programming
  • Using APIs
  • Using Android Studio / IDEs
  • Forking repositories
  • Feature branching
  • Committing in git
  • Commit messages
  • Pushing in git
  • Pulling in git
  • Licensing
  • API keys
  • Defensive programming
  • README.md
  • Pubspec.yaml
  • Achievements system
  • Pitching project ideas
  • Incremental development
  • Sprint
  • Project demos
  • Iterations
  • Breaking down epic stories
  • Emulators
  • Red-Green-Refactor
  • Comments
  • Test data files
  • Functions (especially parameters, in a Clean way)
  • Null safety
  • Async/Await
  • Stateful & Stateless widgets
  • DRY
  • gitignore
  • Reading package documentation
  • Using outside resources
  • Local saves
  • Save/Load features
  • Export/Import features
  • git commands
  • Dependencies
  • Project time management
  • File names
  • Simple, clear class names
  • Encapsulation
  • Software craftsmanship
  • Making UI buttons
  • Code side-effects
  • Delegating (in Software)
  • Delegating tasks
  • Wrappers
  • Polymorphism
  • Defensive copies
  • Text wrapping in a UI
  • Text wrapping in code
  • Test coverage
  • Non-programming skills

There are a few interesting things in this list. I was surprised that there was relatively little about Flutter and Dart in particular. I was glad to see it show up as a concept itself but more excited to see that a student recognized how very cool async and await are. Breaking down epic stories is important since just yesterday we did an in-class exercise where no one remembered that conditions of satisfaction are part of user stories, despite this being a recurring topic of the semester. Specific Clean Code ideas seem to be less represented here than in past years, more emphasis here being placed on technological issues of version control. Unfortunately, there is nothing funny in the list.

We found it easy to draw a line in the list and see that the top four items were selected by the community as the most important. I explained to them that these four will feature on the final exam, and it's up to them whether they want to share this information with their missing teammates or not. This elicited the expected nervous laughter.

Wednesday, December 7, 2022

NaGaDeMon 2022: The Classroom Mob Programming Game

In a rare inversion of media, I already announced my 2022 National Game Design Month project on YouTube before writing about it here. The project is Classroom Mob Programming Game. Visit the site for all the details.

My inspiration came from playing Willem Larson's Mob Programming RPG with my students in CS222. I played it last Spring for the first time, prompted a pair of blog posts about the experience [1, 2]. I played it again this Fall with my students and had a similar experience. I wrote some about how I framed the project in my only other NaGaDeMon 2022 blog post. Here, I want to talk a little about how I brought the pieces together to finish my project last week.

I did not make a lot of progress on the project for the first part of November. I kept ideas simmering but did not put pen to paper very often. As I pulled my notes together, I also had to determine how I would playtest it. Normally, my family provides a convenient testing group, but this game was designed very specifically for my CS222 class. That is, the game was designed for sophomore Computer Science majors and minors who are studying techniques of agile software development. I also didn't want to use my own CS222 class as testers since we already spent two days on Larson's game plus another class meeting to debrief and review from the experience. Also, my students would not be good testers because they already know what the game is supposed to teach: fundamentals of mobbing.

I reached out to my two colleagues who are teaching the other two sections of CS222 this semester to find out if they would send students to an after-hours playtesting session. Turns out, they both independently invited me to come to their class meetings to present the game to the whole class. This was invaluable for two reasons: first, it gave me two opportunities on sequential days to do testing; second, it gave me deadlines by which I had to have iterations ready.

Here are some of the most important properties of my game as viewed in comparison to Larson's.

  • Support multiple teams mobbing in the same classroom at once.
  • More deliberately scaffold students toward good TDD practices along with introducing mobbing
  • Fully completable in a 50-minute class session
  • Rather than add new playbooks as players level up, they unlock new actions that earn them XP, but the number of XP needed for the next level also increases
My game has some PbtA sensibilities, but it looks less like one than Larson's. It's more of a traditional RPG in that you have a role and earn XP, but without the emphasis on playbooks and actions.

The first test went well, but there were several loose ends that needed to be tied up. I had created an ostensibly balanced scoring system to support competition between teams. In practice, it was too fiddly to compute, and some individuals computed their scores incorrectly while others simply threw up their hands and guessed. I almost completely removed scoring from the game for the second playtest, and I don't think anyone missed it. I wrote up a much simpler scoring system that is provided as an optional addition to the game. I fixed some errors on the handouts, but more importantly, I made significant revisions to the actions. The first group of testers had a hard time getting into a red-green-refactor rhythm, even with some gentle prodding from their instructor.

The second playtest went much better, with simpler scoring and better actions. Players don't just get more actions as they level up, but some of the actions actually change forms for better scaffolding. The best example is in the Navigator role, where there is a series of actions that evolves like this:

  • Level 0: Describe a desirable, failing unit test--the "Red" in "Red-Green-Refactor"
  • Level 1-2: Hold the team to the appropriate step of "Red-Green-Refactor"
  • Level 3: Complete a "Red-Green-Refactor" cycle

After the second playtest, I also completely rewrote the game's instructions to follow a more logical flow. Those interested in the details of the game evolution can always check out the commits made on Nov 29 and 30, the dates of the playtestings.

I am eager to use this variation on the game with my CS222 class next semester. I am also considering framing it as a research project, but I need to determine if I will have the spare cycles to pull that off, given my other responsibilities in Spring.

Thanks for reading! I would appreciate if you can help spread the word about this game to folks who may be interested.

Monday, November 21, 2022

Amaro Secondo

Following up on my last post, I processed my second batch of amaro last Friday. So far, I am using the clever name "Amaro Secondo" for it because I cannot think of anything else. Rather than following a formal recipe, I simply grabbed a bunch of things that I thought would be good together. I had some my help from my wife in finding and considering ingredients, and this is what I ended up using.

  • 2 tsp gentian root
  • 1 cardamom pod
  • 1 tsp dried orange peel
  • 8 dried juniper berries
  • 1 tsp lemongrass
  • 1 pinch dried rosemary
  • 1/2 tsp fennel seed
  • 1 tsp coriander
  • 3 crushed roasted hazelnuts
I kept roughly the same volume of ingredients as in the first batch. I used a lot more gentian root after reading an article that suggested a much higher ratio of bittering agent to alcohol compared to the recipe I followed the first time. I did not include any fresh ingredients, in part because my friend who inspired me to try this had himself made two batches, one with fresh herbs and one with only dried. I also did not use the blender this time but instead beat up the ingredients by hand using a wooden muddler; this was not as effective as a mortar and pestle, but it did break up things like the cardamom pod and coriander seeds.

Whereas my first amaro was beautifully green during maceration, this one was a pale brown. However, after processing, I would have told you that they were about the same chartreuse color. Putting them next to each other, we can see that the first one is noticeably more colored than the second.

Two Amari (first batch on the left)

Tonight was the first time I tried them side by side. There's probably a right way to taste test amari, and my approach of just swishing some water between was almost certainly not it. The first batch has a more pleasant aroma than the second: hold it under your nose, and you pick up something between camphor and anise. The second one has almost no aroma at all. Sipping the first, it's again that camphor/anise that hits you first and strongest, with bitter undertones. The second one has a more bitter foundation that seems to change more in the aftertaste. I also pick up subtle notes of what I think is the coriander but may be the citrus peel, a sort of lemony flavor that is unlike the first.

I have a lot of amaro in my cupboard that I need to share before making more, but I do find myself thinking about what I would try next. If I were to go in this citrusy direction, I would include some fresh ingredients along with the dried ones, perhaps citrus peel. I also wonder about adding just plain more ingredients. Some recipes I find online use ratios about like what I have, while others encourage adding much more stuff.

Friday, November 11, 2022

Amaro Primo

Last night, I finished processing my first batch of homemade amaro. I used Marcia Simmons' recipe at Serious Eats to get started. Knowing how the Internet has consumed some of my favorite recipes over the years, I will share what I actually used, which was a slight difference from Simmons' recipe just due to what I had on hand.

  • a broken, incomplete piece of star anise (original recipe: 1 teaspoon anise seeds)
  • a few dried sage leaves (original recipe: 6 fresh leaves)
  • a few ragged but technically fresh mint leaves (original recipe: 6 fresh leaves)
  • 1 sprig fresh rosemary
  • 1 allspice berry
  • a few whole cloves (two or three, I don't remember)
  • 1/2 tsp gentian root
  • 3 cups 190 proof Everclear / grain alcohol
I was able to get the Everclear at Muncie Liquors on Jackson. I ordered the gentian root from Mountain Rose Herbs when the boys and I were also ordering some other esoteric spices for my wife's birthday a few weeks ago. We do not have a mortar and pestle, but we do have a spice grinder. Unfortunately, it is almost exclusively used for processing Szechuan peppercorns; I chose against using it since I did not want to make a numbing amaro. We ended up blitzing the spices in the blender to try to break them up. It did bust them up a bit, but there was so little volume that it had a hard time pulsing them.

I macerated the herbs and spices in the alcohol for three weeks as per the original recipe. Note, however, that the recipe called for 150-proof spirit, and my more recent reading leads me to suspect that I could have stopped the maceration earlier. I kept the mixture in a Ball jar on the counter near my tea and coffee area, which meant I would remember to give it a swirl each morning when making my morning drinks. The most significant change was over the first two days, when it changed from basically clear to beautifully green. About two weeks into the process, I did some more reading where it was recommended to keep the mixture in a dark place. Oops. The last week or so, then, the jar was kept in the liquor cabinet.

Emiko's post at Food52 explains that for 95% alcohol like mine, one typically wants a 2:1 ratio of simple syrup to infused alcohol in order to get to an appropriate ABV and sweetness. That post also mentions that you can get four cups of syrup by combining 3 cups of water with three cups of sugar. This is a helpful ratio to know since it's not otherwise obvious to me how the respective volumes of sugar and water combine to determine the volume of the syrup. A little simple algebra reveals that I needed 4.5 cups of sugar dissolved in 4.5 cups of water, giving me the six cups of syrup I would need to mix with my three cups of alcohol.

On my wife's recommendation, I used a fine metal tea strainer to filter the solids from the alcohol, and this worked great. There may be a few very fine flecks in the resulting liquid, but it was much easier than dealing with multiple passes through a cheesecloth or spice bag. Once the syrup had cooled off (although it was not yet room temperature, because it was late and I was feeling impatient), I mixed the two together and poured the result into a half-gallon Ball jar, with the overflow going back into the smaller jar in which I had done the maceration.

Earlier, during maceration, I occasionally took the lid off to smell the concoction. It basically smelled like alcohol: the fumes from the booze overpowered any sort of pleasant, herbal aroma that I had hoped for. This made me a little nervous. I was surprised then when, as I was straining the alcohol, I could almost pick up two different aromas: one was the intense alcohol but the other was a more mellow, pleasant scent.

Here's the result:

The recipes say to let the combined alcohol and syrup sit for two weeks or so for the flavors to continue to develop, but of course, I couldn't help myself from pouring a little glass for myself. I like it, but I find myself lacking some of the words to describe what it is like. It reminds me a little of absinthe⁠—although maybe that is in part the color⁠—mixed with something grassier. It might be the bitter gentian or the herbal sage that I am picking up on. My wife hasn't tried it yet, as she was early to bed last night. I am eager for her opinion since she has a better ability to name flavors than I do.

I actually have a second batch macerating in the liquor cabinet already. Originally, I was going to wait until this one was done, but then I decided to just go for it, to mix up a bunch of things that sound like they would go well together and see what happens. Watch this blog for a follow up in a few weeks.

My biggest question right now is what to call this. The title of this post is just a bit of fun with Italian, but I thought about perhaps naming them as a sequence. Popes? Letters of the alphabet a la Ubuntu releases? Let me know if you have an idea in the comments.

Thursday, November 3, 2022

Trying Jeff Patton's Opportunity Canvas

Welcome to National Game Design Month! In this first related blog post, I'll share a few observations about my experience using Jeff Patton's Opportunity Canvas to frame a game design idea. I heard about this technique recently when watching Jamie Winsor's 2019 GDC talk on user story mapping. He includes the technique as something he has found valuable for game developers.

I have not fully committed to a NaGaDeMon project yet, but my inspiration to make a short-form RPG to teach about Mob Programming was recently reignited. Regular readers may recall that I wrote a two-part blog post (1, 2) about how I used Larson's Mob Programming RPG in my CS222 class last Spring. I recorded some ideas at the time about how I think Larson's approach falls short of my particular needs. I am at the point in the semester now where I have just introduced this game to my students, and the results were roughly similar. The differences comprise a story for another time. For now, I am considering whether making my own, similar RPG would be a good NaGaDeMon project, especially considering that this can clearly "count" as scholarly productivity as well.

I thought that Patton's Opportunity Canvas might be a good way to determine whether this direction would be fruitful or not. The short answer is that I don't think the Opportunity Canvas exercise gave me any insights I didn't have previously. It is very business-oriented. I was able to interpret things like "business impact" as something more like "departmental learning outcomes," but it still feels like a bit of a stretch. I completed this as a solo exercise, but it is clearly designed to be collaborative, so it's possible I am missing something there as well.

The part that most interested me, and the part that was rather useful, was the identification of both the problems being solved and the metrics for success. In my case, I know I can make my own Mob Programming RPG, but exactly what problems am I trying to solve? I came up with three: streamlining Larson's game into something more appropriate for my audience, students not having good models of collaboration, and faculty not having something they can easily incorporate into a course. For the metrics, local adoption is an easy measurement, but it also made me think through how I might design a study around this project and try to get it published. I also considered that I could use my YouTube channel to talk a little about it and track views, likes, and comments there. Of course, there's always Google Analytics, which can be tracked before or after, say, a conference presentation.

It strikes me that, for my purposes, all this tool is really pointing me toward is good design. In particular, it matches what I often tell my students: have goals, do something to meet those goals, and then see if those goals have been met. It seems obvious, but I see people at the university regularly missing the first and last steps. That is, it is much more common for people to propose solutions than to articulate what problems they are trying to solve, and despite the "culture of assessment" that we're supposed to be growing, it's rare to see useful metrics that haven't been fudged in some way. That also is a story for another day.

I have a little time this morning to think about my research, and this project idea fills the bill. If I don't end up going in this direction, I still have two other project ideas up my sleeve, both being tabletop games. I have a proverbial mountain of assets that I've acquired from Humble Bundle and Epic's giveaways that I would love to tinker with in UE5, but I don't think this November will be the time for that. 

Saturday, October 15, 2022

What it means to be human

I was invited to give a talk in a series about "What it means to be human." I was asked particularly to address what it means to be human in light of technology. My talk was given last night, and what follows is a serialization of the notes I used. These notes may be useful to others, and I expect they will be useful to future-me when I need to come back and reconstruct these thoughts.

What does it mean to be human in light of technology?

Let's start by considering "technology" colloquially. When someone says "technology," most imagine modern computing technology such as smart phones. The wonders of these devices may lead someone to believe that with the right technology, anything is possible. It turns out, that is not true. While this may be my most esoteric point in this essay, I hope that it puts a strong foot forward.

One of the most foundational aspects of theoretical computer science is that not everything is computable. Here is an example that doesn't require you to know anything about programming other than that it is a thing people can do. Let's say you wanted to write a program that takes, as input, another program, and your program tells you whether this other program halts or not. This is called The Halting Problem, and it is not computable. That doesn't mean that it's hard or that someone hasn't thought of a solution yet: it means that we can prove that it cannot be done at all. This may sound familiar to mathematicians or those who have read Hofstadter's classic Gödel, Escher, Bach: An Eternal Golden Braid. In particular, it resonates with Gödel's Incompleteness Theorem, which proves that  for any sufficiently complex system of mathematics (such as algebra), there will be something that is true that is not expressible in that system. You can understand this by analogy by considering the problem of evaluating the sentence, "This statement is false." In a way, Gödel demonstrated that you can say something like that in mathematics. 

The important point here is that technology cannot do everything. Although this is well known among academic computer scientists, it's not the kind of thing you hear from a marketing department or a pundit who is trying to convince you that they have a panacea. Remember the original marketing campaign for the iPad? It is magic. That's a compelling message to sell products, but it's also a lie. The iPad does what it was designed to do. So does the marketing department.

Taking a step back, we can observe that humans have always been "technological" in that we are makers and users of tools. Some tools improve our day-to-day living, such as toothbrushes that are comfortable to hold. Others have had indelible impact on human civilization: writing, money, the printing press, the Internet. What has changed in modern times is the depth and complexity of the networks that support these tools. I was able to understand this more clearly thanks to my Internet friend Chris Bateman, who helped me collect these notes. In particular, I am drawing inspiration from some insights he shares in The Virtuous Cyborg, and I am giving an overview of some of the arguments that he explores more deeply in that text. 

Consider the case of a 18th-century pioneer who moves out to Indiana to make a new life for himself. Let's say he needs a wooden mallet like we might see on Townsends. Making the mallet requires having an axe. The axehead was likely procured from the blacksmith, who acquired the iron from someone who was in contact with the miners who dug it out of the earth. At the tip of the iceberg is a pioneer holding an axe, and if we delve down, we involve dozens of people. Now imagine that you buy a mallet at Lowe's: how many people are involved? At the tip of the iceberg, it's you and the mallet at the self-checkout. Start digging, and you'll see there are thousands, tens of thousands, probably millions of people involved in bringing you together. Consider the data moving over networks, the power that makes it possible, the politics that ensures fuel, the logistics and roads, the manufacturing processes, all the taxes collected at multiple levels, and everything that makes possible a Big Box store.

Even something as simple as a mallet is enmeshed in an incomprehensibly complex network of causes and relationships. This is modern technology. We tend to dismiss this observation as mere trivia and treat the mallet as a morally neutral object. Turns out, it's not.

To understand this point, let me get out of the handyman's toolshed and into something more comfortable to me: digital technology. When anyone writes software, they do it with an intention. There is a purpose behind this work, and that purpose becomes embedded in the thing. In philosophical terms, the tools possess moral agency. This is a powerful idea whose implications still have my own mind spinning.

Don't confuse moral agency for free will. An agent is a thing that takes on an active role to produce an effect. It doesn't have to "choose" to do this. Indeed, the argument I am advancing is that this happens necessarily and automatically. If I spend the weekend creating a game for a game jam, that thing has agency in producing an effect in the player. The same argument can be made for the mallet. Consider that if you have a mallet, pounding things becomes a reasonable answer to many problems. Putting it in technical language, the tool reconfigures the moral space around us. Mallets push us toward pounding things. Facebook pushes us toward doomscrolling. (Once again, I am indebted to Bateman for some of his excellent examples such as ultrasounds and drones, which produce significant effects in our moral decision-making.)

A story from this last week will illustrate my point. I was recently at the International Conference on Meaningful Play. One of the keynote speakers was Heidi Boisvert, who talked about her research investigating how people consume media. She records people as they watch screens, using cameras to capture the emotional responses. The reason she does this is that her collaborators, who work across a broad range of technologies, can design media that is more effective in promoting a social justice agenda. For our purposes, it does not matter whether you agree with her goals or not. My point is that the shifting of moral considerations is the goal of this work. It is not a conspiracy theory: it is modern technology.

There are brilliant people working for media and technology companies whose job it is to diminish your moral agency, although they would probably say "improve engagement" instead. Consider the use of intermittent variable rewards for example. We have known since B. F. Skinner's time that intermittent rewards are better than regular rewards for hooking someone into a desired behavior. Slot machines are the example par excellence, but we see this technique across all of our apps and services. Keep scrolling through Facebook, Instagram, your news feed, or your Netflix recommendations: you never know if the next thing is going to give you a dopamine hit, but maybe it's the next one, or maybe it's the next one. This is not just reward cards that give you a cup of coffee after buying ten. This is Jimmy John's giving you unpredictable surprise rewards, if only you'll buy just one more sandwich.

It is important to remember that there are ethical ways to develop, deploy, and use technology as well. This is a recurring theme in my classes, where I try to help students understand the importance of empathy in the design process, of evaluating your impact, and that there is a responsibility to act ethically. More broadly, not every micropayment is unethical, and technology-mediated engagement with a supportive and creative community can be a boon. However, it may not be obvious which technology is pushing us toward ethical behavior and which is not. This is why it is important that we recognize our human failure modes. We all succumb to intermittent variable rewards. We all fall victim to cognitive biases such as confirmation bias and fundamental attribution error. These, also, are part of being human. When we recognize that we have a nature, and we recognize that technology is not neutral, we position ourselves to consider how to live well with modern technology.

I conclude that our response must be to cultivate habitual and firm dispositions toward doing the good, lest the impact of technology overwhelm our capacity for moral agency. More succinctly, we should practice virtue.* I believe that the traditional cardinal virtues of prudence, fortitude, temperance, and justice are up to the task. Temperance ensures that we not spend inordinate time and resources in relationship with technology. Fortitude gives us the courage to avoid immoral uses of technology regardless of its popularity. Justice ensures that all are given their due in the production, use, and distribution of technology. Prudence remains the queen of the moral virtues, where our intellect powers the decisions that drive our actions.

Technology cannot do everything, and technology is not neutral. Yet, part of what it means to be human is to be integrated with technology. To live a good life requires that we be free to choose the right moral path, and we are best prepared for this if we arm ourselves with knowledge and cultivated virtue.

Thursday, October 6, 2022

The Unprecedented BSU participation in Ludum Dare 51

Over a year ago, I started up a Discord called "Ball State University Game Design & Development." It's a slowly growing community that includes students, staff, faculty, and alumni. It's mostly quiet, but we sometimes talk about games or game design. I also gives me a place to post about opportunities and encourage participation in them. I hope we are starting to see some fruits from this effort since last weekend we had an unprecedented number of BSU-affiliated people participate in Ludum Dare 51. This included one alumnus and four students. 

I wrote about my project and my sons' projects two days ago. Here are links to the other projects I know of that came from BSU. If you know of more, let me know, and I will add them to my list!

I am hopeful that this is positive momentum and that we'll get even more in the future. The Fall Ludum Dare tends to come at the best time. It's a couple of weeks in the semester, so I can encourage students and even incentivize their participation. For example, my CS222 students can earn an achievement by participating in a jam (although none did, as far as I know), and I gave my CS315 students the option to do Ludum Dare instead of their normal weekly work. The next Ludum Dare is in January before the semester starts, which means more people may have free time, but there's no opportunity for in-person nor course-based encouragement. The Spring one tends to fall right before final exams, when students are overwhelmed with work, though I tend to be in a mode where I'm just answering questions and waiting for projects to come in. This pushes me slightly back in the direction of hosting a local jam in Spring. We'll see how the semester goes!

Tuesday, October 4, 2022

Ludum Dare 51: Base Defense (plus four games from the boys)

In today's blog post, I share the experiences that my sons and I had participating in Ludum Dare 51. Each section starts with the name of the game, and this is followed by a link and then the creator's reflection. Enjoy!

My Game: Base Defense

This past weekend was Ludum Dare 51, the latest instance of what might be my favorite jam. What I love about the traditional Ludum Dare "compo" event is that each person handcrafts a game in 48 hours based on a shared theme. That creator does the art, the music, the programming, the writing, and the sound effects, and so everything that comes out of the Ludum Dare compo is wonderfully unique. There's an unadulterated bit of each creator within each game.

The theme was "Every 10 Seconds." I prefer themes that evoke an aesthetic rather than those that almost demand a mechanic. I did my voting before the jam, and so at some point one simply has to live with the results. As I contemplated the theme, I considered other constraints: What kinds of games have I wanted to make lately? What technology have I wanted to explore? I quickly narrowed my focus to making a tower defense game in 3D using Godot Engine. I've never made a tower defense game, but I've long wanted to. My game programming students elected to having a project in 3D, but I've really only built one 3D experience in Godot

My original idea was that new waves of enemies would come every ten seconds, but as I tinkered with the core game loop, I realized two problems with this. One is that creating different kinds of enemies, enough to call it a "wave," was possibly out of scope. The other was that ten seconds is actually a really long time when you're waiting for something to happen in a videogame. I decided to pivot on the integration of the theme and, instead, to have the player lose a random turret every ten seconds. This way, there's a constant pressure on the player to keep building and to stay aware of the board.

The result is Base Defense. You can check it out on the Ludum Dare page which links to the Web build as well as the native clients for Windows and Linux.

I'm happy with how it turned out. I had originally hoped to add more interesting enemy models than just colored spheres, and it clearly calls out for different kinds of turrets or defenses. Both of these features hit the chopping block pretty early. The end of the game is still actually a placeholder from when I got the original loop working, but you know, old memes are the best memes. The one thing I really wanted to add that didn't fit into the schedule was that meteors destroy not just a random target but also adjacent ones, recursively. I think this would have been a really fun way to force players to spread out their defenses, and I also think it would have made it less likely that someone can set up an unstoppable defense force. Yes, if you have the right combination of luck, patience, and skill, you can get the game into a state where there's no way for the enemies to win and you can accumulate points forever. I haven't gotten this, but I've seen my son do it. The positive side of this though is that the game is engaging enough to get someone to want to reach that goal, which is pretty good for a jam game.

Speaking of sons, all four of my boys created their own games for Ludum Dare 51. I asked each one to write a little reflection about the experience that I can share here. The older two boys have their ldjam.com accounts, and so I have linked to their project pages. The younger two boys do not have such accounts, so I've linked directly to Web builds where you can try the games. In each case, the creator's reflection follows the game link. Thanks for checking it out! I'll be sure to share any feedback here with the guys.

#1 Son: Shifting Dungeons

Check it out at the Ludum Dare site.

Shifting Dungeons is not my best game jam project. It’s not really fun. I think that is at least partially because the game does not require many (if any) interesting choices. Once you’ve figured out the strategy, you can win almost every time without needing much skill.

I did enjoy using shaders for the glow effects and styling the UI, and I am happy with the overall color scheme. At one point, I realized that the walls and floor were a cold grey instead of a brownish-yellow grey, and once I fixed that, everything looked a lot better. I also liked the way I organized the attack functionality in the player. When you press a button, it calls an attack function that then calls another function to resolve the appropriate effect.

I learned (not in this project, but recently) that enumerations really just assign names to positive integers, which is very useful for a wide variety of things. In this project, I used enums to distinguish types of attacks and different wall tiles.

Next time, I would like to try to make a more technically interesting game. Nothing in this project was new or unusual, which made it rather uninteresting to build. I also might not make a 2.5-d project next time, since it makes the artwork much harder to draw.

Anyway, thanks for playing my game, and please leave any suggestions you have about ways to improve it!

#2 Son: You vs. the Clock Featuring the Narrator

Check it out at the Ludum Dare site.

This year’s theme for Ludum Dare was “every ten seconds”. In my game, you have ten seconds of life to get as far as you can. The game is text-driven using Dialogic, partially because I wanted to practice my typing skills but also because I know very little Gd script.

I learned how to connect Dialogic to the script, which is how I got the timer, points, and duck to work. I wish I had had the time to add a timer that might make the connection to the theme a bit more clear by visualizing the ten-second countdown.

#3 Son: 10 Second Bomb

Play online now.

Hi, I made 10 Second Bomb, using Construct 2 (free edition) game engine. My idea was that every ten seconds a random tile would explode, like you've seen (or will see) in my game. I did not know how to do that, so my brother taught me about global variables and we could use that to fix our problem. Once I knew how to use global variables, making the player get bombs and the score tracker were easy to code.

Then came the timers (boom tile and new bomb). After I made those, I made the different screens (lose, win, main, start, and rules). I met most of my goals, although if you lose and then you play again and win, you have to click through both the win and lose screens. I don’t know why that happens, so if you do please let me know.

I learned some new things, like how to use global variables. I hope you enjoy (or have enjoyed) my game!

Thanks for reading!

#4 Son: Tim the Hunter

Play online now.

Hi, my game is “Tim the Hunter” in Construct. My idea was every ten seconds enemies shoot, and spawners make new enemies. If you get shot you die.

It was hard to make the coding. At first, you couldn’t move because the gun was stopping you from moving. Then I made the gun be able to move with Tim. I figured that out on my own. I also learned how to make text follow the screen. The point tracker used to not move with Tim, so the text would go offscreen. My brother helped me make the text move with Tim so that the player could see the points no matter where they went. If you press enter to play again, the music will play twice. I didn’t want it to do that, but I didn’t know how to make it stop.

I was happy with Tim’s costume. The bowler hat and overcoat and tie were fancy.





Story: you were hunting when a tornado and you landed on a floating island.

Tuesday, September 27, 2022

Making Truffles

Many years ago, if memory serves me right, my mother-in-law sent me a link to an easy truffle recipe. My oldest kids were pretty young at the time, so this may have been eight or ten years ago. I've used that recipe for years to intermittently make simple chocolate truffles. My two favorite flavors are orange cardamom and mocha. Both are a simple matter of simmering flavorings in the cream, the former using decorticated cardamom and fresh or dried orange peel, and the latter using ground decaf coffee.

I used that recipe for years. For a long time, I could Google for "easy truffle recipe," and there it was. A few years ago, it became a little harder to find, as more and more similar pages and videos showed up in my search results. At this point, I think the original page is simply gone. I could never remember who hosted it; I would recognize it by the prose, layout, and images.

It's really not that complicated, though, and I realize the main thing I needed the recipe for was ratio between cream and chocolate. Last night's searching resulted in my reading more about this ratio. Hungry Happenings has a good explanation, and I'll just summarize here, for my future recollection, this idea:

2:1 Chocolate to Cream Ratio

That's really all I need to know. My old recipe used volumetric measurements of cream and weight measurements of chocolate, which made it harder to remember. The weight ratio is much easier to remember as well as being easy to execute with the kitchen scale.

How do I do it? Heat up the cream, but don't let it boil. Put flavorings in. If they need to simmer, let them simmer for 10-20 minutes. Weigh chocolate chips into a measuring cup. (Yes, the fancy people say not to use chocolate chips, but you know what? It's easy. My truffles are not silky smooth, but I don't mind a rustic truffle.) Pour the cream over the chips and stir it up to make the ganache. Pour it into a broad, flat container, and put this in the freezer for 20-30 minutes to cool. Prep some kind of toppings, like cocoa powder or chopped nuts. Gather children with nominally clean hands. Use a little spoon or scooper to portion out roundish blobs of chocolate, drop into the topping bowls, and let the kids roll them around to coat. Family fun!

Last night, the younger boys and I made a batch for my wife's birthday week. We made a wonderful discovery. One of the recipes I found suggested trying vanilla or almond extract as a flavoring agent, so I looked around the baking supplies. I came across something I don't remember seeing before: a flavoring called fiori di Sicilia. We popped off the top to check it out, and we were wowed by the wonder smell. We put a teaspoon into our 4 oz. of cream. For toppings, we used cocoa powder and crushed pecans. They turned out amazing. The fiori di Sicilia gives a complex citrus flavor, just the right amount for chocolate.

So there you go. It's all story and only an implicit recipe, but I do feel like I leveled up in my trufflemaking last night. No longer bound to an arcane combination of cups and ounces, nor to others' recommendations for flavorings, I am now free to truffle away.



Monday, September 5, 2022

Students' Analog vs Video Game Critical Analyses: A matter of experience and vocabulary... or perhaps of pride?

The students in my game design class just finished studying MDA as an analytical lens and then writing critical analyses of games following Schreiber's recommendations. I advised them, for both exercises, to choose small, simple, analog games, cautioning them that contemporary videogames are games-of-games that are hard to analyze this way when you are just getting started. As one might expect, many students disregarded my caution, although I did not know that at the time of our last class meeting. During that meeting, I had them get into small groups to talk about their analyses and then to share some highlights with the whole group. 

One of small groups happened to have two people who analyzed digital games and one who analyzed an analog game. The interesting finding they shared with the group was that it was easier to analyze the video game than the analog game. This surprised me, in part because at the time I didn't realize how many people had failed to take my advice. I pointed out that there were at least two possible interpretations of their experience: one is that there is an inherent difference between video games and analog games in this regard, and the other is that they have less vocabulary for analyzing analog games. Either one is interesting from a scholarly point of view, and even at the time, I hypothesized that the latter was the case. Two students' hands shot up to further this discussion, but we had to move on: we were veering off topic on a day that had already been way out in the weeds.

After having read all of their analyses, I see that there's a third option: that they simply did a bad job. Turns out that this is the case. Almost none of the students who analyzed video games performed anything like a successful analysis, not in the format they were given. They woefully underestimated such aspects as the resources being used, the state of the game, and the way it is played. For example, none of the students who analyzed video games talked about what players actually do, what actions they perform as part of the core game loop. Rather, they painted with broad brushes, saying things like, to fabricate an example, "The player moves Mario to the end of the level." While that is true, it is hardly an analysis. The state issue struck me as particularly interesting since so many of my students are Computer Science majors. I pointed out to them in my comments that the state of the game consists of those data that you would have to save so that you could load the game later. None of them came close to this understanding, many talking about "state" as if it dealt with the screens of the game: you're either choosing a level or playing a level, to continue the example.

When this kind of thing happens, I am left wondering, "What happened?" and "What now?" A majority of students did not follow my advice and then did a substandard job. I hope that they can learn something from this experience. However, what they learn is about hubris rather than about critical analysis, and I would ideally like them to learn both. This particular class does not have a resubmission policy, and I'm wondering if that is a reasonable thing to add. Resbumissions are convenient for the students, but they lead to more work for the professor and, every time I've used them, worse work by the students. That is, a student who knows they can resubmit later can just submit something poorly the first time, which the professor then still has to grade. The ideal thing would be for a student who did badly on the assignment the first time to recognize this as a deficit and then dedicate themselves to learning the content anyway, but alas, our university systems seem set up contrary to endorsing such virtue.

Tuesday, August 30, 2022

CS315 Game programming project report failure and recovery

A few weeks ago, I wrote about how I removed a cyclic dependency from my CS315 class by moving the project report from a git repository to a GitHub wiki. This solution was clear, simple, and wrong. It turns out that GitHub wikis are only available to public repositories when using GitHub Free. Over the weekend, a student working on the first project reached out to me, pointing out that the wiki feature didn't seem to be available. I confirmed the problem and set about seeking a new solution.

After some consideration, I decided the simplest solution was to remove the checklist item that says that a student has submitted their work on time. This item was the crux of the problem, since it forced someone to either leave it unchecked at the time of submission or to check it prematurely. I did not want to change actual course policy, however, so I had to add a general clause stating that work has to be turned in by the deadline to receive credit. This is a little less elegant, since now a student's grade is determined by a combination of checklist items and a general policy. However, it's a familiar kind of policy, and so I hope students don't mind the inconsistency.

It turns out, this is actually a change in policy, although I didn't think about it until writing this blog post. Previously, someone could use a Save Point to resubmit work that was late, since the deadline itself was in the checklist. Now that it is not in the checklist, the course plan gives students no option to earn credit for submitting late work. This was not quite my intention, since the whole idea of having a Save Point is to deal with unforeseen circumstances, and such circumstances do sometimes lead to the inability to submit work on time. I suppose I better get back to editing the course plan to add another general rule, that Save Points can additionally be used to submit work late. That is even more inconsistent and inelegant, but I have not found another approach to fill the bill.

Incidentally, the first "easy" solution I came up with was to have students just submit two things on Canvas: a link to their repository and a separate project report. Unfortunately, Canvas does not seem to support this. Even though the teacher's interface makes it look like you can require a student to submit both items, what students see is that they can only submit one or the other.

Thursday, August 18, 2022

Summer Course Revisions: CS222 Advanced Programming

It has been a little wobbly here due to my teaching schedule changing, as discussed in my previous post. Because one of my courses didn't make enrollment, it looked like I was on deck to teach my department's CS200 Computers and Society course, which is a university Tier 2 core curriculum course in the natural sciences domain. I've never taught it, but it sounded like it could be an interesting challenge. I started doing some prep work on it, and then I was notified that a colleague was willing to swap a section of CS222 with CS200. CS222 is a course I designed, teach regularly, and love to teach. Also, that CS200 course was scheduled right before my other two back-to-back courses, and so it would have had me teaching continuously from 12:30 to 5:00 on Tuesdays and Thursdays. Thanks to the generosity of my colleague, I am now scheduled to teach CS222 MWF instead of that CS200 class, which is one that he has prepped and taught regularly.

This all happened two days ago. Now, the easy thing to do would be to just copy over my Spring CS222 plans, change some dates, and be ready to go. This is not my way. Regular readers may recall that I ended my reflection on Spring's section by putting forward the proposal of changing the technology that I use to teach CS222. This has been on my mind intermittently over the summer, especially as I spent several weeks exploring game design ideas in Flutter. Pushing aside lingering doubts, I began to design the course with this new technology foundation, and today, I published my plan for the first several weeks.

Obviously, the most important transition has to do with getting the students up to speed with Flutter and Dart. The truth is that they have come in with fairly weak understanding of Java anyway, and so rebooting their language learning experience may have a net benefit. The documentation at flutter.dev is excellent, and you can see on the course plan that I am having them complete several standard Flutter and Dart tutorials and codelabs.

The most important factor here is time. Knowing that they will all have to be going through these beginners' steps means that I am accounting for it in my expected weekly commitment. A few things that I had them do in Java have been pulled out, such as the GradeTool refactoring exercise. One thing that really excites me is that students will be running into higher-order functions and stream processing earlier and more consistently. It is to Dart's benefit that it doesn't carry all the baggage that Java does. I was excited to find the iterable collections codelab as a great example for helping novice programmers understand how this works.

I have started a sample solution to my traditional two-week project assignment and, based on that, traced backward what kinds of things I need to introduce in class in the first three weeks. That is, I have developed a running example in class that, I think, will prepare them to build up a version of the two-week project that is essentially the same as what my students have done with Java and JavaFX in the past. 

I do not expect their reading of Clean Code to be significantly hampered by changing the language of teaching. The examples in the book are all in Java, but I don't think the students ever spent a lot of time with the examples anyway. The prose mostly stands on its own. Indeed, in my ten or so years teaching CS222, I don't remember a student ever referencing or asking about a code example in the book.

Today, I recorded and published my first tutorial video based on the stack of Android Studio, Flutter, and git. I hope to make a few more tutorial videos during the semester based on the kinds of questions my students have or difficulties they encounter. 

I'll be sure to write more about this transition in the future, certainly in my end-of-semester reflection if not before. In the meantime, if you have questions, comments, or suggestions, please feel free to share them in the comments or to email me.

Monday, August 15, 2022

Summer Course Revisions: CS215 Introduction to Game Design

I know what you're thinking. Planning for the Fall already? The trouble is that I was scheduled to teach the new capstone course for the Game Design & Development concentration in the CS department even though this semester will be the first time anyone can actually declare that concentration. We were given orders to try to get students graduating from the new concentrations as soon as possible. Unfortunately, advising didn't push students into this course, and it wasn't in the system when they picked their courses, so that course is critically underenrolled. On paper, I'm still scheduled to teach it, but it will almost certainly be cancelled.

This is relevant because that capstone course was supposed to be the locus for a community-engaged immersive learning project. We always had the back-up plan, though, which was to put that collaboration into the academic year structure I have been using, splitting the project across CS215 Introduction to Game Design and CS490 Software Production Studio. Given the enrollment in that capstone course, I went ahead and "finalized" the plans for an immersive game design class.

The good news is that this is how I have been teaching the course for a while now, and it has been successful overall. I modified the project schedule to include the exercises from Justin Gary's Think Like a Game Designer, which I wrote about earlier this summer (12). I also had to modify the schedule to allow for some of the conference travel I have this semester. I put up the course site today, which has public plans for the first four weeks of the semester. I have the rest planned but have not yet formally published them, waiting until I have a chance to get to know these students a bit.

Because the enrollment in CS215 is a bit higher than I have had in the past, I have moved away from in-class poster presentations. I really like having students present posters, but it doesn't scale to over 15 or so students. I tinkered with the idea of breaking them up into an A and B group and alternating posters and conventional submissions, but this got too awkward. Instead, I'm asking them to put their work on Canvas discussion boards. My plan is to combine small group discussion with random (or intentional) selection of submissions for brief presentation. There are a lot of interesting things that come up during poster presentations, and I am hoping this will still allow those to emerge through the discussions.

Thursday, July 21, 2022

Justin Gary's Framing and Brainstorming

I decided to continue my exploration of the exercises in Justin Gary's Think Like a Game Designer which I started writing about in yesterday's post. My plan was to take one of the items from yesterday's list and try the "brainstorming" exercise. The particular idea I pursued is a video game idea inspired by tabletop role-playing games. I realized that before I could pursue my intended exercise, I had to determine whether this would be a single-player or multi-player game. To address this, I decided to try the intermediate framing exercise that Gary puts between inspiring and brainstorming.

As with yesterday's experience, I found the exercise to be both simple and helpful. There are fundamentally three parts to it: naming the target audience, articulating the hook, and choosing constraints. The audience was described in terms of motivation rather than demographic, which I think is a helpful distinction for my students. The hook is one or two sentences at most, what might be considered a concept or elevator pitch. I went through these steps fairly quickly, but they didn't directly get me to resolve the number of players: the two directions are otherwise similar in terms of audience and hook. After some separate online research regarding matchmaking systems, I resolved to focus on a single-player mobile experience.

The intention for the brainstorming step is that it lead to the prototyping step. It may be worth mentioning, then, that this is where one of my constraints puts up a blocker: I cannot actually prototype this idea any time soon due to other obligations. This restriction is a little upsetting since these exercises are getting me really interested in pursuing this idea.

The brainstorming step has three parts: creation, organization, and elimination. The first step is a conventional exercise in brainstorming proper, where ideas are written down without filtering them. The spirit here is to open the floodgates and let ideas flow. I set a timer for twenty minutes and came up with 28 ideas for this game concept. Two of these had nested points, but I tried to otherwise keep the list "flat." Three items had small UI sketches on the side as well, which I think demonstrates the value of doing this on paper. A few items contradict each other, but most of them simply open up the possibility space. I expected more contradictions around decisions I had not made in my idle contemplation.

The organization step encourages the use of mind maps. I have used mind maps before, going way back to when I first read (and was strongly influenced by) Andy Hunt's Pragmatic Thinking & Learning. I like to do them on paper or a whiteboard, but I ran into two problems: to use a large sheet of paper, I would have to clean off my table or work around my kids downstairs (no way), and the whiteboard in my home office is mostly inaccessible because of shelving units. I think whiteboard mind maps are good for generating ideas, but this was really an organizing activity, so the ability to move nodes around seemed more important than hand-drawing. 

This inspired me to take a side trek into the wild, wild world of digital mind mapping tools. There are many of them, and I quickly determined that what I wanted was (1) easily driven via keyboard for rapid information entry, (2) plain text serialization format for inclusion in version control, (3) a Web interface would be nice, but no vendor lock-in. I found Freeplane, which I had never heard of before, but it completely filled the bill. Turns out, it was available for Ubuntu Linux as either a regular package or a snap. It looks like there are Windows builds, too, should I find myself traveling and without access to a Linux installation. It took me a while to find the Freeplane Handbook, and after flipping through that, I found several nice features that were not obvious. To get started, though, all you really have to know is that enter drops in a new node, arrow keys navigate, and insert adds a child node.

After some initial confusion, I found the core interaction loop with Freeplane to be pretty snappy. Still, it took me almost 40 minutes to transcribe my brainstorming notes into a mind map. That's twice what Gary recommends taking, although he acknowledges that 20 is a minimum, not a target. The time spent was fruitful, though, because it involved decomposing the rough initial ideas into something like a taxonomy of ideas. At the very end of my time transcribing, I discovered how to add icons to nodes, and I marked alternative paths with question marks. Freeplane includes a convenient summary of the map's statistics, so I can tell you that the map had 90 nodes, including 54 leaf nodes and 14 main branches. The serialized form is 14kB of XML. In fact, I made some changes to the map before writing this up, but because of the beauty of version control and plain text formats, I was easily able to go back in time and find this information.

The last step of brainstorming is elimination, the output of which is a short description of the minimum features needed to prototype the game. One of the curious aspects of Gary's book is that he regularly gives five lines for his exercises, and this is clearly not enough space. During the creation phase, he gave five lines, and I filled three looseleaf pages. The elimination step is one of very few where the space is actually accurate to the task at hand. He even says specifically that if you need more room than you are given, you are probably being too ambitious for a first attempt. My own list ended up including seven short features, listed in bullet points, which I think would take about a two or three work days to complete, depending on one particular technical feature I have never implemented. I think these would indeed give me a functional proof-of-concept that would help determine if this idea is worth iterating upon or not.

I have been impressed with these exercises. Not only do I look forward to using them in my teaching, I wish that I had used them myself earlier this summer. I spent about three weeks working with my boys on a side project, after which point we saw that it would require more effort than we wished to devote to it for the summer. I transitioned from there to my own personal project, again spending about three weeks on it. After that time, I have a tech demo from which I learned a lot, but it's not much to show, and honestly, it doesn't quite tell me if the idea is fun or not. Now it might just be the excitement of starting something new, but I do feel like these exercises have given me more structured ways to think about this particular project than my conventional approach of sketches and CRC cards.

Wednesday, July 20, 2022

Justin Gary's Inspiration Exercise: By the numbers

Last winter, I read Justin Gary's Think Like a Game Designer. I know Gary from his work on Ascension, although I cannot remember now where I first heard about his book. I took quite a few notes while reading and considered writing a formal review here on my blog. I discussed it with some people on Discord but never assembled those notes and stories into a review.

I will be teaching Introduction to Game Design again this Fall, and so I am going through my notes from last year and figuring out what I want to change. I pulled out my notebook and reviewed my notes from Gary's book, marking particular exercises from it for possible inclusion in my class. 

One of the exercises that interested me comes from Chapter 5. Gary frames game design as a six-step iterative process of inspiringframingbrainstormingprototypingtesting, and iterating, and Chapter 5 describes the inspiring step. Incidentally, his model is not bad, and using "iterating" to describe a constituent step of an iterative model reflects the informal nature of the book. The exercise itself is described as having six parts, each of which should be given twenty minutes to complete. 

Today, I decided to try the exercise for myself, and in this post, I will give an overview of my experience. I gave each step a full twenty minutes except the last, but we'll cover that when we get there.

The first step is to "review the games you love." The task is to list your favorite games. I set my timer for twenty minutes, and I came up with a list of 123 games. My list includes board games, card games, sports, role-playing games, and video games. The video games represent titles released on the C64, NES, SNES, and PC. One of the strangest ones that came to mind was 1982's Aztec. I could not remember its name, and when I found it, I discovered it doesn't have an entry at Lemon64

I decided to list games I enjoyed, although I wouldn't call everything on it a "favorite." They are all memorable games. There are even a few that I found frustrating for various reasons but still enjoyable. As I continued through the exercise, I realized that I had missed some of my actual favorites, but I did not go back and amend the list.

The next step is to "review the games you hate," which is a clear complement to the first step. The instructions are a bit vague here, asking you to "spend a few minutes" making this list, despite earlier having said that each step should be twenty minutes. My list ended up including only 40 items, and I was stuck at around half that for a while. Some of the things in the list are board games I have gotten rid of, and there is a section of bad mass-market kid and family games. There are relatively few video games on the list, most of these being competitive ones that I played with groups who were much more experienced than I was. I have a few sports and classic games on here as well.

The third step is to "find the gems," to look at the lists of games and identify mechanics and themes that you enjoyed. I appreciate that Gary encourages the reader to try to find the good parts in the disliked games as well. My list included 65 items. Most of the items on my list are mechanisms, but some deal with theme, narrative, emotion, and production quality. I tried to avoid designer jargon, but items like juiciness and game feel still made it to the list. I realize also that some items on my list subsume others, such my listing of "legacy," which includes many other ideas such as campaign play and unlocking content.

I missed a part of the instructions for this step. He encourages you to highlight the items on the list that are the most meaningful to you as you are making the list. In my focus on the list itself, I completely forgot about this. The whole of the exercise is to be done in spirit of avoiding self-censorship, and so I found myself trying to avoid metacognition entirely: just putting down things that came into my mind without judging them. If I were to assign this to students, I might encourage taking a little break here to read the list and then to highlight important items.

The fourth step is to "find the crud," which again presents a counterpoint to its previous step. My list includes 41 things I do not like about games on my lists. Interestingly, almost everything on this list is explained in longer phrases than those on my "gems" list. Whereas the previous list was made in two columns on a sheet of looseleaf paper, this one had to be done on two separate sheets since there was no room for a second column. 

Step five is the culmination of all the previous steps. Here, you are to "look for patterns," going through all the other lists to construct a new list of game ideas. The instructions are to summarize a game concept in one or two sentences, and he is explicit about not self-censoring here. I know it was supposed to be inspiring, but I found myself anxious about his admonition, "If you stop moving your pen for more than thirty seconds, you are doing it wrong." Whether this speaks to my emotional state or my need to do more unstructured creativity is up for grabs.

My list here included 21 items. As I wrote it, I found myself looking almost exclusively at my "gems" list for ideas. His instructions invite you to consider modifying games you did not enjoy by removing the bits you didn't like, but in practice, this felt like it took more mental effort—possibly more than thirty seconds worth, and so I avoided this path. 

Several items on the list are unclear mashups of words, but there's nothing here that I couldn't use as a seed. I kept everything on the list tied to the other lists, and it took effort to force out of my mind those things that have been occupying it. One item is a concept I recently discussed with a friend, but it also reflected the lists, so I kept it. There were a few times where I looked at the list of games I like and then had to stop myself from just writing down a riff on that with no new ideas, but I took this as an inspiration to then turn to the "gems" list to see what could be modified. This didn't happen often, though, and mostly I felt like I kept swimming in the handful of ideas that my eyes kept returning to.

The items on my list emphasize systems and mechanisms over themes and stories, and this is very much in keeping with the ethos of Gary's approach. It is practical, however, since "players form cards to form a whip or chain to grab a resource from the center of the table" is something you can start tinkering with, whereas "a game about hope in the face of desperate circumstances" still has to be refined into something the player actually does.

The sixth step in Gary's list is to "pick your favorite concept and start working on it." That's not a twenty-minute step at all: that's the rest of the book. Perhaps he just needed a better editor.

Note that what I have described here is only the inspiration step of Gary's design model. It is followed by framing, which considers the audience and constraints, and then by brainstorming, whereby specific ideas for the game are considered before prototyping. Perhaps I will return and try these steps in the coming days.

I enjoyed the exercise, and I will be sure to find a way to put it into my class for Fall. I think it would work well as preparation for students' pitching their final projects. There are inevitably students who struggle with finding a starting point for their designs. It may even benefit those who think they already know what they want to do, since such students often find themselves choosing paths that are really out of scope.

Monday, July 18, 2022

Painting Massive Darkness 2: Monks and Necromancers

I am still working my way through the heroes of Massive Darkness 2. Previously, we looked at the base set heroes and then the druids, bards, and tinkerers. Today we are looking at the four heroes from the Monks & Necromancers vs Paragon expansion

Riya (front)

Riya (back)

This set contains a lot of interesting sculpts, and Riya is a great place to start. I like how there is a lot of motion around her despite it looking like she is still. I think that's really what you want in monk. Unfortunately, this figure had some pretty bad mold lines, and the face was hard to clean. I think the paint mostly covers it up, but there's something a bit eerie about her lips--not just the cyan color.

The card art is shown from the front, of course, so I had to make a creative choice about the back of the figure. I was actually on the phone with my mother when my eyes caught the front of the box for this expansion, and I saw that there, she was shown from the back. It quite distracted me from what were were discussing! The illustrator had different colors than I do for the back, but I am content with my choice to echo on her outfit the maroon tassels from her head.

Harin (front)

Harin (back)

Harin's pose is also very cool. Of course the plastic of his cape is holding him up, but the sculpt sells the illusion that he is floating. Also, once again here there is a sort of stillness in his pose and yet an action in his clothing. Maybe I'm imagining things, being an old Dragon Clan player. 

With the two monks out of the way, we move on to the Necromancers, starting with the one who took much longer than her compatriot.

Ygraine (front)

Ygraine (back)

I remember when Ygraine was revealed during the Kickstarter campaign. I was not impressed with the direction things were going. I would have liked more emphasis on classic fantasy tropes early in the campaign. Having the miniature in hand, though, is a different matter. This is a really wild sculpt. Like with Harin, we get the illusion of flight through that strange fox/dragon/stole she is wearing. The hat is just plain bonkers: she's basically wearing a peacock. 

I feel like the fox/dragon/stole should be a focus of this piece, but I worked with it for an over an hour and just couldn't get it to be very interesting. At some point, I simply had enough of it. Putting a face on it did help a lot, though, as did just getting some paint on the pieces around it.

I ended up busting out the wet palette for this figure, but I'm still struggling to get the right amount of thinning and the right amount of paint on the palette. Fortunately, the hat was happy to take basically any mix of green, blue, and yellow.
Mortemyr (front)

Mortemyr (back)

Finally, here's Mortemyr, who is really tame in comparison to the rest of the figures in this box. He was straightforward to paint, and I think he looks pretty good. The stitching on his satchel is sculpted in, and I think hitting those little details give this some class.

Here's a party shot of everybody in the box:

Monks & Necromancers

Next up for me will be Kickstarter exclusive figures from the Darkbringer pack. I have some on my painting table already. Thanks for reading!