@4onen: Blog

The City Without That Number: Postmortem

4onen

2024-10-02

At the end of this post, you’ll find Appendix A where I have the initial notes I made for my game’s plan. I typed them into my phone while taking a walk the very day the theme for this year’s JS13K was announced. That initial scope was exceptional, planning for far more than I think I’d be able to fit in 13kb even given arbitrary time to work on it. Given that initial exceptional scope, I think it’s no surprise that the game didn’t turn out quite like I’d hoped. The final result, however, did not meet even my scaled-back expectations, despite how I felt about it at 2am the night of submission. Let’s talk about that.

The Game

You can play the game here. This is a postmortem for that game, so I’m assuming you’re at least somewhat aware of what it is. The code of the game is available at my GitHub repository (under GPLv3) and also at the JS13K fork of the repository.

The Good

At submission, the game was genuinely impressive in a number of aspects that I should feel accomplished having achieved. I don’t, due to its flaws, but we’ll get to those. First, the areas of success:

The trouble is, while all of these are nice outcomes, I feel they were overshadowed by some pretty large defects.

The Bad

I made some pretty massive mistakes in this project. It, and I, deserve our negative feedback for these errors.

The Last Minute Change

Let’s start with the big one. At 1:53am CDT, just 4 hours before the competition ended, I looked at what I had and decided, in my infinite wisdom as the developer who made it, that my game wasn’t challenging enough. So I made a one-line change to increase the difficulty from rejecting powers of 13 to rejecting multiples of 13.

// Diff from before and after the last-minute change
        -const can_see = (n) => n != N && n != N * N && n != N * N * N && n != N * N * N * N && n != N * N * N * N * N;
        +const can_see = (n) => n != 0 && n % N != 0;

Astute programmers may already see the error. Yes, my zero check and the && condition are reversed from what they should be: n == 0 || ....

In the submission copy of The City Without That Number, it is impossible to bring any number in stats back to zero after it has been nonzero. This results in cripplingly confusing gameplay and makes some maps utterly worthless for their intended purpose. Two of the most critically impacted are dbl and chkr. On dbl because there is only room for one building and no stories, you can only place one building ever, making learning the bulldozer tool and building rotation impossible. chkr similarly allows 2x2 buildings, but placing one in the only possible space is now a trap, preventing you from using the space to work up your 1x1 count.

Of course, these dead ends lead into a bigger issue.

Goals: What are we doing here?

The first feedback for my game, and what led to me recognizing I had shipped the big bug was:

I do not know how to play your game.

This cannot even slightly be attributed to the big bug. I made a mistake that four and five-year-olds should be growing out of: I forgot the theory of mind. I forgot to remember other people aren’t me and don’t know what I know.

The tutorial levels were designed to be tiny practical examples of the game’s behavior, but I failed to communicate that behavior alongside those examples. I gave no indication of success or failure. To make an outdated reference, I had given them cow tools without comment and had assumed they were obvious.

I had two plans in mind, either of which would have greatly helped, both of which at midnight before submission I had decided were unnecessary luxuries, despite their necessity:

  1. Goals. Literally a function on the stats or city info to tell when a win condition was reached and show a “You win” of some kind in the level select. With these, the tutorials would have at least indicated when their learning content was achieved.

  2. Descriptions. Literally just text describing the purpose of each level. Instead, I left users staring at abbreviations so terse they were questioning even their meaning.

I had assumed, having started in the city building genre, that I could get away with the free-form nature of something like Sim City 4. Surely I wouldn’t need to guide the exploration-driven audience of my title. This assumption completely ignored my pivot from the city sim genre to the puzzle genre.

In short, this was an unacceptable failure of game design. It is also perhaps the purest lesson in how “the users are dumb” is almost never the right response to someone struggling with what you’ve made. I wrote an entire lengthy reply of descriptive instructions to that first feedback, only to then test the game myself and discover my big shipped bug. I did not describe my game well enough for them to know there was a bug, to know why it was not working, and to commiserate with me on the perils of last-minute editing. Their confusion was non-obvious to me because I was the one confused first.

Those two major flaws aside, I still made some other painful mistakes with my project, wasting my already-limited time and effort.

The Ugly

These wouldn’t have sunk the ship, unlike the above, but they certainly contributed to the problem.

The Means

Last of all, some of you may be wondering why, after all this, my submission is 9,965 bytes and not around 12,999. Why not something more reasonable? Why, in all my wisdom, did I take a late project with such mistakes and keep crushing it so small?

Two reasons:

These arbitrary limitations self-justified my big mistake of leaving out goals and descriptions until the very last, letting them get bumped from the game entirely.

The Ends

I clearly made mistakes managing this project. Do I regret submitting it under “Completed”? No. I feel like by getting any harsh feedback to my face, it reinforces the lessons I should be learning from this about project management and design:

All y’all be happy out there. Best of luck in the JS13K grading. (I think we established I don’t need that luck.) And, most of all, have a happy winter 2024.

Appendix A: Original notes for The City Without That Number

# todo.md
        We did it! It's okay! You're safe. Welcome to _The City Without That Number._
        
        Small SimCity-like where nothing is 13 (or any multiple)
        
        * Buildings cannot construct if it would make the total count, or count of the same type, 13
        * Walkable urban environments only -- full streets only for commeecial imports/exports (loading/unloading)
        * Currency: Numberlessens (Short: Lsns. Icon: V)
        * Bulding types:
          * Residential (rand color sides, rand color roof, green yard)
          * Commercial (blue-beige sides, beige-blue roof, white yard
          * Hub (Import/Export) (white sides, black roof)
          * Police (white sides, blue roof)
          * Plaza/Park (stretch)
          * Fire (stretch)
        * Demand Types:
          * Residential
          * Import
          * Commercial
          * Export
        * Terrain:
          * Use a heightmap to determine rendering
            * Hill/Plain
              * Normal square buildings
            * Waterfront (stretch)
              * Roof pins at water surf, raytraces toy visuals:
                * Residential: Dock + Party
                * Commercial: Fishing warf
                * Hub: Tug warf
                * Police: Police dock