Wednesday 28 January 2015

Meet Code Baby

I'm just about to finish my fourth year as a full time professional commercial software programmer and, a bit after that, my second year as a hobbyist game programmer. The code I have worked on professionally can be summed up as "data and document management solutions" - about as far away as possible from the open-world style game that Asciilands is shaping up to be. Before I start: when I talk about "game programming" in this post, I'm referring to story driven, open-world style games; not highly-systematic or linear games or minigames.

Here's how my professional programming goes:
  1. Client wants to do X and software does not support this action.
  2. X is similar to existing functionality "Y".
  3. Extend Y to allow the user to perform X.
  4. Or add X as a new piece of capability.
  5. Test that X works as expected.
  6. Test that X works when used in unexpected ways.
  7. Document changes made to allow X (lol).
Asciilands programming works more like this:
  1. Friend plays a bit of Asciilands.
  2. Player tries to do something that they can't do.
  3. Player asks why they can't do that (e.g., "Jared, why can't I pick up the frog I just killed and cook it on the fire to recover my health?").
  4. There is no answer; only shame.
  5. Works for hours to make that thing possible.
  6. Make sure all the other systems that work in harmony with the modified feature still work as expected.
  7. It probably doesn't but the new change trumps old stability so make it all fit.
The key difference here is a subtle one and that is the source of the rules and the source of the expectations regarding what rules are in place.
With commercial software, the users have expectations - usually that the software will fit into their "workflow". They have expectations on how certain features will work based on how other software will work but when something isn't supported, there isn't a failed attempt; there is knowledge that that feature isn't supported (e.g., they can't print because there is no print button).

The discovery methods for finding features are totally different in Asciilands. Players try to do things that can be done in real life (like cooking a frog) and the measure of success isn't whether the software is able to support their workflow, rather not in such a specific way as is the case with commercial software. Instead, the player expects that their knowledge of the world will help them discover features of a game. Well, world knowledge and knowledge of existing game tropes.

The point is, my friend didn't want to cook the frog because he felt like he needed to or because he saw in the manual that frogs could be cooked. My friend wanted to cook the frog simply because cooking a frog is possible in the real world.

This is an extraordinary expectation to need to satisfy with code.

See, the unique thing about making a game is that the story needs to make sense in order to be engaging but to be fun, the player needs to be part of telling the story. But hold on...if the player is part of telling the story, what am I writing? What part does software play?


Here's some circles with some words in them to help me make my point. If you're simply telling a story, you don't need to worry yourself with how the person receiving the story thinks the story should go. Their input does not need to be received. You can literally just write your story and your story is complete. Anything you want the audience to see or hear or know about, all you need to do is include it in your story.
Software doesn't work like that. Software is about processing what the user provides. Usually with software the user has a desired outcome and one or two steps of that outcome are difficult to perform without the use of software (e.g., I want to draw a perfect circle). I know how to draw a circle but it's hard. Luckily, software exists that knows all the exact rules behind producing a perfect circle and it accepts my input (dimensions and colours) and it completes that workflow for me.

Games need to strike a balance between the two. Games need to accept input but also force some output (often against the will of the player). A game needs to contain content that many players will never see or handle ideas by players that the developers would never have considered.


During the development of Asciilands, I have come to realise that I am not writing a story with my software, I am writing a story teller.

To achieve what video games can achieve with non-code story telling, you'd need to tell the story verbally and allow the characters to take suggestions from anyone listening. You'd have to change what happens in your story on the fly. You'd have ideas that would be discarded and sometimes you'll have to think quickly to ensure that it all continues to make sense.

Since I won't be having this kind of contact with my audience, I need to program a story teller who can sit on a server and do it for me. This is why I'm creating Asciilands: the Code Baby!


I have to teach the Code Baby how the world works in minute detail so that when it comes time for him to collaborate with the players in creating the story that will be Asciilands, the story will make sense, be highly variable, be engaging and be fun to be a part of.

In my highschool psychology text book there was short section that sticks in my head when I'm working on Asciilands sometimes. It was about how children learn about gravity by playing with blocks. They learn that if you want to stack them high, you need to keep them centered on one-another. Tipping towers fall over after only a few blocks. Also if you take a block from the bottom, the whole tower falls down.

To program an interactive experience that is designed to reflect reality, you need to teach the code about reality in terms every bit as detailed as the lessons those children are learning from their blocks. Because of this, I often feel like Asciilands is a baby to whom I must teach the ways of the world well enough that it can feign an understanding that would convince a player that the world of Asciilands can be engaged with in all the meaningful ways that they might expect based on their interactions with the real world.



The mistakes that the code makes on account of incomplete information is also sometimes almost charmingly child-like. For example, when I was writing the code that handles monetary value of items and trading, I "taught" the code a few basic rules:
  • Items have different that can be added to or reduced depending on the presence of certain properties.
  • Shopkeepers can give you currency for items and can give you items for currency.
  • Shop keepers will charge 30% more currency for items.

Three fairly simply rules about how to value, buy and sell items. There's a fatal flaw in there that surfaced one day that isn't obvious at all. It is this: Suppose you have an item worth 5 gold and it has bad properties on it that reduce its value into negative numbers, it might end up being worth -10 gold. If you sell this time to the shop keeper, you have to pay him to take it. Fine. Buy it back and the markup is applied meaning he'll pay you 13 gold to take it back. This means you can buy and sell the same items to the same shopkeeper to get infinite gold.

See how a simple oversight and get totally out of control? Additional rules needed to be added; rules that we might seem so obvious to us that we don't even know how to articulate them.


Think back to your childhood, when you were learning about the world and think of mistakes you made because of systems you only partially understood. I remember being confused about hearing people say they need money. Any time my mum wanted money, she just went up to the ATM and got more. To me the rules were as simple as this:
  • Money is needed to buy things.
  • If you need more money to buy more things, take some out of the ATM.
It's easy, in the context of the previously described bug, to think of this lack of understanding as a "bug" in my unfinished programming. I needed to learn more about the rules of the world so that I would have a better understanding of these situations. Having that understanding is what allows me to tell meaningful and convincing stories about the world now.

Obviously Code Baby only needs to learn facts about the world that make sense in the world of Asciilands but even that is a huge amount of world rules when you consider that the mere concept of "things being in locations" and "things moving by changing locations" are totally foreign to a computer and need to be taught from the ground up.

The scenario shown in the comics was a true bug however when I was teaching Code Baby how to handle those situations, the lesson looked more like this:

...and that might actually be the largest portion of Asciilands code ever made public.

Last comments:
On the development side of things, here's a brief list of what's been going on:
  • Huge structural changes to the code to make the game centered on the map instead of the player (i.e., the code now sees the player as a resident of the map instead of the map as the place that holds the player). This change is necessary for things like map-continuity and multiplayer.
  • Fine-tuning various aspects of combat.
    • Working out how different damage types will interact (e.g., a frozen enemy will have increased fire resistance and a wet player will have decreased electric resistance).
    • Making sure that different damage types actually support different strategies rather than all being a means to the same end (e.g., frozen enemies get frozen in place which is good for melee but enemies on fire run around setting other things on fire so you might want to stand back).
    • General balancing and working out ways to make it self-balancing without being stupid.
  • SOUND! Asciilands now has sound effects. They're basic and currently only selectively applied but the challenge wasn't adding them in, the challenge was adding them in in a way that makes it easy to add them in for everything.
  • Making logical tweaks to behaviours to just make everything feel more realistic (enemies used to chase you always from any distance. They now wander around aimlessly until they "see" or "hear" you whereupon they'll chase you until you get far enough away that they lose interest. Complexity is the spice of life).
  • Accidentally added a cool new feature to the editor: you can now play test your map without saving it.
    • This happened in the huge structural changes at the top of the list. I guess it's just a consequence of the whole map-continuity thing.
Thanks for reading and stay tuned for more #shitCodeBabySays!
Oh my god, I ate a whole packet of instant pudding while I was writing this entry.