Bitten by the floating point bug

My game lives in a world of integers. In a modern era of powerful floating point geometry, for reasons of optimisation and simplicity, the main mechanic requires me to use only the wholest of numbers. However, mid-way through development, I decided it might be useful to use box2D in the future. I have my own very specific physics engine within the integer maths framework of my game, but box2D offer a lot of very fast solutions to a lot of mechanics my own physics can’t handle and potentially dumping parts of my world into it and pulling out the solutions as and when it was apt, seemed like a reasonable thing to do (a lot of games use box2D for their physics, including some rather famous ones, I love this anecdote from GDC). Unfortunately, according to the documentation, box2D works best at scales from 10cm to 10m, so my base scale of 1 would not sit well. Taking this into consideration I decided to introduce a world scale and have my entities give their positions and sizes in this scale, then move it back and forth to integer maths where necessary (and in many places hold onto both scale systems for speed, as a test with only moving into ints at the last minute, but every frame, caused a noticeable slow-down from all those casts).

Then I came across a bug where entities were appearing one pixel off from where I was telling them to appear. So I delved into the debugger and found a common issue with floats, but in a form I thought would be “safe”. To quickly recap, floats are stored internally using a mantissa and exponent, with the function being something like mantissa * 2 ^ exponent. If you check out this calculator you can see that the number 123 is actually stored as 1.921875 * 2^6. The problem this has is that the number 0.7 might be stored as 0.6999999992 and if you multiply that by 10.0 and cast it to an int naively you could end up with the integer value being 6 rather than 7 (as someone kindly pointed out, the value 7 is stored exactly as a float, but as soon as you start performing operations on it, then the certainty disappears).

Unfortunately, with my world scale of 0.1, I was taking an object of size 4, turning it into a 0.4 and then later dividing by the same scale to get back to 4 for some internal machination. In this case, sadly, it turned it back into a 3. I scratched my head and ran some tests dividing and multiplying numbers by 0.1 in the function where the problem was occurring, but these numbers all came out fine. As both the numbers were stored as variables, I tried dividing out the 0.4 variable by a float literal 0.1 and it gave me 3, but doing the same with a 0.4 float literal and the variable 0.1 gave me 4. In the debugger it was displaying the variable values clearly as 0.4 and 0.1, not as some almost approximations that would have hinted at a problem. One solution to this was to use roundf, which would give me the number I was looking for, by rounding the float to the nearest whole number, but if this could happen in this one spot, then it could happen anywhere else I was doing the same sort of calculation and I didn’t want to have to spend the time introducing a rounding function everywhere in my code, nor the overhead of calling it in terms of CPU. In the end I decided that, as I wasn’t using box2D now and could kick that can down the road, the thing to change would be having a world scale and doing all the division necessary to get objects into box2D as and when I end up using it.

I guess this is just one more example of where future proofing development has come back to bite me in the ass. That I introduced this issue before being advised against future proofing my project makes me feel a little better, but every day seems like a constant struggle to get the game closer to being finished and wasting hours on bugs like this is not where I want to spend my time (though learning a little something new about coding always feels worthwhile).


The Maths, it burns!

Whilst I am someone who enjoys a bit of maths*, would love to know more and, when playing the theoretical game of “what degree would you do if you could do another one?” would put it up there with physics or generic-interesting-science-I-just-read-about-on-slashdot, I do find I tend to struggle when it comes to aspects of 3D code I feel I should find relatively simple.

For instance, yesterday I decided to implement touch controls. Getting a reasonable framework for touch inputs, to get them from objective C into C++  and fire in my game, took a little bit of thinking about to get right, but was fairly quick. Then I got to the point of taking those inputs and turning them into pan and zoom functionality. It’s not that making the camera pan and zoom in vaguely the right direction took much time, but to get whatever was under my finger to stay exactly under my finger as I panned was a little tricky and to get zooming to work, so that it zoomed precisely between my fingers and kept what was under each finger under that finger exactly, took me about three hours.

 The order of operations I found to work after trial and error (the worst sort of programming, as it often shows you don’t really know what you’re doing, as you’re doing it) was this:

  • Take the inputs in screen space (320 * 480 resolution, not the 640 * 960 graphical resolution of the device)
  • Translate by half the screen space towards the origin
  • Divide by the camera scale
  • Divide by the screen space
  • Multiply by the relationship between the frustum and the viewport (I have this encapsulated in a function called GetMysteriousMultiplier as it’s simply multiplying by 2 and this was my best guess as to why)
  • Subtract current camera translation divided by camera scale
  • Turn this into a translation matrix
  • Translate camera by the matrix
  • Scale camera
  • Translate camera back by the matrix

Now it’s not that I didn’t work out I had to do most of these right from the off, but not quite all of them and not quite in that order and getting it right took about as long as writing everything else did in the first place. Try as I might to picture the scene in my head and do the transformations one-by-one to work out what needed to be done, after enough steps it slipped away from me. Suffice it to say, my MysteriousMultiplier still feels a little bit like this: and I sense it will come back to bite me in the ass at some future juncture (the fact that the first place a google image search found me this image was stackoverflow tells me I may not be the first person to have this sort of issue).

*I spent Christmas 2011, at my parents’ place, writing out every aspect of the Navier Stokes equation  for fluid dynamics on 20 odd sheets of paper to try and get my head around it. I came pretty close until it came to implementing it, then the kernel smoothing functions broke my dainty little mind.

Asset Management

It’s been eleven days since I last updated this blog and two weeks since I wrote about something I’d actually done to progress my game. Last time I wrote about my project I had just finished writing the level loader using pugixml and was refactoring my prototype code into something more generally useful and game-loop like. With each generalisation I added I was removing some presumption I had previously been making, where each of those presumptions had allowed me to not have to think about tricky edge cases or how some feature would work in a fully-fledged game.

In the prototype, if I added a physics object here and a physics object there I could vaguely test the physics system and see if it worked and gave the kind of feel I was looking for. If I placed the two physics objects on top of each other and they interacted badly, I could fix that by just keeping them apart for now and worrying about the issue later. When moving towards a more robust system that I can use to test out a multitude of game ideas, dealing with edge cases, rather than working around them by not using the system fully, stops being an option.

For instance, when I started writing an asset manager to deal with loading textures, I remembered Adam Clixby’s advice about testing in low-memory environments and factored that into the design. So any reference to assets in the game is managed by handles passed to the asset manager and would be agnostic of the state of that asset in memory. A game object might use a specific texture and on creating that object I tell the asset system to give me a handle to that texture, so that later I can bind the texture before rendering the object on screen. In this context that handle is an internal type of the asset system and on passing that handle to the asset manager to get hold of the texture name to bind it, the asset manager will then load, reload or pass an already loaded texture name back for rendering. Now, if I get a message from iOS that the device is getting low on memory, I can dump all the textures and know the system will smoothly reload them when my game becomes the currently interactive app again.

The asset system also deals with multiple objects using the same texture by simply returning the ready loaded texture handle when an identical texture is required from another source (identical by filename currently, hopefully this won’t cause too many issues later). This doesn’t cover all my needs though, as I have textures I adjust during gameplay and could be updating them every frame. There’s an overhead to constantly loading textures into graphics memory, but it’s a requirement for what I’m doing and isn’t prohibitively costly. What it does mean is that I might start off with a 128 * 128 texture, where the texels are being changed frame by frame, then later resize the texture and load new images onto empty parts of the resized texture. Keeping the game in lock-step with these changes, such as resizing arrays in the game for data that relates to the textures and copying old and new data into the correct portions, has taken a good proportion of the last two weeks to get running robustly and without the heart sinking feeling of suddenly seeing uv coordinates flying all over the place as some part of the system gets out of sync with the rest of it.

The result is that I now have a game that can load levels from xml, create game entities and run the gameplay, so that I can quickly prototype a variety of game ideas around a theme. It’s definitely taken me longer to get things up and running this way and I could have been prototyping game ideas in a more throw-away manner, but everything I’ve taken time to code in a considered way are systems that I will need for making the final game and any future proofing lies within the scope of the current project and on the initial platform. It feels like I’m half in full production and half in prototyping but if I’ve balanced it right then the bits in full production are the bits I know I’ll need in the final game and the bits I’m prototyping in a quick and dirty fashion are the bits that will be used to reduce risk and can be happily thrown away. The ideas that make it can then be moved into production territory, once the prototypes have led to definitive design decisions and it’s not a waste to spend time doing it right.

Pearls of Wisdom Goes Forth

With a brief cross-over and much handshaking and “Merry Christmas”-ing before Kostas and Kyriakos left, Adam Clixby and Glen Watts joined me in the Drummond to continue with my day of interrogation. Adam is a founder of Rodeo Games, makers of turn-based strategy games Hunters and Hunters 2 and currently developing Warhammer Quest. Glen is a long-time Lionhead veteran, recently freed and looking to start his own indie games company. I first worked with Glen in 2001 at Dogfish Studios and we both ended up at Lionhead a short time later (Glen via HotGen, myself with a more direct trajectory). Most of the following is Adam’s advice, arising as the three of us talked about making games.

“Testing on iOS is like xbox, testing on Android is like PC” – The Android platform has such a variety of mixes of hardware that testing for Android is much like testing for PC. There are an unfeasible number of permutations of hardware, which almost guarantee that your code will fall over somewhere, causing a very vocal backlash against your game and one star reviews that you have almost no control over. Even a given version of a specific phone can have subtly different pieces of hardware in different territories, one of which might crash and the other of which won’t. This level of testing hell is expensive to deal with and almost impossible for a small developer. iPhones, on the other hand, have much more homogeneous hardware, making testing a far more constrained problem.

“Use the NS data types on iOS” – this is a specific piece of coding advice, but Adam said that loading in from XML to the NS data types made everything very easy in terms of serialisation. The whole data structure just ended up as a dictionary of dictionaries after load and saving became updating those dictionaries and pumping it back out to XML. I don’t know if this will make me redo the work I’ve done with pugixml, but it’s at least worth looking into.

“Throw away everything that doesn’t work between games” – You’d think that between writing versions one and two of the same turn-based strategy game, you’d only be expanding and refining your codebase, but apparently the only things kept between versions were the renderer and asset system. The reason for this is that they (much as Mark advised me to) didn’t over-plan and didn’t write generic systems that were unlimitedly extensible. They just wrote the game they wanted to make as quickly and fat-free as possible. Maybe if they’d known the additions they’d wanted to make for Hunters 2 they could have built Hunters 1 differently and made it extensible in just the right way that more code reuse would have been possible, but that would have required incredible prescience, a lot of luck and still come with the trade-off of time, effort and money. As a self-funded start-up they almost certainly made the right choice. They certainly made the safe one and they’re still in business now, two games down and making a third for Games Workshop because of their success.

“Test for low memory situations” – One of the early bugbears for Hunters Part 1 was the game crashing when it was sitting in the background as the user was using another app. iOS might then decide that it was running out of memory and would dump Hunters or part of its resources our of memory. This wasn’t a situation Rodeo had tested in before release and it caused a lot of unhappy customers. Making sure my app deals with partial or entire unloads, then jumping back to the game where the user left off, will certainly cost time and effort to do, but the alternative is one star reviews and demanded refunds. On switching back to your app after a partial or full unload, Apple gives you a warning message and then display the last frame of your game before it was switched away from, giving you time to get everything back together ASAP.

“For freemium, balance your costs for in-app purchases very carefully” – Punch Quest was originally released as a free-to-play game, where you could earn in-game currency and spend it on in-game items, with the option of buying extra currency to purchase things quicker in-game. It seems the developers were too kind with their pricing of in-game items and with 600,000 downloads, they only made $10,000, forcing them to eventually switch to charging for downloading the game. Here’s the article in depth. Whilst you want your customers to like your company (good will still counts for something) and enjoy your game, you’re still a business and finding a good way of getting people playing your game to pay for it shouldn’t be misconstrued as ripping anyone off. You might want to make it that players could, in theory, play the entire game without paying a penny if they put the hours in, but making that laborious to the point that most player would consider paying for extra items or content is just good business sense. This is in no way advocating pay-to-win, which will definitely alienate your customers in multiplayer games.

“Make something good. Tell everyone.” – It sounds obvious but sometimes the most common of common sense advice is forgotten. If there are two stages to making a game, these are they.

“Give exclusives to interested journalists, then digg/twitter everything to fuck” – If you give an exclusive to a gaming site, you’re doing so because it’s more likely they’ll more prominently display the article about your game, but what you really want is for *everyone* to read it. If you then go on to use all your social media heft to get it out there, there’s more chance of other social media outlets picking it up, which brings us neatly onto…

“Tak’s pyramid of upselling” – Named after Tak Fung, co-founder of Supermono Studios, this isn’t an alternative to making a creative, fun, polished game, but a solid approach to gaining traction in the media to publicize it. Tak suggests that, in the beginning, the big sites are unlikely to have much interest in you. Unless your game is so left-field creatively that it’s news by itself, it’s unlikely to be immediate front page material. However, like any ecology, there is a food chain and whilst the largest gaming sites might have little interest in eating your output initially, they’ll happily eat the best output from the sites one level down. If you find small sites and get them interested enough in your game that they put you on their front page (maybe as an exclusive, as suggested above) then the sites above that are more likely to consume your content from that level, and so on up the chain. This is unlikely to get you to the top in one go, but by the time you do your next round of publicising your game, the sites one level up the chain might have heard of you and could be willing to take an exclusive, until you find yourself getting your emails replied to by the biggest sites directly.

“Be careful and well-crafted with your output, the press might repeat it verbatim” – If you give a journalist some copy to read, there’s a chance that the headline you wrote (or some mash-up of your first sentence) will be the headline of their article and the rest of the article will be a verbatim reproduction (or some condensed version) of the rest of that copy. If you can’t imagine what you’ve handed them looking good as an article on their website, then re-write it until you can. This isn’t any guarantee that what you write is what will end up on their front page as-is (most will at least re-write it to keep within their own style guidelines), but a good failsafe against your poor language skills ending up being the next thing a potential customer reads about you.

“Give the journalists anything and everything they ask for” – Screenshots, videos, sound bites, your sister’s phone number, just do it or you run the risk of the article about your game being at the bottom of their front page, under the articles about the games of people who did.” – This website looks amazing for beta-testing your game. It takes all the heavy lifting out of getting a signed version of your app onto the devices of whoever you like (specific friends or x number of strangers), then feeding back usage analysis to you. It’s something I’ll definitely use and currently it’s free, but great things can’t last forever.

“Always keep the game stable” – At Rodeo they always stop production whenever anyone hits a significant bug and ensure they fix that bug before continuing. I think we all agreed that asserts should be unskippable and should crash the game. If you’re checking something is true and it isn’t then stop and fix now (including it not really being an assert and removing it), don’t let people “come back to it later”, when they never will. Keeping the build functional at all times will save more time than it costs.

“Xcode static analysis” – We used to use lint a little at Lionhead, but there weren’t enough evangelists about it for it to be used enough. Using static analysis and cleaning up all the complaints will get rid of a lot of hard to repro bugs (uninitialized variables and the like) before they cost you time and sanity.

“Pay up front worked better than unlocking in-game” – Hunters Part 1 was initially a free to download game, where you unlocked the ability to continue upgrading your characters beyond level 2. This wasn’t working as well as they hoped, so after a few months they switched it to pay to download. This was worrisome for them as all the people who had already downloaded it for free would get the update and now have it unlocked for free. Only new players would be paying to download the new version and make them any money. It turned out this was worth it as their daily income doubled. No doubt a lot less people got to play the demo version for free, but they made more money in the long run.

“Apple offers automatic refunds but few people take them up on it” – Apple’s policy is that anyone that asks for a refund on an app gets it, no questions asked. The app is also not removed from their device and they can keep playing as normal after the refund. If this sounds bat-shit crazy and scary to a developer, I can understand it, but only around five people per week ask for that refund on Hunters, which says a lot about the people who choose not to pirate games in the first place.

“Use GIT for source control” – Currently I’m using perforce for free on my own computer, but I really need to get everything in the cloud in case others join my project. My perforce directory is in dropbox so I’m reasonably safe from losing it under most conditions, but I shall have to soon do it “properly”. There are many possible solutions but GIT was Adam’s favourite.

“By the time your game is released it has to be your personal favourite game” – I think this is a great sound bite and something that will have to be true before I release anything myself. If I don’t love it and can’t be the best evangelist for my own game then what chance does it have in the highly saturated app store?

Thanks to Adam, Glen, Kostas and Mark for their time and advice (I think they enjoyed giving it as much as I enjoyed rapidly jotting it down). I’m sure I’ll head to Guildford and assault more ex-Lionheaders for their advice in the future, but for the next while I’m going to spend my time doing less typing of English and much, much more of C++. Happy 2013 everyone 🙂