Python Cloud DB: How to Write an HTML5 Game in 30 Days with JQuery and Python

Python Cloud DB: How to Write an HTML5 Game in 30 Days with JQuery and Python

Kicking Ass and Taking Names

“I wanted to do in boxing what Bruce Lee was able to do in karate. Lee was an artist, and, like him, I try to get beyond the fundamentals of my sport. I want my fights to be seen as plays.” – Sugar Ray Leonard

Enough farting around. If you’ve been wanting to write an HTML5 game for some time now, but you were too busy trying to get a perfectly timed grenade jump on Halo 3 while munching away at the leftover Doritos that fell between the cracks in your couch cushion, then you’ve come to the right place. I’ll show you how I did it – and in 30 days. Actually, I lied – it took exactly 33 days from starting to launch to produce Towers of Wolin. Here’s how.

You’ve Got To Have What it Takes

“I’ll think, If this is his first punch, how are the others gonna feel? That’s the only fear I have for myself.” – Sugar Ray Leonard

Day one starts when you decide that in 30 days you’re going to release a game. Read this article on Gamasutra about prototyping in 7 days. These guys were full time, I have a day job so I can only spend on average 2 hours a day (less on weekdays, more on weekends); this works out to around 30 days equivalent time, so that was my goal.

It’s important to be realistic about it – in 30 days you’re not going to make Starcraft III. Well in fact, you’re never going to make Starcraft III unless you have tens of millions of dollars and hundreds of people and a huge marketing budget. What you can make is something
small, simple, and fun. Think Tetris.

Most importantly, don’t be afraid to fail. Don’t be afraid that people will hate your game, you, your dog, and your IDE (I prefer vim). You know what? Fuck ’em. This is your game, and even if you’re the only person in the world that likes it, it’s your baby. That’s reward enough.

Week One: Game Design

“You have to know you can win. You have to think you can win. You have to feel you can win.” – Sugar Ray Leonard

You’ve got four weeks, and little wiggle time at the end. Where do you start? Game design. Many programmers miss this. An awesome technical game with a fast reactive engine that’s not fun to play is still a shitty game. Likewise, artists forget that a beautiful display of visual mastery can still be boring. You’re making a game, not an art museum. You need a design that is, most of all, fun. Think Angry Birds.

Week one is Game Design Week. There are a million great game ideas out there. If you’re a gamer, you probably already have tons of them. When I need inspiration I head on over to HTML5games where they have a huge collection of HTML5 games, all for free, that’s given me lots of ideas. But don’t just think video games, think board games, children’s games like Tubang Preso, sports you’ve played. In the time constraint of a week, you need to focus on the simple.

When I was writing Towers of Wolin, I had just come off being dazzled by WordSquared, and listening to a friend discuss his latest Settlers of Catan match. It was fuzzy, and I briefly thought of doing a Settlers clone like
gSettlers or
JSettlers, but I wanted to do my own game with a unique set of rules. So I started playing around some div tags and SVG graphics commands just to see what I could throw up on the screen, using source images from OpenClipArt. If you’re good at Photoshop or Inkscape you can do this stuff yourself, but I’m not so I used SVG commands instead. I tossed in some backgrounds from CGTextures and
4FreePhotos and pretty soon I was looking at a board of hexagons with a sea background and a few different colored tiles. I wasn’t sure what to do with it so I put on a few farms, fortresses, bridges, RPG stuff. I drew lines for roads, put things at the vertex. There were cool free fonts I saw at Dafont, sound effects at PacDV.
Just messing around.

Now after a few days of this I needed to figure out what the game was actually going to be. Originally I was thinking Massively Multiplayer Role Playing with resources, characters, an economy. Needless to say, such a game would take years if not decades for a single person to write. So I had to toss this out and think about what simple rules might be easy enough to implement but still fun enough to be worthwhile.

At this step in the game of making a game, Simplicity is the keyword. KISS – Keep It Simple, Stupid. At this point you’ll have 1000 ideas, 100 of which are good, 10 of which are implementable. But you can only do 1 idea, so you have to toss all but one game idea, even the good ideas! You’ll have a chance to do them later. Toss everything you can. I tossed characters, multiplayer, the economy, vertex drops, roads, until all I had left was a humble tower on a humble tile. There was only one action, the humble mouseclick. Click on a legal move tile and a fortress is built there. The enemy does the same. Whoever gets the most territory, wins. Game design complete.

Well, it wasn’t really complete. I had to think about the level design – did I want to custom-design all my levels or do it automatic – I chose automatic using a fractal, since I’m lazy and I didn’t want to play the same level over and over again, it’s randomly generated each time. Also I had to think about progression – how does the game get harder, how do you advance levels – I wasn’t sure but later during playtesting I just gave the AI an additional initial move with each level. There was a question of how all the graphics was going to look – some I didn’t toss in until the end – but the basic sprites I needed were defined.

But in sum, it was enough to proceed to the next phase, programming.

Week Two: Programming

“Generally, the more weight you put on, the less effective you are.” – Sugar Ray Leonard

Only one week for programming? Well not exactly, you’re going to be programming the whole thirty days. But your core coding needs to happen in a week. What I mean is, by the end of week two, you should have a basically playable game. It’s going to have some quirks, bugs, maybe missing the splash screen and user login, but the core game mechanics should be present.

But how do we get from design to a running game skeleton? There are many paths to the goal, but first we’ve got to discuss platform. You should have already decided what platform you want to target – desktop, iPhone/iPad, android, browser, Xbox, Gameboy, PS3, whatever. They each have advantages and disadvantages: desktop is great for maximum power and graphics but hard to distribute; iPhone is easy to distribute and monetize but hard to port or expand; android gets you to lots of phones but limits screen space; browser can run anywhere but is harder to monetize; Xbox, Gameboy, PS3, any console device has a big market but production and distribution costs can be very high. For my game, I chose browser because I wanted to reach the maximum audience, I didn’t want to front money for a Mac and a development license, and I have more experience with browser-based technologies.

Once you’ve picked a platform, you can start setting up the framework. I didn’t know JQuery very well when I started, but it was the framework my friends at MindQuilt had the most experience with, so I knew what it could do, and I’d heard good things about how javascript has matured in the past few years. On the server side, I’d already been writing some python, and appreciated its lightweight approach compared to Java, especially with Django and Google App Engine. Plus, I wanted to play around with some of these to learn new technologies and enhance my computer hacking skills. So I got a basic app up without much difficulty.

Essentially your programming task is to convert the game design into functioning code. It’s not quite that clean, because you’ll revise the design and flesh out details as you’re coding, but you need to think about how to implement all those fancy features in the model. A great site I recommend for this “making the dream reality” is Amit’s Game Programming. What helped me the most was his excellent article on Grids. This gave me the algorithms I needed to implement a hexagonal grid, transform world to screen coordinates, and view adjacent tiles. I spent a day stuck until I realized that the origin of an HTML screen is top left, not bottom left as in Cartesian coordinates. Sometimes, we can all be dumb.

With a browser you’ll need to decide on HTML divs, canvas, or flash. I tossed flash right out because I don’t want proprietary stuff and it’s a dead end on iPad. In comparison, getting the game to run on the iPad for me was a simple one-line inclusing of the iPad Plugin
for jQuery. Canvas is trouble on IE but otherwise lets you do almost anything you can imagine: I started with that but quickly shifted to divs when I saw an article that divs can actually be faster in some cases. There are some graphics-intensive games that can only be done in canvas, but for the tile-based game I was writing, divs work just fine and have probably a 10x or more developer productivity. With divs, you have the browser doing most of the work for you with events, lots of library support for moving things around, images, overlapping, dialogs. Canvas is more like writing a dos game back in the 1980s, you have to do everything yourself from scratch. In my case, divs were the better option.

It still gave me trouble with sound – I used JPlayer which is great on FF and Chrome but problematic on other browsers – I’m not sure what the best technology would be for a very sound-intensive game. The site MediaIo worked great for audio conversion, though.

By the way, if you’re going with a browser-based approach I really recommend looking at the javascript on wordsquared, not only did they do an excellent job but the code is clear and well-written and you can see how they do lots of the “tricks” that make the site look and work good.

Enough talk, now for the meat (or soy, for you vegans, or Gagh, for you Klingons). Here’s a chunk of actual jQuery javascript code from the Board class which takes a set of hexagonal tiles, and gives them a fractal elevation attribute. I use this elevation attribute later to assign territory classes: less than 0 for water, +5 for mountains, grasslands in between, etc. The background images for different territory I assign later, I converted them to pngs from svg using fileformat.info.

self.fractalNoiseTiles = function() {
            // fractal noise for tile elevations, to simulate terrain
            var persistence = 0.5;
            var octaves = 4;
            for (var octave = 1; octave 

If you're doing a single player game, as mine is, you'll need an AI. Even with a multiplayer game, you'll want to have a basic pluggable AI just for testing purposes. Now as the IBM Watson match demonstrated, AI can be a fascinating field, but also very complex and difficult. Stick to obvious things you know to avoid getting lost in cascading levels of complexity and end up in Limbo. My first AI for the game, for instance, was very simple - simply move to a random legal position. Then I enhanced this by moving to the coast first, to try and block off enemy entry points, falling back on random moving if this was impossible. Finally I made a more sophisticated AI that took into account not just good moves offensively but also how to defensively block the enemy. Still the AI is not very good, particularly in its ignorance of disclosures. But here's the code for two movers, the Coastal and Random AI movers, in my javascript Player class, to give you a feel for what an HTML5 div-based AI looks like, and how easy it can be.

self.coastalMover = function() {
            // prefer inner coast
            var numMoves = $('.valid-move')
                .not('.perimeter-tile')
                .filter(self.board.isAdjacentTo('sea-tile')).length;
            if (numMoves > 0) {
                var randomMove = Math.floor(Math.random()*numMoves);
                $('.valid-move')
                    .not('.perimeter-tile')
                    .filter(self.board.isAdjacentTo('sea-tile'))
                    .eq(randomMove)
                    .each(self.board.makeMove(self.turnComplete));
                return;
            }
            // prefer perimeter
            var numMoves = $('.valid-move.perimeter-tile').length;
            if (numMoves > 0) {
                var randomMove = Math.floor(Math.random()*numMoves);
                $('.valid-move.perimeter-tile')
                    .eq(randomMove)
                    .each(self.board.makeMove(self.turnComplete));
                return;
            }
            // otherwise make a random move
            self.randomAIMover();
        }

        self.randomAIMover = function() {
            var numValidMoves = $('.valid-move').length;
            var randomMove = Math.floor(Math.random()*numValidMoves);
            $('.valid-move')
                .eq(randomMove)
                .each(self.board.makeMove(self.turnComplete));
        }

Along with the frontend code you will need backend, server-side code. I've heard good things about Node.js, but what I had available was python on Google App Engine so I went with that. It was a lot harder to get the scoring and login code to work than I expected, but that is due more to my ignorance than any real difficulty. Once I got the hang of it, it was a breeze, especially compared to the heavy-handed lugging I'm used to with jboss and war files. Here's an extract of my backend python code for the Scores class, which grabs the top 10 scores out of the datastore and, if the user is logged in, adds on the top score and ranking for that individual user.

def get(self):
        scores = db.GqlQuery( \
            "select * from Score order by score desc limit 10")
        # fetch top scores
        scores_list = [];
        i = 1;
        for score in scores:
            username = 'anonymous'
            if (score.user is not None):
                username = score.user.nickname()
            single_score = {
                'user': username,
                'score': self.format_score(score.score),
                'date': score.date.isoformat(' '),
                'place': self.format_ordinal(i)
            }
            scores_list.append(single_score)
            i += 1
        # append your top score if logged in
        user = users.get_current_user()
        if user:
            score = db.GqlQuery( \
                "select * from Score where user=:1 order by score desc limit 1", \
                user).get()
            # fetch your top score
            if score is not None:
                scores_list.append( \
                    {'user':'','score':'','date':'','place':''})
                # spacer row
                place = db.GqlQuery( \
                    "select __key__ from Score where score > :1",\
                    score.score).count() + 1
                # fetch your top score
                single_score = {
                    'user': 'Personal Best',
                    'score': self.format_score(score.score),
                    'date': score.date.isoformat(' '),
                    'place': self.format_ordinal(place)
                }
                scores_list.append(single_score)
        self.response.out.write(simplejson.dumps(scores_list))

With your basically playable game up and running - not ready for prime time, not even close - but playable, you're reading for serious testing.

Week Three: Playtesting

“We're all given some sort of skill in life. Mine just happens to be beating up on people.” - Sugar Ray Leonard

Okay it's really just "testing", or if you're fancy and want a higher salary, "Quality Assurance", but to make it more exciting we'll call it "playtesting". That is, you get to play your game.

Now playtesting isn't just about seeing if it works. Sure, you need to find the bugs and fix them, you need to do that no doubt. But what it's even more about is discovery. The best QA people you'll find don't just run the test scripts and report the results. Instead, they prod around the limits of the application until it breaks, and try to figure out what this implies about what else might be broken, and why. Where the user experience is lousy, where I'm doing something with menus when I just want to click, and vitally, whether or not it's fun. Most importantly, discover how this implies the game could be improved to be more playable. This is what you need to do while playing the game.

When the tile game was up and running I started clicking away, saw and fixed some obvious bugs, and found out that the game wasn't very fun. It was just too easy to beat the AI. I added a few tweaks for more aggressive playing, but still it got to be boring fast, and took too long to play after it was obvious I would win (or lose). So I added an Autoplay button to speed up play when it looked like you were going to be win - but be careful! - one time I caught myself with hubris and ended up losing after pressing Autoplay. Still, just territory wasn't enough since it didn't give the kind of strategic advantage I was looking for if you capture narrow mountain passes, block off a plain, things like that. So I added the concept of "enclosures", that is, completely surrounding an area with your pieces and barrier land, which then automatically become filled with your own pieces. Not only did this add the strategic aspect, but it also sped up the game. Now, it did end up being the most difficult, time consuming, and bug filled piece of code I had to write for the whole game, but doing the enclosure calculation was not only intellectually satisfying, it ended up substantially improving playability.

There was a lot of iteration during this week of playtesting. I don't want to say agile, because I've heard that term ad naseum until it now has the same amount of meaning as "achieving key objectives with maximum leverage", but there was a lot of tweaks to the graphics, the runtime, the sounds, the rules. As the saying goes, 1% inspiration, 99% perspiration.

Week Four: Refinement

“My ambition is not to be just a good fighter. I want to be great, something special.” - Sugar Ray Leonard

Lots of good game ideas die a premature death because their authors give up towards the final stretch. That's what week four is all about - refinement. Getting your game over the hump from something that resembles a college compsci doodle, to a professional looking game. Now we're not aiming for Bungee-level storyline, thematic videos, and a model-staffed convention booth.

Refinement is what separates the men from the boys, the women from the girls, the mature transsexuals from boytoys. It's the roadwork that you have to put into the game if you want it to succeed. It's not fun, but it must be done. Do you have a splash screen? A score screen? Rules? An About page? How fast does it scroll? Does it flicker? Are the graphics lined up perfectly, or are there gaps? Does it work on different targeted platforms: iPad, Firefox, Chrome, Internet Explorer?

I had to work on all sorts of little details for the game in the refinement stage, most taking longer than I thought. I had developed in Chrome, which is the fastest browser with the best support for most HTML5 features, and it worked fine. Then I tried Firefox and it didn't work at all. I was using the jQuery rotate plugin, which doesn't work on Firefox, so I had to rethink the way I was handling tiles. Then I tried to view it on iPad, which looked horrible, so I spent a day redesigning my top-level div structure until it displayed properly. Multiple sounds had trouble on the iPad so I had to disable most sounds there, touch didn't work so I had to get the jQuery iPad plugin working properly. I didn't have a splash screen, so I had to write one, which was harder than I thought given that it has to appear before the game, after a level is completed, after the game is won or lost, with the rules, all at the right time in the right order. Scoring was even more difficult since it involved using some google APIs I wasn't familiar with, required me to upload a datastore index file, heck I even had to write a custom thousands-separator method for python since one isn't built in.

I thought about efficiency. There's a lot you can do to make a game load and run faster. I looked at the images I was using, switching to jpg instead of png for photographic-type images due to its better compression in this area. I consolidated all my javascript files into a single compact, minimized file with Google Closure Compiler. I made my CSS smaller and faster with the online YUICompressor and then switched my index.html to use the optimized versions. Some things I was using custom images for I found I could instead use existing CSS effects and jQuery functions. I was able to load public domain images off of existing sites like PicasaWeb instead of overloading my app engine. Smaller tile sizes took up less image space and ended up being easier to play with as well.

The refinement step is the biggest pain, the most frustrating, the least fun, but also the most necessary. Your users will appreciate it, and so will you.

Week Five: Release

“A fighter never knows when it's the last bell. He doesn't want to face that.” - Sugar Ray Leonard

You're game is done. Thirty days have passed - or in my case, thirty-three, because I couldn't get scores working. My fault for "leaving it to later". Next time, I'm including all elements of my game before starting playtesting, no matter how "easy" it's going to be so I don't shoot myself in the foot. But finally it was done, uploaded to google appengine, and ready to go. The game had been "knocked out", and like a boxer I was rather exhausted at the end of it all. Quite a relief.

But even being done isn't being done. I got a suggestion to add the rules section so it was clear how to play the game. I showed it to a few close confidants to get feedback. I submitted it to an HTML5 game site for inclusion on their index. And I wrote this blog post. Marketing is the fifth week in a nutshell. Let the games begin.

UPDATE: by popular demand, here is a link to the playable game: Towers of Wolin Playable Game. And here is a link to the complete sources: Towers of Wolin Source Files.