Sunday, December 26, 2021

Getting Torchlight 2 LAN plan working in 2021

One of the gifts I got for the boys this year is a desktop computer for the family room. They've been tinkering around on some old laptops, but I figured it's time for them to have something a bit more beefy. This new rig allows them to stream games onto the Steam Link without needing to use my computer, which is good. It also means that my two older sons can dive into LAN games like Torchlight 2, which my older son and I played many years ago.

Or at least, that was the theory. In practice, when I installed the GoG version of Torchlight 2 onto the better of the laptops and the new desktop machine, they could not see the games each were hosting. Commence approximately 2.5 hours of browsing forums, digging up articles on the Wayback Machine, tinkering with router settings, and futzing with firewalls.

In the end, though, I got it working, and I wanted to share my approach here in case any other poor soul finds themselves in a similar situation. 

1. Allow the application to access your network through Windows Defender. This is kind of a no-brainer, but of course, it won't work if you don't. When you first run the game, it should prompt you to confirm whether to allow it through the firewall, so there's hardly anything to this step.

2. Your network interface priority must be configured so that your active network has highest priority. This was what caused my problems: I had previously configured the laptop so that ethernet would have higher priority than wireless. (Dear Microsoft Engineers: Why would anyone want that the other way around?) This was the root cause of the machines not being able to see each other in the game, even when unused network adapters were disabled. The specific thing to change is the metric of the network interface. You have to drill pretty deep down into settings, kind of like this:

  • Network Adapters
  • Properties of your network adapter
  • Properties of TCP/IP v4
  • Advanced Properties
  • Metric
When I reset the metrics so that the laptop's ethernet had lower priority (a higher metric) than the wireless, everything worked fine.


Monday, December 20, 2021

Reflecting on CS222 Advanced Programming, Fall 2021 Edition

As mentioned in my previous post, there were some irregularities in this semester's CS222 Advanced Programming class. Let me start with what was predictable, though.

I used essentially the same structure in this course as in the past: three weeks of intensive reading and activities; a two-week project completed by pairs; and a nine-week project completed by teams of 3-4. I followed the advice of my colleague in the two-week project and gave the first half as a terminal application then changed the requirements in the second half for a GUI. This is kind of fun for me, but I have less of a sense of whether the students understand that requirements always change. That's probably a less important point than what they can learn about model-view separation, but maybe even that is too new an idea for them. I need to think about whether this is really worth the rug-pulling vs. just returning to the original approach of the two-week project, where the requirements are fixed for both weeks.

For the final project, I said teams should be 3-4, but I allowed one group of two when a pair tried to sync up with an inactive student. I have some regrets about this and need to consider whether I need to be stricter on three. The pair of students happened to be less prepared than other groups, and they both got sick during the semester, so they struggled more than I would have liked. That said, they also reached out for help less than I would have liked. This is why it's still a question as to where the responsibility lies between my course design and their failure to act.

The final projects themselves showed this same shift that I've observed in recent semesters in that all of them involved using web services. Two groups used PokéAPI, one used Overwatch player data, and one used an online recipe service. 

Predictably, they all also used JavaFX, since that's what we covered in class around the two-week project. There's nothing wrong with JavaFX, but it doesn't seem very popular. It's at a good level of abstraction for teaching newcomers to GUI programming. I have been wondering though about what would happen, both in my class and in the rest of the curriculum, if I switched the class over to Dart and Flutter. My main concern is a pedagogic one: it seems to me that you can learn Dart after having learned Java or C# and then appreciate what Dart has to offer, but it's less clear to me that, if you learn Dart, you can go back and understanding what Java and C# are doing without those conveniences.  It's also possible that Flutter's state management would blow their minds. This is pure supposition though; I have serious doubts as to whether this is true teaching intuition or the illusion of ancestor worship. I'm not even sure who uses Java later in the curriculum; I think we've branched out to a point where a lot of upper-level classes are doing languages like Python, and capstone students all get hooked on frameworks like React. I am teaching both sections of CS222 in the Spring, so it's tempting to experiment with a language transition. The problem, of course, is that I'd have to recreate all the surrounding "stuff", like lessons and tutorials. Let me know in the comments if you have feedback about this.

There was a surprising amount of course withdrawals and non-participation from students. However, talking to colleagues across campus, I think everybody saw that this semester. It's unfortunate how hard it is to pin this down: if we had massive changes in young adult mental health or a global pandemic, we could drill down into one of those, but having both puts all of higher education in a deeper quandary. I suspect it's a compounding effect, but that doesn't change the fact that very little of the problem is under our direct control. 

The real surprise for me this semester was the failure of the class to engage with the assignment resubmission and achievement system. Long-time readers will know that this is an essential part of my CS222 course design. Early in the semester, several challenging assignments are given, and someone who really understood the prerequisite material should be able to do them successfully. However, many students don't understand the prerequisite material (for various reasons), and so I allow them to resubmit one of these assignments each week. Except they didn't. I had only a handful of resubmissions, and these were weeks ago. Also, to reward students for engaging in service and lifetime learning opportunities, students can claim one achievement per week. Except they didn't. Students could earn up to 12 credits for achievements (counting for 5% of their final grade), but the most anyone got was 3, and most of the students did none.

I talked to the students in the penultimate class meeting about this, inviting them to share their stories and perspectives. Essentially, they had good intentions but just didn't do it. They would prioritize other work that had imminent deadlines and put off resubmissions and achievements—clearly until it was too late. I didn't take notes in this conversation, but as I recall, everyone who answered gave pretty much the same conclusion: they knew they could do it, but they chose to do something else instead.

Because Canvas cannot handle my grading policies, and students don't listen to the course plan when it tells them not to rely on Canvas' automatic grade computation, I have set Canvas to "hide totals in student grade summary." Someone told me that their grade shows up as a lock, but there's no way for me to verify that with the tools instructors are given. This makes me wonder whether giving them wrong information about their grades actually motivated them to resubmit work, whereas having no information allowed them to ignore this.

A potential fix to address failure to resubmit might be to alter how the assignments are presented in Canvas. Right now, I use a module for each week, and the module contains all the miscellaneous things needed for that week. However, after that week passes, it makes it less clear what to do with this information. If I instead had a module like "Resubmittable Assignments," maybe this would make it more clear. However, I am unclear about whether students actually reference the module structure: I get the sense that they primarily work off the automated to-do list, which sorts items by deadline. Since resubmission has no deadline, we can easily see another case of Canvas working against student-centered learning.

One fix for the achievement system is to make an achievement specifically about making a plan for the other achievements. This would be a lot like the "Did you read the course plan?" quiz that I've been giving: technically easy but rewarding students for doing the right thing. 

More broadly, I know that this course requires students to manage their time well, and many college students lack this skill. I know some teams certainly put in their required hours each week during the final project, but they put those hours all into the final project, to make it as good as they could make it. There's a sense in which I don't blame them: there's a lot of peer pressure to show something good to the rest of the class. Indeed, the day when a large portion of the class stopped coming or withdrew was the day that they were expected to show their two-week project solutions. The design problem for me then is to figure out how to incentivize them to take time away from their final project and put it into some of the other material for the course. The two previously-mentioned fixes might help, but they don't get directly at this root problem. On this Monday before Christmas, and looking at teaching two sections of CS222 in the Spring, it is not clear to me how to do this without a major overhaul.

That's all for today. Thanks for reading. As always, please feel free to share your thoughts, suggestions, and experience in the comments.

Friday, December 17, 2021

What we learned in CS222, Fall 2021 edition

Welcome back to the "What we learned in CS222" series. As part of the final exam in this course, students participate in a divergent thinking exercise in which we list off what we learned during the semester. Then, in a convergent exercise, each student gets a number of stickers with which to vote for the ones most important to them.

One thing that was a bit different this semester was that, in a fit of distraction, I forgot to set the timer. We came up with this list of 129 items in roughly half an hour, but it was only roughly timeboxed. Another first was that one student misunderstood the instructions, marking the sheets that were most important to him rather than the items. We all had a good laugh about this, but it does mean that his votes may not have actually ended up where he wanted them; some were off on the side clearly not marking a specific item, but others were near enough to text that they were indistinguishable from legitimate votes.

The other unique element this semester is the answer to the question you might have from looking at the list below: Who is Jack? Jack is a Computer Science student who was not in my class but had better attendance than several students who were. Jack was enrolled in a separate section of CS222, taught by one of my colleagues, so he was studying similar material. He had a class in the room immediately before my class, so he regularly would just stay sitting with his friends who stuck around for my class. It was the strangest thing: I've had plenty of students sign up for a class and not show up, but I've never had someone not sign up but come. Maybe someday he'll shed some more light on his experience attending both classes. The only time I asked him about it specifically was on the last day of class, after my students had presented their final projects. I asked him which section of the class had better projects. He thought a moment and told us about some of the visually compelling projects in the other section, which he thought were more impressive, but added that my students probably had better code. I'll take what I can get.

Without further ado, here is what the students said they learned.

Refactoring6
Team Coordination5
OO Design4
User stories4
OO Decomposition3
Clean Code Formatting3
TDD3
SRP3
Readability3
Git2
Code Review2
GUIs2
Whiteboard programming2
Jack2
Kembel's design thinking2
Software craftsmanship2
Testing with coverage1
Version control1
Pair programming1
Naming conventions1
APIs1
HTTP requests1
Debugging1
SMART goals1
Branching and merging1
CRC Cards1
IntelliJ IDEA1
Functional Decomposition1
Accessors & Mutators1
User experience (UX)1
Backlog1
ImageView1
Iterations1
View and model layer
JavaFX
Flutter
Web queries
Parsing
JSON Data
Waterfall
Methods & objects
Short methods
FIRST testing
Aliasing
Defensive copies
Deep copies
Scrum
Event-driven programming
Multithreading
Encapsulation
Dreyfus Model of Skill Acquisition
Copyright laws
Licensing
Human Success & Failure Modes
Rubber duck debugging
Pragmatic Programmer
RCM "Uncle Bob"
Retrospectives
Conditions of Satisfaction
Red-Green-Refactor
Acceptance testing
UI templating
Binding (UI)
"God" classes
Packages within project
Dependencies
Gradle
Java 16
Documentation
Environment replication (machine independence)
IDE
Principle of Least Astonishment
Comments
Commit messages
README files
Polymorphism
INheritance
Elegant code
Abstraction
High-level languages
Exposure of sensitive data
Leaky abstraction
API etiquette (user agents, frequency of use)
Testing protocols
Task Lists
Butter dish
Hyperlinks
GridPane
ScrollPane
HBoxes and VBoxes
ChoiceBox
Buttons
Desktop (class in Java)
Inner classes
Holub on Patterns
OO Road simulation
OO Bank example
Risk matrix
History of computing
When is a feature complete?
Machine Learning
Mearns Bux
Assignability of tasks
Try-catch (error handling)
IOExceptions
Stack traces
Stack overflow
Weak warnings
Compiler errors and warnings
Runtime errors
Edge cases
Test before commit
Interfaces
Engines
Run configurations
Class implementations
Abstract classes
Making stuff static
Equals and hashcode
Hashmaps
Depend on interfaces, not implementations
Don't program your own time API
DRY
Import optimization
IDE tools (e.g. format, extract method)
Functional programming
Presentations
Slides
power points

After we closed the discussion, a student pointed out that Clean Code itself was not listed. I had noticed that but didn't say anything. I suppose it's another indication that this was a semester unlike any other, which point foreshadows my upcoming reflection post.

Reflecting on CS215 Introduction to Game Design, Fall 2021

This was the first semester that CS215 was officially on the books as "Introduction to Game Design," and I expected a deluge of students. That didn't happen, probably because (1) we didn't get the word out and (2) nobody knew to look for it. Over time, I hope we can fix both of those. It's a good class, and I think students get a lot out of it. 

My relatively small class was part of another immersive learning project, a collaboration with Minnetrista. I was going to link to my course planning blog post, but it seems I never made one last summer. The structure of the course was very much like past ones, and being face-to-face meant we could get back to doing a lot of the in-class exercises I enjoy so much. The students missed out on some of the digital boardgame and print-and-play content that we had to use last year when asynchronous and online, but that's an acceptable cost as far as I am concerned.

The only friction here lay in the students' final project submissions. Before 2020, I had students create prototypes and deliver those to the community partner. This has two problems: the students don't walk away with a copy of the thing they made, and the partner doesn't always really want them but has to take them. In Fall 2020, I had students make print-and-play games instead, and that format worked well in that students could both have their own copy while also sharing the content with anyone who might be interested. With this in mind, we decided to have the students create their prototypes in the print-and-play style. As described above, however, the students didn't have a whole lot of experience with this format, and many underestimated the effort required to go from their handwritten cards to something reasonably printable. I shared my experience using nanDECK, which at least one student used, but many went through a more laborious and nonautomatable process.

A related problem is one I've seen before but seems exacerbated when looking at print-and-play articulations. Many students show little recognition of how rulebooks work. This is likely related to both their unfamiliarity with the hobby but also, relatedly, with their not having to learn games themselves. If someone else is always teaching you games—including folks on YouTube—then you have very little exposure to what it means to express rules. I am not entirely sure if this is a real weakness of the course or not; it's possible that all I need to do here is encourage the students to try writing the rules earlier. The danger then, though, is that inertia will set in and they may not change the things they ought to change.

I had the students keep design logs, as I have done before. Maybe my memory is poor, but I don't remember so many people being confused about them. Very simple things, like the fact that there is one log for the whole project (as opposed to different logs each week) and that they should be in reverse-chronological order, seemed to trip up most students. I admit, though, that I may have been a confounding factor there, since early in the project I was trying to have them submit combinations of design logs and labor logs, and only one student read the instructions and followed them correctly. Now, of course, the instructions were perfect and it was entirely the readers' fault, but one should not ignore an endemic issue. When I separated the labor and design logging process, students still were confused about what each did. The moral of the story here may be that I need to more clearly express exactly what I want as separate deliverables rather than try to kill two birds with one stone.

It may be worth stating that some students didn't really keep design logs at all, not in any real sense. These students also did not have very polished projects, as one might expect. The trouble came in when I asked the students to self-report a summary of their playtesting results, and I saw some students grossly exaggerate the truth here. I hate that feeling of having to write back to a student and say, "I don't think that's true." When the response is silence, at least I am vindicated.

I still have a major struggle in this course in that the students come in with such vastly different games literacy. I had some students get mad at me this semester when I offhandedly mentioned that Uno is not a very good game. I did not expect such a defense! Others based their games off of contemporary designs such as Photosynthesis, and they're just in a completely different place in the hobby. I explained it to one student this way: imagine teaching a creative writing class where some students have only read "See Spot Run" and others have read The Brothers Karamazov.

Overall, I was happy with the projects. I have already had my end-of-semester meeting with Minnetrista where we talked about which projects look most amenable to digital production in next semester's studio course. I am excited about the direction we're planning to take, but to hear more about that, you'll have to come back to the blog another day.

Thursday, December 16, 2021

Reflecting on CS315 Game Programming, Fall 2021

It was a fun semester working with about 25 students in CS315 Game Programming. Last Fall, the course was online and asynchronous, and it was good to be back in the lab again. One particularly fond memory was at the end of the first project, when I had the students rank each other's projects for a Student Choice award. It was fun to watch them engage with each other's work, an when the votes were tallied, it came out to a tie. We had the two tied students come to the front of the room for an electric game of Rock Paper Scissors to see who would win. That's the kind of serious educational business that you just cannot replicate online.

On Tuesday, the students took their final exam, in which they wrote project reflections that featured three "What went well" entries and three "What went poorly" entries. I shall move forward in the same spirit.

Godot Engine. This was the second time I have taught CS315 using Godot Engine, and I am even more convinced now that it is a great choice for this class. Students can see how ideas they have learned in prerequisite courses manifest when writing games in GDScript, and the few students who have already completed the capstone can similar bring those lessons to bear. We only pursued 2D games, which may be considered a mild weakness if you consider 3D to be essential, but frankly, I don't. I am confident that an earnest student could easily learn the 3D-specific tools and techniques with the 2D fundamentals they learned this semester. The quality of some of the games the students made was really impressive considering their experience level and time constraints.

Personal Progress Reports. I have already written about the frustrations I had in the first iteration of the final project with respect to my traditional self- and peer-evaluation format. I switched to the Personal Progress Report format that I learned from Jason Wiser, in which students report on what they planned to do, what they accomplished, whom they helped and who helped them, and external resources used. I required this to be a multimodal document, including at least screenshots. The students completed three of these weekly reports. Many students struggled with the format initially, particularly the use of multimodal composition: several students simply dropped in images with no explanation, no context, no obvious connection to the narrative. Through repeated feedback, I was able to get pretty much everybody on board. Reading these took more time than expected, but it was a good glimpse into students' behavior. I also was able to clarify any doubts I had about teamwork and consistency of contribution. The few students who referenced Personal Progress Reports in their final exam reflections acknowledged that it was a bit of paperwork to do, but that they also enjoyed having to think about what actually happened during the week. Overall, then, I think it was a worthwhile change, and now I'm wondering if something like this should also be backported into CS222, where I often struggle to get an honest glimpse into what's happening on teams. Note, however, that I did not explore the idea of allocating a fixed amount of points across team members for grading purposes; I have still been unable to dig up any good research here.

Short Intro, Long Final Project. We started with just a few weeks of fundamentals, expressed in three projects and a one-week midsemester ex(j)am. I cut a week here from last year's plan, removing a project that dealt with 3D development. As usual, I gave the students a lot of freedom in designing their final project. Since the course doesn't really cover "game design" but only technical issues, students could pursue anything that would be reasonably in scope. Generally speaking, I was impressed by what the teams put together. I am eager to see if the quality of projects continue to improve as more students conceive of CS215 Game Design and CS315 Game Programming as a logical sequence.

Semi-Public Showcase. To celebrate the students' good work, we agreed to hold a semi-public showcase of their projects. I sent invitations via email to every CS faculty member and major, and I also invited a few other faculty friends. I bought a bunch of cookies, and my son baked two excellent homemade batches of cookies and brought them, too. We got the college social media person to come and take pictures. In the end, though, we only had about about five people from outside the class attend, including zero students. Now, I understand that everyone is busy and students in particular are inundated with so many invitations that they ignore basically all announcements. That said, I couldn't help but feel disappointed, in part because I had spent so many hours planning and in part because so few people were able to play these games, get inspired, and congratulate their makers. It is possible that, in a future year, we could do something more like the CS120 Art Show, having the games someplace public to be enjoyed. I'm not sure I have the endurance for planning that kind of event, though, so I'm really not sure right now where the next logical step is here.

Checklist Grading and Design Quality. Checklist-based grading worked well for the technical matters that are expressed in the syllabus, but it's really not enough to help students think about iterative design. What to do with a team that makes a terrible design decision, which I give feedback on each iteration, and which they never change, to the detriment of their project? As mentioned above, game design is not actually in the learning objectives, but it sure seems like a good opportunity to reinforce some ideas of user-centered design. At the end of the second iteration, I decided to have them try the five-point rubric I talked about in a previous post: clarity, innovation, immersion, flow, and fiero. I explained to them that I didn't quite agree with that taxonomy, but that the goal was to just get talking about design issues. Indeed, teams formed up into clumps and had useful conversations that were then referenced by a few students in their final reflections. It would be easy enough to bring this more formally into the course with just a bit more structure and scaffolding.

The 3D Blind Spot. My supposition is that a student who wanted to learn Godot Engine's 3D features could just do it, and this is based on the same kind of belief as my idea that a student could learn Unity or Unreal Engine based on their experience in the class. However, I have no real data about that. Nobody in the class seemed to mind skipping over 3D. Indeed, students could have done 3D games as their final projects, but nobody seemed to want to. Instead, games had the look and feel of either retro Flash games or 2D indie games. I do wonder, though, as my department is looking at more strategic collaborations with the Animation department, how exactly a student from this course would be able to jump into a collaboration with a 3D artist. Maybe we should try to set this up in a jam experience to see what happens.

Of course, we had all the normal pros and cons of a semester, with some students really excelling, some falling behind, some showing up every day and asking good questions, some refusing to show their faces. That's all pretty normal. Overall, this course was a great joy to teach this semester, and I had a wonderful time working with the students on their projects. I'm hopeful that they are inspired to carry on, join some jams, and keep sharing stuff with the community.

Wednesday, December 15, 2021

Reading "Procedural Storytelling in Game Design"

Last night, I finished skimming through Procedural Storytelling in Game Design, and I decided to use this post to capture some of my reactions to it. The book is a collection of essays edited by Tanya X. Short and Tarn Adams, published in 2019 by CRC Press. It consists of 28 chapters, which are divided into the themes of Structure and Systems, Worlds and Contexts, Characters, and Resources.

Kate Compton's first chapter provides a good overview of generators. In fact, the first chapter is an edited version of her public tumblr post, so go ahead and check that out. She presents an AI-lens on generation, framing the capabilities of generators in terms of the human skills they mimic. Then, she summarizes six approaches: distribution, parametric methods, tile-based, grammars, constraint solvers, and agents and simulators, which includes traditional CS techniques such as steering behaviors, genetic algorithms, and cellular automata. This essay also defines the 10,000 Bowls of Oatmeal problem as one of the complications of producing meaningful generators.

I can easily generate 10,000 bowls of plain oatmeal, with each oat being in a different position and different orientation, and mathematically speaking they will all be completely unique. But the user will likely just see a lot of oatmeal. Perceptual uniqueness is the real metric, and it’s darn tough.

From this introduction, I had assumed the rest of the book would dive deeper into each of these ideas. I was disappointed, then, when that wasn't the case. Most of the essays are descriptions of how procedural storytelling was used in different projects—some familiar to me, some not. They tell of design challenges and constraints, and the stories are interesting but generally atheoretical. Perhaps, once again, my hopes for formalism in game design were too high. I was reminded of a recent conversation with a technical friend and game designer, a conversation in which we both experienced finding lots of advice and stories but relatively little theory and practically no empirical evidence.

It leaves the book in a funny place: I was able to pick up on some lessons from the storytelling within because I've done similar work, but it's not the case that I could hand this to an undergraduate and ask them to explore some of the techniques presented in the book. There's just not enough detail. However, I did get links to several projects that were hitherto unknown to me. These include the tools Kate Compton's TraceryBruno Dias' Improv, and James Ryan's Expressionist, as well as Stéphane Bura's essay, "Emotion Engineering in Videogames." I look forward to taking a closer look at these over the break. 

There were a couple of other generally useful ideas that I picked out of the reading.Adam Saltsman's chapter, "Plot Generation," introduced me to the useful concept of froth, which he claims emerged from the LARP scene. He defines it as "the way we tell each other stories after a match and the way we construct narratives about all the cool stuff that happened during the game—that whole phase of play that is sort of after the game but sort of not." 

Tanya X. Short's chapter, "Maximizing the Impact of Generated Personalities," includes a useful counterpoint to traditional narrative design. The usual advice for a writer is, "show, don't tell;" indeed, that's something I regularly tell my own students. However, for generated characters, her advice is "tell, then show." That is, use the affordances of videogames to give the player a hint about the character and then reify that personality through an interaction. Her example from The Shrouded Isle shows how a character has the "accusatory" personality tag, which allows the player to quickly recognize this as a part of the character's personality, rather than having to establish it through a Karamazovian mountain of text.

The title of Darius Kazemi's early chapter emphasizes his main point: "Keeping Procedural Generation Simple." This is echoed in a few other chapters as well, that procedural generation should be simple and deployed both thoughtfully and tactically. 

I have been a fan of Dan Cook since playing Triple Town and reading at The Lost Garden, although I cannot remember now which of these came first. (Egads! The Lost Garden URL has changed and the old RSS feeds stopped working three years ago, but Dan has been posting things. Well, now I have even more stuff to read over the break. Fellow Feedly users, update your feeds.) It was interesting to read his chapter about Triple Town and contrasting the point he was trying to make with how the game was received and played. He is quite frank about the unexpected disconnection, its implications for design, and how some of the same mistakes emerged in different ways in future projects. 

The most interesting technical chapter was "Procedural Descriptions in Voyageur" by the aforementioned Bruno Dias. In this chapter, he digs into his tool, Improv, and describes how a set of increasingly complex filters and generators can be used to solve a creative design problem. 

I've had some procedural storytelling ideas kicking around my "Game Design Ideas" folder for some time. More recently, as part of a grant proposal, I spent some time with Reigns: Her Majesty to think about its narrative system and compare it to an old project of mine, Social Startup Game. Through my interest in Flutter, I also came across Filip Hráček's Knights of San Francisco, which got me thinking more about generative narrative as a presentation layer for a simulation. I am inspired to try making something of a similar genre, but knowing that the first three steps in Glassick's model are clear goals, adequate preparation, and appropriate methods, I hoped to find something in Procedural Storytelling in Game Design that would push me in a fruitful direction. Unfortunately, this was not the case. I am eager to look into those items I've shared above, and maybe therein I will find some techniques to sink my teeth into. That said, it's also possible that everything I need to know is already in my head: after all,  judging from the stories in the book, it all boils down to the prudent use of grammars, tiles, parametric methods, and automata. I suppose, then, that I'm just at that point where I need to choose between research and making the first prototype. I'll let you know how that goes.

Wednesday, December 1, 2021

Four Boys and National Game Design Month

Maybe you've had a chance to read the epic post about my experience with National Game Design Month 2021 and the making of Blobbo Globbo. Regardless, at the same time that I was building my November project, I was also encouraging and mentoring my boys in their own NaGaDeMon projects. The older three had participated last year, and this was the first that all four undertook their own projects. 

The motto of national Game Design Month is "Make-Play-Talk," and so to satifsy that last piece, I have encouraged the boys to write reflections about their experience. For the younger boys, I gave some prompts that I use with my college students: What went well? What did you learn? What would you like to do next time? Below, you'll find links to their projects and copies of their reflections. Enjoy!

#1 Son (14): Goblin Dungeon

Repository: https://github.com/the-alex-g/NaGaDeMon2021-2

The Linux build can be found in the release.

Reflection:

For NaGaDeMon 2021, I made a Minesweeper-like game in C++ to help me learn the language. Titled “Goblin Mining”, the game is played by moving around a ten by ten board with wasd. Goblins and ogres are randomly distributed around the playing field. The game is won when all the goblins are revealed — and lost when the player enters a space with an ogre.

My original idea was to make a 3d roguelike in Godot. I started that project, but was rather unmotivated and felt like I had no time to work on it. I had recently joined the local FIRST robotics team, Phyxtgears, and I was interested in joining the programming team. The robot programs are written in C++, and I knew none of that language. The other team members taught me some of the essentials, and C++ was similar enough to other languages I had used that I was able to understand what they taught me pretty quickly. Over Thanksgiving week, I started work on Goblin Mining. Since life had slowed down for the holiday, I had plenty of time to work on it and was able to get it finished before the end of the month.

My favorite part of the project was figuring out how to modify the text that was being printed in the console. It is done by inserting strings of the form “\033[Xm” into the text, where X is a number between 0 and 107. For example, 31 makes the text red, and zero resets the text to default. Here is a link to the website where I found this information. I made a header file with all of these modification strings in it, then learned how to include it in my main project.

There were only a few problems I encountered making this game. One issue was that sometimes the entire board has been revealed and the game does not end. Another was that I could not find a way to enlarge text being printed in the console. A third complication arose when Dad and I tried to use Emscripten to publish my game on the internet.

After giving up on using Emscripten, Dad helped me to make and release a Linux executable for my game. I learned about read, write, and execute permissions in the process. However, making an executable for Windows was not feasible.

The entire game is played in the console, and when the player wants to move they must type w, a, s, or d and then press return. Sometime, I want to try and figure out a different method of taking input so the player does not have to hit “enter” every time.

I enjoyed making Goblin Mining, and I think it is actually rather fun. Even with my limited knowledge of C++, I was able to create the game without too much trouble. Then, on November 30th, the last day of NaGaDeMon, I learned about classes and inheritance. If I had had the time, I would have rebuilt my game to include these concepts. As it is, I have an idea for another, similar game I could make with my newfound knowledge.

Dad's note: I am proud of my son for exploring C++. He looked up and used some interesting features to get this game working. Unfortunately, some of these are POSIX-specific features, which complicated trying to make a Windows build. We tried emscripten for putting the game on the web, but getting his input scheme working would have required a lot of rewriting. He was able to figure out how to make Linux builds himself, and I helped him look into trying to build it for Windows; first, we worked on this together, and then I spent even more time trying to sort out all the issues myself. After a surprising amount of effort, I was able to get mingw to compile his program and then to run it on wine. Unfortunately, I hadn't seen that in the code, he also calls Unix shell commands like clear, which simply don't port to a Windows environment. There wasn't any way to get this working without a rewrite that would have taken him past the end of November. I learned a few new things working with him on this process though, and he's learned a bit more about platform issues.

#2 Son (11): Infinity Dungeons

Web build: https://the-g-force.github.io/NaGaDeMon-2021-L/

Reflection:

This year for Nagademon I made a platformer in Godot. I have never made a game in Godot before, so it was all very different from anything I had ever done before.

In the game you are a guy with a sword running through randomly selected levels using the arrow keys to move and jump. In the levels there are three kinds of enemies. All of the enemies are slimes that move across the floor. There are slow green slimes, medium-speed yellow slimes, and fast purple slimes, all of which can be killed by swinging your sword using the down arrow.

Being my first game in Godot, I think it went pretty well. I had to ask for help a lot but that was to be expected. I had fun making the art and animations, and I think that the end result was pretty good. Making the sound effects was fun. Given more time I would have added more animations, sound effects, enemy types, and levels.

Dad's Note: I am really proud of this guy for diving into Godot Engine. He has been building stuff in Construct and Kodu for years, but this was his first experience with text-based programming and a more robust engine. I gave him and his younger brother some tutorials early in the month to get them started. It was a bit too abstract for the younger brother, but #2 son really caught on. Fortunately, his older brother has done quite a bit of Godot Engine work, and so he stepped in to help answer questions.

#3 Son (9): Dungeon Runner

Reflection:

I didn’t get to do all the things I wanted to do because I kept on forgetting to work on my game. But the scope may have been too big in the first place. One of the main things I wanted to do was to add enemies. One of the neat things I learned to do was to make you “climb” ladders by double jump when you overlapped them.

I am happy with the art I made, and all the coding that went into the game.

Enjoy!

Dad's note: He didn't get the game fully working, and we talked a bit about how and why that happened. His first pass at a reflection glossed over this, but I encouraged him to really think about it. His final reflection is a great improvement and more honest.

#4 Son (6): Dragon Game

Reflection:

The dragon's flying animation went well. I learned how to draw dragons. I usually draw other animals. In my next game, I would like to make a castle background.

Dad's Note: This is this guy's first year participating in the event, and he also built his game using Construct 2. When he first demonstrated his game to me, I was blown away. He was so pleased with every aspect, and almost none of it made any sense to me. Seriously, you have to check it out. This is the same kid who designed our family classic, Joe Johnson Gets Captured. He has a unique sense of design. 

I asked him if there was anything else he wanted to share, and he remembered that, when I played the game, I recommended documenting some instructions on how to play. Here they are:

Down arrow to shoot. Up arrow jump. Right and left arrow move. Shoot ghost to kill it. Click red ball to start lightning animation.

Monday, November 29, 2021

The Story of Blobbo Globbo: A National Game Design Month 2021 Project

This is my third post celebrating National Game Design Month (NaGaDeMon). The first, brief post described a technical issue with Godot Engine, and the second, longer post described by that first post didn't really matter any more.

Earlier today, I pushed the button and published the itch.io page for my NaGaDeMon project, Blobbo Globbo. If you want the TL;DR, go to that page, download the Windows or Linux builds, plug in a game controller or two, and enjoy!

Blobbo Globbo is a one- or two-player arcade-style game. The core gameplay involves shooting slimes, which captures them temporary orbs. Before the orb dissipates, you can kick the enclosed slime across the screen, running over other slimes for combo points. It is highly inspired by classic games like Bubble Bobble, Snow Bros., and Tumblepop

I have wanted to make a game in this genre for years, and in fact, I started one in May as a potential summer project. I spent about two weeks on it before my analysis was that I would not be able to see it through, in part because the art requirements far exceeded my capacity to draw. Getting better and more efficient with asset production is a perennial secondary goal of my projects, but given the complexity of the summer meant it wasn't the time to pursue it. This was, in part, because of an entirely unlikely and absolutely amazing summer vacation. Yes, for once, I chose relaxation over the joy of work! Also, I was pretty burned out from an academic year of pandemic management.

After my first project went sideways, I returned to the idea of making a game like Bubble Bobble. With only three weeks left in the month, I opted to prototype using Kenney's platformer pack, which I use extensively in my game programming class. I briefly considered trying to replace this art with my own, but I'm content having made a game whose play aesthetics match the visual aesthetics of the pack (if I may say so). I also pulled in a few other public domain visual assets, which are all listed in the project documentation on GitHub.

The start of a round

The music is all original, composed in LMMS using exclusively the SID emulator. I wanted to capture a retro sound akin to what I enjoy hearing on Slay Radio. I was also inspired by a talk that my colleague Christoph Thompson gave at the Symposium on Games a few weeks ago, in which he described the history of game audio as being one of compromises. He talked about how the C64 overcame its significant memory limits by including an audio synthesizer, generating audio rather than playing back streams of data. I was able to take some simple themes from my imagination and arrange them in LMMS, but I have to admit that when it came to controlling the SID emulator, I was fairly well just playing around. I understand the four waveforms that are available and generally how different waveforms can combine to make different sounds, but I don't have a clear aesthetic or compositional sense of what makes a song like the theme from One Man and His Droid so amazing and iconic. (Of course, Rob Hubbard probably took more than an hour to compose it...)

I also created most of the sound effects, although a few were picked up from public domain sources. Mine were made using the sxfr plugin for LMMS, which I've used in the past for many jams and projects. Previously, I have created separate project files for each sound effect, which is kind of tedious. For this project, I realized that I could use the "export tracks" feature of LMMS, allowing me to maintain just one project file that contained all the sound effects. This made it easier to compare sounds and match levels, but creating sound effects in LMMS still has the negative side-effect that you cannot export fully-trimmed audio. The exported WAV files contain a lot of silence at the end, which I then have to clean up in Audacity. I looked briefly into SoX to automate this processing, but after some attempts, I realized it was taking more time to automate than to just do manually.

Player 1 has some points and Player 2 is losing a life

About halfway through the project, once I had the fundamental gameplay working, I started scaffolding in some of the other conventional pieces such as the main menu. In my first pass, I found an appealing "splat" image, chose a typeface, pulled in some greens, blues, and pinks, and got the menu working. Playing through, the difference in visual tone was jarring: the ad hoc title screen was saturated and bright whereas the levels—using Kenney's platformer assets—were muted and soft. This emphasized to me the importance of having a palette. Before working on any other gameplay, I picked out the key colors from the asset pack. I put these into the palette in Godot Engine, which I had never used before but seen used in some video tutorials. What a great feature! Now, with a single click, I could easily get my menus, HUD, and effects to draw from the same colors.

My game design courses focus on system design, and my game programming courses focus on technical implementation issues. This means that there's a vast area in between that I don't often get to explore, and that's one of the reasons I stay active in game jams and events like National Game Design Month. Particle effects and shaders are good examples from this project. I show students some basics of particle effects within engines like Unreal or Godot, but we don't spend a lot of time looking deeply into them. For Blobbo Globbo, I am happy with the particle effects used to "warp" between levels. They are not going to win any awards, but they are much more interesting than the usual one-day example I give about making simple explosions. Shaders are an area of game development where I understand some theory but have very little practical knowledge. For Blobbo Globbo, I slightly modified a found fisheye effect that is used subtly when a slime is captured. The teleportation animation includes a simple vertical wipe that I was able to get working myself. There are horizontal and a circular screen wipes used in the early scene transitions. I had to find some tips on how to approach the circular one, and I modified both to use smooth stepping for a softer visual effect. That in particular is a tool I'd like to keep on my toolbelt for future shader work.

Speaking of my game programming course, if you're a long-time reader then you'll know that they have a sort of menu of options they can choose from to earn A-level grades. One of the options it to implement a pause menu. Although I've graded many student projects' pause menus, I've never actually made one myself, so that was one technical feature I decided to include in Blobbo Globbo. It was fun. Not much else to say about it, really.

Finally, a real pause menu

The gameplay underwent a few significant changes over the last three weeks. Originally, if a projectile hit an already-captured slime, it would be ignored. However, this led to a gameplay problem where one could just spam the shoot button with impunity. There is, after all, no limit on the speed of shooting, in an attempt to capture the arcade cabinet feeling of button-mashing. Instead, I made it so that a captured but non-kicked orb, when hit with another projectile, would pop. Since points were only earned by the kick, this meant that a player who overzealously shoots would eliminate their own opportunity for points. It wasn't until playtesting it with my kids that I realized that this was far too subtle: there was no way for the player to see that they were missing the opportunity for points. Instead, it seemed a conservative and reasonable thing to do to just sit in one space and shoot as many projectiles as possible. This cleared the board, which is the implicit goal of the design, but without earning any points, which of course should encourage a particular kind of play. After this test, I redesigned the shooting and capturing system so that shooting a captured, non-kicked orb would pop the orb and release the slime. This makes it more clear that care should be taken with shooting, and that points are earned by well-timed kicks.

There are always opportunities to introduce new enemies and new levels in a game like this, but if I were to put more time into the gameplay, I would start by exploring some other directions. Right now, if you complete all six levels, the game loops but increases the difficulty of the enemies (the speed of all the slimes and the fire rate of the pink ones). I think it would be interesting that if a captured slime is released, either because of the orb timing out or being popped before being kicked, it either increased the difficulty rating of that particular slime or changed it to a harder type. Another improvement that is common within this genre is adding pickups that spawn across the board, either by themselves or as a result of interaction with enemies. These give a reason to traverse the board rather than sit in tactically advantageous places.

One of the design challenges I faced was how to express to the player how to play. It's a simple enough game that one can stumble across the handful of inputs: move, jump, shoot. It's less obvious that one ought to run up to captured slimes to kick them until you've seen it done. I make my game programming students include some kind of instructions in their games so that I can figure out how to play them. Most students meet this requirement by dumping instructions onto the main menu screen in some kind of fanciful font, which has the awkward result of being less learnable than if they didn't include instructions at all. One of my design goals, then, was to do better. My solution was to put in a static tutorial screen, which disappears after seven seconds but can be clicked through, that shows the core loop. The original design used Kenney's Input Prompts pack, but these were designed for pixel art, and my kids pointed out how out-of-place they looked during testing. I found Xelu's free prompts pack and was able to pull in some higher-resolution images that fill the bill. It didn't have exactly what I wanted, which was a controller-neutral depiction of which buttons to press, but I was able to piece together something approximating that by composing blank buttons with labeled ones.

Tutorial screen

The name of the game came from a dinner conversation with my family. I asked what I should name it, and all manner of silliness ensued. When I described it as having slimes or blobs, somehow "Blobbo Globbo" came up, because you sort of glob the blobs. That got enough laughter that I decided to keep it. Conveniently, a poet might also use it as a partial rhyme for "Bubble Bobble," especially of you go full Cockney. Please include your thematic poems in the comment section.

It enjoyed spending time in November creating this game. As usual, one of the greatest delights comes from watching my kids play the game. I hope you will enjoy it as well. Keep in mind that, like most of my games, it is free software licensed under the GPL, so you are welcome to download the code from GitHub and tinker with it yourself.