Thursday, July 9, 2020

Deploying Godot Engine Web Games to GitHub Pages with Continuous Integration

After figuring out how to use continuous integration with Flutter Web apps on GitHub Pages, I turned my attention to Godot Engine. Through my FamJam projects, I have developed a pair of scripts ( and
) for building and deploying games to GitHub Pages. It seemed like a natural extension to see if I could do this automatically. This could be useful both for my Fam Jams and, of course, for my revised game programming course.

In addition to GitHub actions, the other two critical pieces to getting this to work are aBARICHELLO's Godot CI Docker image and, as used in my Flutter approach, peaceiris' GitHub Pages Action. Here is the simple version:

My custom build script usse NatrimCZ's approach of reducing project download size by zipping the project files and extracting them client-side, and it was surprisingly straightforward to incorporate that into an alternative GitHub workflow:

Either approach, just like with Flutter, requires you to have an authoritative push to gh-pages before using GITHUB_TOKEN for authentication will work; once again, you can do something like this to get that done:

git push origin master:gh-pages
Also, as mentioned in the comments, the script assumes that you have already configured the project with HTML5 export and that you have set the export location to build/web.

Wednesday, July 8, 2020

Deploying Flutter Web apps to GitHub Pages

I spent most of the day trying to find the easiest way for my students to publish Flutter Web apps to GitHub Pages. My quest started at zonble's Medium post, proceeded with my taking a closer look at GitHub's workflow and actions documentation, and finally tripping across the handy GitHub Pages action. After a bunch of testing, I'm feeling confident about my approach, which I will explain below.

The essence of the approach is to use a custom workflow by placing the following file in your project in the path .github/workflows/workflow.yml. Then, whenever you push to master, the workflow will be triggered and your built application will be deployed to GitHub Pages.

This approach is susceptible to the known problem with first GitHub Pages deployments using GITHUB_TOKEN. The problem can be entirely avoided by creating and then specifying a personal access token for the repository. However, I think a simpler approach—that also requires fewer tokens cluttering up the configuration—is to do one manual push to gh-pages, after which the simpler workflow will work as expected. My suggestion is, before pushing to the master branch on GitHub, push your local copy to the remote gh-pages branch, as shown below.

git push origin master:gh-pages

That's enough for GitHub to recognize that you will be deploying to that branch. Follow that up with a push to the remote master branch as usual, and you should be all set.

Tuesday, July 7, 2020

Summer Course Revisions 2020: CS445 Human-Computer Interaction

After wrapping up my preliminary planning for my Game Programming course before the holiday, I turned my attention to the necessary revisions for my Human-Computer Interaction course. I had a few ideas swimming around my mind, but I decided it would be best to go back to my notes from last time I taught the course, which was Fall 2019. I re-read my end-of-semester blog post, and this reminded me of how terrible that semester was. I had sort of forgotten how painful that course was, but it was good to be reminded.

I decided not to include a community partner for the Fall. I have been disappointed with what my students have been able to provide in this course. While the pandemic makes it easier to work with partners who are distant, it also removes the crucial ability to sit in a circle and have an honest chat. The risks are just too high right now to ask an external partner to donate their time to the students. Of course, if I get good learning outcomes from the students, I would love to have them engage with a community partner in subsequent experiences (such as the game studio course). The topics are just too hard for the students to grasp to ask them to be able to learn them and apply them to a partner's benefit in one semester, given all the other constraints.

The course plan that I just put online lays out the first several weeks of the course in good detail. During these weeks, students will be reading Don Norman's The Design of Everyday Things and completing weekly exercises to help them build their understanding. I have used this book in the past several semesters, and I like that the students can both learn from it and practice learning from expert writings (rather than conventional “textbooks”). The weekly exercises are all in a format that involves individual reading and work from Thursday to Tuesday followed by a period of online peer review from Tuesday to Thursday. In this way, I hope to simulate some of the discussions and ad hoc peer reviews that I would normally do face-to-face in the classroom.

I have been disappointed in the past with students' ability to bring knowledge from DOET into their future work in the semester, and so I added a new culminating assignment that asks them to apply the book's principles to their CS222 projects. In part, this copies the inspiration I use in CS222 when I have them look at their CS121 projects: having them look back on their work, after they have had a chance to step away from it, should give them more objectivity while also reminding them that, despite imperfections, that work was important to their journey. This report is currently designed as a two-week writing assignment with an explicit, graded check-in point halfway through. This will give me and the students' peers an opportunity to give them feedback on which parts of the report are working and which are unclear before the students complete their final submissions.

The course plan as of this writing only goes through the DOET readings and analyses, but my planning notes go several weeks farther. My plan is to get them into Flutter, specifically the Web support that is currently in the beta channel. The thing I like about Flutter is the “code as design” approach, in which the code clearly reflects the application structure. I have seen many students in this course and CS222 get hooked on a drag-and-drop UI builder such as scene builder, leading to two dangerous outcomes: they lose the insights and power about software structures that are gained through programming, and they still design bad-looking interfaces. I'm hopeful that Flutter will give us the right level of abstraction to avoid these two pitfalls.

What I would like to do is have them learn Flutter by creating a simple project, which at this point will likely be a grade calculator. It's simple and familiar, but there is still plenty of room for students to go in different design directions. Then, I would like to use this simple example to introduce readings and techniques of usability evaluation, Gestalt vision, and accessibility. That last point is a new one for the course despite its importance: it has frequently been one of the topics I have cut when doing community-engaged projects because, inevitably with community projects, there are problems that the teams need to put their heads down on and fix.

I would like to wrap up the semester by having them make a larger project that they can use to bring together all the analytical tools and techniques that they have learned. I am still a little uncertain about the context for this project. I may just open it up to them, as I do in CS222, but this runs the risk of students falling into a quagmire of code and not appropriately deploying the other cognitive tools we are learning. I may just give them a canned project for that reason. Two that have come up recently in my own practice are a tool to judge student showcase entries, as in the CCSC Midwest Conference, or a tool to help students manage checklist-based specifications grading, as in my Game Programming course plan.

I think I will return to the CS445 course plan in the next few days and add details for those other assignments. Looking at it now, I realize that I forgot to add the due dates to the Web site; since I cannot yet even access the Canvas page for the course, I may as well trick out my lit-html templates to include the deadlines online. In any case, I had a productive morning of planning, and it seemed like a good time to write this blog post in the gap before lunch.

As always, thanks for reading, and feel free to share any feedback or questions you have about the plans.

Thursday, July 2, 2020

Family Painting: Arcadia Quest - Beyond the Grave

Remember how much fun the G-Force had painting Arcadia Quest and then the Riders expansion? Well, while we were playing through Riders, I saw that Beyond the Grave went on a great sale online, so I jumped on it. I had not picked up my brushes for a bit, but once I primed the Beyond the Grave minis and showed them to the kids, they were very excited to get going. I think we painted this set in just over a week. Hurrah for summer schedule!

We started with the Skelebones, which come in two sculpts.

Skelebones by me, my wife, and #3 Son
Skelebones by sons #1, #2, and #4

I think we all expected these to be standard skeleton minis but they're really not: they have arms and legs rather than just bones. This is indeed some dark magic. I thought they were pretty fun to paint and that everyone did a nice job. Notice the nice glowing eyes on #1 Son's model. I should also mention that I left #4 son (who is 5) to his own devices most of the time, leaving him to mix and thin his paints. Sometimes I would notice that he had not thinned nor thought to mix them and give him a hand, but this is all pretty much his own work. Not too bad for a little guy!

Slasher Zombies by me and my wife

The Skelebones were the only minion with six copies, so in the next painting session, my wife and I completed the Slasher Zombies shown above. Again, I had a good time with this one. For the armor, I painted it all in purple then undercoated the trim in white before painting it in red. I believe my wife tried to leave the primer showing for the red on hers and had more frustration. I like how the face turned out on mine, and I think my wife did a great job on the facial highlights on hers, too. I think she wanted the brains on hers to be more pink but had a hard time getting a good tone. For mine, I had a pretty good plan going into it, starting with a mid pink, darkening the recesses, and highlighting to get a wet look.

Axe Flinger Zombies by the Boys (in age order)

While Mom and Dad worked on the Slasher Zombies, the boys worked on these much simpler Axe Flinger zombies. #3 Son interpreted the skin color to be much brighter than his brothers did, but that's fine. Purple skin and white hair is taken from the card art, but it is kind of a strange combination. #1 Son is doing a great job with his highlights and shadows these days, and I think we can see that #2 Son is on the cusp of this as well. If he took a bit more time to drop a little Nuln Oil around those eyes, for example, he would get a lot of bang for his buck. He's ten years old and doesn't like to sit and focus on a mini as long as I do, but I think as he develops patience and if he has desire, he could reach the next level. Also, I would be remiss not to say those are darned good pupils by the youngest boy.

Necromancers by #1 and #4 Sons

The next painting session was also a 4-2 split on models, and I let them pick their preferences in ascending age order. Sons #1 and #4 both picked Necromancers. Once again, #1 son really nailed it, and I think the nice paint job is accentuated by a nicely balanced color scheme. On the right is a really great job for a five year old, on a figure that I can't help but call "The Necromancer with the Derpy Eyes." He may show up in a campaign someday.

Ghosts by me, my wife, #2 Son, and #3 Son

I knew when I first opened up the game that the ghosts would be an interesting painting challenge, given that they are practically monochromatic. Four of us painted them while the other two worked on the Necromancers. The shade color on mine is arguably too dark for a ghost; it's certainly a bit darker than I intended, which I didn't realize until my wife asked about it and we held our side by side. It makes my ghost look a bit more manic, but that's not necessarily bad. #3 Son saw it all as basically one tone, but #2 Son did a nice job getting variation in his. I don't know if he missed the red/magenta spots or purposefully left them blue.

You cannot tell so well from the picture, but my wife saw a Bride of Frankenstein streak in the ghost's hair that I didn't notice. It's a streak of dark blue on the left side of the head. In the card art, I only read it as a shadow, but when I looked at her paint job, I think she captured what the artist intended. 

At this point, we were out of minions, and the rest of the painting was done in the evenings by my wife, my two older boys, and me. Here they are in no particular order.

The Black Brothers by #1 Son

My eldest son wanted to paint the figure on the right, and he basically finished it one night, so we also gave him the one on the left to paint. A positive result of this is that they really look like they go together. For the black armor, he went for a non-metallic metals (NMM) approach, which I guess I didn't really understand when he asked what I thought about NMM. Personally, I avoid it because it's so hard to get right. I didn't realize it was what he was going for here; I thought it was more of a painted or patina armor. In any case, I think for tabletop quality it's great: the bright white highlights sell the idea of glint. Looking closer, it doesn't have quite the dynamic range to sell it, but hey, who's looking closer? I think the paint job is helped by the fact that the armor is not really noteworthy, so it's easy to read as "black armor." The facial expressions of these two characters are the focal points, and he really nailed those parts. The swords, too, are much more interesting than I initially gave them credit for: he got a nice shine on them that does not draw attention but really sells the story.

Frank by my wife

My wife did a great job on Frank, although I think she doesn't give herself enough credit for it. The card art for Frank is, frankly, boring. Who puts a white shirt on a flesh golem? The sculpt is also rather featureless, just kind of bulbous. She struggled with white—who doesn't?—and was concerned that the result looks dirty. Personally, I think it's great for someone who only paints every few months at the kitchen table. 

The real seller here though is the bottom of the shoe. Get this: it is a perfectly flat sculpt. She painted in the texture that you can see on the picture. I had no idea until she pointed this out. Nice work, honey!

Dread King by #2 Son

The Dread King is the Big Bad from this expansion. The card art is compelling, and I think the sculpt, while maintaining the chibi style, is exciting. Before I had the chance to ask any of the boys if they had preferences, #2 Son asked if he could paint this one. I think he did a nice job on it, especially the flesh tones, where you can see his efforts at highlighting. He asked for advice halfway through, and I encouraged him to use the Nuln Oil and Agrax Earthshade (the only things we use besides the Vallejo Basic Colors set) to get more contrast around the teeth. Originally, they were hard to distinguish from the rest of the skill, but he got just the right amount of contrast to make them pop.

At this point, you may be wondering, "Paul, was there anything that made you buy this set besides the fun of family painting and of playing the game?" It turns out that there was. When I was considering whether or not to pull the trigger on this one, my brother informed me that there were sculpts based on characters from Young Frankenstein. Well, that's easy.
Dr. Spider and Ivan, painted by me

I painted Dr. Spider with the rest of the family as we worked on the figures shown above, but Ivan I actually painted at my regular painting station one evening while catching up on some podcasts. 

The first night working on Dr. Spider was spent entirely on his face, and I am really happy with how it turned out. The only real bummer here is that the card art features kinky Gene Wilder hair, but the sculpt has a completely different texture. Sure, it was probably easier to sculpt than curls, but it's not Gene Wilder hair. The serum he is holding was painted using techniques from this article, which I regularly reference for such things.

Ivan was pretty straightforward, once again the most time being spent on his face. It wasn't until I was painting the eyes that I discovered another very disappointing difference between the art and the sculpt. The card art clearly has Marty Feldman eyes, but the sculpt just his big eyes facing forward. It wasn't just a matter of painting the eyes, either, since the pupils are sculpted in. If I had noticed this ahead of time, I would have filled the pupils and redrilled them (or at least painted them) off in different directions. It's a lost opportunity on an otherwise fun model. The brains turned out fine, and I'm especially happy with the redness on the nose and cheeks.

In summary, then, a great time with the family, a fun time painting, but a minor disappointment that the figures don't look more like Gene Wilder and Marty Feldman. The older two boys are chomping at the bit to play, and so I imagine we'll get this to the table tonight. 

Thanks for reading!

Tuesday, June 30, 2020

An Evening with Friends and Dungeon World

Periodically, I pick up a rulebook for a tabletop roleplaying game and imagine myself running a session, like the old days. In October of last year, I was inspired to pick up Dungeon World, and I remember finding it very interesting. Yet, like most of the RPGs on my shelf, it was filed away without being played. It was instrumental in my making Kapow during last year's National Game Design Month, but it never actually got to my table.

There's something mysterious and alluring about tabletop roleplaying games, and despite some reflection, I'm not entirely sure what it is that draws me to them. Certainly, I spent an enormous amount of time planning and running such games in my youth, all the way up through undergraduate, but then it took a precipitous drop from my time and attention. My relationship with tabletop RPGs is a topic for another day, but suffice it to say that the pandemic gave me a weird sort of inspiration to get a group together to try Dungeon World. I could play with anybody, regardless of distance, using online tools that I really wanted to learn anyway as I get ready for a mostly-online Fall semester. We used Roll20, which was impressive although awkward in many places. For what it's worth, about an hour in we gave up on the integrated peer-to-peer voice chat and just set up a Google Hangout instead.

I thought it would be a fun bit of reflection for me to go through the DungeonWorld agendas,  principles, and moves for GMs and see what I hit and what I missed. DungeonWorld was released under a Creative Commons Attribution license, so I don't feel bad about including these rulebook excerpts here. You can even crossreference my notes against the relevant part of the book online if you can handle the ads. Of course, if you like what you see, buy the book to support the creators.

Another bit of preface before I get into the details. I didn't talk to the other players about whether I could write publicly about them and the game. I won't mention the players by name; I'll be referring only to their characters. There won't be enough here that you could reconstruct our story because these are just my notes. My goal in sharing here is not that you can rebuild our adventure, but that you can see how I think through what happened and compare it to other experiences. Getting into it, then, it's sufficient to know that Serah is a halfling druid, Brandon is a human ranger, and Tristan is a human thief of the con-man persuasion.


Portray a fantastic world

I think I did good job here. Since I didn't know what kind of characters the players would make ahead of time, I couldn't prep something attuned to their particular skills. Instead, I drew upon the Eye of Clune dungeon I had designed two years ago for my kids. It, in turn, was inspired by design advice from Runehammer / ICRPG.

Fill the characters' lives with adventure

I made sure to ask a lot of questions during character creation. Although none of the players mentioned this, I think it was more questions than they expected, but it served exactly the right purpose: building up a world around the characters that was filled with potential adventure. It was just one session, so I'm not sure if I "filled" them with adventure, but the possibility is there.

Play to find out what happens

I had created the dungeon ahead of time, and although they surprised me with some choices, it was still kind of pre-made. I don't wish to sell short their innovations within this space, but I also think it's the case that once we went past character creation, I turned a bit more toward a "I am the GM who made the adventure" mode, not asking enough questions that could have given them some agency. For example, they were attacked by harpies, but it didn't have to be harpies, and the cave was set in the side of a cliff by the canyon, but it could have been anywhere. I'll say more about this in a discussion of the principles.


Draw Maps, Leave Blanks

My memory of this principle was that it was metaphorical, but re-reading the principles this morning, I see that it is literal. We played most of the game without a map, but when there was some confusion about what I was describing, I sketched it on the board. In our post-game debriefing, one of the players mentioned this as a good move and encouraged the use of the map. During preparation, I had decided against predrawing anything in part because I didn't want to fall into the quagmire of assets and fancy dungeons, but I definitely think my player was right: a simple sketch of the room shapes made a huge difference. In retrospect, we should have done this with the town, the cliffs, the river—just laid out roughly how pieces fit together. On the other hand, we could call this all a blank that we can fill in next time, if we play again.

Address the characters, not the players

When I think back to the tabletop roleplaying games of my formative years, I cannot remember if my DMs or I did this, but since returning to the hobby with my kids, I've definitely done my best to follow this. None of the players commented on it, but I did notice that some preferred to refer to their characters in first person and some in third, which was interesting.

Embrace the fantastic

Like I mentioned before, I think I did a good job here with the setting, the mystery. ICRPG calls this the DEW: Danger, Energy, Wonder. It's this kind of thing that excites me about creating more stories.

Make a move that follows

I think I did a good job chaining the pieces together into a believable fiction. There was a logical structure.

Never speak the name of your move

I mentioned to them that I made moves, but I never told them what my moves were, only that they were "hard" or "soft." I had printed up a list of my moves to have on hand during the game, but I never referenced it. There were just a few spots where my improvisational system was shutting down, perhaps from fatigue, and maybe having the list on my table would have helped inspire me faster to come up with something to do when they failed or got a middling success.

Give every monster life

The aforementioned harpies were guarding their nest, which I think I described in a believable way. They weren't interesting but one could see how they fit into the ecosystem. The adventure didn't have many other monsters, not in the conventional sense. Maybe I should have added more "live" things that had their own agendas: everything else, like the magical hallway creature and the skeleton guards, where really reactionary.

Name every person

The only people besides the players who came up were those mentioned during the backstory. Too many of them went without being named. I'll have to remember that so we can fill in the blanks with some kind of flashback or retcon should we have a chance to play again.

I'll mention that I took a bunch of notes on paper, and I thought about putting them into a binder or something. However, I think what I really ought to do is put them in my GM Notes in Roll20.

Ask questions and use the answers

As mentioned earlier, this went really well during character creation, but I think it fell off a bit during the adventure portion. Here's an example: the druid came from the river and could change form into river animals, but we never established the climate of the river. At the end of the adventure, the druid wanted to turn into something big and strong, but what was that? A hippopotamus? A musk ox? We even said out loud that we never really established the climate, but I did't ask them to specify. In retrospect, I should have (although in my defense, it was already about an hour later than I said we'd run, so I was trying to help us wrap up).

The easiest part of this principle is asking "What do you do?" to the players after making a move. That was easy, and falls right into my normal mode of running a game.

Be a fan of the characters

I think it was clear to the players that we were all telling a story together and that I wanted them to succeed, although this wasn't explicit. However, being a fan of them also caused me a bit of systemic consternation. There were a few points where the players described their characters doing something really interesting, really fantastic or heroic, and my instincts were to want to give them some mechanical benefit, like D&D Advantage or ICRPG Hero Coin—something tangible they could turn in later for a benefit. Indeed, during our debrief, I mentioned this specifically. After doing a bit of reading and thinking about it this morning, however, I think this was my defaulting to a D&D/ICRPG view of the game rather than a PbtA one: I probably could have used my moves in ways that rewarded them for heroism and cleverness in a more subtle way. Maybe I did and didn't think of it that way at the time? This is one area, clearly, where I'm still seeking to understand the system.

Begin and end with the fiction

This is another case where everything made sense in the game, but the context was, by necessity, a bit small and impersonal. That said, during the End of Session move, the player had interesting interpretations of their bonds' resolutions. Also, after a little thinking, they came up with an insightful answer to the question of whether they learned something new or important about the world: they learned that the old secrets that they discounted may actually be true. That's a nice hook!

Think offscreen too

I really didn't do this at all. There was an important opportunity that I had missed here. Early in the adventure, the ranger was separated from his companion, which kind of left him without one of his major class bonuses for the whole adventure. I could have taken an opportunity to "move the camera" to show what his animal was doing while they were down in the cave, whether it was worried or in danger or simply at peace. I imagine, though, that this particular principle comes into play more when there are developed fronts.

GM Moves

Use a monster, danger, or location move

Harpies attacked, traps triggered, a tremor started—this is an easy one.

Reveal an unwelcome truth and Show Signs of an approaching threat

I put those two moves together because I'm not sure I've distinguished them adequately in my mind. When I thought of cases where I did one, it could have just as well been another. Perhaps what this really means, then, is that I really did the latter and not the former.

Deal damage

We did a bit of this, although I kind of forgot about debilities: there was a good case where I could have done that instead of a d6, in retrospect.

Use up their resources

I did not do this at all, not through the GM's power over the world. They were in a dark cavern and they used up adventuring supplies as torches, but I never invoked this in response to something they did. Re-reading the move's description, it mentions that the "using up" need not be permanent, the example being a sword flung across the room. That's a good aspect that I had not considered, although thinking back on the story, I'm not sure if there was an opportunity for this or not.

Turn their move back on them

This seems like a good place to use those tricky 7-9 results. I am not sure I did this move explicitly, since I reached almost exclusively for Offer an Opportunity with a Cost. I think perhaps this tells me that I could sometimes make the world simply turn their move, without my having to present them with a dilemma—which, as mentioned, sometimes was hard to come up with when it felt warranted.

Separate them

I did not take this move as part of my actions, but they ended up separated several times due to their own actions. When I was involved, it was part of giving them a choice: you can climb down to safety, but it will put the rest of the party at risk, so do you save your own skin or warn them of the danger?

Give an opportunity that fits a class' ability

Honestly, I was expecting a more stereotypical adventuring party, not a Druid, Ranger, and a Thief. I did not think about this being a move I was taking, although they were able to turn the situation into places where at least the Druid and the Thief could really shine. Maybe if I was quicker on my toes I could have set up situations for the others? It is something for me to consider, though again, I wonder if it would be easier after sleeping on the party composition.

Show a downside to their class, race, or equipment

This did not come up. I love the idea of it, but it never really crossed my mind.

Offer an opportunity, with or without a cost

The idea of "success with a price" is part of what intrigued me about the whole PbtA movement. Maybe I need to actually scale back my use of this move, but I think the players did enjoy all the choices I offered. (At least, it looked like they were enjoying the choices, which were almost all of the "save myself or the party" variety.)

Put someone in a spot

Now that I look at the list, maybe this is more of what I was doing than offering an opportunity? I nee to think more about this taxonomy perhaps.

I should mention that I watched quite a bit of a Dungeon World one-shot on Roll20 that was led by one of the codesigners of the game. I was actually trying to figure out how best to use Roll20 when I watched the video, but it was also enlightening to see how Adam Koebel ran his game. However, because the GM never speaks his move, it's hard to see how he's deploying the rules vs simply improvising. I wonder if anyone has tried, as a sort of qualitative evaluation of a session, to code his actions as moves to see which he is using. I need to hold on to that idea for next time someone asks me to supervise a qualitative games research project.

Tell them requirements or consequences and ask

This is probably the move I should have pulled out when a player failed a roll and I wanted them to succeed anyway. Again, it has shades to me of the other two, and it's not completely obvious to me that I can see that I did or did not blend this with those other two. As such, it's not completely clear to me if it would be valuable for me to disentangle them or not. (But, you know, finding these cases is the point of this reflection, so this is progress.)

Dungeon Moves

I can keep this section short. I didn't really account for the dungeon moves as different from the GM moves. I suppose this points to the fact that I should have had that list of moves front and center to help me navigate my options, or perhaps it points to my having a bit of a linear, pre-built adventure for them instead of something more reactive.

Wrapping up

As I've worked on scheduling and prepping for last night's game, I also found myself wondering whether my kids could play this game. The older ones would do fine, #3 Son might get it, but #4 Son is still pretty young. He could not read his own sheet, and I'm not sure that a 5-year-old's "Yes And" is quite like a 13-year-old's. I'd hate to cut him out, though. I admit, I was kind of shocked to go back and look at the post I mentioned earlier, about the Eye of Clune adventure. That wasn't last year, it was two years ago. The littlest guy did not play with us as he was only three, but #3 Son played, and he was only five. #4 Son played our games of Kapow back in November, but in sort of a made-up sidekick role. Anyway, I'm torn: I like the idea of building a world together, but I'm skeptical of the boys' ability to have it make sense and be fulfilling for everybody. I suppose part of my point here is to say that I was really grateful to be able to play with some adults who were willing to work together on a world and a story without fighting with each other or picking their noses.

That's it for today's blogging. Thanks for checking it out. My next step along these lines is to re-read the chapter on Fronts and try my hand at those. If you have any insights to share about the system, observations about the game, or responses to my reflections, please feel free to leave them in the comments.

Monday, June 29, 2020

Summer Course Revisions 2020: CS315 Game Programming

Earlier today, I wrote about some of the constraints and unknowns I'm dealing with as I move forward with Fall course planning. Here, I want to share a reflection about how I've thought of my Fall 2020 Game Programming course (CS315). The course plan is online, and I welcome you to take a look and let me know what you think.

Godot Engine

The most obvious change is a switch from Unreal Engine to Godot Engine. I have spent a lot of time getting to understand UE4 and how to teach it, and so it was no small decision to make the switch. When we first set up Fall's schedule, my plan was to teach the class in our computer lab with our nice desktop rigs. However, with the shift to online instruction, I have to face the fact that not every student will have equal access to machines that can run UE4. We looked briefly into remote desktop solutions, but that was not possible either.

Godot Engine was a clear runner-up. It is free software, being licensed under the MIT License, and it is multiplatform. The documentation is astoundingly good, and it seems that there's enough people working with it to find good answers to common problems online. It has a small footprint, both in terms of the editor and deployment, and it doesn't take a workhorse desktop machine to get good performance. Indeed, when you look at the actual features my students have used from UE4, they rarely even use what makes that engine so powerful. Godot also publishes to the Web, which is one of the main reasons I've been happy to use it with my family. Its scripting language looks a lot like Python, which our CS majors learn in their introductory course. The node and scene system may at first be surprising to my students, but I am hopeful that I can use to explain concepts of object-oriented design. I think its approach may be like studying Lisp: you may not use it all the time, but it gives you a different way to think about program structure.

Course Project Structure

My intention for the course is that the students start by working through the well-known Dodge the Creeps tutorial before going into a tightly-scaffolded Angry Birds-style project. I struggled a bit with how to scaffold the experience, but I decided to go with weekly submissions with well-defined steps. I think that this series of steps should help students learn what I want them to learn, although I freely acknowledge that this is not the only series of steps that could do so. Most of my students coming into the class have no real game development experience, and so small steps with check-ins is probably worthwhile. It will mean I have to spend more time reading submissions, since each student will submit one per week, but this is mitigated by the use of specifications grading and checklists. I have written before about this combination, indeed sometimes positively and sometimes negatively. Regardless of whether or not a subset of students struggles with conscientious completion of checklists, it is a lot easier for me to verify a checklist than to grade a submission from scratch.

A challenge with this approach arises if a student falls behind. What if a student is content with a C on the first iteration but seeks an A on the second iteration, but their previous work has not set them up for success on the subsequent? At this point, I am going to accept this as a possibility where the answer has to be that they go back and retool the previous increment to support their higher aims. There is a possibility that I could drop reference solutions after each iteration, or ask successful students to share their implementations with their peers, but I think I'm going to go with the more direct, linear approach. There's a lesson within it that is hard for students to learn: your choices when writing software have consequences. Even after CS222, when students always proclaim that they have seen the light, I still see students not building up solid foundations from which to work. Since the project will only last about a month, I think it's OK for there to be some pain around mistakes, since it's the kind of pain that leads to growth, and without too significant of consequences.

My plan on paper is that once we finish the three iterations of Project 1 that you can currently see online, we will have a class discussion or vote about whether they want to have a final iteration that lets them pull all the pieces together, or if they want to jump into a second, 3D project. Until I get to know the students, I don't know which they will prefer. In any case, my plan is that the second project last 2–3 weeks only, so that they can see that 3D is basically 2D but with an extra dimension. I mean, that's literally what it is, though it has a mystique about it. This will then position the students to be able to move into a final project, which I have not yet specified. Right now, I think I will make the final project group-optional, and I expect to give the students plenty of opportunity to give input on how it will be graded.


I am concerned about our ability to form a community of trust and respect without being able to hang out together in the lab. When I teach game programming in the lab, I spend some time doing direct instruction and worked examples, but I moved a lot of that to my game programming playlist on YouTube a while ago. (I have not yet put any Godot Engine content onto that channel, although I expect I will do some in the Fall or later this summer.)

My solution for this class is to award course credit for “community participation,” and to allow students to get these credits in various ways. The simplest and default case that I plan for the course is that, after a major milestone, students will post links to their games and repositories to a discussion board on Canvas. Then, other students will be able to earn community participation credit by reviewing and responding to three other students' projects. I am sure this will be nowhere near as exciting as our showcase days in the lab, but at least it will get students thinking outside of themselves for a bit.

I have written up a few other ways for students to earn these credits as well, drawing in large part upon my experience designing achievements for CS222. As of this writing, these alternatives include: participating in jam; creating a tutorial, blog post, vlog, stream, etc. relevant to course goals; serving in a leadership role in a community or campus organization relevant to course goals; or anything else they pitch that I approve. I'm hopeful that this will help students remember that while they are accountable for their own work, we're all in this together.

The Weekly Schedule

Of course, we will have to roll with the punches in the Fall, but I also need some kind of plan to get started. Right now, that plan looks like this: on Tuesdays, we'll do a live, synchronous meeting that is recorded for those who cannot attend. Here, I'll introduce the project for the week, explaining tricky parts, and perhaps showing the first couple of steps to get moving forward on it. On Thursdays, I'll do a sort of workshop / Q&A session. I am not sure exactly how that will go, but it will give me a chance to address to the whole class any patterns of questions I have seen. Maybe it will be like last semester's optional Zoom meetings in CS222, where I had no sense that students even knew I was there, but I'm hopeful that we can try to make it worthwhile for students to drop in. Unlike CS222, when each team was doing their own projects and could rely on each other, CS315 will have many people working separately toward the same goal, and I think this will mean more incentive to come and talk to each other.

A missing piece here is something like “office hours.” I have essentially given up on traditional office hours for various reasons that will derail this post—including even an argument that they are counter to social justice, believe it or not. I have been inspired though—and emboldened by an article on Medium recently written by my friend Travis Faas—to do some kind of less formal, streamed experience. A student who needs confidential help can always set up a traditional meeting via email, of course. This alternative would be something more like “Pints with Paul” if my students were all over 21, or if we didn't have ridiculous alcohol laws. “Programmin' with Doctor&nbsplG” doesn't have quite the same ring to it, but the idea is that I would be on something like YouTube or Twitch, actually actively working on something. Students could stop in and see what I'm doing, how I work, engage with the process, or ask about something currently happening in class. At that point, I would put my own thing down and we'd work a bit on theirs. I don't know exactly how that would work, but it's an adequate description of where my head is right now.

Over 4000 Words and Counting

I will mention briefly that the projects page for the course right now has over 4000 words and only specifies up through the third iteration of the first project. It contains more direct instruction than would normally put onto such a page, but I need students to be able to work primarily from it rather than from lab interactions with me and with each other. It struck me as I was working on it that I was in a sense writing a short book about Godot Engine project development, including self-evaluation exercises. It makes me wonder whether I can generate any additional value from this effort beyond what will help twenty or so undergraduates in one semester. For example, I could post the link to the course more broadly, or share it Godot Engine discussion boards or something.


Another change to the course plan is that I (finally) have an explicit license included on the page. I regularly fight with students about intellectual property, frustrated in their lack of education in this area despite the ubiquity of digital media. At the same time, my own publicly-shared course plans never really said anything specifically about what I was allowing other people to do with them. There is now a clear statement that the plans are licensed under the Creative Commons Attribution-ShareAlike license. In fact, my original plan was to also include the NonCommercial restriction to the license, but the license selector pointed out that this would mean my work was no longer part of free culture, so I removed that clause.

As always, thanks for reading, and feel free to leave a comment or a question.

Summer Course Revisions 2020: Platforms for Publishing Course Content

I took a little break after completing Flying Leap and then, about two weeks ago, I switched to full-time planning for the Fall semester. I figured that the easiest course to revise would be my game programming course (CS315), and so I started with that. However, as I wrote up my preamble to the actual course content, I realized it was long enough, and coherent enough, to be its own post. So, rather than jump into CS315, I will share with you how I ended up back to web components.

In the first week, I spent a lot of time thinking about how to present information to my students and guide them through a good experience that will likely be online and with some synchronous meetings. Neither of those variables have actually been specified by the university administration, but it is what I expect, given what I know so far. The curious reader may be interested to know that the university seems to be prioritizing the use of in-person meetings for freshmen, while upperclassmen get shifted to online courses. The default stance seems to be that classes will be online and asynchronous, which essentially removes all scheduling restrictions from students. My department (and at least one other) have petitioned to keep the schedules in place, having regular synchronous meetings with students. We expect this to be approved as long as we agree not to make attendance mandatory and to record all sessions for students who need to watch them asynchronously. I'm still not sure exactly what tools I'll use for this, in part because the university is promising some support as well... but again, we don't have official word yet. Even our Canvas pages for Fall are not available yet. So, I move forward with planning, hoping I'm not stumbling into a trap.

I didn't get much real planning done that first week because I spent more time feeling out my options. I discovered a few months ago that my go-to starting place for course sites—the PWA Starter Kit—is no longer under development. The project site recommends using OpenWC instead, so I looked into that. Although I understand web components and lit-html, the other pieces were all new to me. It was not clear if it would be a worthwhile investment in learning or a quagmire, so I wanted to make sure I understood my requirements and the implications of my decisions.

I looked into scripting content directly into Canvas after my friend and Taylor Computer Science professor, Dannie Stanley, pointed out that they have a well-documented Web API. Looking into this, I was also surprised to find that Canvas is free software. I tinkered with it a bit, but I decided it was not for me. I would have to bind too much of the structure of my course to their epistemology, which of course would not fly. I like the idea of being able to write my specifications once and publish them to Canvas, rather than my current approach of maintaining a Web site and then adding slots for submissions on Canvas, but it's not worth the shoehorning that would be required.

I also looked into simply using Markdown for everything and hosting the content on GitHub pages. I actually starting writing up the CS315 course plan this way in order to get a sense for it. It was very fast to write and easy to host and modify, but it broke down once I started thinking about grading. I expected to use specifications grading or digital badges (or both), and this is where my traditional web components approach really shines: I can define the content of this kind of course artifact as data and then write programs that manipulate it into different forms, including HTML+CSS for presentation and Markdown for documentation.

In the end, I decided to buckle down with OpenWC and rebuild my course sites in lit-html and web components using their toolchain. It took a bit of work, but now I have everything set up. Since I was getting my hands dirty, I switched parts of the site over to material web components rather than Polymer, even though there's a big warning on those repositories that says they may change while in development. I am a wild man.

It would be dishonest of me not to mention that I spent an embarrassingly long amount of time trying to get source code highlighted properly on my course pages. I tried highlight.js as well as prism, but both had problems integrating with my toolchain. After many hours of work, I got prism working good enough for the minimal use case... then I abandoned it and just left the code unformatted in a <pre> block. Maybe you've had that happen before, each attempt saying, "This will probably fix it and then I'll be done," and then you finally do fix it after two days of work, and then you say, "This was not worth it. This is not important. Where is my beer?"

The next blog post in this series will talk about the changes I'm making to my CS315 Game Programming course. See you then!