Tight FPS Solution
July 7th, 2005
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.
Filed under: actionscript
26 Responses to “Tight FPS Solution”
-
kiroukou Says:
July 7th, 2005 at 3:56 pmHi Andre,
It runs at 33 fps here with a 800 Mhz computer and IE.
Thanks
++ -
Juan Carlos Says:
July 7th, 2005 at 4:26 pmRan at 33 in Safari 2.0 on 1.5ghz powerbook. Same in Camino, except flashed 29 for half a second but then right back to 33.
-
F Says:
July 7th, 2005 at 4:44 pmalso 33 fps - 2000 MHZ Windows PC, Firefox 1.0
-
caseyc Says:
July 7th, 2005 at 6:31 pmWin XP 2.8 Ghz ran perfect 33 in Firefox, but was not playable in IE very very very choppy.
-
micael Says:
July 7th, 2005 at 11:59 pm33 with 3Ghz - firefox.
-
caseyc Says:
July 8th, 2005 at 1:11 amJust a follow up, it now seems to run fine on my IE, must have been a glitch in the matrix.
-
Staticreator Says:
July 8th, 2005 at 2:02 amOne 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.
-
Tobi Says:
July 8th, 2005 at 9:54 amI tested it for one of my games. I set global FPS to 120 and the desired framerate to 33,5.
Test results:
Intel/WinXP
IE and Firefox 31.9 fpsMac/MacOSX
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?
-
André Michelle Says:
July 8th, 2005 at 12:02 pm@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. -
Staticreator Says:
July 8th, 2005 at 2:37 pmOkay, setInterval calls runs code that’s something like this…
var f:Number = getTimer();
if ((f - lastTime) >= (1000 / frameRate)) {// Your code here
lastTime = f;
}
-
caseyc Says:
July 8th, 2005 at 4:15 pmStatic, 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.
-
André Michelle Says:
July 8th, 2005 at 4:47 pm>…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.
-
tomsamson Says:
July 8th, 2005 at 7:08 pmi´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).
-
André Michelle Says:
July 8th, 2005 at 7:16 pmI’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. -
Staticreator Says:
July 8th, 2005 at 9:05 pmI’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.
-
André Michelle Says:
July 9th, 2005 at 6:12 pm@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.
-
joa Says:
July 9th, 2005 at 6:18 pmThe 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.
-
Staticreator Says:
July 9th, 2005 at 11:28 pmAndre:
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.
-
joa Says:
July 10th, 2005 at 11:25 amAnother 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?
-
pinkstar Says:
July 11th, 2005 at 2:15 pmich 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.
grüße,
pinky -
paul Says:
July 13th, 2005 at 1:56 pmich sitz an einem 3 ghz pc und hab die selben ergebnisse wie pinkstar.
gruss
paul
-
paul Says:
July 13th, 2005 at 2:01 pmbei percys beispiel funktionierts in beiden browsern.
-
Loma Says:
April 27th, 2006 at 9:02 amit 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 betahope this helps you a bit
love your site and examples andre ;) -
Troy Gilbert Says:
May 19th, 2006 at 10:46 pmJust 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).
-
André Michelle Says:
June 2nd, 2006 at 2:35 pm -
Andre Michelle » Blog Archive » Stable FPS Test Says:
April 18th, 2008 at 12:34 pm[...] tried one more time to get a stable frameRate in browser enviroment and an old workaround works fine for me now (flash9player [...]

