Friday, April 28, 2023

What we learned in CS222: Spring 2023 edition

Today was the last day for me to talk to my CS222 class. Monday's class will be their final presentations back to me. As part of my wrap-up, I kept my tradition of having the students make a list of what they learned and then voting on the things that are the most important to them. This year's CS222 class came up with 99 items in 15 minutes. I gave each of then six stickers for voting. The winners are:

  • TDD (6)
  • Version Control (6)
  • Clean Code (5)
  • Red-Green Refactor (5)
  • git & GitHub (4)
One could argue that there are two pairs in that list that are essentially equivalent. There was only one item with four votes and many with three, though, and so this was a convenient place to draw the line.

For the deeply curious (or future self who wishes access to these data for research purposes), here's the complete list of items the students came up with and their vote totals. 
  • TDD (6)
  • Version Control (6)
  • Mob Programming
  • CRC Cards
  • Meaningful Iterations
  • Model-view separation (2)
  • Dart (1)
  • Flutter (2)
  • Studio
  • Clean Code (5)
  • Teamwork
  • Agile
  • SRP (2)
  • Prioritization
  • Google is your Friend (1)
  • Stack Overflow (2)
  • Defensive Programming (2)
  • OOP (1)
  • APIs (1)
  • Legibility
  • git & GitHub (4)
  • UI stuff (1)
  • Branch management (1)
  • Time management (1)
  • Error correction
  • Data modeling
  • Diagnosing
  • Debugging (1)
  • Breakpoints (2)
  • Refactoring
  • Accountability
  • Hot keys
  • User stories (1)
  • SMART
  • Product delivery (1)
  • Finding packages
  • Researching over invention (1)
  • Human success & failure modes
  • Change notifier
  • Enumerated types
  • Acceptance testing (3)
  • Red Green Refactor (5)
  • Conditions of Satisfaction (1)
  • Humble view
  • Essay formatting
  • Experimental code (2)
  • Learning tests (3)
  • Production code
  • When are we done?
  • Human interaction (1)
  • Generalization
  • Class work vs career work
  • Design thinking (1)
  • Formatting
  • Take a break and come back
  • Fonts
  • Utilizing professor's feedback
  • Async
  • Work distribution
  • Managing state (3)
  • Widgets
  • DRY (2)
  • Scaffolding in UI Design
  • Mobile vs Desktop views
  • Releases (e.g. EXEs)
  • GitHub Actions (2)
  • Tagged releases
  • Commit messages (1)
  • Merging vs Rebasing
  • Lifetime Learning
  • Test coverage
  • Format on Save (1)
  • Rollbacks
  • Feature branches
  • Shelving (2)
  • Commit conventions
  • JSON data
  • Switch
  • gitignore (2)
  • Key management
  • Presentations
  • Null safety
  • Futures
  • pubspec.yaml
  • Minimizing state
  • "late" variables
  • Flutter template
  • Pop
  • Prepping for internship
  • Professionalism
  • Resume crafting
  • Separating classes
  • Android manifests
  • Overflow boxes
  • Team communication tactics (1)
  • Public accessibility / licensing
  • Group discussion (3)
  • Teaching a lesson
  • README files (1)

Tuesday, April 25, 2023

Encouraging the study of writing for aspiring Computer Science students

I was on a game developer's Discord channel the other day, and a guest posted an off-topic but important question: as a graduating high school student looking to get into a Computer Science degree program, what should I plan to study? I think the author had "hot topics" in mind, and the short discussion covered a few of these. I replied that they should plan to study writing:

Writing. It's not hot or new, but it is a killer skill and underappreciated in CS education and maybe higher education generally. Learn to formulate your thoughts clearly and articulate them well, and many doors open up to you.

This raised some eyebrows, particularly given the popularity of ChatGPT. I had a few minutes on Sunday morning to start fleshing out a reply to the curious and the skeptics.

When anyone can generate text, all the more reason to learn how to write (compose). It's hard not to fall into traps of semantics, so I will quickly explain.

Writing is fundamentally long-form thinking. You are limited in your memory of what you can process, so writing increases the quantity of what you can consider. This has nothing to do with text generation. Indeed, generated text has the illusion of thinking only because it was trained on content that required thinking. (Including the content of me and countless writers whose work is copyrighted and was taken without our permission, but I digress.) 

Let's look at the essay as an exemplar. "Essay" is one of those words that has been destroyed by many modern school systems, but it comes from a root word that means "an attempt." That is, an essay is an attempt to understand something. Given that, look again at one of the classic forms of essays: form a hypothesis, come up with a handful of ways to support it, consider the strongest arguments against it, conclude for or against it. Turn each of those into a paragraph. Don't forget counterarguments--that might be the best part. The outcome of this is not just transmission of something in your head. The outcome of this is that you are now smarter, and so can the reader become. 

Personally, I recommend the old editions of Strunk's Elements of Style as a starting place--the old, public domain ones. They are fun to read. The advice is timeless, and the specific examples of what people got wrong in written English 100 years ago are really funny: some are things we've never heard of today, and some are mistakes people still make. 

On the philosophical side, I recommend Orwell's "Politics and the English Language," which includes some of the best writing advice I've ever found.

This was when I realized I was running into the character limit and running out of time, so I stopped there. I am copying the text here not because it's an unassailable defense of the liberal arts but because I hope it helps someone, and maybe I can find it again later if I need it.

Addendum: The person who posted the original question thanked me for the reply, stating that they were curious about my own writing. That's when I showed my hand and admitted that I am, in fact, a Computer Science Professor.

Tuesday, April 18, 2023

Summer Course Revisions (in Spring?): CS315 Introduction to Game Programming

I'm pretty sure I've never done a "Summer course revision" this early in the year, but I recently had a radical idea: what if I did my job while I'm getting paid instead of when I'm not? Sorry, I don't mean to be too cynical. In fact, I am grateful. I have an opportunity right now to do some of the work that I'd normally have to push off until summer. 

The danger of doing any kind of course planning this early is that teaching assignments can still be shuffled around. Right now, I am scheduled to teach one of my favorite courses: CS315 Introduction to Game Programming. Reviewing my notes from last year's class... it turns out, it was pretty good. The changes I want to make are minor, and I think I can mostly take last year's plans and repeat them. One of the big differences is the release of Godot 4.0, which means I will either have to recreate some videos or link to them with caveats.

The course plan is already up, and I have the first four weeks of projects revealed. The following weeks should be similar to the previous year's class, but I don't like to have all of that open at once. This policy gives me a chance to plan ahead while also having the opportunity to get to know my students and see where their interests lie.

As a result, there's really not much of a post here. This post is mostly here so that if I later check to see when I worked on planning Fall's CS315 class, I'll find this.

Monday, April 17, 2023

Configuring a Flutter Web App for Continuous Integration using GitHub Pages

GitHub Actions lets you build and deploy a Flutter Web app directly onto GitHub Pages. However, if you do this in the naïve way, it won't work properly because the base href for the app will be wrong. You need to give the repository name as the base href in order for the built site to work. Here's a configuration file that will work out of the box.

name: Continuous Integration

on:
  workflow_dispatch:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - uses: subosito/flutter-action@v2
        with:
          channel: 'stable'

      - name: Download Dependencies
        run: flutter pub get

      - name: Run Unit Tests
        run: flutter test

      - name: Build
        run: flutter build web --base-href='/${{github.event.repository.name}}/'

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./build/web
          force_orphan: true
          user_name: 'github-ci[bot]'
          user_email: 'github-actions[bot]@users.noreply.github.com'
          commit_message: 'Publish to gh-pages'

The workflow-dispatch is optional. It gives you the option to click a button on the Actions page of your repository to force a build rather than waiting for a push. 

Friday, April 14, 2023

It tolls for thee

On Thursday, I had the opportunity to visit a high school and talk to some students about Computer Science. I brought two of my own students with me. We arrived early so that we could get signed in and set up. As we were getting oriented in our room, there was a piercing monotone played over the PA system. We all assumed that this was the "bell" to change classes, and one of our hosts confirmed that this was true. A few minutes later, the PA played an alternating pitch, a series of tones akin to an ambulance. Indeed, it sounded like an alarm. One of my students started from her seat, and the three of us looked up at each other. Seeing that our host was unperturbed, we asked what that sound indicated. He told us that it was a warning that class-change time was half over.

The school played a terrifying sound over the loudspeaker, and no one was terrified but us.

School seems to be working.

Wednesday, April 12, 2023

Notes from the Inaugural Game Preproduction Class: Draft Schedules

 Last week, my teams presented their draft macro charts. This week, they presented their draft schedules. All of the teams made good progress here. I showed them how to use pivot tables to figure out how many hours they had for each priority level; they could use this for task assignment as well, but none of them had yet gotten into the level of detail required. We had some useful conversations about the relative merits of pairing or mobbing on some tasks while parallelizing others.

One of the groups included four formal playtesting sessions, not for validation of any particular feature but for general feedback. The other two groups recognized that this is valuable for scheduling. This led us to a discussion about the kinds of things that take time that were not yet in their schedules. These are the categories we identified:

  • Creating a store presence
  • Playtesting
  • Organization and administration
  • Release engineering
  • Community building
  • Legal / Business / Tax
  • Marketing (posters, handouts, YouTube, release party, shirts)
  • Convention travel
  • Dealing with contractors
I look forward to see how the students incorporate these into their final schedules. As they work on their schedules, their macros, and their vertical slices, I think they are really coming to understand how many different pieces need to come together for this to work.

As we were wrapping up, one of the students commented that, although he is quite fond of his project, he thinks our best bet would be to kill two of them and all work on one. I consider this a good result, as the student is seeing how much work even one of these projects will require.

Thursday, April 6, 2023

Notes from the Inaugural Game Preproduction Class: Draft Macro Documents and Charts

My three teams presented drafts of their game macro documents and macro charts today. I am glad that I devoted a day to this. Each team made reasonable progress on the documents, and our discussion highlighted places for them to improve.

One of the groups had shown a draft macro chart earlier in the semester, and they had a lot of ideas contained in each row, essentially one level per row. I advised them to break these down into gameplay beats or player experience beats. The one that this team showed today had much better decomposition of ideas. I am grateful that they showed that early draft since it meant that the whole team could see how much better the newer version was.

I asked the students to compare the macro document and the macro chart and whether one of them drove the other. The one respondent mention that he felt that the two complemented each other, that they worked together. My inclination is to think he is right, and I presume the rest of the class felt the same way despite not speaking up. I still have no personal experience with macro charts, and I'm torn between those and one-page design documents for potential exploration in my personal work.

One of the teams covered their title screen as being part of the macro chart, but an aspect that all of them missed was the concept of fail states. That is, all of them treated their draft of the macro chart as a "happy path story." I urged them to also think about what happens with the player loses or fails so that they do not miss requirements in the draft schedule, which is due at our next meeting. The students pointed out that Lemarchand does not address death or failure in his macro chart, and so they weren't sure how to do it. I suggested that simply breaking down the chart into headings, like "Narrative Path" and "Fail States" might do it. I will be interested to see how they decide to handle these cases.

Another fruitful conversation arose around the linking between rows. In a few cases, students talked about how there was a narrative connection between chronological experiences, but these were not represented in the chart. This was a good opportunity to point out that this is what the chart was actually for: to express these linkages clearly at the macro level. This dovetailed into a good though short discussion of macro vs micro design, and also to one student's frustration at not feeling confident in making design decisions. Once again, this discussion pulled into the value of these charts: that the chart makes you face these decisions, and it's a low-stakes way to figure out your scope before you even start worrying about scheduling the production of individual assets.

Tuesday, April 4, 2023

The studio that proposed a quiz

My game studio preproduction class (CS390) is reading Richard Lemarchand's Playful Production Process, and I think it has been a good fit. This same semester, my other studio class (CS490) is working on an Immersive Learning project in collaboration with Minnetrista. This latter group has been struggling with the "Validation" column on our task board and particularly how it relates to playtesting. Many weeks ago, I copied chapter 12 from Lemarchand's book for the CS490 class in order to help them. I referenced it a few times in conversation but did not get a strong sense of traction from it. During the retrospective meeting at the end of the last iteration, it became clear that the students still did not understand playtesting and did not read the chapter I gave them. Funny how that works.

The way I structure the retrospective meeting is that, as we walk through the board of sticky notes, anyone can bring up potential action items. These are tracked on a side board. At the end of the meeting, individuals can champion items from this list, and then the team decides whether or not to invest team effort into making the corresponding change to our methodology.

When it became clear that no one done the reading, there was an awkward pause, and I suggested to our volunteer scribe that I could give the team a quiz about the reading. There was some nervous laughter from the students, but I reminded them that we were not committing to anything yet, and that this was actually a helpful way to put some weight behind the expectations to read this chapter in an otherwise completely project-oriented class. Someone (and I cannot remember if it was I or a student) then added the idea of a structured discussion group around the chapter, which serves the same goal but is a bit less hamfisted.

With the sticky notes all read, we moved into the discussion of the potential action items. I was surprised that a student raised her hand and said, "I think we should have a quiz on the reading." That turned some heads! Her argument was basically the same as mine: it is actually important, and if we put a grade on it, she--and others--will be motivated to do the work. I took a straw poll to see who would be interested in this, and it was only her. I applaud her honest self-evaluation here, even if the rest of the team didn't want to go that direction. However, right afterward, we agreed to set up a structured discussion around the reading, so the first student's momentum was definitely not lost.

A series of unrelated events have me thinking again about the Socratic method, and I decided that this would be an interesting way to approach the discussion of the reading. I asked each of the students to bring either three good questions about the reading or two good questions and a good observation about it. I gave a brief explanation of what I meant by "good," pointing out that the questions should be open-ended, thought-provoking, and designed to move us toward better understanding and improved practices.

When it came time for the discussion, I asked the students to sit in a circle. My plan was to have them toss Cosmo the Space Monkey from speaker to speaker, but when I picked up Cosmo, I realized that his shiny jacket was badly shedding glitter. We ended up tossing Anzen the Safety Pig around instead. I did not have a good method for choosing who would start, so I asked them to pick a number, and the first person to guess became our first speaker. (More specifically, I asked for a number between one and 8 bazillion. A student guessed 58,412 (or something), and I told her she was right. Another student sighed and said, "I was going to guess 14." I told them that they were also right.)

I took many pages of notes, summarizing each question and each response that came up. Having them speak one at a time certainly helped my ability to keep notes. The first question may have been my favorite one since it got into a specific and important part of the reading: is the system image (how the game presents itself) of the game close to your image [designer's model] of the game or something else, and why? These are powerful concepts from the text, and I was disappointed that the discussion immediately turned away from the text and toward an undisciplined sharing of perspectives that were not clearly related to the reading. This was followed by a comparatively meager question of whether we should set aside time for playtesting. The answer, which the was the first response from the team and which you and I both know already, is yes. 

After a few questions, I noticed that the same people kept speaking, so I wrote "Pig equity" on the whiteboard without saying a word. Most of the students certainly noticed this, but I didn't see any change in who was speaking. The team seemed to already lay the groundwork that whoever wanted to speak would get the pig rather than what I preferred, which is whomever has the pig decides who should have it next.

Most of the questions had a practical bent, such as, "How do we deal with the awkwardness of staring at people while they play?" A few struck me as real, intellectual attempts to understand the concepts in the reading, such as, "The reading suggests that grumbling about playtesting can be good for a team as long as it is controlled and short-lived. Would this be good for us?" There were a few disappointing questions that unfocused the discussion and moved people toward armchair philosophy, but in a few cases, the students themselves were able to draw conversation back to the text.

This whole time, I was seated in a corner taking notes. A friend in classical education told me that, during such discussions, he likes to walk around the circle, peek in at questions on students' papers, and use these and gentle nudging to help shape the conversation. Ours was not overly chaotic, but I do wish I had set up the room to permit me to do a bit more of this shaping.

I told the students at the beginning that we'd timebox the discussion to half an hour, and I was faced with incredulity. I set the timer for 25 minutes, and at the end, I felt like we could have kept going fruitfully. It was not entirely clear to me that all the students recognized this. Yes, they had had a discussion, but they had not actually made any decisions. That is, despite facing questions like, "Where are we going to conduct testing?" no one actually did anything about it. I wonder if they were trapped by the pattern that most of their classroom discussion has been completely unproductive, as if the talking itself is the goal rather than the discovery of truth and appropriate action taken thereupon. Generally speaking, though, this group, despite its strengths, has shown that it has challenges perceiving opportunities for fruitful action. That is, it is not that they are avoiding activity but that they don't see the opportunity for it. Indeed, this is reflected in the validation problem that gave rise to the need for a discussion group in the first place. Since the beginning of the semester, I have told them that validation is context-dependent: there is no one way to validate tasks, but instead, we have to think about how we really know whether any particular thing is done. We make small steps toward better understanding, but I am still trying to think of ways to help this team see and then seize these opportunities.