Thursday, April 22, 2021

An unexpected teaching adventure: wrapping up a programming languages course

At the start of the semester, each course in the department had to have a "back-up instructor" designated, just in case the primary instructor fell ill. Usually such cases are handled on an ad hoc basis, but given the global pandemic, the college wanted us to be prepared. Turns out, I was the back-up for Programming Languages, and that professor was rendered unable to finish the course. So, as of last week Thursday, I have taken over two sections of CS431: Programming Languages. 

I am happy to help, although it has taken significant overtime to get stabilized. I now have more than twice as many students than I did before taking over the course, and the original instructor did not leave any plans for moving forward. I taught Programming Languages a few times in grad school, but not since. Naturally, the approach I would have taken, to lead to particular conclusions at the end of the semester, is not the path they took. It feels more like putting together a two-week workshop on the topic rather than wrapping up a semester, except that I am also suddenly in charge of their final exam and final grades.

All that said, over the past week, I have been able to meet my design goals. I put up exercises for Weeks 14 and 15 of the semester, and I designed the final exam. For Week 14, I decided to look at object-orientation, which is covered some in the prerequisite courses but had not yet been revisited in the PL course. In particular, I decided to look at one of the SOLID principles that we don't get to in CS222: Dependency Inversion. The department syllabus includes some objectives dealing with declarative languages and knowledge representation, and so for Week 15, I created an introduction to Prolog. I have always loved Prolog, and it was a treat to get back into it after over a decade away from it.

I decided to release these two weeks of lesson plans under CC BY-SA 4.0, as I have done for my other courses this semester. You can find them at https://github.com/doctor-g/cs431. The final exam is a secret, of course, but it emphasizes the core ideas of these two weeks of activity. Whereas I generally leave my lesson plans on my CS department Web site as an archive, I haven't decided yet if I will keep that repository up indefinitely, migrate it to csweb, or delete it once the semester is over. If you try to follow that link and it's gone, you'll know which route I chose.

Monday, April 12, 2021

The difference a decade makes: Revisiting Morgan's Raid

In summer 2011, my team released Morgan's Raid, an educational game about Indiana's Civil War history. I wrote about it in the early days of this blog, and my post about our use of entity component system architecture remains one of the most visited pages here. The game won the Indiana Historical Society's Outstanding Project Award the year it released, and my collaborator Ronald Morris featured the game in teacher in-service trainings. We wrote papers and a book chapter about it, gave several internal and external presentations, and even adapted it to be playable in Indiana's juvenile detention facility. 

Unfortunately, it has been unplayable for several years. We built the game atop Java Web Start technology, which was deprecated with the release of Java 9 in 2017. Once it became clear that it was beyond the scope of teachers and IT staff to configure machines that would run the game, we took the Web site down, as we did not want to mislead teachers.

Recently, I have been investigating sources of funding to revitalize Morgan's Raid, and I have a few grant proposals currently under review. My evaluation is that the work is beyond the scope of what I can do in an existing course. In fact, I did once have a small section of CS315 many years ago in which the students tried to rewrite the project in Unity, but it was too great a task for them to learn a new engine and understand enough of the original implementation to do the port.

I have spent some time reviewing the original implementation and piecing together how it might be implemented in Godot Engine. I approached it as I did Canning Heroes: Special Edition, but Morgan's Raid is a much more complicated game than Canning Heroes. Also, it was from much longer ago, and I myself don't even have a version of it that I can run, which means I am working from a combination of screenshots, memory, and the original implementation. 

One of first things I noticed from the original implementation is the mess of manually-managed dependencies. The game was programmed using Slick, which was itself built on LWJGL. These required both portable and platform-dependent native dependencies. We also used numerous third-party libraries, particularly from the Apache Commons but also including Guava, EasyMock, and JodaTime. All of these were handled manually within a hand-rolled ant build script. While Maven existed at the time, none of us knew about it; I would not learn about Maven until later projects using PlayN, which required it. These days, my Java projects are all powered by Gradle. This means that if I want to add a dependency, it's a simple matter of tweaking a value in a build script. Looking back at Morgan's Raid reminded me of the reality of "dependency hell" and how good my students have it these days.

The map in Morgan's Raid was represented by 63 512x512 tiles arranged in a 9x7 rectangle. At the time, we had to write the logic to dynamically load only those tiles that were visible so that we would not blow out the client's memory. In my Godot experimentation, I took those original tiles and just loaded them all into the editor at once with no problems. It may also be worth noting that the original implementation was pretty naive. Someone made the whole map in Photoshop by using a paper texture background, and then chopping the large map into these 63 pieces. Much of the map is actually empty aside from this texture. Now, I know it would make a lot more sense to just do that background texturing in-engine with a repeating texture, but we didn't know that at the time. Put another way, it's not just the technology that changed, but my own knowledge and ability to mentor students.

The original implementation used configuration files to specify the locations of the various cities. They are not rendered into the map background but rather overlaid as sprites. All the paths were similarly specified through configuration files, whose data were manually entered based on historic maps and contemporary GPS coordinates. In my demo Godot build, I instead instanced a City scene for each city and just dropped it into the editor. This would have blown the minds of the original Morgan's Raid team, who spent an enormous amount of time transferring data between different representations: if they could just drop a city or draw a path in-editor, our turnaround time would have been much greater.

I remember being very proud of the version control and continuous integration system we set up for Morgan's Raid. The systems administrators got local servers running Mercurial and... something for CI that I cannot remember now. It was my first foray into this kind of devops, and I learned a lot from it. It took a lot of effort from the systems administrators and myself to get this up and running, but now, we can do all of this immediately and for free on GitHub. Like Maven, GitHub also predates our project, but none of us was using it at the time, and it certainly didn't have the de facto standard status that it does now. Indeed, this was back before git had improved its command-line, and I was deep into the Mercurial camp anyway. These days, I can get everyone in a junior-level CS course using continuous integration via GitHub Actions by the second or third week of the semester. 

One of the shortcomings that our research found in the original game is that too many of the mechanics are hidden from the player. There is little feedback to the player about how a choice they are making will impact the future, or how past choices impacted the present. These were intentional decisions made under the reasoning of "fog of war," but our analysis of the game (published in GLS in 2013) showed that this was probably a mistake. I hope that we get a chance not only to re-engineer this game for modern audiences, but also to revisit some of those design decisions. As I recall, we were on the verge of adding the Copperheads and other historically-inspired narrative elements to the game when we had to freeze our features. 

I may continue to tinker with my initial Godot implementation when I find some time during this semester, in hopes that I can then work with a larger team and with dedicated time to complete the effort. This code can be found on GitHub in case anyone wants to take a look, but keep in mind that it's not really set up as a community project, with Issues or any kind of reasonable documentation. 

Saturday, April 10, 2021

Painting Thunderstone Quest Barricades

The Barricades expansion to Thunderstone Quest was released in 2019, and I got my copy from backing the "Back to the Dungeon" Kickstarter campaign. I still remember my surprise at opening the box and finding two miniatures in it. I actually felt a tinge of disappointment: I didn't really want any more minis for this game. They just serve as tokens, but because they are so stylized, it introduces a bit of ludonarrative dissonance that there is no connection between this token and the game. Anyway, I primed these two figures, and then they sat on my painting table for over a year, soaking up positive vibes whenever I looked at them. 

I was going to say that I started them after finishing the Shadowed Paths expansion back in December, but now that I think about it, I think I actually started them before receiving that set. Anyway, the point is that these guys needed to be done, so did finally finish painting them... around December. And then, they sat on my table until today, when I varnished and flocked them. I look forward to putting them into my massive Thunderstone Quest box. (I wrote in my previous painting post about why there's been a big delay in posting any painted minis.)

Enough story—on with the figures!



This is the first one of the two that I painted. Looking over it (you know, for months), I decided it would be fun to try to accent the long robe by doing a warm gradient, and I am happy with how it turned out. The flesh and the pants are similar in tone, and I chose a neutral light grey for the wrappings and scarf so that attention would be drawn to the warm colors. The gold trim and accents I think also help tie it all together. 

Although my other Thunderstone Quest figures are more creatively based, I wasn't very creative with this nor the other one. I just used some basing paste, the mix of flock I used on my Journeys in Middle Earth characters, and some static grass. In retrospect, she would have looked a lot better on something like a desert base: the natural brown and green is an unintended contrast against the rest of the figure.



Here is the other figure, preparing for a heroic downward strike in a manner that I can't help but think this armor could not possibly support. Oh well. I do think the blue, silver, and steel work well together, coupled with the natural brown leather accessories. The color of the satchels pick up his hair and boot colors in a nice way.

A lot of my miniature-painting involves matching colors from game illustrations, but I had to choose my own palettes for these two. I am happy with how both turned out. They were both a bit too small for me to put in the eyes, though, so I decided to leave them with just the shadow of a face rather than dotting in miniscule pupils. 

We played Barricades Mode of Thunderstone Quest just a few times, but we have never desired to go back to it. We always end up either playing a scenario out of the books until the books are done, and then we switch back to Epic mode.

Also, over the past few weeks I have made some improvements and additions to my Thunderstone Quest Randomizer app. Feel free to check it out and let me know what you think. There's a thread about it over on BoardGameGeek, and it's free and open source, so you can check out the repository as well if you're interested.

Painting Runebound: Fall of the Dark Star

When I first saw the Fall of the Dark Star scenario pack for Runebound, I was not impressed. I honestly cannot remember my hesitation, but suffice it to say I did not buy it. Fast forward through the other expansions, dozens of plays with my boys, and rumors that the game will never be reprinted nor receive other expansions, and I ended up buying Fall of the Dark Star on the secondary market. Now, my Runebound Third Edition collection is complete.

Does it matter? Well, not really, but my boys and I played this PvP scenario once so far and really enjoyed it. The other competitive PvE scenarios often end up with an anticlimax, where no one is able to defeat the Big Bad and everyone loses. With Fall of the Dark Star, there will always be a winner. It suffers from the kingmaker problem, where a player who cannot win the game can fairly easily affect who does win, but that's with us: it felt like a big battle royal, which is all we really wanted.

Here is Zyla, the hero (?) from the scenario pack.


I started painting her in November or December, and then she sat on my desk half-completed until today. I had not even picked up my brushes since then. Part of the reason was that the three almost-completed figures on the table were uninspiring. Zyla's sculpt is OK, but I'm finding myself tired of painting the FFG-boardgame-scale miniatures. They look good within the game, but the scale doesn't fit well with other games. When I used Elder Mok as my apprentice in a Frostgrave campaign last Fall, he just looked tiny compared to everyone else, especially the oversized Ajax sorcerer from Massive Darkness, which was my wizard. 

The other reason you haven't seen any painting updates from me is my teaching schedule this semester. My MWF class meets 4-6PM. This means that I get up, make a cup of tea, and am "at work" from around 7:30AM. 4PM feels like quitting time, and in a normal semester, it might be when I'd pull out the paints for an hour's painting before dinner. We're just a few weeks from the end of the semester, and I feel like I still haven't figured out how to manage my work and free time this semester. Maybe it's pandemic fatigue, or maybe I just need to ask not to be assigned such late classes in the future.

Anyway, after a long delay, there's a finished figure. She's very blue and purple. The card art has her holding a green ball of magical energy, which provides some much-needed contrast. The sculpt does not include this, which is sensible, and I did not feel like trying to mold one myself. It leaves her a bit monochromatic, but at least there's some good differences in depth between the near-black, the deep purple, and lighter periwinkle wings. Incidentally, the card art does have her as eyeless with some kind of face mask or helmet on. She's a weird one.

Next painting post should be up soon...