A Tourist In Paris: JS13KGAMES 2017 post-mortem

Jerome Lecomte
Dec 3, 2017 · 11 min read
The tiny blinking square is a tourist, and the big blinking square a monument…

Game ideation

Art direction

Just imagine a pixelated tourist running around with a camera and no map!
Camera? Check! Map? Check! Helpless running around? Check!

Technical choices

6-year-old me managed it, so how hard could it be?
Yup, Paris can be sneaky with the Tourist :(

What went right

Fun fact: the background color is different everytime.
The tweet generated by the game for a player to share his score.
Accurate response on the left, approximate response on the right.

Lessons learned

#1 — Have your boilerplate code ready before the jam begins

#2 — Have a few game ideas ahead of the jam.

Since last JS13k, I’ve listed a dozen game concepts on paper (mostly puzzle or reflection games, because that’s the genre I like the most), and waited for this year’s theme to see which idea would suit it the most…

#3 — Join the JS13KGAMES Slack channel

#4 — Know your code obfuscator

// src/game.js
var atlas = { hero: new Image('hero.png') };
function render() {
var posX = 0,
posY = 0;
drawImage(atlas.hero, posX, posY);
}
render();~$ uglifyjs src/game.js -o dist/game.js --mangle// dist/game.js (indented for clarity)
var atlas = { hero: new Image('hero.png') };
function render() {
var a = 0, // only local variables get renamed
b = 0;
drawImage(atlas.hero, a, b);
}
render();
// src/game.js
(function() { // IIFE
var atlas = { hero: new Image('hero.png') };
function render() {
var posX = 0,
posY = 0;
drawImage(atlas.hero, posX, posY);
}
render();
})()
~$ uglifyjs src/game.js -o dist/game.js --mangle// dist/game.js (indented for clarity)
(function() {
var a = { hero: new Image('hero.png') };
function b() { // variables local to IIFE gets renamed
var c = 0,
d = 0;
drawImage(a.hero, c, d);
}
b();
})()
// src/game.js
var atlas = { hero: new Image('hero.png') };
function render() {
var posX = 0,
posY = 0;
drawImage(atlas.hero, posX, posY);
}
render();~$ uglifyjs src/game.js -o dist/game.js --mangle --toplevel// dist/game.js (indented for clarity)
var a = { hero: new Image('hero.png') };
function b() { // renamed even though global
var c = 0,
d = 0;
drawImage(a.hero, c, d);
}
b();
// src/game.js
var atlas = { hero: new Image('hero.png') };
var entityType = 'hero';
function render() {
drawImage(atlas.hero, 0, 0); // dot notation
drawImage(atlas['hero'], 10, 10); // square brackets with strings
drawImage(atlas[enemyType], 20, 20); // square brackers with var
}
~$ uglifyjs src/game.js -o dist/game.js --mangle --mangle-props --toplevel// dist/game.js (indented for clarity)
var a = { a: new Image('hero.png') };
var b = 'hero'; // value does not get renamed to 'a'
function c() {
drawImage(a.a, 0, 0); // ok
drawImage(a['a'], 10, 10); // ok
drawImage(a[b], 20, 20); // KABOOM! a.hero no longer exists
}
// src/game.js
var indexHero = 0,
indexEnemy = 1;
var atlas = [ new Image('hero.png'), new Image('enemy.png') ];function render() {
drawImage(atlas[indexHero], 0, 0);
}
~$ uglifyjs src/game.js -o dist/game.js --mangle --toplevel// dist/game.js (indented for clarity)
var a = 0,
b = 1;
var c = [ new Image('hero.png'), new Image('enemy.png') ];function d() {
drawImage(c[a], 0, 0); // index renamed like other variables
}

In conclusion (or “so… I made a maze game”)

Jerome Lecomte

Written by

Software engineer turned web developer and father of four, I create pixel art, video games and visual experiments on the Web.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade