Scoping to Learn: Why I Start Things I Can’t Finish

A hard look at reality

When I was working on “Does Canned Rice Dream of a Napkin Heap?”, I wanted (besides making a really cool game) to gain enough skill with Unity and C# that I could move forward on my commercial game project (aka Sunflower, because code names are fun). Now that Canned Rice has shipped (and I’ve recovered from three weeks of illness), I’m orienting on my next goal.

I’m not a strong enough coder to start on the commercial project.

If I hadn’t spent three weeks sick, I might be ready – but I did, and I’m not going to delude myself otherwise. I just didn’t learn enough.

That’s all right! I’ve hit skill barriers before, and I know how I’m going to handle this one.

I’m not going to work on Sunflower yet. Instead, I’m going to start something I can’t finish.

Why avoid working on Sunflower?

With rare exception, the goal of a game dev is to ship games. No one will praise you for your half-written games, no matter how brilliant they may be.

(For example, my Lovecraft-inspired, procedurally generated IF game has languished in the darkness since early 2011. It could be spectacular. It could be flatly terrible! But it didn’t ship, so either way, it doesn’t count.)

But there’s a direct relationship between ability, speed, and quality. If your existing abilities encompass the necessary skill set for a given project, then you can work at top speed while making a minimal number of mistakes. But if your existing abilities do not encompass the necessary skill set, then the quality of your work will be much lower at the beginning than it will at the end.

I believe in continuous learning. I’ve been working in Inform 7 since 2006, and I’m confident enough to write tutorials and provide expert help, but every time I start a new project, I still expect to learn something along the way.

I’ve only been working with C# since October. I expect to learn a lot more from starting a C# project than I do from starting an Inform 7 project.

learning curve graph

Disclaimer: This approximates my personal understanding only, not the typical language learning curve. It was heck of a lot easier for me to learn I7 than C#. (Your mileage may vary.)

I’ve already settled on Unity with C# for Sunflower. If I start working now, I’m going to learn a lot along the way, which means that I’m going to make a lot of mistakes along the way. Since one of my current skill holes centers on software architecture in an object-oriented environment, it’s possible that my mistakes will be unrecoverably severe.

When you’re an indie game dev, especially on a solo project, then you are your own greatest resource. Your personal energy, morale, and health become resources that need to be managed just like your personal finances and schedule.

You know what really hurts morale? Scrapping your entire code base.

Sometimes code bases do need refactoring – and if I have to refactor, then I have to refactor. But I’d rather improve my skills to the point where I get it right the first time – or believe that I can get it right the first time – before I start on Sunflower. It’s a straightforward risk assessment.

What are my actual goals?

I want to build Sunflower, but I don’t have the skills for it yet. Therefore, I need to improve my skill set until I’m ready for Sunflower. Specifically:

  • I want to improve my C#.
  • I want to learn design patterns.
  • I want to improve my software architecture.
  • I want to make mistakes in a safe environment.

You’ll note that Unity isn’t on this list. When I got started in Unity, I began with a foundation of C and then jumped simultaneously to C# and Unity. This was not the best decision because it was difficult to untangle what I needed to learn about C# from what I needed to learn about Unity. I’m going to improve my Unity skills deliberately as well – but I’m tackling C# first.

Why not ship a smaller game as a learning project?

The Canned Rice ship has sailed, but there’s a rainbow of options in between “start the big project” and “ship nothing”. I could start a new project in the Canned Rice size range. Why don’t I ship a series of small practice projects, instead?

Back at Thanksgiving, I stole a few hours away from family to build a version of Conway’s Game of Life in C#. I’m pretty confident in the architecture – but then, it’s easy to be confident when the program only contains two classes (MainClass and Cell).

I could keep going on this program. There are some reasonable features I could add to increase the complexity – for example, I could allow the player to enter an initial configuration rather than seeding the game randomly, and I could add functionality for controlling the game speed. There’s one spot where it iterates unnecessarily through all cells rather than just looking at the cell’s immediate neighbors, and that should be cleaned up for efficiency. I could even create output that isn’t a flickering ASCII monstrosity.

ConwayLife ASCII

But… one reason to work on a larger, unshippable project is that I’m trying to improve as a software architect. Any C# project will help me learn more about software architecture, but architecting a small program is significantly different than architecting a large one, rather like painting miniatures differs from painting murals. It will be most useful for my future purposes if I’m working on a project that is as large or larger than Sunflower.

Another factor to consider: if I commit to shipping a project, then I commit to shipping a project. At that point, I have to care about the user experience, which means things like tutorials and UI polish and efficiency are no longer optional. At that point, the ninety-ninety rule comes into play:

“The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.” – Tom Cargill

No game project is ever the size you expect it to be. Shipping a game project involves not only design, writing, code, art, and sound, but layer upon layer of QA testing, playtesting, design refinement, bugfixing, and polish. In a situation where I’m shipping a project, I’m going to take those steps, and a month-long practice project is likely to spiral out of control into two or three months – and that means I’m spending a lot of time on things that aren’t related to my C# goals.

dragon comparison

This art change is from the only time I redid significant work during a game jam. Halfway through Clockwork Dragons, I ditched the snaky dragons on top for the cuter dragons on the bottom.

Theoretically, I could avoid those layers of refinement and polish by joining a time-limited game jam, since no one expects game jam results to be sparkle with polish. But by their nature, game jams favor fast work and rapid results over care, consideration, and elegance, which is antithetical to the kind of learning I’m trying to do.

Once I’m satisfied with my C# progress and turn my attention to Unity, shipping a smaller project is a great plan. My priorities are different with Unity – focusing on polish will force me to concentrate on things that I need to improve, rather than drawing me away from the things I want to improve. But for now, the plan is…

Dreaming the impossible dream

Arguably, I could be hammering on tutorials instead of working on a throw-away project. However…

Impossible dreams are fun.

Like most people, I learn best when I’m having fun. If I hit a comprehension block and the problem is I need to learn this, it’s important, but it isn’t much fun. By contrast, if the problem is I can’t do the cool thing I want because it’s on the other side of this comprehension block, then I’m much more motivated.

Basically, I’m managing my own enjoyment for practical purposes. It’s like being the evil overlord living in my own skull.

This isn’t the first time I’ve worked on an impossible project for professional development purposes.

I spent the summer of 2013 working on a

  • procedurally generated,
  • infinitely large,
  • noncombat
  • roguelike
  • with dynamically generated text descriptions.

(As an elevator pitch, that really lacks something. I can barely read it without the bullet points.)

I called it Wanderland. I wrote it in C, and I started out by opening Head First C to chapter 1.

Because of Wanderland’s sheer scope, I always knew that I would never complete the project. (It was sort of like setting out to make Dwarf Fortress from scratch, and I am no Tarn Adams.) I worked on it for twelve weeks, and I refactored every system in the game repeatedly as I figured out better ways to accomplish them. When I showed off my proof of concept at Gameloop 2013, the end result had much of the necessary infrastructure, and virtually none of the structure to go on top of it.

wanderland 1

wanderland 3

wanderland 2

Also, the UI was lacking something. It’s a theme.

Working on Wanderland gave me direction in my learning. Seeing Wanderland grow gave me confidence that I was succeeding. And knowing that it was always too large for completion gave me the ability to throw it away.

I’ve looked at my options. I’ve considered the possibilities. I’ve decided to do it again.

So… what’s the new project?

It’s a text-based, multiplayer game called Greetings, Survivors. It’s a post-apocalyptic dystopian game with a weird sense of humor.

Also robots. Many robots.

I’ll tell you more later.

Hey… don’t you have an overdue Inform 7 tutorial?

Sure do! Everything you want to know about dwarves in Colossal Cave (or the quick-start version, at least) will be along later this week. Promise.

Bookmark the permalink.

4 Comments

  1. I spent the summer of 2013 working on a

    procedurally generated,
    infinitely large,
    noncombat
    roguelike
    with dynamically generated text descriptions.

    WANT. WANT SO MUCH. MUST HAVE. *sob*

    Seriously, how did you find it was working with dynamic text descriptions in C? I can’t imagine doing something like this without Inform 7’s nice substitutions and phrase calls — also I don’t know anything besides Inform 7 — but there are things I’d like to do with text generation that might not be nicely shovable into the Inform 7 box. So I’m wondering about other frameworks to do similar stuff in, although C seems really intimidating.

    Also, I really want that. Are you sure no one is going to praise you for your half-written games? I’ll do it! And it worked for Crowther too!

    • I stand corrected. Someone has praised me for my half-written game! (How unexpected.)

      For the most part, the string manipulation wasn’t too bad. I broke the string manipulation into many separate functions and called them sequentially from inside a larger function, kind of like I would have done in I7 with “to say” rules.

      The obnoxious part of string manipulation was allocating all the memory. “I want a new string” isn’t adequate – you need to define exactly how big the string should be beforehand. (Ditto new rooms, new items, new NPCs, etc, etc)

      I also spent a whole lot of time (and typing) flowing down the lines of connection. Generally speaking, I was only passing one object around from function to function, and it was the PC. From the PC, I could trace almost anywhere I needed – but that meant I kept running down these giant chains like PC->room->item->name in order to show what was in the room (and that particular example only finds the first item on the ground!)

      C is also really not pleasant when things go wrong. If you try to access the nothing object in Inform 7, you get a “hey stop that” error message, but your game continues. If you try to access a null in C, you get a seg fault and then your project crashes without even a function name and line number to tell you where it was. If you’re working heavily with random numbers, this means a whole lot of salting the code with debug markers and then a whole lot of running the code over and over to try to re-trigger those exact crash circumstances.

      So… given the choice, I wouldn’t start Wanderland a second time in C. I’m glad I learned C, and it was an important foundation for my understanding – but shifting to a higher-level language (something like C#, Java, or Python) would save a whole lot of time and headache.

      • Thanks for the info! Sounds like it’s the sort of thing that might be worth (for me) prototyping in Inform and then transferring over to one-a-them higher-order languages if I don’t need most of the Inform stuff–does Python require memory allocation? Of course I’d have to learn Python, and also get around to prototyping something in Inform.

        • I’ve never learned Python – but I do know Python has automatic memory management, so you don’t have to allocate memory or free it by hand.

          You do have to create your own objects by hand though… assuming they’re there and attempting to act on them won’t autocreate them. (As opposed to the lovely Inform construction of “The President is a person in West Wing.” Man, Inform makes so many things easy!)

Leave a Reply to Carolyn VanEseltine Cancel reply

Your email address will not be published. Required fields are marked *