January 3, 2012
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:
- It is a very fast way to get a lot of variety, which helps the world look
natural and convincing.
- 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:
- Trees are made up of blocks of varying sizes and colors.
- Blocks are laid out in straight lines to make branches, with blocks
getting smaller along the branch.
- Starting from the main branch (the trunk), side branches split off
recursively.
- Lengths and angles are randomly jittered, so some branches are longer,
some are shorter, they branch off at slightly different angles, etc.
- 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:
- Warm tones with plenty of yellow in the shades of green. This helped
create the warm, lazy summer afternoon feel I wanted.
- Cooler blue tones to help make the yellow fireflies stand out. The
fireflies looked great but the forest felt too cold.
- 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:
- Syncing input to breathing gives a slow pace
- Possible to run
- 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.
February 28, 2011
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:
- Scrolling view
- Left edge of window pushes players along
- Gravity and collision dection with the terrain
- Jumping (to make it over the ledges)
- Random level generator (we don't want to build levels by hand)
Still tweaking the gameplay in a lot of ways:
- Added a pain animation to make it obvious when you get hit.
- Added horizontal acceleration/deceleration which makes the controls feel a lot more "juicy."
- The level generator was putting holes at the start of the level which turns out to be a bad idea (especially if a player starts in a hole). Tweaked it to only put holes in after a certain distance.
- Made movement faster
- Players now face the direction they are moving
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:
- Player movement stops when punching and when getting hit.
- Players could punch too frequently, so I made the punch action take a little longer (but kept the animation the same speed so it looks like a good, fast punch. There's just a delay at the end where you can't do anything).
- Always face the other player. Getting in a fight while facing away from the opponent is just weird.
- Made holes deep enough that you can't see the player standing at the bottom
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:
- P: debug mode
- O: stop scrolling
- ESC: quit game loop
(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.)
May 9, 2009
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:
- Towns produce resources based on the surrounding terrain.
- Towns can trade with each other through a complex trading network.
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.
December 5, 2008
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.
October 30, 2008
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.
September 12, 2008
I’ve finished a first pass at building cities on an island. You can create a new island* and then start building on it. You can start cities, build roads, and irrigate bare land to create fields. There’s also a terraforming menu, so you can flatten mountains and fill in the ocean if you want. Terraforming won’t be there in the finished game, but makes it easier to play around with different island shapes at this stage. Some of the basic building logic is implemented (so you can’t build a road across mountains, you can’t build a city in the water, etc.)
The interface is…simple. It is the simplest interface that could just barely be construed as working. I’ll definitely be spending more time on this, but I want to get the core of the game working first.
As I hinted at in my last post, I’m writing this game in 2 distinct parts:
1) A library which implements a simple island economy game
2) A django app which puts a nice user interface on this library
By implementing my core game logic as pure (non-django-related) python, I have a bit more freedom writing tests and experimenting. I’m just writing normal tests using the unittest module. I’ve started on a basic economy, and so I have a couple command-line programs that let me poke around at different parameters trying to get something reasonably stable and convincing.
The live version is running at http://naru.countlessprojects.com. If you try it out, I’d appreciate any comments, questions, or feedback you might have.
* For now, I’m requiring sign-ins using google accounts. This was the fastest way for me to make sure no one else can edit your maps. I definitely want to allow instant, no-sign-in play later, but right now there are much bigger features to tackle.
July 22, 2008
I’m finding that BlobProperties are a very handy way to optimize for the App Engine Datastore. The first iteration of my island map had a Map model, and a Tile model. It used entity groups, so one Map entity was the parent of 100 Tile entities. Nice and clean, and of course dog slow. You don’t want to be loading 101 entities with every request if you can avoid it.
I added some quick-and-dirty benchmarking to time the datastore calls and then tried several different approaches. The one I settled on was BlobProperties and pickle. Basically, my Map model has a BlobProperty which stores all the tiles in pickled format. When I load the map out of the datastore, I use pickle.loads() and before I save the map back, I use pickle.dumps(). This means that I only have to load a single entity out of the datastore to display a map.
Nice side benefit: My core game logic is now pure python, so it is really easy to work on it outside of app engine (or even django). This is handy when writing benchmarking tools, testing, and prototyping new algorithms.
Possible drawback: I think I will hit compatibility problems if I try to load old pickled objects after renaming python modules. If this becomes a problem, I plan to start pickling an intermediate format like a dict instead of full objects.
July 1, 2008

Some of the folks at Google have released a sweet Google App Engine Helper for Django. It consists of a skeleton Django project with all the little tweaks necessary to run on top of App Engine, and it makes it really easy to get started.
I used the helper to start a simple Django app that shows tiled maps, using the images I previously created. Making a map generator is way, way down on the list of things that might possibly make this game fun, so I just quickly made three 10×10 islands manually. Here’s the code which generates the island in the screenshot:
island1 = _Expand("""O O L L O O L L L O
O L C_road_s L L L L F L O
O L L_road_en L_road_ew L_road_ew F_road_esw C_road_w F O O
O L L L L F_road_ns F L L O
O O O L L L_road_ns L L L O
O L L L M L_road_ns L L L L
L L L L L L_road_ns M L L L
L L L M M L_road_ns L L L O
O L L L L L_road_en C_road_w O L O
O O O L L L L O O L""")
The app picks one of the three islands randomly and spits out an HTML table containing the image tiles. A little bit of CSS makes it fit together without borders/gaps:
table {
border-collapse: collapse;
}
td, tr {
line-height: 0;
padding: 0;
}
.island {
border: solid 1px black;
float: left;
margin: 1em;
}
If you want to see it live, the latest version is running here.
June 22, 2008
Smooth coastline!
For the island game I’m creating using App Engine, I need a tiled map. I wasn’t expecting this to be difficult, but the sheer number of different tiles required is daunting. If I limit roads to only entering a tile from the north, south, east, or west, there are still 15 ways for roads to cross a tile. Since I don’t want blocky, square islands with abrupt land/ocean transitions, I need a set of 46 coastline tiles. Start multiplying by different types of base tile (forests, fields, mountains, tiny villages, big cities, etc.) and the situation quickly gets out of hand.
Blocky coastline
The only sane solution appears to be transparent overlays which are composited on demand. I don’t see a way to do server-side compositing with App Engine (plus I don’t think it would scale well), so that leaves client-side compositing. I did a simple mock-up with transparent PNG images, using absolute positioning to stack them on top of each other. It seems workable. Traditionally, transparent PNG images weren’t supported well by IE6, but since only 10% of the visitors to my site are using IE6, I might just forget about supporting it.
So that’s the long-term plan. In the spirit of getting a working prototype as quickly as possible, though, I’m going to start with a really simple tileset where I can pre-generate all the combinations and just serve static images. Here are the 6 tiles I’m starting with:
Ocean
Land
Mountains
City
Field
Road
I’m not going to allow roads over mountains for now, so there are 50 possible tiles (16 road combinations * (city, field, land) + ocean + mountains). Pre-generating all the combinations is a snap using PIL.
#!/usr/bin/env python2.5
import os
from PIL import Image
def composite(images):
"""Composite a stack of images, [0] on top, [-1] on bottom."""
top = images[0]
for lower in images[1:]:
top = Image.composite(top, lower, top)
return top
def combinations(list):
"""Generate all combinations of items in list."""
if list:
for c in combinations(list[:-1]):
yield c
yield c + [list[-1]]
else:
yield []
def load(name):
return Image.open(os.path.join('sources', '%s.png' % name))
def save(name, image):
image.save(os.path.join('img', '%s.png' % name))
def make_roads(name, above, below):
"""Save tiles with roads. Images in above will be composited above
the roads. Images in below will be composited below the roads."""
roads = dict(w=load('road_overlay'),
s=load('road_overlay').transpose(Image.ROTATE_90),
e=load('road_overlay').transpose(Image.ROTATE_180),
n=load('road_overlay').transpose(Image.ROTATE_270))
above = [load(filename) for filename in above]
below = [load(filename) for filename in below]
for directions in combinations(sorted(roads.keys())):
out = composite(above + [roads[x] for x in directions] + below)
if directions:
save('%s_road_%s' % (name, ''.join(directions)), out)
else:
save(name, out)
def main():
save('mountains', load('mountains'))
save('ocean', load('ocean'))
make_roads('land', [], ['land'])
make_roads('city', ['city_overlay'], ['land'])
make_roads('field', [], ['field_overlay', 'land'])
if __name__ == '__main__':
main()
PIL also comes in handy to paste together the first proof-of-concept map using the new tiles:
#!/usr/bin/env python2.5
import os
import sys
from PIL import Image
TILE_SIZE = 50 # Width/height of a tile in pixels.
in_file, out_file = sys.argv[1:3]
data = [line.split() for line in open(in_file).readlines()]
map = Image.new('RGB', (TILE_SIZE * len(data[0]), TILE_SIZE * len(data)))
for y, row in enumerate(data):
for x, name in enumerate(row):
image = Image.open(os.path.join('img', '%s.png' % name))
map.paste(image, (x * TILE_SIZE, y * TILE_SIZE))
map.save(out_file)
And here it is: The first example map!

Next on the agenda: Getting Django running on App Engine and serving this example map using HTML.
May 30, 2008
Neat! I’ve been kicking around the idea of making a simple online game for a while, and now Google App Engine pops up. I love great coincidences, and this is definitely one to take advantage of. App Engine is still really new, so it is hard to tell if it is a good vehicle for writing online games. There are certainly people trying, but instead of sitting on the sidelines watching them, I’m going to wade in and find out for myself: I’m going to build a game using App Engine.
Time for a rough design. I like to start with limitations, figuring out where the boundaries are. The most basic limitation is that I’m just one guy, so the game needs to be pretty simple for me to be able to finish it. The grand scale of a game like World of Warcraft is right out, obviously. I don’t know flash, and I’d prefer not to get bogged down in complicated Javascript, so that means HTML and simple AJAX. This suggests a board game, or some kind of 2D game on a fairly small map. App Engine brings another set of limitations. There’s no background processing (between requests), which makes a turn-based game attractive. There’s also not a lot of CPU available for each individual request, which suggests I should stay away from complicated AI, physics, etc.
Ok, so I’m going to make a small 2D turn-based game. As I was thinking through the limitations, I was building up a list of examples; a list of games that would fit within my constraints that I could use as a reference:
At this point, I’m thinking some kind of colonization/economy game, drawing inspiration from Sim City, Civilization, and Oasis (aside: Oasis is a great turn-based game. It is small and simple, yet fun; a really good example of how to cut a game down to the bare essentials). The core focus will be on expanding an economy by building cities and roads, and managing trade. I may also add a discovery element with exploration (i.e. the map is hidden at the start) and/or a technology tree. To keep things simple, I’ll probably just make the map into an island (keeps the player constrained).
A basic game might run something like this: The player starts with a single settler on the coast of the island. They explore the island a bit and build a tiny village. Once the population starts to grow, they can build other villages elsewhere on the island. At first, the villages will be self-sufficient, but as they get bigger and turn into towns, they will need to be able to trade with other nearby towns to get food, manufactured goods, etc. Building roads to connect towns will facilitate trade between them (towns on the coast might be able to trade using ships). As towns turn into cities, trade becomes even more important. The player can start building sea ports and airports to bring in foreign trade and tourism from outside the island.
I want the towns to have different characters. There might be a small fishing village, or a sleepy farming town, or a busy industrial port city, or a bustling metropolis. I also want the player to have to think a little bit about where they build a town, so some places on the island will be better for certain types of towns. For example, towns surrounded by fields will be great at producing food. A small village surround by mountains will barely produce any food (but it might produce a lot of raw materials like iron ore or gold). A sea port could only be built in a town on the coast.
Along the same lines, I’d like there to be several different, viable approaches to developing the entire island. For example, you could make lots of money from tourism, or by having a strong industry and relying on exports, but you probably can’t do both (that is, if you destroy the natural beauty of the island with factories, tourism will drop off).
One of the weak points of my design is that I don’t have a good idea what the end of the game will be. What are the player’s goals? It could be open-ended, like Sim City, or have a goal like Civilization, or have both a goal and a time limit, like Oasis. I like how Oasis explained both the goal and time limit as part of the narrative (”The barbarians will attack in 90 turns. Build up your defenses”) instead of just setting arbitrary limits. I’m not sure what the right answer is for my game, so clearly this will need more work.
Fortunately, my first constraint (I’m only one guy) makes it easy to design the multiplayer aspect: There won’t be one. Or rather, there won’t be anything substantial. I’d like to have a few embellishments, like some shared high-scores tables (highest population, highest GDP, top tourist destinations, etc.). I might also find a way to give in-game references to other players, similar to the tombstones in Oregon Trail (in Oregon Trail you would occasionally see tombstones with names of players who had died before at that spot).
Ok, that’s definitely enough of a design to get quite a ways into the game. This post is going to be the first in a series of posts chronicling my progress on the game. Likely next steps: getting the beginnings of a map up and starting in on the economy. Till next time…
March 17, 2007

A couple weekends ago I wanted to play around with some game ideas, to see if they were super-awesome or boring. I needed a simple framework to prototype them on, so I whipped one out using pygame. Then I sketched up some art. And made an installer.
And totally forgot to play around my original game ideas.
Damn. Maybe next time.
Anyway, here it is: a simple scrolling demo made with python and pygame. It has no real purpose (unless you want to do scrolling in pygame).
OSX
Windows
Source (Linux)
April 18, 2006
Last month, TR bought a Perplex City starter kit for my wife and I. What a cool game! There are so many levels you can play at. You can solve puzzle cards by yourself. You can join up with others online and solve cards together (including some really hard cards requiring group efforts). The city itself has a lot of depth, with record companies, pharmaceutical companies, schools, blogs, and newspapers. Some of these “companies” run ads in London newspapers, and puzzles from the game have shown up in newspapers and magazines. Finally, you can hunt for the stolen cube and try to get the $200K reward.
Many of the puzzles make fun programming challenges. I’ve been doing them in python, since that is such a great language for rapid programming. Sweet Dreams (#85) makes an obvious candidate:
#!/usr/bin/env python
a = 1
b = 1
while a < 400000:
c = a + b
a = b
b = c
print c
My wife solved Rickety Old Bridge (#106) much faster than I was able to write the program (although the program found that there are two similar solutions, not just one). This was a good one to learn generators with:
#!/usr/bin/env python
class bridge:
people = { "kurt":2, "scarlett":5, "violet":1, "sente":10 }
states = [ {"near":people.keys(), "far":[], "moves":[]} ]
def move(self, source, dest):
""" yield all new states formed by moving
a person from source -> dest """
for state in self.states:
for person in state[source]:
yield {source: [s for s in state[source] if s != person],
dest: state[dest] + [person],
"moves": state["moves"] + [person] }
def to_far(self):
self.states = [s for s in self.move("near", "far")]
def to_near(self):
self.states = [s for s in self.move("far", "near")]
def score(self, state):
times = [self.people[name] for name in state["moves"]]
total_time = max(times[0], times[1]) + times[2] + \\
max(times[3], times[4]) + times[5] + \\
max(times[6], times[7])
return total_time, state["moves"]
def print_scores(self):
scores = [self.score(s) for s in self.states]
scores.sort()
scores.reverse()
for s in scores:
print s[0], s[1]
def run(self):
self.to_far()
self.to_far()
self.to_near()
self.to_far()
self.to_far()
self.to_near()
self.to_far()
self.to_far()
self.print_scores()
if __name__ == "__main__":
b = bridge()
b.run()
The program I came up with for solving Magic Square (98) takes a long time to run but eventually starts finding candidate solutions about 2.2 million squares into its search:
#!/usr/bin/env python
def comb(nums, n):
if n == 0: yield [], nums
else:
for i in range(len(nums)):
for tail, remaining in comb( nums[:i] + nums[i+1:], n-1):
yield [nums[i]] + tail, remaining
def rows(nums):
if not nums: yield []
else:
for row, remaining in comb(nums, 4):
if sum(row) == 34:
for other_rows in rows(remaining):
yield [row] + other_rows
def check(grid):
magic = True
for i in range(4):
if sum([row[i] for row in grid]) != 34:
magic = False
if sum([grid[i][i] for i in range(4)]) != 34 or \\
sum([grid[i][3-i] for i in range(4)]) != 34:
magic = False
return magic
count = 0
for grid in rows(range(1, 17)):
count += 1
if count % 100000 == 0:
print count / 1000, "K"
if check(grid):
print grid