Play Testing

August 10, 2009

The last couple of programming sessions have been sort of directionless for me. I wasn’t really sure what I wanted to change, so I opted for trying to make the game more “fun.” I know, I know, a crazy concept. With no idea how to do that I decided to just play a bit and see if there was anything that could be made a bit better. Well it didn’t take too long to start compiling a list of stuff. Right off the bat was the mouse pointer. Every other game with a first person view has a cool little crosshair type thing to chase around, whereas Rift has a mouse pointer. I also noticed that the steering was twitchy to the point of being stupid, which makes it really hard to dogfight. Also, why no shields? Seriously, how did I never get to that?

So these things and others have now been crossed off the list. It’s surprising how little things like this can go a long way. The next thing I decided to add was spawn points. You know how it works, you jump into an area and after a while some bad guys show up. Then a bit later some more show up. And so on until you either leave or die. Well I created a spawn point and immediately ran into a new and interesting problem. I found that when you had about 6 ships chasing me down my refresh rate would drag down to 1 fps.

This was cause for concern. Oddly enough I noticed that my Physics rate was holding steady at my pre-defined 40 frames per second. So how is it that Physics could remain unchanged, while refresh was dragged down? That’s when I started to remember something from those physics articles I posted a while back. The way the physics loop works is every time through the loop I accumulate time. When enough time has passed I chew up that time in physics. This is all well and good when the game is humming along in empty space. However there’s a real problem when things get busy. What happens when it starts taking longer then a second to calculate all the physics for the past second? The shit hits the fan and your frame rate goes down to 1 frame per second.

Just to pound the point home a bit, let’s say you decide to run 10 physics loops a second. At time 0 you start your game loop and your physics takes 0.18 seconds. Then you run your render and that takes 0.02 seconds. Now you start your game loop over and you have 0.2 seconds worth of physics to run. That’s 2 physics loops. So those two loops takes you 0.36 seconds and then you do your render for another 0.02 seconds. Now you start your third loop and you have 0.38 seconds of physics, or 3 full runs. That now takes you 0.54 seconds. You see where this is going. Every loop you get further behind. Eventually your game just becomes a huge physics number cruncher and stops responding to your input. That’s about what Rift did when 6 bad guys jumped into the spawn point.

Thankfully a long time ago I created a neat little utility program for Rift. The idea is that in debug mode you can break into Rift, flip a bit, and then the current state of the physics will dump to an xml file. Then you can open up that xml file in my test program and poke it with sticks to see how it responds. Well it turns out that with 500 lasers on the screen, 40 physics loops was taking around 3 seconds. Oops. What do you do? Well I started off by getting a nice little profiling tool called Very sleepy:
http://www.codersnotes.com/sleepy/
I fired that up and ran through my code, but it didn’t tell me anything I thought was useful. According to it, all of my time was spent doing things like dereferencing smart points and adding vectors. Surely that couldn’t be the problem? So I started adding counters and timers and what not, and looking at the code path. I found some troublesome square routes, and I copied my heavy STL lists into raw arrays. All of that helped a bit, but I was still taking over a second, which was still WAY too long. That’s when I started to wonder about the sheer quantity of calculations.

The thing about lasers in Rift is that they don’t actually collide. This is by design because lasers aren’t supposed to bounce. So why was my physics loop taking so long? I had 500 lasers that weren’t running any collision detections, should be cake. Well it looks like the problem is simply that when you have 500 objects in a container, and they all need to check against each other, and you need to do that 40 times a second, you end up doing over 5 million comparisons. Turns out this takes a bit of time, even in release mode. So yes, Very Sleeps was telling me the truth, all of my time was spent doing fast things. The problem was just that I did so many fast things.

The fix? I split up the physics a bit so that all of the lasers go in their own container that doesn’t bother to check against itself. Is there a moral, a lesson? I guess it’s that sometimes you have to abandon generality when things go wrong. I’m actually running into this a lot more as I try to work less on the engine and more on the game. Suddenly all my nice abstractions are falling down as I try to add specifics. Some of that is just because my engine has flaws, and some of that is just due to trying to make game specific things.

Next on my todo list is video. I want to make an animation for jumping to a new area. There are a number of articles out there about playing an avi on top of a texture. I just have to figure it all out. Looks interesting. Let’s see how far I get.

posted by james wells at 3:37 pm

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment