Ludum Dare 34 Postmortem
Fifteen minutes after the theme announcement, my friend Ben Homan walks through my front door. Not really my front door, I'm just a subletter. But this is a first. Normally he ignores our instructions to walk in without knocking. The first time, he texted me from the driveway.
Jesse Kooner walks in, also unannounced, bearing frozen pizza. Before he can even kick his shoes off, I loudly explain the theme: a never-before-seen tie between "growing" and "two-button controls".
Jesse has no laptop. I dig out an old one from my closet. I plug it in and start working on a few Windows updates. 72 to be exact.
Meanwhile, we decide which technology to use. Jesse's less code-focused skillset leads him to prefer Unity, while Ben wants to use the weekend as an opportunity to become more familiar with Node.js. We decide on Node.js. Jesse will provide creative input and artwork.
My roommates, a brother and sister, arrive home from an apparently underwhelming Christmas light show. The concept of a game jam is foreign to them, but they're good sports. We spend a half hour playing QWOP with them.
Our design parameters:
- Multiplayer. Otherwise, what's the point of Node.js?
- Probably 2D due to the limited timeframe. Although Jesse is more comfortable working in 3D.
Jesse originally suggested doing this competition a few weeks ago, when he wanted to create a mash-up of "Cookie Clicker" and a tower defense game. He resurrects the idea now, only halfway joking.
Ben likes the idea of a multiplayer vine growing game. I'm partial to a text-based social game about growing a social media brand. No one commits to anything yet.
Ben is not a big gamer, so I pull up a few famous HTML5 games on his laptop. Cursors.io. Agar.io. 2048. This last one interests me in particular, as it involves growing numbers.
I'm pitching Ben and Jesse on a multiplayer version of 2048. I envision a free-roaming world filled with numbered tiles to collect. Instead of collapsing numbers together against the edges of the board, players would find walls and structures within the world to collapse their numbers against.
- How can two or more games of 2048 occur simultaneously on the same board? In normal 2048, the player controls all tiles on the board. We decide to give each player a unique color, and allow them to assimilate unclaimed, grayed-out tiles.
- What happens when tiles from two players meet? We decide that whoever moves first gets to own the resulting collapsed tile from a move.
- How do players traverse through the world? We toss around the idea of procedural generation, but eventually decide on hand-crafted, linear levels linked together via portals.
- This raises the question: how do the portals work? And what happens to a player's tiles once they exit a level?
We've eaten two pizzas. We have a Git repository and a Slack instance which is ultimately only used to test out amusing Slackbot responses.
Although the game is 2D, we decide on a 3D art style with an orthographic projection, to allow Jesse to use his skills in Maya LT, which he promptly installs on my old laptop.
Ben works on the server with Node.js, while I start on the client with Three.js.
Ben heads home first, then Jesse. I pass out on my bedroom floor.
I wake to find Ben working in the kitchen. He spends the morning building boiler plate for the server, while I work out some Three.js details.
I return from a run just in time to catch Jesse pulling up with donuts. After lunch, he and I spend the next few hours working out a pipeline between Maya and Three.js.
I tweet our first screenshot, featuring colorized instances of Jesse's tree model displayed in a horribly distorted orthographic projection.
Without the server API to code against, I run out of things to do on the client. Ben finishes the data model, but he has trouble conceptualizing the rules for player movement. I haul my laptop over to indulge in some good old-fashioned pair programming.
Break for dinner. Burritos. Jokes.
Jesse continues modelling. With the basic API done, I start working to make the client consume it. Ben works on an image loader. We want to design the levels in GIMP.
Ben takes off. I've got player movement, animations, and tile numbers done.
Multiplayer works. Jesse and I play a few games against each other. It's fun! It's a game! We work out some issues with the level loading code and try to get an interesting level loaded.
Problem: it's pretty easy for one player to gain the upper hand and quickly assimilate all the tiles on the board, making it impossible for other players to move and grow.
Solution! Players should only control tiles within a certain radius of their "center". Outlier tiles are grayed out, free to be picked up by other players.
Fix implemented. Jesse heads home and I turn in.
Tweet another screenshot before heading to church.
At this point, I'm having an existential crisis about the name. I fire off a few panicked texts about it.
Ben and I are back to the grindstone. Jesse arrives with sandwiches and more donuts! Ben adds a cool username feature, but we eventually axe it to keep things simple.
Tweaks and bug fixes all day. Ben works on the level format, while Jesse lays out some levels in GIMP.
More polish. I put in Jesse's cloud models and a "connecting" spinner.
We finally brainstorm a name: Tile Risers. Jesse whips up a logo in Maya. We go through seven iterations before everything lines up in our janky export pipeline.
I spin up a Digital Ocean droplet, allocate an S3 bucket, commit the production URLs, and start filling out the submission form.
Time's up! Fortunately, we have another hour to submit. I later found out I misread the rules, and we actually had a whole extra 24 hours. At any rate, we were done. I commit two small bug fixes after submission, which is within guidelines.
- Three.js is easy and fun.
- ES5 causes a lot of pain by continuing silently when we ask it to do ridiculous things like "compare an object to an integer".
- Ludum Dare is a blast and you should do it.
- Play Tile Risers, view the source, and vote for it!