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
- 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.
- 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.
- 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.
- 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
- It takes 27 bears to get a treasure chest (bears -> churches -> cathedrals -> treasure), so a correctly-placed bear is worth 18.5 coins.
- A crystal used to combine two cathedrals to get a treasure chest is worth 167 coins (1/3rd of 500)
- A crystal used to combine two houses to get a mansion is worth 33 coins (1/3rd of 100)
- 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...
- 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.
- 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).
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:
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:
- Failing to explain things. Don't post a gameplay video with no commentary
and hope viewers understand. They won't.
- Explaining artistic intent. It doesn't explain why I would want to play
your game. It also uses too many words.
- Explaining story. A compelling explanation of your games story takes
too many words. Skip it.
- 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:
- Type of game. Just a few words. 2D platformer. Racing game with
RPG elements.
- Coolest unique thing. Rewind time to fix mistakes. Tear down and
rebuild the entire world.
- 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.
- 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:
- Make it longer than 60-90 seconds. Most viewers won't watch that long
- Try to explain everything.
- Cram too much information in.
- List features of your game. This is boring and not a good use of
precious time.
- Release a bad trailer. You'd be better off with no trailer.
Do:
- Make sure the first 5-10 seconds capture attention.
- Use a simple dramatic story arc. A clear beginning/middle/end structure
which builds to a climax is good.
- Show what the game is about.
- Capture the style or feel of the game.
- Use zoom-in to focus on the important parts of busy/complex
gameplay footage.
- Use slow-motion to help the viewer catch important parts of fast gameplay
footage.
- 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.
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:
- Ask "What's been done?" Find the conventions.
- Do something else, something new.
- 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.
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.
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.
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.)
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.
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.
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.