Communicating With Players

By now every iOS developer knows that making a great game and putting it on the App Store is only part of the work. In order to get significant sales, it needs to be noticed. You need to spend a significant amount of time in marketing and PR, making sure that blogs cover it, magazines review it, or at least jump-starting it with a group of devoted and vocal forum fans.

Most often, the advice stops there. So you get your initial sales spike and then sales go way down. What do you do then? Usually, developers release new features and updates. That’s great, but how do you get people to notice it. You need to establish some form of communication with your players.

Update Messages

The simplest form of communication is through the “What’s new” section in the update. You can use that section not just to list what features you added and what bugs you fixed, but also to let your players know about other things: plans for the future, other games to try, or even the URL for your Facebook group.

Credit goes to Igor for bringing up this idea and pointing out the URLs are even clickable in this field (but they aren’t in the app description).

Of course, if you’re like me and you update your apps only once in a while, this technique isn’t as effective. Right now my iPhone tells me I have 67 new updates available. I’m clearly not going to be reading through the release notes of each one.

In-Game News

fg_promo.jpgA more direct way of reaching out to your players is to have some sort of in-game news system. At any point you can update a file in your web server with any news, and it is displayed in the game. It can be implemented in many different ways depending on “on your face” you want to be about it: a pop up that comes up when the user runs the game, a ticker that runs constantly across the bottom of the screen, or, what I did for Flower Garden, a news icon with a badge indicating how many unread items there are, that brings up the news page when you tap it.

Make sure players are able to click on URLs in your news messages so you can direct them to different web pages easily. More on that on a bit.

Emails

Update messages are only good for players who update their apps (ahem, ahem), and in-game news for active players who’re currently launching your apps. For maximum effect, you can send an email newsletter and that way you can also reach users who played the game at some point in the past, but aren’t currently playing it now. They’re the ones probably most interested in new updates and features, and chances are you can rekindle their interest in the game.

To do this, you should encourage users to register for your mailing list, or collect their emails with their consent in some other way. This was a technique I started using back in December of last year with great success.

I’m currently using Your Mailing List Provider as a means to delivering thousands and thousands of emails [1]. By the way, don’t miss a chance to join the Flower Garden mailing list 🙂

Facebook

Similar to the mailing list approach, Facebook groups can be a very effective form of communication. An additional benefit is that friends of your players might see them participating in the page and might make them try out your game.

Case Study: Pocket Frogs Cross-Promotion

All that is fine in theory. How does it work in practice? I have been using all four forms of communication for a while, and I’m definitely seeing good bumps of sales and downloads with each update and each major communication.

Last week, Ian and Dave from Nimblebit and I, decided to set up a cross promotion between Pocket Frogs and Flower Garden.

pf_promo.jpg

I updated the in-game news and send out an email newsletter coinciding with the latest Flower Garden update telling the players that if they downloaded Pocket Frogs from within Flower Garden, they would be awarded 5 doses of fertilizer. Nimblebit awarded players a flower if they downloaded Flower Garden Free from within Pocket Frogs.

When you have over a million downloads in a week like Pocket Frog did, that kind of player communication is the equivalent of a nuclear cannon. The effects of the cross-promotion were obvious the instant the news went live:

fgf_chart.png

As you can see, Flower Garden Free made it all the way to the number 56 in the iPhone Top Apps chart in the US! The effect even spread to the paid version of Flower Garden:

fg_charts.png

Pocket Frogs at the time was hovering at around #9 on the charts, so it was difficult to have much of an impact on that position without major numbers, but we suspect it might have hovered there a little longer because of the extra downloads from Flower Garden.

Here is what the downloads for Flower Garden Free looked like for the last month. The Pocket Frogs cross-promotion is quite noticeable:

fg_downloads.png

All those downloads also translated into in-app sales through the Flower Shop. Here are the revenues for that time period:

fg_revenue.png

One consequence I wasn’t expecting, but in retrospect I’m not that surprised about, is that the ratings for Flower Garden Free dropped by a whole star (from 4 to 3), with a large percentage of 1-star reviews. That’s because a lot of people who wouldn’t have downloaded Flower Garden otherwise did it anyway, didn’t like it, and deleted it right away.

To wrap things up on a better note, there was yet another side effect of the cross promotion. The Pocket Frogs link was using my LinkShare referral code. Sending all those users to the App Store to download a free game link resulted in about $200 in referral profit for the week.

Conclusion

Communicating with your players is more than just profitable: It’s crucial to the sustained success of your games. Make sure you try to engage with them in every way you can, keep them up to date with developments in your game, and don’t hesitate to run the occasional cross-promotion, especially with other games that are a good match for your target audience.

[1] If you decide to use them and wouldn’t mind using my referral code (WQHVUF), I can get a small percentage back.

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.

My Standing Desk Experiment

I’m not sure where I first heard about standing desks. It was probably about a year ago in some online article, but it didn’t have much of an impact at the time. Since then, the benefits of standing (or rather, the dangers of sitting down for prolonged periods of time) has been appearing in the news more often. Some people even went as far as setting up treadmill desks!

Initially I dismissed it for me because I’m reasonably active: I either run or bike 5 or 6 days per week, and the rest of the days I go for a walk around the neighborhood. It was the combination of increased studies on the effects of sitting, some people in my social circle finally making the jump and raving about it, and me developing some problems in a hamstring that finally made me consider it more seriously. And trust me, if you’re a cyclist or a runner, the last thing you want to have is hamstring problems.

It turns out that my 5-mile morning runs weren’t making me immune to the dangers of sitting. It’s not how much exercise you get per day, but how long do you sit on a chair continuously. And no, buying an fancy, expensive chair might help with your back, but it’s not going to do one bit of good with all the other problems.

One of the many advantages of working from home is that I can try weird things that would be much more difficult in a regular workplace. I also have a track history of liking to experiment on myself [1], so it didn’t take much convincing to give this a try.

After some initial research, it appeared that the way to go was an adjustable-height desk. That way you can work standing, but you still have the flexibility to sit down whenever you need to. I also found out that apparently this is not all that uncommon in Europe. The only drawback is that adjustable standing desks are not easily available here in the US, and the ones that are out there are aimed at offices and big companies, with matching eye-popping price tags. Even though Flower Garden continues to do well, I wasn’t quite ready to plop down several thousand dollars on something I might end up hating.

standing_1.jpgSo I decided to start cheap and work my way up from the bottom. First I had to decide if I even liked this whole working-while-standing thing. I wasn’t even sure I would be able to type! I thought about raising my desk with cinder blocks, but I would have to raise a lot and would make it very unstable. So instead, I created four stacks of books on top of my desk and put a board on top. Then I was able to put the keyboard, computer, and monitor on the board and give that a try.

Let me tell you: It was weird.

At first I didn’t know how to type. My fingers were constantly off to the side. It turns out my initial height was too low. You really want to have the keyboard at a height that puts a 90 degree bend on your elbows. That’s what they say about the sitting position, but somehow I can manage to have less. However, standing, I really needed that height.

Even once I adjust the height, the first day was kind of rough. After an hour, I was definitely feeling it in my feet. I think I did half a day the first day and I felt totally exhausted. All that running wasn’t helping that much standing at my desk apparently.

Fortunately things got better very quickly. In a few days, I was able to work for hours without much problem. I would find myself constantly shifting my weight between my feet and moving around a little bit. I was definitely liking that whole standing thing.

standing_2.jpgAt this point I decided that the stack of books was too annoying, but I wasn’t quite ready for an expensive desk. So I picked up a Fredrik Ikea desk from Craigslist for $50. The nice thing about this desk is that it can be assembled so the top of the desk is almost at any height. You can’t change it on the fly, but at least it serves as a standing desk.

Finally I was able to work standing and be comfortable at the same time now that I had space for more than a mug along with the keyboard. The extra shelves on the desk were also very handy (one over the table top and one underneath).

After spending a couple of weeks with the desk, I decided that I definitely liked standing and it was something I wanted to continue doing long term. I felt more focused while standing, and my productivity was up. An unexpected side benefit was that when someone else comes into the room, they can walk right up to the desk and we can look at the monitor together, or look at some papers, much more easily than if it was a sitting desk.

However, it was also clear that I needed to switch things up a bit. Spending the whole day standing continued to be pretty tough on my feet, and it even made it so I didn’t want to work any longer than I had to. I really had to combine the standing with some hours of sitting down, which is probably a healthier thing to do anyway.

At this point I had two options: I could go full out and get a motorized adjustable desk, or I could get an adjustable draft chair which are tall enough to sit comfortably at a standing-height desk. Since I already had a nice office chair, and the Ikea desk was a bit wobbly set up like that, I decided to spend the money on the motorized desk.

Again, after a bunch of research, it seemed that one of the best options was to order a (very appropriately named), GeekDesk online. They have them in two sizes, Classic and Mini. It turns out I wanted something more in the middle (around 60″ wide), so I ended up ordering the Mini frame and a desk top from Ikea for $80. It wasn’t cheap, but it was way cheaper than the alternatives and all the reviews and experiences I read were very positive.

It arrived very quickly and it was a breeze to assemble. I did have a scary moment that it looked like one of the wheels didn’t fit in the metal opening, but I eventually managed to coerce it. Hopefully this kind of manufacturing problems aren’t common.


x2_277d29f.jpegx2_277d225.jpeg

I can only describe the final setup with one word: Awesome. The desk isn’t wobbly at all, and it takes just a few seconds to change heights with the push of a button. Not just that, but I can fine tune the height at any moment in tiny increments. And in the sitting position, I can put it low enough to make typing very comfortable (most desks are set up too high to type really comfortably for me).

My daily work routine has settled into working standing in the mornings, sitting for an hour or so after lunch, standing all afternoon, and then sitting in the evening I have have to do some work. With the wonderful weather here in Southern California, I’ll often take my sitting work time outside in the back patio in the shade. So all in all, I probably spend one or two hours sitting down at the desk.

Yes, it was a significant amount of money, but it’s something I’m using every day and it improves both my productivity and my health. Definitely worth it.

Standing desks have one downside though. This situation happens embarrassingly often. Good thing I work home alone!

[1] A few years ago I gave polyphasic sleep a try. It was actually really great for gaining extra hours, but eventually I gave it up because I was constantly out of sync with the rest of the world. I’d do it again if I were spending months alone in a research station in the Antarctica.

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.

Lag: The Bane Of Touch Screens

Lag in games is as inevitable as taxes. It’s something we can try to minimize, but we always need to live with it. Earlier this week, I noticed that input for my new iPad game was very laggy. Excessively so, to the point it was really detracting from the game, so I decided I had to look into it a bit more.

Lag In Games

got_lag.pngI’m defining lag as the time elapsed between the moment the player performs an input action (press a button, touch the screen, move his finger), until the game provides some feedback for that input (movement, flash behind a button, sound effect).

Mick West wrote a great article on the causes of lag in games, followed up by another one in how to measure it. I’m going to apply some of that to the lag I was experiencing in my game.

Lag can be introduced in games by many different factors:

  • Delay between gathering input and delivering it to the game.
  • Delay updating the simulation to reflect new inputs.

  • Delay rendering simulation state.
  • Delay displaying the latest rendered state on screen.

The new game runs on the iPad and involves moving objects around the screen with your finger. To make sure it wasn’t anything weird with the rest of the game code, I wrote a quick (and ugly!) program that draws a square with OpenGL that follows your finger on the screen. When you run the sample, the same lag becomes immediately obvious.

The iPad is a much larger device than the iPhone, and it encourages a physical metaphor even more. As soon as you attempt to move an “object” on screen, the lag kills that sense of physicality. Instead of moving an object around with your finger, you’re dragging it around with a rubber band. It moved the player from applying direct action on screen, to being removed and disassociated with the actions on screen.

Loop Structure

The place to start looking for lag is in my main loop. The main loop looks something like this:

	ProcessInput();
	UpdateSimulation();
	RenderWorld();
	PresentRenderBuffer();

So I was reading the input correctly before the simulation. Nothing weird there.

Touch input is delivered to the code as events from the OS. Whenever I received those events (outside of the main loop), I queue them, and then process them all whenever the main loop starts in ProcessInput().

The loop runs at 60Hz, so the lag here is at most 16.7 ms (if you’re running at 30Hz, then you’re looking at a delay up to 33.3ms). Unfortunately, the lag I was seeing in the game was way more than one frame, so there was to be something else.

Rendering

For some reason, I thought that iDevices were triple buffered. I ran some tests and fortunately it looks like it’s regular double buffering. That means that if I render a frame and call presentRenderBuffer(), the results of that render will be visible on screen at the next vertical sync interval. I’m sure there’s a slight lag with the iPad screen, but I’m willing to be is close to negligible when we’re talking about milliseconds, so we’ll call that zero.

Main Loop Calls

The game uses CADisplayLink with interval of 1, so the main loop is called once every 16.7 ms (give or take a fraction of ms). I thought that perhaps CADisplayLink wasn’t playing well with touch events, so I tried switching to NSTimer, and even to my old thread-driven main loop, but none of it seemed to make any difference. Lag was alive and well as always.

That the simulation and rendering in the game are very fast, probably just a few ms. That means the rest of the system has plenty of time to process events. If I had a full main loop, maybe one of the two other approaches would have made a difference.

It looks like the lag source had to be further upstream.

Input Processing

On the dashboard, press and hold on an icon, now move it around the screen. That’s the same kind of lag we have in the sample program! That’s not encouraging.

A touch screen works as a big matrix of touch sensors. The Apple OS processes that input grid and tries to make sense out of it by figuring out where the touches are. The iOS functions eventually process that grid, and send our programs the familiar touchesBegan, touchesMoved, etc events. That’s not easy task by any means. It’s certainly not like processing mouse input, which is discrete and very clearly defined. For example, you can put your whole palm down on the screen. Where are the touches exactly?

TouchesBegan is actually a reasonably easy one. That’s why you see very little lag associated with that one. Sensors go from having no touch values, to going over a certain threshold. I’m sure that as soon as one or two of them cross that threshold, the OS identifies that as a touch and sends up the began event.

TouchesMoved is a lot more problematic. What constitutes a touch moving? You need to detect the area in the sensor grid that is activated, and you need to detect a pattern of movement and find out a new center for it. In order to do that, you’ll need several samples and a fair amount of CPU cycles to perform some kind of signal processing on the inputs. That extra CPU usage is probably the reason why some games get choppier as soon as you touch the screen.

Measuring Lag

Measuring lag in a game is tricky. You usually can’t measure it from within the code, so you need to resort to external means like Mick did in his tests.

I decided to do something similar. I pulled out my digital video camera, and started recording my finger moving on the screen. The quality leaves much to be desired, but it’s good enough for the job. I can see how far my finger gets from the center of the square, but that’s not enough information to quantify the lag. How fast is my finger moving exactly? Fortunately, that’s something I can answer in code, so I added that information to the screen [1]. Now, for a given frame, I can see both how far the finger is from the center of the square and how fast it’s going.

lag_test.jpg

The square is 100 pixels wide. When I move my finger at about 500 pixels per second, the center of my finger is on the edge of the square. That makes a rough 100 ms total delay from input until it’s rendered. That’s a whopping 6 full frames at 60 fps!

What Can We Do About It

As iOS developers, there isn’t much we can do. Make sure your loops are set up correctly to avoid an extra frame delay. Make sure you provide feedback as soon as you can and don’t delay it any longer than you have to. Other than that, there’s nothing much we can do.

I’ve been saying this for a while, but I’m a big fan of layers as long as you can get to the underlying layers when you need to. Here’s a perfect case where it would be fantastic if Apple gave us raw access to the touch matrix input. Apart from being able to process the input faster (because I know what kind of input to expect for the game), can you imagine the possibilities that would open up? Input wouldn’t be limited to touch events, and we could even sense how “hard” the user is pushing, or the shape of the push.

At the very least, it would be very useful if we had the option to allocate extra CPU cycles to input recognition. I’m not doing much in my game while this is going on, so I’d happily give the input recognition code 95% of the frame time if it means it can give me those events in half the time.

I’m hoping that in a not very far distant, iDevices come with multiple cores, and maybe one of those cores is dedicated to the OS and to do input recognition without affecting the game. Or maybe, since that’s such a specialized, data-intensive task, some custom hardware could do the job much faster.

Until then, we’ll just have to deal with massive input lag.

How about you? Do you have some technique that can reduce the touch event lag?

LagTest source code. Released under the MIT License, yadda, yadda, yadda…

[1] I actually shrank the OpenGL view to make sure the label wasn’t on top if it because I was getting choppier input than usual. Even moving it there caused some choppiness. This is exactly what I saw last year with OpenGL performance dropping when a label is updated every frame!

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.

Google App Engine As Back End For iPhone Apps

As soon as a game involves servers, there’s no such a thing anymore as “ship and forget”. Flower Garden put this in evidence about a month ago when I started getting complaints from users that the Flower Shop kept going down. Sometimes they weren’t even getting the items they were purchasing! (fortunately they can always do a free re-download, but they don’t always know that).

Flower Garden was using a shared Dreamhost server to upload bouquets, host in-game news, and, most importantly, to serve the Flower Shop (which involves hosting the static shop files, redeeming promo codes, recording transactions, verifying receipts with Apple’s server, and delivering purchased content). All the Flower Shop functionality was implement in PHP and using a mySQL database.

After some stressful sorting through the logs, it looked like the server was running out of memory and killing PHP processes. Dreamhost’s technical support didn’t help much and just claimed that I was simply something that happened and they would be happy to sell me a virtual private server. I was surprised to hear it was using up a lot of memory, and certainly nothing I could see with the tools available to me showed that. I certainly hadn’t done any changes in a while and traffic was constant. Doing some Googling at the time brought up lots of other angry Dreamhost users in a similar situation, so I suspected server configuration problems.

Whatever the case, I couldn’t let it be that way and I had to fix it somehow. I briefly considered a virtual private server, or even a dedicated host in some highly recommended providers. But in the end, the simplicity, scalability, and affordability of the Google App Engine won me over.

Now that Flower Garden has been using the Google App Engine for several weeks, I still think it’s fantastic. I wish someone had whacked me on the head when I started writing server code and forced me to use it. Hopefully this post will be more pleasant than a hit to the head and will still have a similar (good) effect.

Google App Engine Overview

appengine_lowres.gifEven though I was pretty much completely new to the Google App Engine (I had looked into it briefly before the launch of Flower Garden but dismissed it because they couldn’t support the amount of email traffic I needed), it took me two days to port over everything. Actually flipping the switch from the old system to the new one took a while longer, but that required more courage than work. More on that later.

This is not a Google App Engine tutorial. Instead, it’s going to be an overview of what it can do and why you should consider it as a backend for your iPhone app instead of using a shared or even dedicated server.

The first shock (at least for me) when looking into the Google App Engine is that you can’t run PHP. You’re limited to Java or Python. It turns out Python is my go-to scripting language, so I was thrilled at the idea. PHP is fine, but Python is a whole class above.

Next, it took a bit of adjusting to the fact that the environment to run anything on the Google App Engine has to be carefully controlled. You need to create a configuration file indicating the entry points and their handlers. Fortunately, all of that is well covered in the extensive online documentation.

This is what the Flower Garden config file looks like, indicating both static files and several execution entry points:

application: st-flowershop
version: 1
runtime: python
api_version: 1

handlers:
- url: /catalog
  static_dir: catalog

- url: /emailassets
  static_dir: emailassets

- url: /news
  static_dir: news

- url: /moregames
  static_dir: moregames

- url: /.*
  script: purchase.py

If you hit one of the URLs listed as static_dir, you get those files directly (like the in-game news). Anything else is handled by the Python script purchase.py. Google even provides the webapp framework that easily allows you to connect different parts of the script to handle different requests and easily get to the input parameters.

Once you’re past that and you have the requisite “Hello World” up and running, then it’s all fun and games.

One of the great features of the Google App Engine is that it comes with a fully-featured, local environment. This environment is installed automatically with the Google App Engine SDK, and there’s nothing to configure. It’s certainly nothing like setting up Apache + mySQL + PHP in your dev station! That way, you can do all your work locally, and only update the servers when you’re confident everything is working.

Beyond this, the only other thing that is different from what you may be used to is the datastore. They provide a query language called GQL, which is not exactly SQL, but it’s very similar. Close enough that I had no trouble porting over my very simple queries anyway.

Adding data to a data store couldn’t be simpler. For example, to add a promo code, I need the following class definition:

class PromoCode(db.Model):
	code = db.StringProperty()
	productid = db.StringProperty()
	amount = db.IntegerProperty(default=1)
	singleuse = db.BooleanProperty(default=True)
	enabled = db.BooleanProperty(default=True)

And then I can add it this way:

	promocode = PromoCode()
	# fill it up here
	promocode.put()

How do I check if a promocode is valid? I can use the SQL-like syntax, or something even simpler:

	q = PromoCode.all()
	q.filter("code =", code)
	return q.get()

Once you know that, you can go to town with your Python programs.

Google App Engine Advantages

Scalability
This was the big reason that forced me to move away from Dreamhost. I have no way of testing how scalable it really is, but I’m going to take Google’s word for it. They know a tiny little bit about scalability. And besides, Flower Garden is nothing compared to other apps (it serves about 1.5 requests per second on average).

Since I don’t know how things are implemented under the hood in the Google App Engine, I don’t have a good feel for performance best practices. So I’m hoping that my very simple queries (add to the end of a table, or see if a record is present) are just fine. If not, I can do some tuning down the line (and I won’t have to wait for any approval to make the code go live!).

Local environment
The local environment is simply great. It makes developing a pleasure. You can add any test data you want to the local datastore through a web interface without affecting the live server. Probably my favorite feature is the console: Since the server is running locally, you can print out any debug info in the server code and you can see it live as you perform some action. That saved me hours of debugging compared to doing it on a remote server with php!

Server synching
In the past, I’ve synced my server scripts through ftp and I kept meaning to write an automated script to do that. In this case, Google provides a script (and a GUI tool) to do the actual synching with the servers, which is great. It even waits a few seconds until it can verify that the new version is live on the server.

Python
I’m not a big Java fan (although I used it a bit way back in the day when it first came out), but I do love Python. For a program with some complexity like this, it’s definitely a much better choice than PHP.

Real-time stats
The Google App Engine web console displays real-time stats of access to your site. You see it expressed in requests per second and you can visualize it in the past few hours, days, or even month. You also have access to all the logs, and you can filter by type of log message (debug, info, warning, error).

Price
This is one category where the Google App Engine definitely shines. Every day you’re given a free quota of bandwidth, disk usage, and CPU usage. If you stay under that quota you don’t pay anything. If you go over, you pay per unit as you go (at very reasonable prices). You can even set a maximum cap on daily spending so you don’t encounter any nasty surprises at the end of the month.

So far, Flower Garden has been hovering right at the edge of the outgoing bandwidth free quota (the rest of the metrics it doesn’t even come close). So even if traffic were to double, expenses would be very reasonable.

Development Tricks

Along the way, I figured out a couple of interesting tricks that helped me during development.

Bypass the App store for testing
For me, few things are more annoying than doing development in the actual device. Iteration is slow and stepping with the debugger is mostly impossible (seems to depend on the mood of the debugger that day). So I try to do the bulk of the development on the simulator and just test on the device when things are ready.

Unfortunately, the device can’t access the App Store, which makes testing all the server functionality dealing with the App Store painful. What I did was to add a define that, when present, the program bypasses the App Store but still functions as usual.

Local server
During development, you want to be using your local server. In my case, I set it up so that Debug versions of the code access the local server, but Release and Distribution ones access the live one.

There is one problem: The Google App Engine server, by default, binds itself to localhost, not to the IP address of your network card. That meant I was able to hit it from the simulator just fine accessing http://localhost:8080, but not from the device. In order to access the development server from the device, I had to explicitly tell the server to bind itself to another address like this:

dev_appserver.py --address 192.168.1.150 FlowerShop

Now I can access the server at 192.168.1.150:8080 from both the simulator and any device.

Switching servers
Porting the code took just a couple of days. Making the switch on the live server was a lot scarier though. I couldn’t wait for a new update to be released because that seems to take over a week these days, so I forwarded requests from the old server to the new one.

I did it one system every day, avoiding weekends which is when there’s the most traffic. News was easy, and so was the web view with more games. But I ran into a snag with promo codes and Flower Shop purchases.

Initially, I was just redirecting requests in .htaccess this way:

Redirect permanent /Shop/catalog http://st-flowershop.appspot.com/catalog
Redirect 301 /Shop/catalog http://st-flowershop.appspot.com/catalog

As I learned the hard way, POST variables aren’t preserved in a redirect of that kind (I guess to avoid state being changed in multiple servers). I tried a bunch of things, but in the end, I wrote a quick php script that gathered all POST variables and re-posted them to the new request. A bit ugly, but it did the trick:

<?php
function PostRequest($url, $_data) {

    $data = array();    
    while(list($n,$v) = each($_data)){
        $data[] = "$n=" . urlencode($v);
    }    
    $data = implode('&', $data);
    // format --> test1=a&test2=b etc.

    $url = parse_url($url);
    if ($url['scheme'] != 'http') { 
        die('Only HTTP request are supported !');
    }

    $host = $url['host'];
    $path = $url['path'];

    $fp = fsockopen($host, 80);

    fputs($fp, "POST $path HTTP/1.1\r\n");
    fputs($fp, "Host: $host\r\n");
    fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
    fputs($fp, "Content-length: ". strlen($data) ."\r\n");
    fputs($fp, "Connection: close\r\n\r\n");
    fputs($fp, $data);

    $result = ''; 
    while(!feof($fp)) {
        $result .= fgets($fp, 128);
    }
    fclose($fp);

    $result = explode("\r\n\r\n", $result, 2);
    $header = isset($result[0]) ? $result[0] : '';
    $content = isset($result[1]) ? $result[1] : '';
    return $content;
}


print PostRequest("http://st-flowershop.appspot.com/purchase", $_POST);
?>

Conclusion

I hope this post is enough to at least make you interested in checking out the Google App Engine and help you get over a couple of the initial hurdles. I’ll definitely be using it in any future projects.

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.

Reconsidering Version Control

Ever since I turned indie, version control just hasn’t been much of an issue. Gone are the days of hundreds of multi-GB files that changed multiple times per day. With small teams of one or two plus a few collaborators, Subversion hosted remotely worked fine. Of course, all the cool kids these days are going on about how their distributed version control systems solve world hunger, but I’ve been mostly ignoring it because I have better things to do with my time (like writing games [1]).

Yesterday things changed a bit. As a result of last week’s “growing” post, Manuel Freire is going to join me to help with Flower Garden development. That makes two of us banging on the same codebase, and from two different time zones, so we don’t get the benefit of being in the same closet as it was the case with Power of Two Games. Since I was in my get-things-done mindset, I figured I would just set up a new svn repository for the project, move over the Flower Garden data, give us both access to it, and move on.

But no, it couldn’t be that easy. Can you guess what the first words out of his mouth were when I asked him about version control? “Oh, I love Git!”

That was the last straw. I had to do a mini-research session on version control systems, so I spent a couple of hours looking into it. If we were going to move over to something, now would be the time to do it.

Git and Mercurial

Git and Mercurial both look great. I was debating which one to go with until I realized that they’re both two flavors of the same thing, so it comes down more to personal preferences and tastes. This is best description I found on the differences between Git and Mercurial. When it comes to computers, I’m totally a MacGyver guy (actually, that might be true when it comes to anything now that I think about it), so that made my decision easier.

The big feature everybody keeps talking about for distributed version systems is effortless branching. That’s great, but I really have no intention of branching much. I haven’t created a single branch in the last four years, and I don’t expect to start doing that now. Next.

The other big feature is working disconnected from the network. That’s something I could use, but considering I’m only offline a handful of times a year, it really isn’t enough of an incentive to switch to a whole new system.

Git sounds like a great tool for large, distributed, open-source projects with hundreds of contributors, but frankly, I couldn’t find anything else that was worth mentioning for a small project and a handful of people. I feel like someone is trying to sell me a Porsche when my beat-up Hyundai is still perfectly functional for driving to the grocery store once a week. Am I missing something obvious?

Hosting

Hosting the actual repository was part of the consideration. This is for a private project, so all open-source sites are out. Ideally I wanted to host it just like I do with Subversion in Dreamhost, but the instruction page on how to install Git and Mercurial are enough to put most people off. Clearly, there’s a steep learning curve there.

server-rack.jpgSo I asked on Twitter for recommendations. I’ve learned that Git and Mercurial users are definitely very vocal and are always willing to help someone join their ranks. Within minutes I had all the suggestions listed below:

Prices varied a lot. From the $25/month/user of Kiln, to the $6/month of RepositoryHosting (gets you unlimited users and 2GB of storage). The Snappy Touch repository is already over 2GB, so it would end up being a bit more expensive than that, but not too bad.

Of those, Github was definitely the most recommended. I was starting to feel Git might not be the one for me, so I looked a bit more into RepositoryHosting because they had Subversion support. It turns out they also provide Trac, which is a great tool, although I already have that set up myself.

Wish List

Binary files

The one thing I really want in a version control system is good large binary file handling. I check in everything under version control, source code, assets, raw assets, and even built executables for each version. I want to be able to throw multiple GB psd files in the repository and have it work correctly (meaning fast, and using the least amount of space possible).

Perforce did an OK job with that. Git and Mercurial apparently are both horrible at it. So is Subversion, but at least it’s a tool I already know and I don’t have to spend time learning the ins and outs of how to optimize the Git database or how to make backups, or cull unused trees.

GUI

I love my command-line tools. I live in Terminal for a good part of the day, and having a real shell is one of the things that makes my life so much more pleasant under Mac OS than under Windows. But there are some things for which a GUI tool is a really useful addition, and version control is one of them.

On the Mac, I’ve been using Versions as a client for Subversion and it does everything I want. It’s fast, handles multiple repositories, lets me browse history, diff changes, etc. From my brief search and other people’s comments, there’s nothing quite like that for Git or Mercurial yet. That’s a pretty big, gaping hole.

Low-level access

Looking at all those hosting providers, I realized how much I want to have low-level access to the database. I want to be able to back it up myself, and run svnadmin when I want to. A lot of those hosting sites looked really pretty, but you were very limited in what you could do.

Coming To A Decision

If this were a thriller, you’d be disappointed. I’m afraid there are no plot twists and you can already guess the conclusion.

In the end, since neither Git nor Hg are built to address my biggest need (large binary files), I’ll stick with svn. It might be old, it might not be cool, but it serves my needs, I already know how to use it, I have the tools, I can admin it and fix a problem. I can concentrate on what matters instead: Writing games.

I decided to continue hosting it myself on Dreamhost. I can easily have one repository for every major project. However, by default, Dreamhost creates svn repositories using htaccess security and HTTP protocol. That’s OK, except that none of the actual data is encrypted as it would be if I were using ssh. I could use HTTPS, but then I would have to set up a certificate and pay for a fixed IP address, so instead I found an alternate way to have a secure connection.

All Subversion repositories live in a user account (svnuser). I create a new user group for every repository, and change all the files in the repository to belong to that group. Make sure you also set the SGID bit so any files created in that directory still belong to the group. Then I can create a new shell user for every collaborator, and add him to the groups of the repositories I’d like him to have access to. At that point, he’ll be able to access the repository as svh+ssh://username@hostname.com/home/svnuser/repository. All safe and secure.

Bonus SVN-Fu

Here’s something that I learned yesterday while I was moving repositories around. It’s probably common knowledge for seasoned SVN admins, but it was new to me.

I had a repository that included a bunch of my projects. What I wanted was to create a new repository that still had all the history, but only for the FlowerGarden part of the tree. I knew about svnadmin dump for transferring whole repositories, but I didn’t know there was a very simple way to only transfer part of it.

First you need to dump it as usual:

svnadmin dump repository > repos-dumpfile

Now, it turns out you can process the dump file before adding it back to another repository. So we can do:

svndumpfilter include FlowerGarden --drop-empty-revs --renumber-revs < repos-dumpfile > fg-dumpfile

Finally, you can add the resulting dump file into a fresh repository and have all the history for that project and only that project:

svnadmin create flowergarden
svnadmin load --ignore-uuid flowergarden < fg-dumpfile

Amazingly, for a repository that was over 2GB, that only took a few minutes. Go Subversion!

[1] Or reading. Or going for a walk. Heck, even sleeping would be a better use of my time than futzing around with a new tool.[2]

[2] And yes, I realize I sound like a grumpy old man. Getting there apparently. Now get off my lawn.

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.