A story of making a 13 kB game in 30 days. “The Wandering Wraith” post mortem.

13th August 2019

  • It should be super easy to learn — there will be over 200 other games. Who has time to learn them all? The game should attract from the first second. Looking at past editions that’s the mistake that a lot of games do.
  • I don’t want blocky look or pixel art — that’s how most of the games will probably look like. I wanted my game to stand out and look differently. I wanted it to be organic with lots of curves, gradients, and animations.
  • The difficulty must be approachable — another sin committed by lots of past games. They are so difficult I can barely beat them. A 13kB game should be a short and fun experience in my opinion.
  • Be forgiving to players — don’t force them to repeat large chunks of the game. The game should be beatable in a single run. Savepoints are welcome.
  • Good enough is good enough — there’s no time to polish things indefinitely. When something is good enough then just leave it and move to the next task.
  • Celeste for great mechanics and movement feeling (from what people say, I didn’t play it)
  • Limbo for awesome vibe and physics

Day 1

  • quick refactoring — which is crucial since at the beginning I had no idea how the game will finally look so I will iterate and change ideas rapidly.
  • runtime error prevention — especially with strictNullChecks flag turned on. If the code compiles, it mostly runs as intended. Huge efficiency booster.

Day 2–3

First working draft

Day 4 (5.78 kB)

M1 287.5l1.5.5c1.7-1.3 3.4-2.4 4.8-.2.9 1.3.8 3 .5 4.1L6 293.1c-4.9-1-4-3.5-5-5.6z
Parallax background and terrain

Day 5 (7.52 kB)

  • render a single huge texture with the size of the level — actually one for each frame so 30 in total. This eliminated texture swapping and reduced draw calls. A single texture had around 4000x2000 resolution. Unexpectedly for the first few seconds, the framerate was around 2–3 FPS rising slowly over time stabilizing at desired 60FPS. I didn’t have time to investigate the problem and dropped the idea as experience for players was worse than before.
  • a texture atlas — one big texture with all my sprites. That’s an elegant solution for the problem but would require a separate algorithm for packing the sprites into the texture. What a waste of bytes. Worth doing but not when having 13kB constraint.
The result after day 5. Lots of tweaks are still required.

Day 6 (7.96 kB)

Basic platforming
Rigid bodies simulation

Day 7–8 (8.3 kB)

Day 9 (9.04 kB)

First hero design

Day 10 (8.24 kB)

Mangling properties names

const foo = { bar: 1 }; 
const field = “bar”;
console.log(foo[field]);
  • add those symbols to the whitelist
  • or rename the properties

Zipping and the entropy of information

for (let i = 0; i < 100; i++) {   
console.log("foo");
}
console.log("foo"); 
console.log("foo");
...
console.log("foo");
<console.log("foo");>*100

Day 11 (7.72 kB)

First draft of grass
Final version of character animations
Light mood
Dark mood
Final version for comparison

Day 12–15 (7.33 kB)

Editor in action
400 70 0–2–6l14 1c12 5–19 13–8 34 25 3 25 6 48 1l15–2 0–3c6 0 12 4 32–1 2 4–4 5 0 11dl7 0dc4–8–3–4 0–11 9–4 14 0 23–1–1 8–6 8–3 13d13–5 7 4 21–1d2–5–4–5–1–10 17 4 78–1 81 2l0 13dc19 0 11 18 33 15d48 2 57–6 102 0l0–11c10–1 23 3 43 5l-1 21–406 1czm253 26c10 2 16–6 18–2l0 7 9 0 0 9 10 0 0 10–18 0–19–15czC138 16C314 20C251 29C228 32C184 8C350 24dpv318 43dv309 43v165 24v184 18v350 36V318 31dV309 31dV217 21s158s295s91s347s223

Day 16–17 (7.51 kB)

Day 18 (7.33 kB)

  • improved character design
  • improved hills rendering
  • added progressing through levels
  • added menus
  • added savepoints
  • added sounds
  • added spikes on terrain and platforms
  • added death with particles effect

Day 19 (9.21 kB)

  • going down the slope makes the hero fall for a moment
  • going up the slope increases friction slowing down the hero
  • collision responses were ok for a simple ball but sometimes very strange looking for a hero with legs
  • generally hard to make robust hero controls with a fun feeling
The red dot represents the contact point
  • running — triggered when the contact point is below the hero. In this mode, the hero is glued to the ground. He can move left and right and is not slowed down by high slopes. The stickiness is achieved by finding the nearest ground using raycasting and teleporting hero to that position.
  • climbing — triggered when the contact point is at the side of the hero and he is not running. In this mode, the hero is frozen and cannot move. He can only jump which changes the mode to falling.
  • falling — triggered when the contact point is above the hero or there is no contact point.
  • flying in a bubble — triggered by touching a bubble.
Final platforming experience

Day 20-21 (9.73 kB)

Day 22 (9.8 kB)

Day 23 (9.97 kB)

Day 24 (10 kB)

Day 25 (11.3 kB)

The final version of the title screen
Who can beat me?

Day 26 (12.4 kB)

Day 27–30 (13.3 kB, 2 bytes left)

What went right

  • the look and sound are better than I expected. I’m quite proud of it.
  • the editor turned out to be the single best decision I made in the process.
  • the pacing of development was good. I had something playable early, could afford to drop bad ideas and introduce new ones and had time to polish the game.
  • the game is playable I think. Much better than my last attempt.

What went wrong

  • meeting the “back” theme — I introduced the theme late in the development and all I have is a single sentence on the title screen. Some gameplay mechanics related to the theme would be a nice addition.
  • level design — that was the hardest thing during the process. I wish they were more creative, balanced and interesting. Some puzzles here and there would be cool.

Summary

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store