Tight FPS Solution

PercyPea (well known from flashkit – mario kart thread) sent me an email, where he describes a solution to force the browser plugin to hold the FPS very tight.
I tried it for my tileengine games/supermario. It seems to be true and I really would like you to give me your framerate at this example. It should be about 32/33 and actually firefox makes it fine. PercyPea makes also a thread on flashkit, where you can post your comments.

The idea is to adjust 120 FPS and slow down by running a loop untill the necessary milliseconds are passed. Simple as for example java do.

27 thoughts on “Tight FPS Solution”

  1. One thing, it’s not a great idea to have a while loop running (Like Percy’s example) until the desired time has been reached. It’s a much better to have a setInterval running with a 0 millisecond interval, and use an “if” statement instead of a “while”. Rendering is much smoother that way. I’ve been using that for about a year already.

  2. I tested it for one of my games. I set global FPS to 120 and the desired framerate to 33,5.

    Test results:

    IE and Firefox 31.9 fps

    Safari 1.0 13,3 fps (on an old iMac)
    Safari 1.3 and Firefox 1.04 33,3 fps (on a Dual G5)

    So I think this are very good results, although I don’t quite understand how this script works? Anyone could explain this a little bit deeper, please?

  3. @Staticreator:

    Does setInterval with 0 Milliseconds forces the playing not entering the next frame ?
    I have tried some codings, but it doesn´t work.
    Any codesnippets would be nice.

  4. Okay, setInterval calls runs code that’s something like this…

    var f:Number = getTimer();
    if ((f - lastTime) >= (1000 / frameRate)) {

    // Your code here

    lastTime = f;

  5. Static, no offense, but I think you are missing the point… PercyPea’s script essentially forces the player to “hold” on the current frame until enough time has passed to simulate the framerate. Your setInterval solution will only work if you build everything around it (with event listeners, etc) the beauty of the while loop method is that it doesnt require any modification other than changing the fps and adding the few lines of code.

    ps – Andre, have you ever tried to use a streaming sound on the timeline to get a regular framerate? I would be interested to see the results on the mario game.

  6. >…use a streaming sound…

    I have tried this on another project, but it failed. If the player needs more time to compute for one frame, it runs choppy again. I have also tried FPS around 12 to make sure, that the player can solve a frame, but also choppy jumps.

    I wonder if there is another solution to force the player to wait. Perhaps a nested recursive function won’t decrease the CPU this way.

  7. i´m not convinced of the code snippet. its a nice idea but sadly had way different results on various machines. besides that the loop raises constant cpu requirement a lot on slower machines (which maybe normally could have actually almost reached the target fps).

  8. I’ve tried several methods to force the player to wait, but it seems to be impossible to avoid the choppiness in the IE.
    Anyway, Firefox was the problem, where the solution runs fine. A browser switch for IE would enhance the player performance for most browsers.

  9. I’m not missing the point, it took me a lot of time to come to the conclusion that this was a better way to handle things. When you think about it, it’s the same as the while loop, the method is called repeatedly until the right timing has been reached. The only difference is that things are handled more relaxed, and rendering is smoother. Forcing the player to wait isn’t the idea, your code does a fraction of the work compared to the player, so take as little time as possible.

  10. @Staticreator:

    Do your script forces the player to wait ?

    I don’t get your idea. If you running a fast setInterval, which only broadcast code after a given time, what about playing MovieClips ? Are there running with almost 120FPS ? That is the question, we are talking about.

  11. The only technique I knew before is based on timeouts. There is a tutorial from the mIRC demo-scene (which is really small, hehe).

    You can read about it here.

    It’s all about setting an interval of (1000 / DesiredFPS – deltaT) milliseconds.

  12. Andre:

    If you want MovieClips to play using Flash’s built-in system (rather than relying on your own animation code like I do), my technique won’t do the job.

    Sorry, I should’ve explained more, I’ve got a movieclip-spawning class that adds custom methods to movieclips at runtime. This allows me to have much more control over animation (Like adding methods that are based on what the movieclip’s purpose is). You can play nice with AS2 by using custom intrinsic classes. While it adds extra code, animation stutters less than with PercyPea’s technique because it doesn’t lock up the code while waiting.

  13. Another reason is the speed of objects if you decrase the FPS by an interval or a loop. You would have to animate all objects using AS to synch them.

    Or is there any other possibility?

  14. ich schreib mal meine testresultate in deutsch daher, geht am schnellsten ; )

    in firefox rennt mario ohne probleme mit 33fps über den screen, im IE ruckelt das ganze mit unspielbaren 0.0000023 fps und zeigt trotzdem 33fps an. also das schaut ungefähr so aus: ich drücke die pfeiltaste nach rechts und es passiert erstmal nichts. nach einigen sekunden springt der hintergrund einige meter weiter. also vollzieht das game im hintergrund doch irgendwie die schritte die ich an der tastatur mache, stellt sie aber erst dar, wenn ich die tastatur loslasse und eine weile nichts mehr mache.

    achja, ich hab hier einen pc mit 3ghz cpu und 1gb ram rumstehen.


  15. it runs smooth at 33 fps and after 10 secs the frame rate drops to 1-7 fps and it sucks up the cpu
    I’m running it at a 2.6 dual core pentium 4 with flashplayer 8.5 beta

    hope this helps you a bit
    love your site and examples andre ;)

  16. Just wrote a lengthy post and lost it because of your anti-spam measure… ouch. Might I suggest tweaking that a bit?

    What I basically said:

    The technique described is what’s commonly referred to as a “fixed timestep” in traditional gamedev. There’s a coder named “Jare” that has a good example of it (in C++) if you want to give google a shot.

    The problem with this approach is it “busy waits.” Busy waiting will effectively prevent the Flash Player from handling it’s background work (e.g., garbage collection). This will force it to do the background work once your frame completes, thus further delaying your next frame which further delays the frame after that and so on… the end result can be a vicious cycle if the loop is not limited.

    I suspect this problem is occuring because I ran into the same problem as Loma did above (with a similarly powered machine). This appears to me to be a classic unregulated fixed timestep issue. See Jare’s comments on undersampling/oversampling to prevent this.

    The ideal is to not busy wait, but rather keep the Flash Player’s “loop” going so that background tasks (garbage collection mainly) get performed at the Player’s leisure. I’ve just picked up Flash over the last week or so (using only the excellent Flash Develop, no MM Flash IDE for me!) so I don’t have this quite working yet, but here’s my plan:

    Since Flash already has a main loop (onEnterFrame event handler), I’m using it as my main game loop. Each time my event handler is called I determine the delta since the last frame (getTimer). I accumulate this each frame. Once my accumulator exceeds a given threshold (the length of time my desired frame would take, i.e. 1000/12 for 12fps if using getTimer) I run my internal game update. I then decrement my accumulator by whatever is appropriate for my desired framerate (1000/12 for 12fps).

    At this point, the accumulator may still have too much time in it (if the user’s Flash Player’s frame rate is lower than your desired fps, for example). Here you need to decide whether you run your game loop again (and decrement the accumulator) and again until the accumulator drops below the threshold (in which case your total onEnterFrame update will take longer and longer and eventually timeout the Flash Player). Or, do you skip ahead to catch up (which may or may not work depending on your game engine). I usually choose to simply max out at rendering one update per Flash Player frame. That way the game simply slows down if the user’s Flash Player slows down, but my game never causes the player to slow down progressively worse (as I and Loma saw with your example). This would be the wrong decision for network play as it would likely cause a desync between players (or force all players to slow down to the slowest player).

    I should note: the supermario game worked as expected on my laptop at home, which is actually a much slower machine than my desktop I’m using right now at work (which was afflicted like Loma described above).

  17. This is a BAD way of doing it.

    It will mean that flash uses a 100% of the CPU constantly.

    Better just skip to next frame, until necessary time has passed.

Comments are closed.