How not to make a game leaderboard service.

 

My recent XNA game (Taptitude) on Windows Phone 7 is doing pretty good now that we’ve released the first 4 mini-games free. In making Taptitude we decided to use WCF REST’ful web services to implement leaderboards. Being a total n00b at writing web services we incorrectly assumed everything was working perfectly and went ahead an released the game.

A few days later we started seeing some ridiculously high scores in the leaderboard. At first we didn’t know what the issue was and thought someone had found some clever way to cheat. This was on our ‘Draw a Circle’ mini-game, so maybe someone was tracing a circle and getting crazy scores?

A few days later we released “Stay Inside” and times like 23 minutes were getting submitted (a good time is more like 20 seconds). Now we knew something was up because the same user was submitting scores like that every couple minutes…not even possible.

At this point, Nate realized that all of the crazy scores were from the de-DE locale. What could be so special about de-DE? We started by repro’ing the problem by setting Thread.Current.CurrentCulture to de-DE. Sure enough we started seeing the problem (among other issues). A little bit of debugging later and we narrowed in on the root cause.

Q: What does the floating point number half way between 1 and 2 look like in the de-DE locale?
A: 15 if you’re an idiot and parse it using the en-US locale.

It it’s still not obvious what I’m talking about, consider these unfortunate facts:
1) Germans (among other regions) write decimal points using a comma, where as the US uses a period.
2) When parsing a float from a string using the en-US culture, comma’s are ignored.

Combine these and you get something like “1020.56” in English becoming “1020,56” in German, and then our en-US web service parsing it as “102056.0”!

We had other issues as well with Dates, but I’ll save that for another post.

Moral of the story: Test on every locale you plan to ship to, even if you’re not localizing. Oh, and make your services culture insensitive too.