This is a detailed account of the first thirty days of a new game I’m building. I’m hoping this gives you some insight into what it takes to build a game all by yourself. Each day in this developer log has a lesson learned/nugget of wisdom. If you don’t have time to read the entire log, here are the three most important things I’d want you to walk away with:
Know your weaknesses (and avoid them). Play to your strengths. I know what I’m good at (intuitive controls, polished game mechanics, narrative/artistic style), and I know what I’m bad at (sprite animations, sound, high production value content, intensive physics). Too many times I’ve seen developers taking on more than their current competency. It’s better to underestimate your capabilities and finish a game than aim way too high and eventually give up.
Don’t toil for months without releasing. It’s the absolute worst thing you can do in a world where digital distribution (and subsequent updates) are effortless to make. The speed of iteration detailed below is what you want to shoot for when building your own games. You want to be a indie game developer? Get fast at coding and prototyping. Get something out there. Iterate publicly. Get feedback often. This is the one advantage you have over large AAA companies. You are a “real person” that can have a human-to-human conversation about what’s good and bad about your game. “They,” are faceless, slow-moving companies who don’t care about any one person’s opinion. Get something into the hands of your customers and have a conversation with them. I want to flip a table every time an indie game dev says “So I’ve been working on my game for about 8 months now and haven’t released…” Don’t be this guy.
Discipline and habit. Stop dreaming and get to work. Passion and motivation waxes and wanes. Discipline and habit will get you to the finish line. Here’s how to start:
I finally wrapped up A Noble Circle, and was hungry to start on my next project. I had two games in mind: a RTS based off of Sins of a Solar Empire; or a turn-based card dueling game based off of Waving Hands. You’ll notice something about each one of these projects. They are all based off of previously created works (A Noble Circle was inspired by Edwin Abbot’s novella Flatland… even A Dark Room was inspired by Candy Box).
There is a great video that’s worth a watch called Everything is a Remix. Make peace with the fact that there are no unique ideas, and go build something (however much you think it’s a “ripoff” of something that’s already out there).
After much deliberation (like 5 minutes), I decided to go with the RTS.
Here’s what I started with:
Here’s what it looks like after 30 days of development (about 5 hours of work per day):
And most importantly. It’s already in the App Store.
I will repeat this. It. Is. Already. Released.
Before I take you through the development process day-by-day, let’s get some “in before” questions/comments out of the way.
Here are some questions/comments that I know will come. So I’ll take the initiative and try to answer them ahead of time.
I’m afraid to release an unfinished product. People may play it, not like it, and never come back.
Chances are, no one will download your game anyways. You have to have a community you are catering/marketing to. You probably have no marketing budget, and you probably aren’t a well-known developer. So you don’t have to worry about people not liking your game, because you have to have downloads in the first place to get to people hating it.
You are a meany face.
The situation of no downloads is a great position to be in. You have no stress of flopping. The fact that you actually released something is a mark of success. Remember those dreamers that do nothing but dream? You are no longer one of those people. It’s only uphill from here.
If you get downloads, sure, some of them will hate what you built (A Dark Room has 2000 negative reviews… some of them are absolutely vicious). These people are not your customers. What you want to find is those who see promise in what you are building, and are excited to get the next update. They will stick around and support you (and your future projects). Make contact information easy to find online and in your game. The sooner you get your game out there, the faster you can find your fans.
If you’re really concerned about a bad first impression, try restricting the release to a small region (on mobile you can select which countries you can release to). Absolute worst case, you can kill the project name and rebrand it. So maybe use a throw away title if you’re really really worried.
That’s fine for small projects, but even marginally larger titles can’t support that fast of a release cycle.
Hogwash (I’ve always wanted to use that word). The MMORPG Shroud of the Avatar, after raising $1,919,275 via Kickstarter did its first release a few weeks in. They created a room with a chicken in it. That’s it. The team got something out there for people to see and play around with. Straight from the horse’s mouth, Shroud’s producer (Richard Garriott) talks about incremental development and releasing early. So don’t tell me your game is too big to release incrementally.
I can’t make a game that fast. I have a full time job, so I can’t devote that kind of time.
Make a smaller game.
And with another group of friends during another weekend, I built a Cards Against Humanities Clone.
And yet another weekend, with yet another group of friends, I made a “Massively Multiplayer” Dive Kick Clone.
With each game you build, you add to your personal asset library. With each game you build, you get faster at spinning up a new environment, and getting things to show up on the screen.
I can’t code. I don’t even know where to begin.
Learn to code. Get that spinning square working. Read this post I wrote just for you.
Now let’s dive into the world of game dev. One day at a time. Each day will have the lesson you need to learn from it.
This was my first attempt at a multiplayer game on iOS. I had no idea how to do this. I knew it’s possible to do (a game called Spaceteam supports local multiplayer). So I did what any professional, successful, and accomplished developer would do. I Googled for “ios local multiplayer tutorial”, came across this blog entry, and rolled my head on the keyboard until I got something working.
It’s impossible to keep every api, technique, pattern, etc, in your head. You have to learn to search for things, read mindfully, then ask for help if you’re still stuck. This is a process that you have to get comfortable with. You’ll be doing this your entire development life.
After about a day of tearing my hair out (something you also have to get used to). I got a simple “hello world” working using MultipeerConnectivity.
Here is what my amazing RTS looked like at the end of day one:
The code name for Mildly Interesting RTS (MIRTS) was Slow Time
Strategy (STS). I reused icons from A Noble Circle and have my own
“spinning square starting point iOS app” that I use as a spring board
(which is why you see the spinning square on the screen). When you tap
MultipeerConnectivity does its magic. I don’t even have
anything printing to the phone’s screen. It just prints to the
The iOS simulator (the device on the far left) is dog shit slow. Use a real device (middle) for building video games. You can see the console output on the right saying “hello” when I tapped my phone.
It took me an entire day to get that working. Other people will look at it and say “What, that’s it?” But developers know that feeling of refusing to give up and then finally succeeding. When you deal with this kind of stuff, take a moment to “experience” that wonderful rush before moving on to the next infuriating task.
Local multiplayer was a huge unknown for me. After I figured out how that worked, I essentially mitigated that risk. If you have too many “I don’t know how to do this” moments in your game, then you probably need to start on something smaller. For MIRTS, the only real unknown for me was that initial device handshake.
With my biggest risk out of the way, I put multiplayer on the back burner and worked on the most important part of every game, the game loop.
I had a rough idea of how I wanted the game to work:
I took my spinning square, changed it into a non-spinning circle, and added it to the screen 84 times. I then created 84 labels, and used Photoshop to create a blue and red colored node. I then wired up this terrible front-end to my terrible game loop.
Here’s what the game looked like at the end of the day:
With regards to speed in development and prototyping, if you don’t think you can create what I’ve done above in a short period of time (front-end, game loop, or game logic), take a step back and brush up coding. This “game loop, plus game logic, plus front-end” concept should really be muscle memory.
When you have a blank canvas, it can be overwhelming to figure out what to work on next. I could have went a number of different directions:
I decided on multiplayer. Now that I have real game state, I wanted to make sure my assumptions about transferring the data weren’t wrong. That, and I really couldn’t play (in order to flesh out the engine) without… ya know… having someone to play against.
Being able to verify an assumption took precedence over the other two options. After making sure I had a solid serialization strategy for sharing data over the wire, only then did I work on the engine and UI:
Here is my super awesome game being played over local multiplayer.
With an uneven number of control points, one could get the advantage and then win by overpowering the other person. By day three, I was really close having one of my friends try the game out and play against me.
I scheduled a day to play the game with my friend and self imposed a deadline. With some semblance of strategy in place (plus all local multiplayer risks and assumptions resolved), I was ready to work on the visuals.
This game was butt ugly. A part of me finds it really frustrating that people need “super realistic over the top visuals”. Personally, I feel those novelties fade over time. Artistic qualities/style give what you build longevity (Ico, Journey, Flower, The Witness, and Windwaker being a few examples)… I’m a bit of a hypocrite given that the graphics of Sins of a Solar Empire were what initially drew me to it (I stayed for the game mechanics).
The engine for my RTS represented location within a coarse grained 7x12 grid. Unit locations were only granular to that grid (as opposed to granular to the pixel).
This gave me a bit of freedom with regards to how the units were represented on the screen. I decided to do floating “particles” that orbited the center of the node.
Enter math from stage right.
As a game developer. It doesn’t hurt to have a cursory knowledge of algebra and trigonometry. I was able to build all the sprite movements in both MIRTS and A Noble Circle by understanding Trig Ratios.
Here is the formula for getting the center of each grid/quadrant (simple algebra):
def quadrant_size game device_screen_width / game.grid_width end def quadrant_location grid_x, grid_y [ quadrant_size * grid_x, quadrant_size * grid_y ] end
To get the unit’s orbiting animation, the following formula was used (which was ran every time in the render loop):
new_x = quadrant_center.x + Math.cos(unit_angle) * orbit_distance new_y = quadrant_center.y + Math.sin(unit_angle) * orbit_distance sprite.position = CGPointMake(new_x, new_y)
After the node’s position is updated, I increased or decreased the orbiting radius based on how far away the unit was from the center of the quadrant:
orbit_distance += orbit_growth_speed * orbit_growth_direction if orbit_distance > quadrant_size.fdiv(3) orbit_growth_direction = -1 elsif @orbit_distance < -quadrant_size.fdiv(3) orbit_growth_direction = 1 end angle += orbit_speed * angle_direction
Here is what it ended up looking like:
Aside - Here is a scene from A Noble Circle (which uses a similar “orbit” formula):
Aside - And another fancy orbit formula usage (so art, much style):
With the fancy orbiting in place. I wanted to make the movement between the nodes smoother. Keep in mind that the engine for my RTS represents the game as a 7x12 grid. For moving a unit from one point to another, I simply set an estimated time of arrival. With the current time and the ETA, I can use math (gasp) and interpolate the in-between frames using Penner’s Easing Functions.
For unit movement, I used Linear Easing (with no acceleration):
ending_position * time / duration + starting_position
Which looks like this (I cleaned up the UI a bit too… the dots are super tiny):
Aside - Here is an application of the Quint Easing Function in A Noble Circle. “Quint” is to-the-power-of 5 (Quadratic would be to-the-power-of four).
Here is how you’d ease in:
def ease_in_quint time, start, change, duration change * (time /= duration) * time * time * time * time + start end
Here is how you’d ease out:
def ease_out_quint time, start, change, duration change * ((time = time / duration - 1) * time * time * time * time + 1) + start end
And what it looks like:
The last day before my first round of play testing was to make sure multiplayer still worked. Over the last couple of days, new game state properties were added. I had to make sure all this was being properly serialized and sent over the wire to player two.
There was a bit of work to make sure the game wasn’t too chatty. At one point I was sending updates ten times a second. This was way too much data going over the wire (so much, that move inputs from player two weren’t getting a chance to make it back to the host). I added a bit of logic within the game engine to only send updates if an action occurred, or if something actually changed on the map (most of the time is spend decrementing cool downs and waiting for ETAs to be reached). If nothing changed within the game, only the logical clock would be synchronized (the logical clock is an integer representation of time within the game engine… this tiny piece of information was synced so that movement interpolation on player two’s screen was fluid).
If the paragraph above was way over your head, stay clear of networked games until you have a solid grasp of everything before day 6. Concepts such as serialization, interpolation, logical clock synchronization, etc are not necessarily difficult to grasp. It just may be too much content to take in all at once. Take a look at the Multiplayer Dive Kick Clone that me and a group of my friends built during a weekend hackathon. A lot of these concepts are covered there.
I play tested with my friend for a couple of hours. It’s very, very difficult to have someone play your game over, and over, and over again. So when you’re at a point where someone is about to play test, don’t expect a ton of replays. We played about ten games before I exhausted the favor he was giving me by playing my crappy RTS.
Here is what MIRTS looked like in all its glory after one week:
This is the speed and competency of a “seasoned” game developer. Ask yourself if you can accomplish what I’ve done in a week’s time (~30 hours). Review what was covered in these days. Study up on what you feel you’re weak in. Try to recreate parts of this game.
The next entry will cover week two.