How Many Pages of Code in an Indie Game?

FLUTTERFLY is done and launches for iOS this week! And after almost nine months of non stop work, it’s time to reflect. How much work did I actually do? With an app it’s tough to tell sometimes. You bang on your keyboard typing code at the prompt… then you compile… and then an app appears as a single icon on a device you can put in your pocket.

Unlike a novel, you can’t flip through it and feel the pages. Unlike a movie, you can’t scroll through the timeline to get a sense for every frame. It’s a game! It has no real physical mass, as it were.

So I decided to convert EVERY PAGE of code I personally wrote into a pdf, then in photoshop, shrink them down into little jpegs and line them all up. It’s a fascinating way to get a sense of the over all work involved in an indie game.

So: HOW MANY PAGES OF CODE IN AN INDIE GAME?

The answer?

An astonishing 1,266 PAGES OF CODE in Flutterfly that I wrote myself.

(SCROLL DOWN TO SEE ALL THE PAGES!)

A few big caveats:

1. There is obviously WAY more code in the app than just the stuff I wrote myself. There are tons of amazing plugins that I bought and used. And of course the Unity3d game engine which the whole thing is built on probably has enough bits to fill a library. But for this experiment, I think the page count of the stuff I wrote personally is a pretty cool metric.

2. Pages of code are generously spaced. It’s not like this stuff is packed in there. You’ll see from the images below that code, in this case C#, is not very dense when it comes to the amount of space it takes up. So take those 1,266 pages with a grain of wide-margined salt.

3. Code is repetitive. There’s a lot of code that repeats. For instance, almost every class I wrote starts with
using UnityEngine;
using System.Collections;

It’s part of the lexicon. So it’s not like every line of code is completely unique necessarily.

4. A lot of code gets deleted. The game evolved a lot over nine months. So entire sections were ultimately zapped. I’d estimate that at least a good 10-15% of the final product were axed and aren’t pictured below.

5. There is a lot of work that goes into a game that is NOT CODE. There’s animation and sprite sheets and models and sound and camera work. So the code is maybe half of the whole story. At most.

6. A lot of programmers pride themselves on writing super condensed, tight and streamlined code. The less code the better! I’m not one of those guys! I’m more from the literate school: lots of comments and notes to myself. Just fyi.

7. I’m seeing now that a couple blank pages snuck in there. Whoops. Converting over a thousand pages of code into little thumbnails is no easy task unto itself. I highly recommend this little photoshop script if you’re interested in trying the same for your game!

So without further ado, here are the 1,266 pages of code I wrote for FLUTTERFLY over the last nine months. I’ve colored some of it RED and have annotated those sections. Figured it’d be interesting to get a sense of how much of the code did what exactly. Who knew powerups were so complicated?

See you after the long scroll!

code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
code
WindManager

Whew! I feel exhausted just looking at all of that.

And sometimes writing code is like creating music– it just flows out of you. But more often than not it can be a very exacting and painstaking process where you battle through mazes of logic to just write a single line.

Mostly though, I’m excited about starting the next project! Time to open up a new blank page one.

PS: I did a similar experiment with my previous, smaller app SPIDER PRANK. If you’re curious, you can check it out here!

Leveling Up Your App: 3 Lessons I Learned the Hard Way

So I’m about to launch FLUTTERFLY — a brand new side-scrolling color matching game. Guide colored butterflies as they migrate and match colored blocks.

For those of you who’ve been following this blog or who follow me on twitter, you might know that FLUTTERFLY actually started as FLUTTER. Flutter was a previous incarnation that was a simple endless game. There were no levels. No powerups. No stages. Just one endless side-scroller that went on and on.

I started work on the original Flutter in Feb 2014, and working in Unity3D, quickly got something up and running. The original core concept was to take a fun color-matching / tetrisy mechanic and make it a side-scroller. Could I combine two genres to make the whole greater than the sum of its parts?

It took another few months to polish the game into something I considered finished. And I uploaded Flutter to the app store in mid-May 2014 to (drumroll)… the sound of crickets! Flutter opened with a whimper. Despite some nice feedback from some folks in the community, sales were pretty non-existent. So… game over??

But I still believed there was something great at the core of Flutter. I thought the gameplay was original and fun. The app, however, had a long way to go. For the past five months I’ve been working non stop to make Flutter better. In fact the new version has evolved so much that it’s really an entirely new game. So goodbye Flutter and hello FLUTTERFLY!

In the meantime, here are THREE LESSONS I learned the hard way that I’ve worked very hard to fix.

 

1. PLAYERS WANT TO WIN

I created Flutter originally as an endless side-scroller mainly because I wanted to finish an app quickly and not spend five years on it. Why design 100 levels when you can design 1, amIright? And of course the endless platformer/flappy/runner is a tried and true genre all unto itself. But there’s just one problem. You never win. It’s not a problem for games like Flappy Bird. I think the frustration of dying repeatedly is what spurs players on in a game like Flappy. It’s addictive masochism.

flappy fun

But that sort of hardcore die, die, die experience flew in the face of my app. I discovered too late that people really liked these butterflies. They didn’t want them to die! And when they died, they felt bummed and didn’t want to play anymore. I needed to let people win. So I’ve spent a big part of the last several months developing levels.  I added a FLOWER object that served as a goal for players to reach.  Now players could actually win!

Now players can WIN

Now players can WIN

It has been a lot of extra work, but I think the results have been worth it. Playtesters are experiencing joy with the app finally. Saving butterflies is compelling. Winning is compelling. And it keeps people playing. Besides, I don’t want to be the guy forcing people to kill all their butterflies, right? Because that’s what an endless game is. It’s inevitable death. The lesson for me is that I had a happy game on my hands—not the casual equivalent of Team Fortress 2 (God, but I do love me some Team Fortress 2).

LESSON #1: If losing your game isn’t fun, players better be able to win it.

 

2. SCREENSHOTS MATTER

FLUTTER 1.0 looks great in motion. I made a trailer that I think showcases it nicely. But stills? Not so much. I had this idea I’d be Jony Ive and use this minimalist solid color approach. Helvetica everywhere. The problem is this makes for really, really boring screenshots. So I’ve gotten to work adding particles, flares, glow effects and a nice handwritten font. It makes a world of difference. The game is much more beautiful, both in playmode and in a still screenshot.

Which game would you rather play?

Which game would you rather play?

When you’re an indiedev and no one’s heard of you or your game, screenshots are THE first thing people will look at. I’ve learned the hard way that your screens gotta be amazing. There’s a chance no one will watch your video, not least of all give your game a try.

LESSON #2: If no one wants to play your screenshot, no one will want to play your game.

 

3. ONE MECHANIC AT A TIME

At its heart, Flutter is a pretty simple game. Or so I thought. Match butterflies with colored blocks. What’s so hard about that?

But sometimes as a dev it’s hard to see your own game clearly. If I’d been honest with myself I’d have admitted that there are actually many different kinds of blocks to match: avoid black ones, match identically colored ones, and hit the correct side of a dual colored block. In Flutter I’d spent a good deal of time on a lengthy tutorial hoping this would be enough to get players comfortable. But it wasn’t and they weren’t. They were confused.

I failed to realize that my game really had more than one mechanic. In a way it’s semantics, but I think it’s helpful to think of a mechanic as any one thing a player does that gets a unique result. Matching a black block is DIFFERENT than matching a colored block: it’s a different mechanic. As a result, people were confused playing Flutter. There were too many mechanics thrown at them all at once.

Flappy Bird can get away without a tutorial and without levels. Press the screen once and the bird goes up. That is the ONLY mechanic in the game. But even an ostensibly simple game like Angry Birds has several mechanics happening. If you think about it, the game is more than just a slingshot. Tap the yellow bird and it goes quicker. Tap the blue bird it splits apart. Hit ice and it shatters. Hit wood and it breaks. Pigs with helmets are harder to kill than pigs without. Etc. And the player has to learn and master each one of those new elements. And if you don’t want a frustrated player, introduce new mechanics ONE AT A TIME.

In FLUTTERFLY, what was once a one shot tutorial is now a series of 15 levels (There are over 70 levels in Flutterfly, but the first 15 probably cover what was in the original Flutter tutorial).

Learning is now spread out over many levels

Learning is now spread out over many levels

The player learns the same tutorial content, but it’s spread out over time. Now the player is engaged and having fun as they learn. Moreover they have time to master each new mechanic before moving on to the next. It’s no fun trying to learn to ride a bike and swim at the same time. (For more on this, see Daniel Cook’s amazing presentation on feedback loops.)

LESSON #3: Players can only master one mechanic at a time.*

* notable exception being if the mechanic is so well known it’s part of the vernacular—like running and shooting in an FPS. WASD. We all know that.

FLUTTERFLY launches in a matter of days and so far reactions have been extremely positive. It’s also just super fun and rewarding to see an app you’ve put a lot of love into get better and better! Mainly though, it’s a reminder to me that sometimes you gotta just keep grinding to level up.

Make an App to Make an App (plus how to get Dirty in Unity)

Sometimes you end up making code that no one will ever see. Case in point: FLUTTERFLY has a bunch of different levels made up of different colored boxes. Several boxes put together make what I’ve dubbed a ‘Glow Box Set.’

A picture speaks a thousand words so here’s what the glow box sets look like in-game:

set01

set02

And here’s a glimpse at the Unity3D inspector window for everything that goes into one set:

glowboxset

There are a ton of parameters to keep track of: position variables for all the boxes, what type of box each one is, are we raining? Is this the last set in the level? etc. etc.

For a while I was tweaking all this manually. Now you can imagine that for a game with over 100 levels, where each level consists of 6-20 sets, the work becomes unmanageable real quick.

So I took a few days to design an app for my app. I created a new blank scene and set up a tool for level creation.

It seemed like a big pain in the arse at first, but it honestly went quicker than expected. And now that the tool is done, designing levels is a breeze– and even fun!

Here’s a look at my nifty new tool at work:

tooldemo

Much, much better than manually entering Vector3 position values one at a time.

Getting Dirty in Unity3D

So here’s a bonus PRO TIP for you Unity guys/gals out there. So you have your awesome level editor working and you make your tweaks in playmode, hit stop and WAIT! Where’d all my changes go?

As every Unity dev knows, changes made in Editor in playmode are not persistent. It has to do with serialization which is a huge topic unto itself. But I don’t want a seminar in serialization– I have a game to make! To get my level editor working I just needed to know one thing: How do you programmatically change prefab parameter values in Editor during runtime and have them stick around when you hit stop?

Easier than you might at first think. You just have to GET DIRTY.:)

Add a

using UnityEditor;

to the top of your class, and then call

EditorUtility.SetDirty(yourObject);

to save changes to values you tweak in Editor playmode. With my tool, I call SetDirty when I press the ‘Save’ button (shown above).

Now you can write a ton of values quickly and procedurally at the click of a button (ie– where should all these boxes go? well here’s 100 Vector3’s generated by code). Just be sure to comment the above two lines out before building, because as far as I can tell Unity won’t build if any of your scripts have a UnityEditor ref.

With the tool, now at least I have a fighting chance to finish this thing! Plus it has made level design quite enjoyable– a nice change from the torturous process of manual tweaking.

Odds Are

Okay so Flutter 1.0 landed with a dull thud in the app store. But THAT’S OKAY! It has only encouraged me to make it better.

So I’ve spent the last few weeks adding POWERUPS.

Boy are these fun to play with! More on those soon.

powerup

But in the meantime, I was thinking the other day about games and apps and what if you could pull back their skin and see their guts. Like what if you could take a game and strip it of all the design and particle effects and fancy graphics etc. What would be left?

I think it would look like this basically:

odds

These are ODDS. Aren’t they beautiful?

Specifically, these are the odds that specific powerup types will occur depending on our current difficulty level.

You can see from the array setups that there are 8 levels of difficulty (top to bottom), and 11 powerup types (left to right).

At difficulty 0, when a game first starts, the odds are 80% you’ll get a powerup type 0 (the most basic and rudimentary powerup type), and a 20% chance you’ll get a powerup of type 1.

Looking at the numbers feels like peeking into the Matrix to me. I find it fascinating that looking these over you can almost get a kinetic sense of the gameplay. This is the soul of the machine.

As a developer, odds are always top of mind. And of course with something like powerups, this is just the tip of the iceberg. There are other things to consider.

My coding style is pretty verbose. I comment the hell out of stuff to make sure I don’t get confused later. Apparently this is called Literate Programming. Here’s a snippet of comments outlining some of the odds logic at work:

// *** THIS IS WHERE THE MAGIC HAPPENS WHERE WE PICK WHICH POWERUP TO MAKE THIS ***
// need to consider a few things like:
// 1. have we already used this powerup recently? for some powerups that matters a little
// 2. certain powerups should be more prevelant at higher difficulty levels
// 3. of course only pick from powerups that are unlocked/available
// 4. if we *just* unlocked a powerup, we should probably use that one at least once in the following game
// 5. blackopolypse requires a lot of black blocks in the glowboxset
// 6. flutterworks requires a lot of colored blocks in the glowboxset


Isn’t life itself just an infinite array of odds?

Now that’s an odd thought!

T-Minus

FLUTTER is launching this Thursday at 12:01am… which ostensibly means tomorrow night.

05

So what does a solo developer feel on the night before launch?

FEAR
EXCITEMENT
ANXIETY
NERVOUSNESS
IMPATIENCE
EXHAUSTION
HOPEFULNESS
DREAD
TERROR
LIKE I WANT TO HIDE
LIKE I WANT TO JOYFULLY SHOUT
PRIDE
CHAGRIN
ANTICIPATION

There’s a large moon rising out the window. Tomorrow night it will be full. A sign? Who knows. As always with these things it could be a huge embarrassing bellyflop. At the same time, I’m very proud of it. I think it’s a very good game. Maybe even a piece of art.

As a solo dev I don’t have the resources of a studio to, say, throw a fancy launch party or do extensive beta testing. I showed it to some friends and they liked it. I know some of you might say- ‘hey! actually even indie devs have the ability to a/b test and get surveys filled out and do pr and marketing…’

You’re right. I’m very aware of that. But I’m also very aware of the opportunity cost. I’m an indie dev. I am one solo dude. Every second I spend sending out some pr email is a second I COULD BE SPENDING DEVELOPING THE NEXT APP.

And that is what I’ve been doing instead.

I’m already working on the next one.

I have a lot more control over making a game as amazing as I possibly can than I could ever have trying to market to a global audience for zero dollars. And maybe it’s naive. But I pride myself on stubbornly clinging to the belief that great art– great product– great entertainment– is the absolute best marketing there is. Build a great app and they will come. Apple has made that at the very least feasible.

Thanks for reading! I hope very much that if you purchase Flutter you enjoy the experience and have way more than $1.99 worth of fun with it! I hope it makes you smile. And curse. :)

Whether the masses take a shining to it or not, I’ll be dusting off the keyboard and working furiously on the next one. Perhaps by the light of that full moon.

Sebastian

New App!

Wow– it has been a long time since I wrote! I have been extremely busy– and I’m proud to announce that a new app of mine is about to… take flight. :)

I spent the last two months in a very harrowing Snake Plissken like Escape From New York. Packed up all my belongings, said goodbye to all my friends, office coworkers, neighborhoods, coffeeshops, bars and jumped a plane for California. All in the midsts of the worst Winter I’ve ever experienced in the Big Apple (40 degrees in late April– WHAT??!) and sneaking in coding and design every chance I had.

I arrived in CA two days ago (finally on Apple time!), and uploaded my new app yesterday.

uploading

Somehow screengrabs of this beautiful moment in Xcode never get old. :)

The journey to the completion of this particular app was particularly harrowing because of all the above stated hurdles.

And after reaching the finish line, I indulged in a little nap at the parent’s house. My mom snapped a pic and added some embellishments in photoshop– a little hint at the new app along with a clue as to where I inherited my photoshop skills:

20140501SebastianButterfly_w

More details coming very soon! For now, I’m going to enjoy some well deserved sunshine.

It’s good to be home.

New Update!

Well it’s been a while since I last blogged! And at long last I’m proud to announce the release of Spider Prank Lite! There are a ton of new features and two new spiders as well.
IPHONE5_EN_00004
There were a handful of commenters who said the spiders in the previous version seemed unrealistically loud and large… so now there are expert settings where you can chooses a realistic sound mode. You can also change the size of the spiders and fly to meet your own preferences.

Most importantly, I spent a good chunk of time optimizing for the ipod 4g. This was no small task. The ipod 4g has about half the RAM of the already kinda long in the tooth iphone 4. I almost had to write a completely different, lower rez version of the app to launch when an ipod 4g is detected… otherwise the device just couldn’t handle it. But using every trick in the book it’s running smoothly now.

And as mentioned– two brand new spider species to check out: Wolf Spider and Brown Recluse!

Hope you enjoy the update!

Coming Soon!

A HALLOWEEN TREAT is coming soon…

tarantula_snapshot

blackwidow_snapshot

How Many Pages of Code in an Indie App?

I was curious! So I just finished my iphone/ipad app: Spider Prank. How much work had I actually done? I know I’d worked like a dog for almost a YEAR on nights and weekends. But how much code had I actually written?

Well, there was only one way to find out. I saved all my code as pdfs, then opened in photoshop and saved each page as a tif. Then using some neat Photoshop actions, I shrank the images down and tiled them. I basically made sprite sheets out of them.

The result?

424 PAGES of C# code that I had personally written.

A friend joked that I had written the Great American Spider Prank novel. She wasn’t far from the truth. When you’re deep in development it’s hard to tell how much work you’re actually doing. There’s no such thing as ‘page count’ in scripting. And all your work is broken up into different classes of differing lengths.

But that’s a lot of writing!

Now granted, every page isn’t totally filled in. And it’s at least double spaced I’d say. But as a former screenwriter, I can safely say that I wrote the equivalent of at least 3 movies.

A few other notes– this is all the code that I wrote personally. But there’s a TON of other code in the app in the form of plugins I bought, cool license-free snippets I found online, and of course the huge C# and Unity3d libraries I built the whole thing on. So my code that you see below is just the tip of the iceberg when it comes to the bits in the game (gfx & sound aside).

Also I thought it’d be neat to highlight portions of the code to get a sense of how much code it took to create a specific result. In my app, I have a semi-intelligent spider that crawls around and reacts to swipes, gravity, taps etc. So in the code below, I’ve highlighted in RED all the portions that control the spider alone. All the rest is UI, photo import, saving/loading, localization etc etc etc. But the spider is quite a large chunk. Almost feels like peeking at a decrypted genome.

If you ever wanted a look at how much code goes into a little app, check out the code below and make sure to keep scrolling! If you’re a developer, how much code did you write for your game? I bet it’s more than you think!

code01

code02

code03

code04

code05

code06

code07

code08

code09

Delayed Launch

Okay– so *officially* I launched Spider Prank last week in the App Store. But *officially* I’m launching today. :)

The reason is as follows. I spent a ton of time with localization. Localization is simply translating all your app stuff so that it’s localized for different regions (Chinese, Korean, Russian etc etc.)

The great challenge, especially for an indie dev one man show, is that you not only need to localize your *app*, but also you need to localize all the itunes stuff that goes along with your app.

What does that mean?

Well first you gotta translate all the words that show up on itunes itself. The writeup basically.

Here’s my writeup in Russian:

**********************

ПАУЧЬИ ПРОДЕЛКИ

Невероятно реальные трехмерные ПАУК И МУХА на ваших iPhone and iPad!

ИСПУГАЙТЕ ВАШИХ ДРУЗЕЙ

АНОНС: http://www.SebastiansGames.com/RU

Насекомое ПОЛЗАЕТ. Оно ШИПИТ и АТАКУЕТ.

Оно реагирует на смахивания, касания и ГРАВИТАЦИЮ.

Уверяют, что оно настоящее!

Реалистичная, жужжащая муха вызывает их любопытство, а затем выскакивает паук и здорово пугает их.
Установите таймер: пауки появятся тогда, когда их менее всего будут ждать.
Используйте ваши фото в качестве фонов. Сделайте снимок экрана для фона, чтобы было похоже на то, как будто паук попал в ловушку в вашем устройстве.

ЭКСТРЕМАЛЬНЫЕ ЗВУКОВЫЕ ЭФФЕКТЫ И ТРЕХМЕРНАЯ РЕАЛИСТИЧНОСТЬ
РЕЖИМ НЕСКОЛЬКИХ ПАУКОВ

ВАЖНО: Совместимо с устройствами 4-го поколения и выше.
ВНИМАНИЕ: Максимальное количество пауков и фоновых фотографий зависит от поколения устройства.

Спасибо за поддержку НЕЗАВИСИМОГО РАЗРАБОТЧИКА. Чтобы узнать больше, посетите http://www.SebastiansGames.com

**********************

Now I’ve translated my app into ten languages (English makes 11), so do that ten times. Or I guess work with professional translators to do that ten times.

Then the hard part.

The itunes art.

Every time you have an app in the App Store you need to provide itunes with the requisite art to showcase your app. Five images. For each of the three screen ratios.

So five iphone4 images:
spiderprank_IPHONE4_01spiderprank_IPHONE4_02spiderprank_IPHONE4_03spiderprank_IPHONE4_04spiderprank_IPHONE4_05

Five iphone5 images:
spiderprank_iIPHONE5_01
spiderprank_IPHONE5_02spiderprank_IPHONE5_03spiderprank_IPHONE5_04spiderprank_IPHONE5_05

And five ipad images:
spiderprank_IPAD_01
spiderprank_IPAD_01
spiderprank_IPAD_01
spiderprank_IPAD_01
spiderprank_IPAD_01

And then you translate them.

Ten languages… times 15 images.

DE_IPAD_00000ES_IPAD_00000IPAD_FR_00000IT_IPAD_00000JA_IPAD_00000KO_IPAD_00000PT_IPAD_00000RU_IPAD_00000TH_IPAD_00000TR_IPAD_00000ZH_IPAD_00000

150 images to doctor in photoshop and translate correctly. No small feat!

And the reason the latest version of the app is late is that I’d just finished all of this work… and didn’t realize that when I submitted just the translated stuff to Apple, it would take them another week and round of approval to approve the artwork/itunes descriptions alone.

I’d mistakenly assumed that since my binary (the actual game data) was unchanged, I could skip the long approval process.

Live and learn!!

So long story short, now the game, the writeups, the itunes art are all properly localized. It’s official.

I’ve launched!