There are a lot of subtleties involved when framerates go over 1000, and a lot of strange things suddenly start happening. I guess this is partially reflected in the "don't allow really short or really long frames" comment in the ID Quake source, but it would have been nice if that had been followed up with "...because this, that and the other happen". All the same, I don't expect that Quake was ever tested at this kind of framerate back in 1996 so I'll let it pass without further comment.
One item of concern is dynamic lights. There are some dynamic lights in the engine which are given a die time of 0.001 seconds after they are spawned, with the obvious intention being that they will last for one frame and be respawned again immediately afterwards. At over 1000 FPS we suddenly have them lasting for more than one frame, with the end result being that we could have multiple such dynamic lights on the go at one time. If we were running at 5000 FPS we would actually have 5 dynamic lights being thrown around a player who has the Quad Damage - bad for performance indeed (although at that kind of speed performance isn't something you worry about).
A really weird and subtle one emerged in conjunction with timer decoupling. In order to get smooth and responsive input it's necessary to accumulate input events every frame, then gather them up and send them to the server at 72 FPS. This only becomes an issue at this kind of framerate (when movement suddenly becomes ultra-jittery otherwise); run any slower and you can ignore it.
Anyway, when I simulated a framerate of 10,000 FPS (via host_framerate) I discovered a very strange effect - pressing the forward key would cause me to move backwards, and vice-versa. Some digging around revealed the answer - Quake transmits the forward movement to the server as a short (16-bit) integer. This has a maximum and minimum of about 32,000, and the accumulated input was causing it to overflow and wrap.
I guess that's a definite case of a protocol limit on how fast Quake can run. I'm not too certain of where the precise cutoff point is; I measured it around the 5,800 FPS mark but can't be any more precise.
Particle effects are another interesting one, and this affects framerates below 1,000 too. I mentioned this one earlier, but the technical details are that it's necessary to split particle spawning off from CL_RelinkEntities. CL_RelinkEntities is called by CL_ReadFromServer, which must be called every frame (otherwise movement goes totally to herky-jerky land), but if you spawn particles behind a rocket every frame you'll be spawning maybe 10 times as much as you should. So particle spawning needs to also run at a slowed-down rate otherwise the faster we go the more we'll hurt framerate. At maybe 1000 FPS it translates into a halving of framerates every time a smoke trail is spawned.
All rather curious stuff indeed.
Tuesday, May 17, 2011
Running at over 1000 FPS
Posted by
mhquake
at
12:05 AM
Subscribe to:
Post Comments (Atom)
3 comments:
"..pressing the forward key would cause me to move backwards, and vice-versa."
Heh, I've seen this happen when cl_forwardspeed is set to some insanely high number as well (over 32000 I guess).
In fact, I used this 'behavior' to make a neat lil' 180-degree-turn-script when I was using Qrack a few years back (not that I ever used it effectively in-game tho).
Anyways.. interesting stuff indeed, at least now I now what was going on behind the scenes ;)
This in-depth research is giving me a headache just thinking about all the little plot twists and surprises you've mentioned.
There's more twists to come!
Post a Comment