Growing, Indie Style

The media have covered to death both sides of the coin: The stories of developers striking it big, and how the great majority of indies don’t recoup their costs. A few days ago, Markus looked at indie iPhone development and how there is a middle-ground group of developers that are able to make make a living at it without going broke but without getting that big hit. Let’s call them the developer’s middle class.

Markus suggested that about 20% of developers fall in that middle class, but my gut feeling, when it comes to iPhones and games, is that it’s more like 5-10%. But it’s just a made up number based on personal observation anyway. It would be very interesting to conduct some sort of survey (or analyze the App Store data), but I fear the results would get muddled up due to the differences between full time indies, hobbyists, and big companies.

Snappy Touch falls squarely in the developer’s middle class. I’ve been very lucky and Flower Garden’s sales have been remarkably stable, hovering at around $2,000 per week (and spiking up during promotions and new updates).

For the 90% of developers that don’t make their money back, their choices are limited to either stopping, or digging deeper in their pockets (or somebody else’s pockets) and try again. For the 0.1% that hit it out of the park, they bring in so much money they can pretty much choose to do anything they want without risking the company.

For us middle-class developers, things are tougher. We have two choices:

  • The first course of action is plodding along doing what we’re doing, making a reasonable living and putting some money aside. We can build our personal and business nest egg, and then a bit more. And we can love every minute of it.
  • Choice number two is to take any spare money and reinvest it in the company. And in the case of iPhone development, that can only mean getting more people involved creating the games.

time-vs-money.jpgThe first choice is nice and safe. We can keep doing what we love, making a living from it, and even saving some money. Assuming the App Store doesn’t collapse overnight, we might be able to pull that off for a few more years. But it has a horrible hidden cost: The opportunity cost.

Most long-term, successful apps will require a fair amount of updates. New content keeps users interested, and they also expect support for new hardware (iPad, iPhone 4, etc). All the time I spend creating updates for Flower Garden is time I don’t spend making a new game. At the top of my list of hundreds of game ideas, I have four or five that I know will be successful, but the bottleneck from making them happen is my bandwidth. I can only do so much by myself.

That’s why I’ve decided that Snappy Touch needs to grow. Mind you, I’m not talking big corporation, I don’t ever want to even get to 20 people. But I would love to eventually be able to have a small team working on a new project and a few other developers maintaining and updating existing projects. I envision it happening mostly as distributed development and not in a traditional office setting.

The problem is how to start. Going from one to two people is probably the hardest step in growing a company. It’s a 100% increase! That’s probably another reason why successful startups often have three people involved from the start: Adding a fourth person is “only” a 33% increase in size, which seems more manageable.

Adding another person is also scary from a money point of view. It’s going from saving just a bit of money, to potentially spending it all so that maybe we can produce more games and make more money in the end. That’s a lesson I learned very clearly in Dope Wars: You need money to make money. To get crazy scores in that game, you had to take a huge loan out from the start (and then be really lucky). Except that in this case there’re no loans (I’m totally self-funded). And it’s also not a game, it’s real life.

Having said all of that, I’m going to turn this post into a recruiting tool (which is great because it self-selects the target audience to people who read this blog or follow me on Twitter).

Position Description

[Edit: Thanks for the overwhelming response! I already have enough candidates and the tricky part is selecting just one! I’ll post again whenever a similar opportunity opens up. Thanks!]

I’m looking for an programmer intern/part-time entry level position. Later on, if things work out, it could become a full-time position. I’m looking for someone who can dive into the Flower Garden source code and quickly be able to start maintaining it and adding features. I’ll definitely remain involved with the project, but I’ll be mostly setting the direction and working on the harder bits. I expect us to be in contact on a daily basis, and set up a quick iChat call once or twice a week (or if you’re local we can work half a day a week together).

Requirements

  • Very familiar with iPhone development (you should have some apps under your belt).
  • Very familiar with Objective C and the UIKit framework
  • Good knowledge of C (and a tiny bit of C++)
  • Available to work 10-20 hours per week. This is very flexible.
  • Bonus points for knowing Python or having used the Google App Engine.
  • I’d prefer someone who can work for several months (and maybe longer term).
  • Local to San Diego would be great, but not a requirement as long as we can voice chat easily.

Compensation is hourly and based on experience, but remember this is an intern/entry level position. Possible bonuses based on performance and sales. Sounds like something you’d be interested in? Drop me a note and convince me you’re the right person for the job..

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

Customizable Color Sections With OpenGL ES 1.1

One of the items in my ever-growing list of things to write about, is the rendering techniques I used in Flower Garden. In the end, it would make for a post with lots of pretty pictures, but there’s nothing particularly ground-breaking. After all, it’s all limited to OpenGL ES 1.1 on the iPhone, which means only two texture units and a two-stage texture combiner. As a result, more interesting ideas keep bubbling up to the top of the list and the poor rendering idea keeps getting passed over.

Every so often, something happens that bumps up the priority of one of the items in my list. Maybe it’s another related blog post, or a game coming out with something relevant to what I wanted to write about. In this case it was a tweet from Paul Pridham [1]:

tweet.png

Customizing colors in a sprite or texture is very frequent in games, from changing player characters into blue and red teams, to creating color variations of an armor piece, to letting the player pick the exact shade for their pet’s fur color. Or, in the case of Flower Garden, to change the colors of the petals on the fly.

There are two requirements for this:

  • We want to change colors dynamically.
  • We only want to affect certain areas of the original texture.

That rules out creating texture variations ahead of time, although that might be a valid approach sometimes if you have lots of art resources, don’t mind increasing the download size, and you have a fixed number of variation to deal with. It also rules out modulating/blending the texture by a particular color because it would tint all the texture, and we want to limit the effect to particular areas (leave the player’s arms their normal color, but change their shirt color).

This is one of those funny cases that it was a lot easier to do many years ago, when we used palletized color modes. You could set all the custom color areas to a particular palette entry, and then update that entry on the fly. Ah, all the awesome tricks palettes opened up the door to! I still miss them to this day.

color.jpgIn modern hardware it’s also really easy to do with a shader, but Paul wanted to use it across any iPhone device, and the majority of them are still stuck on OpenGL ES 1.1, so fixed-function pipeline it is.

The simplest approach would be to just render the model twice: First pass renders the texture, and second pass renders the custom color bits (you can render them with a white texture modulated by the global color to get the right color). The main drawbacks are that you’re doubling the number of draw calls, and, with 3D objects, it gets a bit tricker because the second pass needs to use the glDepthFunc(GL_EQUAL) depth comparison function.

The better way to do this is using the texture combiners. Texture combiners allow us to perform a limited number of operations to control the final look of a pixel. We can add two textures, or multiply them, or even do a few more complex operations. The true power of the combiners is that they can be chained together, so the output from one feeds into the input of another, allowing us to create much more complex operations.

The iPhone 3G is limited two two texture combiner units [2], but even two combiners are good to create a good range of effects.

Let’s think about what we want to accomplish. We want to leave some parts of the texture completely alone and display the original pixel value. In some other parts of the texture, we want to replace the pixels there with a custom color. Actually even better, we probably want to multiply those pixels by a custom color. That way we can author the part of the texture that is going to change with grayscale details, and our color adds the tint to it.

Let’s express it mathematically. Let’s make a function M that is 1 for every pixel we want to color, and 0 for the ones where the original texture is supposed to be displayed. Our desired color is c and the texture it t. In that case, the final pixel color (p) is:

p = M*(c*t) + (1 – M)*t


texture.jpgmask.jpg

We could express that with two combiners: The first one is a modulate (multiply) operation with c and t, and the second one an interpolation operation between the result of the previous combiner and the original texture, based on the function M.

Obviously M is just a mask texture. We can paint it white where we want to color the texture, and black elsewhere. We could even use the alpha channel of the original texture, but there’s one big thing to watch out for: If you have your texture as a png and process it through the default iPhone resource operations, the image will be premultiplied for you (whether you want it or not), so your color information will be set to zero everywhere that the alpha channel is zero. Oops. You’ll probably want to use the alpha channel to store transparency anyway, so we’ll keep the mask separate. If not, make sure you encode the image yourself (as raw or PVRT formats) so it’s not premultiplied ahead of time.

Are we ready transfer that formula to the texture combiners? Not quite. Apparently (and this was just trial and error, I haven’t seen it documented), the texture assigned to a combiner can only be the one at that stage. If you look at the second combiner, we would need to have the first texture as one of the parameters, in addition to the mask.

So instead, we can reorganize the function above like this:

p = c*(M*t) + (t – M*t)

What did we gain by that? The color is what’s going to change dynamically, but the mask and the texture always stay the same. We could precompute the M*t term by simply multiplying the texture and the mask. We can call that new term A. We can do the same thing with the (t – M*t) term, which just means turning black all the pixels in the texture where mask will go. That one will be B. The easiest way to “precompute” those values is just doing it in Photoshop and exporting it as a new png.

A.jpgB.jpg

Our new formula is now:

p = c*A + B

Nice and simple! Now we can really add that to the texture combiners like this:

// c
glColor4f(m_customColor.r, m_customColor.g, m_customColor.b, 1);

glActiveTexture(GL_TEXTURE0);
// A = M*t (precomputed)
glBindTexture(GL_TEXTURE_2D, m_maskHandle);
glEnable(GL_TEXTURE_2D);
// c*A
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glActiveTexture(GL_TEXTURE1);
// B = t - M*t (precomputed)
glBindTexture(GL_TEXTURE_2D, m_textureHandle);
glEnable(GL_TEXTURE_2D);

// c*A + B
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);

One more thing to watch out for: Because we’re using two textures, you need to have two sets of texture coordinates. In this case, we want them to be the same, so we can just point them to the same set of data:

glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].u);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].u);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

That’s it! You can see the results in the included project and play with the register combiners to achieve different operations.

At this point I was going to describe the texture combiner setup I use in Flower Garden to render the petals, but this post ended up taking longer than I had hoped for (I’m trying to shoot for an hour per post, but this has taken me already two hours between the code and the the post itself), so I’ll save that for another time.

[1] Paul developed Sword of Fargoal, by far my favorite iPhone RPG.
[2] The 3GS allows up to eight I believe.

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

Prototyping: You’re (Probably) Doing It Wrong

You’re not alone, I was also doing prototyping wrong until a few years ago. There are probably many different ways of prototyping games correctly, and maybe your way works great for you. In that case, a more accurate title for this post could have been “Prototyping: I Was Doing It Wrong”.

A good game prototype is something fast/cheap that allows you to answer a specific question about your game. The key points there are fast/cheap and specific question. It’s not a level of a game, it’s not a “vertical slice”, and it’s certainly not an engine for the game.

Chris Hecker and Chaim Gingold gave one of the best presentations on the subject of rapid prototyping. It was hugely influential for me, and it made me re-think the way I do prototypes. If you get a chance, find the audio for the presentation, it’s definitely worth it.

Mistake #1: Going With The First Idea

proto_2.jpgEvery company I’ve ever worked at has done this mistake. The team hashes out a bunch of ideas, and somehow they pick one (or create it by committee). Maybe they’ll create a prototype to show something about the game, or maybe they’ll dive straight and start writing a design document and developing technology. If you’re lucky, or you have an extremely talented game director, the game that comes out of the other end might be fantastic. In most cases, it’s just a so-so idea and the team only realizes it when the first level comes together, years later, at around alpha time. At this point the choice is canning a project after spending millions of dollars, or patching it up to try to salvage something. Neither idea is particularly appealing.

Creating a prototype for a game you know you’ve already committed to is pointless. It’s nothing more than an exercise to keep management happy. Frankly, I even made that same mistake at Power of Two, when we prototyped the game idea we had in mind and immediately moved on into pre-production (and yes, later we realized we had to change things to make it more interesting).

What I do now is to force myself to prototype several of my top ideas before committing to any one project. I have a page (actually, a wiki page) with every game idea or thought I have. That page has way over a hundred entries, and every so often I cull and reorganize it, bringing up the most promising ideas towards the top. Whenever I’m in prototyping mode, I start grabbing them from the top and prototype them.

proto_1.jpgWith a good prototype it’s easy to see if an idea is worthwhile. If it’s not, I discard it and move on to the next one. If it has potential but it’s just so-so, I either choose to continue just a bit longer (to ask another, better question) or I shelve it back in the list of potential game ideas. Maybe at some later time, things might click in or I might have a new inspiration and the game idea might become a lot stronger.

Also, often times, after doing one prototype and deciding against it, a new idea will come up. Usually a variation on the original prototype or something directly sparked from it, so I’ll find myself jumping to that idea instead of one of the ones I had saved in my list.

Eventually, one idea will click and you’ll know that’s “the one”. If you’re lucky (or unlucky) enough to have that happen with the first one you try, I still recommend doing a few more prototypes. If nothing else, you might be prototyping future projects, so it’s certainly not wasted time. For my current project, I went through eight prototypes before finding “the one” (several of them were a collaboration with Miguel). Eight to ten prototypes per project is roughly what I’m hearing from other indies with this approach.

Mistake #2: Not having a good question

A good prototype attempts to answer a question about the game. But not all questions are created equal. First of all, a question needs to be relevant and crucial to the project. “Can I have a pretty settings screen?” isn’t a particularly difficult question to answer, so it doesn’t deserve its own prototype. “Can I control little planes by drawing smooth lines on the screen?” is a much bigger unknown (before Flight Control anyway, today you can just download the game and immediately answer yes).

proto_3.jpgAlso, a good question is concise and can be answered in a fairly unambiguous way. “Is this game awesome?” isn’t a good question because “awesome” is very vague. A better question might be “Can I come up with a tilt control scheme that is responsive and feels good?”. Feels good is a very subjective question, but it’s concrete enough that people can answer that pretty easily after playing your prototype for a bit.

Even though most questions are about game design, they can also be about any other aspect of the game. Maybe you’re doing something tricky with technology and you want to make sure it’s feasible. If not, there’s no point in even starting. It’s more uncommon to think of prototyping art, but it’s also a very valid approach: “Will this art style allow foreground objects to stand out enough?” “Will the lighting approach allow the player to see important features in enough detail?”. Often you can do these art “prototypes” directly in Photoshop or a 3D modeling package.

In the case of Flower Garden, the main unknown was the technology behind the procedural flowers. So I created a prototype to answer the question “Can I create compelling procedural flowers that grow in real-time and the user can interact with them?”. The prototype had several parts to answer that question: the geometry generation, the animation, the simulation, and the rendering. There isn’t anything else particularly ground-breaking in the rest of the Flower Garden code, so as soon as I was able to answer “yes” to that question, I green-lighted the project and started production on it.

For larger projects, you might have several major, outstanding questions, so you’ll need to do multiple prototypes. Unless they’re very closely related, I find it easier to keep them separate instead of building on top of the same prototype.

Without a good question, it’s too easy for a prototype to go on for a long time. You feel you’re making progress because new things are added, but you have no real sense of when to stop or when it’s done. You really have to focus on the question, ignore everything else, and be merciless in your approach.

Mistake #3: Taking too long

proto_4.jpgOne of the key concepts in the definition of a prototype was that it has to be fast/cheap (which are two sides of the same coin). What’s fast enough? It depends on the length of the project itself. It’s not the same thing to do a prototype for a two-month iPhone game, than for a three-year console game. Also, a larger, more expensive project probably has more complex questions to answer with a prototype than a simple iPhone game.

In my case, I shoot for one-day prototypes. If you already have the tech to create games with, one day allows you to focus 100% on answering the question. By the end of the day, or even before, I have a pretty good idea how the game is going to work out. My shortest prototype ever was a 2-hour one. I thought it was going to be longer, but I managed to complete everything to answer the question in two hours (for the record, I didn’t can that idea, but I shelved it for a possible future project).

Game jams are a great way to get over the mental block of doing quick prototypes. There you are focused on making the game on a very short time, surrounded by people trying to do the same thing. I can’t think of a more fun way to prototype than that!

Also, think beyond programming. Is there a faster way you can answer the prototype question? Maybe you can use the modding capabilities of an existing game, or even do a mockup with paper moving pieces around. Don’t fall in the trap of thinking you have to code a prototype if something simpler and faster will do.

If you find that a day is not enough, take a step back and really ask yourself why you need more time. Were you getting side-tracked on things that were irrelevant to the prototype (menus, tech, art, etc)? Are you asking a question that the prototype can’t answer? Do you have the game idea clearly defined in your head?

Mistake #4: Building a system, not a game

proto_5.jpgWhen you’re making a prototype, if you ever find yourself working on something that isn’t directly moving your forward, stop right there. As programmers, we have a tendency to try to generalize our code, and make it elegant and be able to handle every situation. We find that an itch terribly hard not scratch, but we need to learn how. It took me many years to realize that it’s not about the code, it’s about the game you ship in the end.

Don’t write an elegant game component system, skip the editor completely and hardwire the state in code, avoid the data-driven, self-parsing, XML craziness, and just code the damned thing.

When you’re prototyping, it’s a race to answer the main prototype question. Everything is expendable. Don’t even worry about memory leaks, hardwired numbers, or how you load resources. Just get stuff on the screen as quickly as you can.

And don’t ever, ever, use the argument “if we take some extra time and do this the right way, we can reuse it in the game”. EVER.

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

IAP Bundles: More Than Just Good Deals

fg_bundles.jpgIn-game point bundles are nothing new. Even before the time of in-app purchases, Zynga was famous for releasing “points” apps to increase your game reputation or other stats. The fact that they released not just one way of getting points, but many different apps at different price points, was something I dismissed as a marketing tactic to try to get noticed on the charts.

Fast-forward to now, and as more companies are jumping into the bandwagon of games that need “points” to make progress, we’re still bundles. Again, I chucked that up to legacy reasons and doing what worked with the standalone apps.

Discovering Bundles

It was at the last 360iDev in San Jose, that Mark Johnson said something that really stuck with me. I can still hear him say it with his fine British accent: “I think we might be underestimating how much people are willing to pay for in-app purchases”. Really?

As soon as I had a chance, I looked at the best-selling IAPs for some popular games. The screenshots below were taken today, not back when I looked at them, but the results are very much the same. I let you guess which games these IAPs came from.

werule.pngwefarm.pngcastlecraft.pngfarmville.png

I was very surprised with what I saw. The top-selling IAP was never a $0.99 one, and there were bundles of $49.99 or higher towards the top! That was crazy! I was indeed underestimating what players are willing to buy by only offering a measly $0.99 fertilizer bottle in Flower Garden!

Bundles In Flower Garden

As part of the next Flower Garden update, I decided to run a little experiment and add two more fertilizer options: A $2.99 one and a $5.99 one, each of them giving you a slightly better deal on fertilizer (20, 70, and 150 doses). That was still nothing compared to the price tags I was seeing in those other games, but I didn’t want to alienate users by slapping some ridiculously high bundle prices.

The results?

The most popular item by number of sales was still the single fertilizer bottle for $0.99. But a lot of people took advantage of the the other two bundles as well. This is how fertilizer sales for Flower Garden Free have been for the last two months:

fertilizer_sales.png

But now, let’s look at that same period by plotting revenue (again, only Flower Garden Free, the full version is very similar but it wasn’t easy to combine the two to display them here):

fertilizer_revenue.png

Now the two bundles are a lot closer to the single bottle, especially the larger, $5.99 bundle.

More Than Meets The Eye

In the end, were bundles effective, or are people buying the same amount of fertilizer and leaving less money in the process? Unfortunately I can’t answer that question from a pure data point of view. Looking at fertilizer sales before and after I introduced the bundles is no good because the number of users increased dramatically at each update. I can’t even normalize them by the number of sales, it would have to be by the number of daily users, and unfortunately that’s not a statistic that I’m tracking.

However, I think we can argue two really good points about why bundles are great.

1. More choice

Having different levels of bundles give players more choice on how they want to purchase something. From what I’ve read about buyer psychology, people love having choices when buying something (just don’t give them too many choices!). They are more involved in the buying process, they evaluate it, and they feel better about the decision they eventually make. So that seems to indicate that more people might buy fertilizer if there are a few bundle options than if there’s only one.

2. Commitment

This is the biggie. Whenever a user purchases a $5.99 bundle (or a $49.99 one!), they became more committed to your game. You can also guarantee they will come back again to get their money’s worth from that purchase. Even if they had the intention of coming back to your game without the purchase, having spent that money is a nice reminder to do so. And having people come back to your game is what this is all about: They will explore more of the game, get hooked more, make more in-app purchases, show it to more of their friends, and send more bouquets to their family.

I have no doubt that I’ll be using bundles in the future. Players get a good deal, and you get committed players. It’s a win-win situation.

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

Remote Game Editing

I’ve long been a fan of minimal game runtimes. Anything that can be done offline or in a separate tool, should be out of the runtime. That leaves the game architecture and code very lean and simple.

One of the things you potentially give up by keeping the game runtime to a minimum is an editor built in the game itself. But that’s one of those things that sounds a lot better than it really is. From a technical point of view, having an editor in the game usually complicates the code a huge amount. All of a sudden you need to deal with objects being created and destroyed randomly (instead of through clearly defined events in the game), and you have to deal with all sorts of crazy inputs and configurations.

The worse part though, is having to implement some sort of GUI editing system in every platform. Creating the GUI to run on top of the game is not easy, requiring that you create custom GUI code or try to use some of the OpenGL/DirectX libraries available. And even then, a complex in-game GUI might not be a big deal on a PC, but wait and try to use that interface on a PS3 or iPhone. After all, making games is already complicated and time-consuming enough to waste more time reinventing the widget wheel.

Remote game editing manages to keep a minimal runtime and allow you to quickly create native GUIs that run on a PC. It’s the best of both worlds, and although it’s not quite a perfect solution, it’s the best approach I know.

Debug Server

Miguel Ángel Friginal already covered the basics of the debug server, so I’m not going to get in details there.

The idea is that you run a very simple socket server on the game, listening in a particular port. This server implements the basic telnet protocol, which pretty much means that it’s a line-based, plain-text communication.

The main difference between my debug server and Miguel’s (other than mine is written in cross-platform C/C++ instead of ObjC), is that I’m not using Lua to execute commands. Using Lua for that purpose is a pretty great idea, but goes against the philosophy of keeping the runtime as lean and mean as possible.

Instead, I register variables with the server by hand. For each variable, I specify its memory address, it’s type, any restrictions (such as minimum and maximum values), and a “pretty name” to display in the client. Sounds like a lot of work, but it’s just one line with the help of a template:

registry.Add(Tweak(&plantOptions.renderGloss, "render/gloss", "Render gloss"));
registry.Add(Tweak(&BouquetParams::FovY, "bouquet/fov", "FOV", Pi/32, Pi/3))

And yes, if I were to implement this today, I would probably get rid of the templates and make it all explicit instead (ah, the follies of youth 🙂

TweakUtils::AddBool(registry, &plantOptions.renderGloss, "render/gloss", "Render gloss");
TweakUtils::AddFloat(registry, &BouquetParams::FovY, "bouquet/fov", "FOV", Pi/32, Pi/3);

The debug server itself responds to three simple commands:

  • list. Lists all the variables registered in the server.
  • set varname value. Sets a value.
  • print varname. Gets the value for that variable.

For example, whenever the server receives a set command, it parses the value, verifies that it’s within the acceptable range, and applies it to the variable at the given memory location.

Telnet Clients

telnet.pngBecause we used the standard telnet protocol, we can start playing with it right away. Launch the game, telnet into the right port, and you can start typing away.

However, most telnet clients leave much to be desired for this. They all rely on the history and cursor manipulation being handled by the shell they assume you’re connected to. Here we aren’t connected to much of anything, but I’d like to be able to push up arrow and get my last command, and be able to move to the beginning of the line or the previous word like I would do in any text editor. The easiest solution I found for that was to use a telnet client prepared for that kind of thing: A MUD client! Just about any will do, but one that works well for me is Atlantis.

So far, we’ve implemented the equivalent of a FPS console, but working remotely. And because the code is fully portable, our game can be in just about any platform and we can always access it from our PC. Not just that, but we can even open multiple simultaneous connections to various development devices if you need to run them all at once.

Custom Clients

Game parameter tweaking is something that is OK through a text-based console, but really comes into its own when you add a GUI. That’s exactly what we did at Power of Two Games. We created a generic GUI tool (based on WinForms since we were on Windows at the time), that would connect to the server, ask for a list of variables, and generate a GUI on the fly to represent those variables. Since we knew type and name of each variable, it was really easy to construct the GUI elements on the fly: A slider with a text field for floats and ints, a checkbox for bools, four text fields for vectors, and even a color picker for variables of the type color.

It worked beautifully, and adjusting different values by moving sliders around was fantastic. We quickly ran into two problems through.

The first one is that we added so many different tweaks to the game, that it quickly became unmanageable to find each one we wanted to tweak. So, in the spirit of keeping things as simple as possible (and pushing the complexity onto the client), we decided that the / symbol in a name would separate group name and variable name. That way we could group all related variables together and make everything usable again.

The second problem was realizing that some variables were changing on the runtime without us knowing it on the client. That created weird situations when moving sliders around. We decided that any time a registed variable changes on the server, it should notify any connected clients. That worked fine, but, as you can imagine, it became prohibitively expensive very quickly. To get around that, we added a fourth command: monitor varname. This way clients need to explicitly register themselves to receive notifications whenever a variable changes, and the GUI client only did it for the variables currently displayed on the screen.

tweaker.png

During this process, it was extremely useful to be able to display a log console to see what kind of traffic there was going back and forth. It helped me track down a few instances of bugs where changing a variable in the client would update it in the server, sending an update back to the client, which would send it again back to the server, getting stuck in an infinite loop.

You don’t need to stop at a totally generic tool like this either. You could create a more custom tool, like a level editor, that still communicates with the runtime through this channel.

Flower Garden Example

For Flower Garden, I knew I was going to need a lot of knobs to tweak all those plant DNA parameters, so I initially looked into more traditional GUI libraries that worked on OpenGL. The sad truth is that they all fell way short, even for development purposes. So I decided to grab what I had at hand: My trusty tweaking system from Power of Two Games.

I’m glad I did. It saved a lot of time and scaled pretty well to deal with the hundreds of parameters in an individual flower, as well as the miscellaneous tweaks for the game itself (rendering settings, infinite fertilizer, fast-forwarding time, etc).

Unfortunately, there was one very annoying thing: The tweaker GUI was written in .Net. Sure, it would take me a couple of days to re-write it in Cocoa (faster if I actually knew any Cocoa), but as an indie, I never feel I can take two days to do something tangential like that. So instead, I just launched it from VMWare Fusion running Windows XP and… it worked. Amazingly enough, I’m able to connect from the tweaker running in VMWare Fusion to the iPhone running in the simulator. Kind of mind boggling when you stop and think about it. It also connects directly to the iPhone hardware without a problem.

VMWare Fusion uses up a lot of memory, so I briefly looked into running the tweaker client in Mono. Unfortunately Mono for the Mac didn’t seem mature enough to handle it, and not only was the rendering of the GUI not refreshing correctly, but events were triggered in a slightly different order than in Windows, causing even more chaos with the variable updates.

Here’s a time-lapse video of the creation of a Flower Garden seed from the tweaker:

Drawbacks

As I mentioned earlier, I love this system and it’s better than anything else I’ve tried, but it’s not without its share of problems.

Tweaking data is great, but once you find that set of values that balances the level to perfection… then what? You write those numbers down and enter them in code or in the level data file? That gets old fast. Ideally you want a way to automatically write those values back. That’s easy if the tool itself is the editor, but if it’s just a generic tweaker, it’s a bit more difficult.

One thing that helped was adding a Save/Load feature to the tweaker GUI. It would simply write out a large text-based file with all the variables and their current values. Whenever you load one of those, it would attempt to apply those same values to the current registered variables. In the end, I ended up making the Flower Garden offline seed file format match with what the tweaker saved out, so that process went pretty smoothly.

Another problem is if you want lots of real-time (or close to real time) updates from the server. For example, you might want to monitor a bunch of data points and plot them on the client (fps, memory usage, number of collisions per frame, etc). Since those values change every frame, it can quickly overwhelm the simple text channel. For those cases, I created side binary socket channels that can simply send real-time data without any overhead.

Finally, the last drawback is that this tweaking system makes editing variables very easy, but calling functions is not quite as simple. For the most part, I’ve learned to live without function calls, but sometimes you really want to do it. You can extend the server to register function pointers and map those to buttons in the client GUI, but that will only work for functions without any parameters. What if you wanted to call any arbitrary function? At that point you might be better off integrating Lua in your server.

Future Directions

This is a topic I’ve been interested in for a long time, but the current implementation of the system I’m using was written 3-4 years ago. As you all know by now, my coding style and programming philosophy changes quite a bit over time. If I were to implement a system like this today, I would do it quite differently.

For all I said about keeping the server lean and minimal, it could be even more minimal. Right now the server is receiving text commands, parsing them, validating them, and interpreting them. Instead, I would push all that work on the client, and all the server would receive would be a memory address, and some data to blast at that location. All of that information would be sent in binary (not text) format over a socket channel, so it would be much more efficient too. The only drawback is that we would lose the ability to connect with a simple telnet client, but it would probably be worth it in the long run.

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.