Zovirl Industries

Mark Ivey’s weblog

Triple Town Economics (How to Never Run Out of Turns)

When I first started playing Triple Town I was annoyed that I kept running out of turns. It felt like the kind of dirty trick a Facebook game would play. Actually, I just wasn't good at the game. It is possible to earn enough coins from each game to pay for your next game. It also makes the game more fun: instead of bears being troublesome creatures messing up your high score, they are profitable resources to be exploited.

Ironically, now that I don't need unlimited turns I bought them anyway because I want the other game modes.

The economics

  1. Turns cost between 0 and 4.75 coins/turn, depending on how much play per day (because you get 150 free turns per day). Example: 150 free turns plus buying turns twice: 550 turns for 1900 coins, or 3.45 coins/turn.
  2. You get paid 1 coin per turn (at the end of the game). You also get paid based on your city's rank, but I'm not sure what the formula is so I don't worry about it.
  3. Mansions pay 100 coins each (at end of game). Castles pay 200 coins, but require 3 mansions, so it is better to just keep the mansions.
  4. Treasure chests pay 500 coins.

For the example 550 turn game, you need to make 1900 coins total. You'll get 550 coins (#2 above). If you can get 3 treasure chests, you made a small profit. Or if you get 2 treasure chests and 4 mansions, you also come out ahead.

Further Nuances

  1. It takes 27 bears to get a treasure chest (bears -> churches -> cathedrals -> treasure), so a correctly-placed bear is worth 18.5 coins.
  2. A crystal used to combine two cathedrals to get a treasure chest is worth 167 coins (1/3rd of 500)
  3. A crystal used to combine two houses to get a mansion is worth 33 coins (1/3rd of 100)
  4. Using crystals & robots to make rocks -> big rocks -> treasure chest requires 7 crystals and 1 robot. 71 coins per crystal. You're better off using crystals to combine cathedrals, except...
  5. At the start of the game you get lots of crystals and sometimes start with a couple rocks. If you get crystals before you have anything useful to combine, the rock -> treasure route is reasonable. This can be a quick way to pick up 500 coins at the start of a game.
  6. All those crystals at the start of the game also mean the early game is more profitable. Once the crystals stop coming and the map is filling up with ninja bears, it is time to scrap the city and start a new one.

(I play the Android version of Triple Town. I don't know if the iOS, web, or kindle versions have different economics, but you could do the same analysis).

Alpha in WebGL and Canvas

I've been learning WebGL and have been confused how alpha blending works. Coming from working with the 2D <canvas> API, the WebGL behavior was was surprising to me.

(This post uses some recent HTML5 features which won't show up properly in older browsers or IE. I know Chome and Firefox will show it correctly).

The Problem

The demo below uses WebGL to draw white, gray, and black triangles in a range of alpha values, all with the standard gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA). The results are weird. For example, why does the row of black triangles get lighter than the background as alpha decreases? If you change the background to be almost-but-not-quite white, why do the white triangles stop fading entirely?

For reference, here's a version done using the canvas API which behaves as expected and clearly shows the differences in alpha behavior between canvas and WebGL:

The Answer

As I learned from Gregg Tavares, the answer to the puzzle is that WebGL blends the alpha channel differently than canvas does. Using the standard gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA), WebGL's blending equation for alpha is:

A = Asrc * Asrc + Adest * (1 - Asrc)

If you start with an opaque buffer and render a semi-transparent polygon, the result is that the buffer is now semi-transparent (A = .5 * .5 + 1 * (1 - .5) = .75).

This transparency allows the white background of the page to show through and blend with the WebGL colors. Putting text behind the WebGL canvas makes this obvious:

Gregg details several ways to address this, including using { alpha: false } when requesting the context:

Game Marketing Tips From GDC

I gleaned some game marketing tips from several talks at GDC this year.

Tom Francis (Gunpoint) described how to explain games in writing, while Kert Gartner showed how to make good trailers for games. The techniques are quite similar since both require efficient communication. Taken together, these two talks were filled with great advice for telling people about your game. Also, Nathan Vella (Sword & Sworcery) explained how they used consistent PR to communicate the spirit of their game to potential players.

How to Explain Your Game in Writing

Tom Francis talked about explaining a game to impatient readers. Keep the explanation short, about 3 sentences, by means of ruthless editing. Do not make these common mistakes, they waste words:

  1. Failing to explain things. Don't post a gameplay video with no commentary and hope viewers understand. They won't.
  2. Explaining artistic intent. It doesn't explain why I would want to play your game. It also uses too many words.
  3. Explaining story. A compelling explanation of your games story takes too many words. Skip it.
  4. Saying it is "innovative" or "awesome." These words mean nothing coming from the creator of the game.

Instead, you need to fit these 4 things in 3 sentences:

  1. Type of game. Just a few words. 2D platformer. Racing game with RPG elements.
  2. Coolest unique thing. Rewind time to fix mistakes. Tear down and rebuild the entire world.
  3. The fantasy. Not story, that takes too many words. Just the fantasy: You're a criminal driving around a sprawling city. You're searching for your sister in a creepy forest.
  4. Give one example of the gameplay. You fly your helicopter up the river bed, staying behind the trees to avoid detection, then sneak over the ridge to drop the commandos off at the enemy base. You drive your moped up the stairs, through the shopping mall, then jump over the embankment to get away.

Focusing on efficient communication makes it more likely you'll get your point across before the reader loses interest. Tom has posted his talk here.

How to make a good trailer

Kert Gartner explained how to make good trailers for games. Similar to Tom's points about terse writing, Kert stressed the importance of keeping the trailer short.

Don't:

  1. Make it longer than 60-90 seconds. Most viewers won't watch that long
  2. Try to explain everything.
  3. Cram too much information in.
  4. List features of your game. This is boring and not a good use of precious time.
  5. Release a bad trailer. You'd be better off with no trailer.

Do:

  1. Make sure the first 5-10 seconds capture attention.
  2. Use a simple dramatic story arc. A clear beginning/middle/end structure which builds to a climax is good.
  3. Show what the game is about.
  4. Capture the style or feel of the game.
  5. Use zoom-in to focus on the important parts of busy/complex gameplay footage.
  6. Use slow-motion to help the viewer catch important parts of fast gameplay footage.
  7. Leave the viewer wanting more.

He showed several example trailers with a detailed explanation of the techniques going into each one. It would be worth going over to his blog to see the examples.

How to Keep Your PR Consistent

Nathan Vella talked about PR for Sword & Sworcery. I was impressed by how much they focused on consistency and on getting the feel & spirit of their game into their PR material.

Nathan had a couple tricks for making sure the vision for the game is communicated in the PR. First, base the PR on the vision for the game instead of the game itself. If you base the PR on the game, the vision will be watered down. It is ok to reference the game, obviously, but make sure the PR is being influenced by the vision. Second, make sure that the person who is in charge of the vision for the game is involved in the PR directly. Ideally you want your PR and your game to feel like part of the same whole. Example: gameplay in Sworcery is tied to phases of the moon, and they kept this same astronomical spirit by doing sales of the game around the solstice.

There was also the mechanical side of consistency: use the same fonts in your game and your PR material. Use the same color palettes. Use the same sound effects. Maintain a common voice between your game and your PR (and make sure all your PR uses a common voice, especially if multiple people are involved in producing it).

You can see some of this consistency in action over at the Sword & Sworcery website, where they talk about "electric computers" and the soundtrack being available on vinyl & audio cassette and where they label their search box "What do you seek?". It feels like their website came from the same weird world that Sworcery is set in.

Artisan Games

I like the idea of approaching game development as an artisan baker would approach making bread or the way a craftsman would approach making a piece of fine furniture. Making unique, high-quality products for a discerning audience. Artisan games.

There were a couple talks at GDC this year that reminded me about this, especially Nathan Vella's talk on how they making Sword & Sworcery stand out by taking taking risks, targeting a niche audience, and keeping quality high.

Unique Games

Nathan started with the business reason for making a game which stands out: There are so many games out there, it is easy for your game to blend into a sea of similar games. Making a game which stands out is a big step towards success. I also have a personal reason: I want to make something new, something unique. Games take so much time to make that I don't want to be making games that have already been done.

Making a game that doesn't stand out is straightforward: just follow convention. Do what other games do. Each game platform has a set of common trends that you can follow. Making a game for iOS? Use cartoon graphics, one or two simple mechanics, and keep the game short. Making a Facebook game? Have an energy mechanic to encourage players to return tomorrow, use asyncronous multiplayer, and nudge the player to invite their friends. If you always take the "safe" option when faced with a business choice, your game will probably blend in. If you want to stand out, you're going to have to start breaking conventions, ignoring trends, and taking risks. Nathan kept coming back to the idea of taking risks throughout his talk.

Amir Rao (Bastion) spoke during the failure workshop and mentioned a great safety net to use when making a risky game:

  1. Ask "What's been done?" Find the conventions.
  2. Do something else, something new.
  3. If #2 fails, fall back to the conventions you identified in #1.

Falling back to convention sounds like a great way to make progress if the risky innovation doesn't pan out. On Bastion they ditched a gardening mechanic that wasn't working but their game still stands out because they bucked trends in other areas of the game. You don't have to innovate on every aspect of your game to have it stand out. It is ok to stick to conventions in some areas.

Discerning Audience

Nathan specifically warned against trying to make a game with broad appeal. Yes, the payoff is huge but there's also stiff competition. He compared it to a lottery. Instead, Nathan suggested going after a niche. This lets you target your game specifically to your audience. You will be able to know your customers and know what they want. You're much more likely to stand out to your customers because you're making a game just for them. You can tailor your PR so you are speaking directly to your niche. Nathan pointed out that there are enough game players now that niches can still be huge. They've sold something like 350,000 copies of their niche game on iOS.

High Quality

The last part of artisan games: quality. Nathan said on Sworcery they decided it was safer to slip their deadline and over-run their budget than to release a rushed game that wasn't great. In the end, they found that finishing a risky game well opened a lot of doors. This echoed what Kert Gartner said in his talk on making trailers for games: a bad trailer is worse than no trailer, so either make an awesome trailer or don't make a trailer at all.

This seems especially important if you're trying to build a reputation for great games. The one caveat I would add is that it probably doesn't apply if you are just starting out. New developers usually don't have the skills to making high-quality games. That's normal. If you are new it is more important to make lots of games than to get stuck trying to make your first game high-quality. Quality will come with practice. Going back to the baker analogy, no one expects a beginning baker to make a perfect loaf. If you have the skills to release quality games, though, it seems like a sound choice to do so instead of rushing crap out the door.

Making of an HTML5 game: Forest

I wrote earlier about Forest, a meditation game I made for the Super Friendship Club's Mysticism Pageant (you can play it here). That article covered my motivations and inspirations, but not the details of how it was put together. This article covers the details.

Overview

The game uses HTML5, specifically the <canvas> tag for graphics and the <audio> tag for music. The world is procedural, which means that instead of using photoshop to paint the levels by hand I made some algorithms to generate the world. This has two advantages:

  1. It is a very fast way to get a lot of variety, which helps the world look natural and convincing.
  2. It was more fun. I didn't have to sit down and paint 20 or 30 different trees by hand.

I worked on this in the evenings and on weekends for about three weeks during the pageant, and then spent a couple more weeks cleaning things up and polishing it after. It is about 1500 lines of JavaScript.

Procedural Trees

I had the good fortune to be able to work on the code for generating the trees while sitting on the porch of a cabin near Lake Tahoe. It was quite relaxing, reclining in the shade of towering pine trees while making a virtual forest.

The normal way of doing procedural trees appears to be L-systems, but that seemed too complicated. I did something simpler:

  1. Trees are made up of blocks of varying sizes and colors.
  2. Blocks are laid out in straight lines to make branches, with blocks getting smaller along the branch.
  3. Starting from the main branch (the trunk), side branches split off recursively.
  4. Lengths and angles are randomly jittered, so some branches are longer, some are shorter, they branch off at slightly different angles, etc.
  5. At the end of some branches a foliage block is added in a somewhat-random shade of green.

Procedural Grass and Dirt

Grass has somewhat random heights and colors:

// Returns a css color string like "rgb(30,40,50)"
function rgb(r,g,b) { 
  var f = Math.floor; 
  return "rgb(" + f(r) + "," + f(g) + "," + f(b) + ")";
}

var width = 3;
for (var x = 0; x < SCREEN_WIDTH; x += width) {
  // Draw one blade of grass
  var shade = Math.random() * 5;
  context.fillStyle = rgb(40 + shade, 110 + shade, 50 + shade);
  var depth = Math.random() * 2;
  var height = depth + 10 + Math.random() * 10;
  context.fillRect(x, SCREEN_HEIGHT - GROUND_HEIGHT + depth, width, -height);
}

(I didn't bother including it in the sample code, but there's also a little logic to adjust the color if the grass is in a sunbeam)

The dirt has randomly-sized dark and light rectangles layered on it:

// Ground
context.fillStyle = "rgb(35, 50, 50)";
context.fillRect(0, SCREEN_HEIGHT, SCREEN_WIDTH, -GROUND_HEIGHT);

// Dark spots
context.fillStyle = "rgb(32, 47, 47)";
for (var i = 0; i < 20; i++) {
  context.fillRect(Math.random() * SCREEN_WIDTH, 
    SCREEN_HEIGHT - Math.random() * GROUND_HEIGHT,
    Math.random() * 50 + 10, 
    Math.random() * 50 + 10);
}

// Light spots
context.fillStyle = "rgb(38, 53, 53)";
for (var i = 0; i < 20; i++) {
  context.fillRect(Math.random() * SCREEN_WIDTH, 
    SCREEN_HEIGHT - Math.random() * GROUND_HEIGHT, 
    Math.random() * 50 + 10, 
    Math.random() * 50 + 10);
}

Canvas optimizations

I started out just drawing the entire canvas from scratch in every frame, using fillRect() calls for almost everything (remember, the grass, dirt, trees, and player are all made out of blocks). Performance was terrible.

I did some testing and found that at 30 FPS I could only expect to get 5000 100x100 pixel fillRect() calls. That's not nearly enough. Each tree is built from about 1000 blocks so that would only get me five trees. Worse, <canvas> appears to be fillRate() limited. If I want to fill the whole 800x600 canvas, I only get 500 fillRect() calls.

Since the trees don't change, I looked into pre-rendering them to off-screen canvas elements, then using drawImage() to copy them into the main canvas. Performance testing suggested that at 30 FPS I could get about 35 800x600 drawImage() calls. This is more than enough, since I only need 3 layers of trees to give enough depth.

For scrolling, there are two canvases for each layer. When one of the canvases scrolls off the left side of the main canvas, it is redrawn and starts scrolling in from the right side of the main canvas. This means in total, there are only 8 drawImage() calls per frame (three tree layers plus one ground layer, two canvases per layer).

Colors

I tried different color palettes:

  1. Warm tones with plenty of yellow in the shades of green. This helped create the warm, lazy summer afternoon feel I wanted.
  2. Cooler blue tones to help make the yellow fireflies stand out. The fireflies looked great but the forest felt too cold.
  3. A day/night cycle slowly changing between bright, warm greens in the daytime and dark, cool blues at night (there were even stars which came out at night). This turned out to not be as awesome as I had imagined.

In the end, I compromised and ended with with a somewhat cooler version of #1:

Text

I browsed through Google's repository of web fonts until I found Tangerine Bold, which I think goes very nicely with the theme.

I wanted to use JavaScript to render the text into the canvas directly, but I couldn't find a way to make it blocky. The obvious solution is to draw the text at a small size so the pixels are large in relation to the text, then enlarge the image. However I couldn't stop the browser from doing interpolated scaling, so the text ended up blurry instead of blocky.

I gave up on JavaScript for this and used Python instead to pre-render the text into images. I also added a slight drop-shadow to help the text stand out from the background. Using images instead of rendering from JavaScript adds about 300 KB of data to download, but at least it works.

from PIL import Image, ImageDraw, ImageFont, ImageFilter

def colorize(image, textColor, backgroundColor):
  colored = image.convert("RGBA")
  colored.putdata([textColor if value == 0 else backgroundColor 
                   for value in image.getdata()])
  return colored

text = "Breathe"
font = ImageFont.truetype('Tangerine_Bold.ttf', 36)

image = Image.new("1", font.getsize(text), '#FFF')
draw = ImageDraw.Draw(image)
draw.text((0, 0), text, font=font)
# Use nearest-neighbor when enlarging to make it blocky
image = image.resize([i*2 for i in image.size], Image.NEAREST)

coloredText = colorize(image, (187, 221, 153), (0, 0, 0, 0))
shadow = colorize(image, (0, 0, 0), (0, 0, 0, 0))
for i in range(3):  # Takes several blurs to get blurry enough
  shadow = shadow.filter(ImageFilter.BLUR)

shadow.paste(coloredText, (0, 0), coloredText)
shadow.save("breathe.png")

Movement

I wanted the movement to have a specific feel:

  1. Syncing input to breathing gives a slow pace
  2. Possible to run
  3. Possible to quickly slow down from a run

When space is held, there's an acceleration which decreases as the player's speed approaches the target speed. Rapidly clicking space builds up an acceleration boost which allows running. Finally, drag slows the player down quickly from high speeds but has little effect at slow speeds.

The acceleration from tapping space once is so small it can barely be noticed. This gives a bad experience if the player just taps space once at the start of the game because it looks like nothing happened. To fix this, if the player isn't moving and space is pressed, the speed jumps straight to the target speed. This provides nice feedback and makes it obvious that pressing space did something.

function Player() {
  this.x = 0; // position
  this.dx = 0; // speed
  this.ax = 0; // acceleration
  this.clicks = 0;  // Number of times player pressed button within clickWindow 
  this.clickWindow = 5; // Number of seconds to measure button presses over
  this.running = false; // True if player is holding down button
  this.targetSpeed = 50; // Desired speed if button is held continuously
}

// dt is how much time has elapsed since the last call to update()
Player.prototype.update = function(dt) { 
  // calculate bonus acceleration for clicking button rapidly
  this.clicks = Math.max(0, this.clicks);
  var clickRate = this.clicks/this.clickWindow;
  var boost = 49 * clickRate * clickRate;

  var drag = .003 * this.dx * this.dx;
  this.ax = boost - drag;

  if (this.running) {
    // When running, provide an alternate, possibly higher, acceleration
    this.ax = Math.max(this.ax, boost + this.targetSpeed - this.dx); 
  }
  
  this.dx += this.ax * dt;
  this.x += this.dx * dt;
}

Player.prototype.startRunning = function() {
  if (this.running) {
    return;
  }
  this.running = true;
  if (this.dx == 0) {
    // not moving yet, provide a "kick" so it is obvious something happened.
    this.dx = this.targetSpeed;
  }
  this.clicks++;
  var that = this;
  setTimeout(function() {that.clicks--;}, this.clickWindow*1000);
}

Player.prototype.stopRunning = function() {
  this.running = false;
}

var player = new Player();
var SPACE = 32;
$(document).keydown(function(e) {e.which == SPACE && player.startRunning();});
$(document).keyup(function(e) {e.which == SPACE && player.stopRunning();});
// Prevent space from scrolling the page
$(document).keypress(function(e) {return e.which != SPACE});

Metrics

Google Analytics can do event tracking, which is perfect for gathering metrics on how many players start the game and how many players make it all the way to the end.

function trackEvent(action) {
  if (_gaq) {
    _gaq.push(["_trackEvent", "forest", action]);
  } else {
    console.log("Analytics not loaded. Not logging event: " + action);
  }
}

Even though the game only lasts five minutes, the metrics made it obvious that players were leaving before finishing. Based on this, I added the "Breathe" and "Relax" reminders in the middle to hint that the game doesn't just run on forever. Metrics showed an improvement in the number of players reaching the end after this change.

Forest: A Meditation Game

The Super Friendship Club runs month-long game pageants where participants make games related to a theme. For the Mysticism Pageant I made a meditation game called Forest.

Most games are about doing: building empires, killing monsters, driving fast. This game is about not doing, about breathing. There's no score, no goal. It isn't fun like other games, but is hopefully enjoyable. It's not really a game, but that's the best word I can come up with. ("Experience" would be more accurate but that sounds silly and has too many syllables)

Go play it now.

Inspiration

I wanted to do a game about meditation but mediation usually involves closing one's eyes and sitting very still. While I was struggling to figure out how to translate this to an interactive game, my wife and I attended a meditation workshop with Thich Nhat Hanh. One of the techniques we practiced was walking meditation, and I saw this was the solution: One does not need to be sitting with closed eyes in order to fully experience the present moment. This became the concept I would try to communicate to the player.

I loved the first half of pOnd, and wanted to make something similar to that, but taking the subject more seriously. I think pOnd's ending cheapened the experience, as if the creators didn't really believe in what they had started. They had a brilliant mechanic, though: encouraging the player to synchronize their breathing with their actions is powerful.

The forest spirits that are so prevalent in Miyazaki's films kept popping into my thoughts. Not only did they fit the mysticism theme well, they improved the game in several ways. Their appearance (or startled flight) provides feedback to the player. They move with the player's breath, deepening the synchronization. Finally, they provide a simple narrative hook for the start of the game.

Mechanics

I decided the core mechanic would be walking through a forest by pressing space as you breathe in, releasing as you breathe out. A quick prototype showed this was relaxing and engrossing.

At first I wanted to make the player figure this out on their own, to encourage a sense of discovery. The original version of Forest dropped hints about going slow and only showed the instructions about synchronized breathing if the player slowed down. If they didn't slow down, there was a "failure" ending which hinted at the player being too hurried. Metrics revealed that almost no one went slowly enough, though, so I gave up on that. Now everyone gets the breathing instructions and there is no way to "fail."

I wanted there to be an "aha!" moment when the player stops running and starts walking slowly. I intentionally try to mislead the player at the start by telling them how to run, hoping to get the player to experience the contrast between running and then relaxing. However, I deliberately avoided artificially increasing this contrast by changing the way the game is rendered when running. It would have been easy to decrease color saturation, draw trees in less detail, etc. but that wouldn't be true to the theme. The whole point is that the player notices more when walking, not that the game shows them more when walking. The detail has to be there all along to be authentic and not just a fake effect.

When making most games, much time is devoted to finding pleasurable reward loops. Basic breathing meditation is already enjoyable, though, so the game just tries to nudge the player to try it. I avoided adding traditional reward loops on top of this, partly because this risked smothering the fragile pleasure from meditation, and partly because I was concerned about replacing intrinsic motivation with extrinsic motivation.

One Last Thought

Many of the best games teach the player something, improve them in some way. This is something I aspired to. Being conscious of one's own breath is a powerful relaxation technique that can be used anywhere. Learning to relax and release stress is important skill that most people can benefit from. I have no illusions about achieving wide-spread public health gains via this game, but I do hope that it helps at least one person lead a more relaxed life.

A fighting platformer, in HTML5

Back in October, Google hosted a two-day HTML5 game jam at their San Francisco office. Chris Killpack and I both attended and paired up to make a game. This is a playable log of our progress.

Brief note on the demos: They work in Safari, Chrome, and Firefox. They don't work in Internet Explorer 8. I haven't looked into why (this is game jam code after all).

Day 1, 2:45 pm

We got started a bit late and don't have much of a plan. The intial idea is to make a simple 8-bit fighting game, two player hot-seat. Chris sets up a repository on his subversion server while I start a simple game loop rendering to a <canvas> element.

Day 1, 4:00 pm

play

Basic keyboard controls started. A and D move, R punches (we're expecting the player to use two hands for this, by the way). Chris is working on sprites. We found a collection of adorable 8-bit versions of Street Fighter characters, and they're animated. We'll use these as stand-in art until we either can get permission to redistribute them or until we replace them. [In the end getting permission got complicated so we drew new art from scratch.] Chris is converting the animated gifs into sprite sheets and writing a class to manage them.

Day 1, 7:00 pm

play

Sprites are working. Now there are keyboard controls for both players (player one still uses A, D, and R. Player two uses left/right arrow to move and comma to punch). Moving away makes you block punches. Player health is shown at the top of the screen, and the game resets when one player runs out of health.

Added debug mode (press P), which draws the exact locations of the players, collision boxes and shows keycodes as you press keys.

We have enough working to start tweaking gameplay. Made it so players can't move while punching. Fiddled with the punching range a lot until it felt right. Made getting hit push the player back a bit (which makes the punch seem a lot more powerful).

Day 1, 9:15 pm

play

Worried that a straight fighting game will be boring. Decide it should also be a platformer with pits that the players can fall into. This requires a bunch of new features:

Still tweaking the gameplay in a lot of ways:

Done for the day.


Day 2, 8:45 am

Chris can't make it today. I start off slowly by cleaning up code from yesterday.

Day 2, 1:00 pm

play

Added throws. You can't block throws, so if someone is blocking all your punches, throw them. Throws also take a long time, though, so if you miss you'll be vulnerable.

Made scrolling stop if O is pressed (scrolling is annoying when developing)

Lots of tweaks to the feel of the game:

Day 2, 2:00 pm

play

A few more tweaks to gameplay: Players start farther apart, there are more holes, and players actually die in the holes now.

The official game jam will be over soon so I added some instructions, an intial "Fight!" screen and a "Game Over" screen. It is surprising how much more finished this makes the game feel.

Day 2, 6:00 pm

play

After I got home I worked on the game a little more. Tweaked damage values. Only start killing players after they fall a long ways into a pit. Made the game loop exit if you press ESC.

I also added some noise to the sky and ground. This is a trick I learned from Amit Patel and it does wonders for pulling things together visually.

This is the final verison of the game. You can get the code to this game on code.google.com

In addition to the keys documented in the instructions, there are a couple other keys useful for debugging:


(Note: I've modified the code slightly in these snapshots. To make it easier to post, I've jammed everything into a single .html file instead of splitting out separate .js files. Also, as mentioned above, these aren't the character sprites we started with because we didn't have permission to redistribute those.)

Refining a Game Until it is Fun

I’m crafting an economy game using Python and Google App Engine.  Called Island of Naru, it is a simulation of a small society on a tropical island. The core design revolves around production and trade:

Because terrain affects production, the location of a town matters. A town surrounded by mountains, for example, can’t grow very much corn, while a town surrounded by corn fields can’t mine very much iron ore.  The disparity between locations is what drives the need for towns to trade with each other.  By trading with each other, our hypothetical mining camp and farming town can become much more prosperous than they could on their own.

The previous release of Island of Naru added simple trade: cities that were connected by roads could exchange goods.  The latest version adds simple production: towns near fields will produce food, towns near mountains will produce raw materials, and towns near factories will produce manufactured good.  This change is exciting because it means the core game concept is now playable.  In essence, this is the first version of Naru which actually resembles the game I set out to build.  Now it is possible to start experimenting with the game design, looking for the fun aspects of it and bringing those to the forefront. Much like a rough draft of an essay, the game needs rework and refinement to bring out the best qualities buried inside it. I’ve already done a little exploring with some changes I’ll talk about below, plus I have some half-formed, fuzzier ideas about where the fun may be hiding that I’ll mention at the end.

As soon as terrain-based production was finished, my first thought for improvement was to make the economy more complex by providing ways to enhance production and by adding another resource type: manufactured goods. Production of raw materials can be improved by digging mines in mountains, while irrigating fields increases the amount of food they will produce.  Manufactured goods are only available if you build a factory next to a city. These changes gave the game more depth.

Next I added exploration. I want the player to have to think about where they build their cities, especially the first one.  It should be beneficial to hunt around a little for an ideal site, and I think that with a little tweaking, this can be accomplished now that terrain impacts the city’s production.  I’m hoping that exploration will help enhance the feeling of landing on a new island and looking for a good spot to build.  The island starts out unexplored except for the beach where you came ashore.  You can then explore outward from there.  I tried making the player explore one tile at a time, but I found that it took too much time: most of the player’s clicks were spent exploring instead of building.  That’s not what the focus of the game should be, so I changed the exploration to uncover several squares at a time, which helped.  With exploration, the early game is more interesting because the player has to balance exploring with the need to start a town as soon as possible. 

Finally I tried to tweak the numbers behind the economy so towns could grow to larger, more realistic populations.  This change took more effort than I expected because it uncovered some problems with the way I was calculating demand and the happiness of the population.  Fixing it involved modifying the internals of the supply/demand system to allow more control over the minimum and maximum required amounts for each resource.  This not only fixed the problem, but also gave me more control over the balance of the game, which may be useful later. The new numbers don’t seem glaringly low, so the game feels more realistic now.

Even with these improvements, I feel like the fun is still buried. So where should I look next? I have three guesses. First, I suspect the game needs more depth. There are only three resource types at the moment, for example. The trade is also very simple. A more complicated trading network with bottlenecks and different capacities for different types of roads would be much more interesting to manage.  Right now, once a player connects all the cities with roads, there is nothing else to manage.  There’s no upkeep, improvement, foreign trade, or ports.  I expect adding these details will help a great deal once the game is almost finished, but they should probably wait until the bare skeleton of the game is a little more refined.  You don’t start decorating a house until after the walls are finished being built.

My second guess for making the game more fun is adding a goal. In its current state, Naru is just a toy, not a game.  Sure, the player can invent a goal for themselves, like “highest island population in 100 moves” or “biggest single city” but self-imposed goals aren’t very powerful motivators.  I think imposing some goals and adding a high-score table or two would help add a competitive edge to the game.  I may add a simple goal just to give some direction to the player and avoid confusion about what they are supposed to be doing, but fancier changes like multiple goals or score tracking need to wait until the core idea provides more fun on its own.  High score tables enhance existing fun, they don’t magically make boring tasks fun.

I think the biggest thing hiding the fun is lack of resource constraints on the player.  They can build everything for free, so nothing feels valuable.  For example, the player should have to agonize a little over the perfect location for their first city, but right now there’s no need: if they find a better location later they can always just build a city there.  Similarly for roads: the player should feel a sense of accomplishment when they manage to add a new city to the trading network but since roads are free this isn’t difficult and there’s no sense of accomplishment.  A typical game goes something like this: build a city in the flatlands, build a second city by the mountains, build 4 road segments to connect them, build a factory, uhh, now what? 7 moves into the game the player already has access to every resource. Each new city gets connected to the others in a handful of moves, and the end result is that the player doesn’t spend any time thinking about the trading network.

I’m going to try the standard solution to this problem: gold.  Make the player pay for building cities and roads, so they are more valuable.  I’m not sure what the mechanism will be for getting money in the world.  Sim City had taxes to raise money, Oasis let you search for followers in the desert, Civilization made you use special “settler” units that were difficult to obtain.  Any of these would work; the key thing is that the player has to make choices about what they want to build with limited resources.

If you want to play the game now, even though the fun may still be elusive, go to http://naru.countlessprojects.com.  Feedback is always welcome, of course. You can leave it below.  I’d be especially interested to hear any thoughts about refining game designs to uncover hidden fun within them.

Naru: Combining the economy engine with the map

The latest installment of Naru (an island economy game) joins the economy simulation and the island maps.  Now when you create an island, it will have the economy engine I wrote about earlier running behind the scenes.  This means that cities can trade with each other if you connect them with roads. By clicking on the city names, you can control the production levels of the cities and see graphs of population trends in the city.

I also improved a few issues in the UI. The squares of the map are now shaded slightly, making it easier to click the square you intended to. Also, cities will automatically connect to roads now; you don’t have to build both a city and a road on the same square.

Simulation for Island of Naru’s economy

 After prototyping the basic map editor, I’ve switched to working on the backend of Naru recently.  Specifically, I’ve been working on the simulation of the island’s economy, which is going to be the meat of the game.  

My approach has been to create a dashboard that exposes the interesting stats and graphs them over time.  I’m trying to make it easy to visualize what happens when I tweak the various values. I’ve found the graphs to be really helpful in illustrating how trends work their way through the system.  I can do something like connect two cities (so they can trade), then run through several turns watching how the populations grow & shrink until they hit a new steady state.  

I think I have the simulation to a point where it is starting to be convincing. The population of each city depends on whether the citizens are happy, which in turn depends on whether their needs are met.  For example, if they don’t have enough food, they will be unhappy and will eventually move away.  If they have an abundance of food, they will be very happy and more people will move in to the city.  At the moment I only have 2 resources in the simulation: food and raw materials (which could some day be turned into manufactured goods in a factory).  Cities can be connected by roads, in which case surpluses can be distributed to other cities.  This means that the total population of the island should increase as more towns become connected (because the surpluses won’t be wasted). The only control the player has is over the amount of resources produced by each city and the road connections between cities.

If you want to play with the simulator, you can get started by going to http://naru.countlessprojects.com/island/economy

I’m pretty sure there are still lots of bugs in it. I haven’t written tests for most of the code because it is still very much a prototype. Still, any feedback you have would definitely be appreciated.