Frame rate problem 120 fps

Hi, I’ve played a bit with the html 5 exporter and I realised that my exported game is 2x faster on my 120 Hz screen when played in a browser as if the key in config.lua fps = 60 was ignored during the build. What should I change to keep the function onEnterFrame processing 60 times per second even on a 120 fps screen?

Interesting. I don’t know how our internal timing is tied to a device’s screen refresh rate. But I’ll pass this on to the engineers.

Rob

Is there a URL to the game we can look at?

It is not a good idea to tie your game logic to a frame rate.  It is better to use an elapsed time and a preferred rate or period.

For example:

This is wrong/bad (movement rate will vary and not maintain an actual rate of 500 pixels per second):

local assumedFPS = 60 local speed = 500 local pixelsPerFrame = speed/assumedFPS local obj = display.newCircle( 10, 10, 10 ) function obj.enterFrame( self ) self.x = self.x + pixelsPerFrame end Runtime:addEventListener( "enteFrame", self )

This is correct/good:

local getTimer = system.getTimer local speed = 500 local obj = display.newCircle( 10, 10, 10 ) obj.lastT = getTimer() function obj.enterFrame( self ) local curT = getTimer() local dt = curT - self.lastT if( dt \<= 0 ) then return end self.lastT = curT local dx = speed \* dt/1000 self.x = self.x + dx end Runtime:addEventListener( "enteFrame", self )

Also, you can’t control enterFrame the way you want to.  The best you can do if you have too much code dependent on this is to write a wrapper that uses my proposed delta-time based fix that manually calls your old code when 16.67 ms has passed.

The issue is related to **window.requestAnimationFrame() .**The number of callbacks is usually 60 times per second, but generally match the display refresh rate in most web browsers as per W3C recommendation. 

Fix will come with next daily build.

Yes I know this roaminggamer but sometime I go that bad/wrong way because I need my game to be deterministic and I’m to lazy to code the best way  :stuck_out_tongue:

Also don’t forget that having a logic which depends on the time elapsed since the last call like you did is also a wrong/bad movement because it’s not deterministic (because your dt is never exactly the same and you can have approximation due to limited precision of floating point arithmetic).

The ideal solution (deterministic and framerate independant) is to have an engine which computes at a desired fixed deltaTime and having rendering part dissociated from computing the engine. But you have to interpolate rendering between the previous and current state of the engine (which is painfull to do). If I take your code, I would just add an accumulator coupled with a security like this:

function obj.enterFrame( self ) local curT = getTimer() local dt = curT - obj.lasT if dt \> SECURITY then --add a max to dt, so that it allows the engine to catch up during a lag dt = SECURITY end accumulator = accumulator + dt obj.lasT = curT while ( accumulator \>= PERIOD ) do local dx = speed \* PERIOD/1000 obj.x = obj.x + dx accumulator = accumulator - PERIOD end end

And for displaying the object, you have to interpolate between previous obj.x and current obj.x

By the way, for my problem, it was physic based game: http://honeyponey.fr/claw/

And I still notice the problem. The simulation is running too fast on my 120Hz screen even if there is no movement logic in onEnterFrame event.

So I guess there is something wrong as vitaly1 said.

Also, fun fact, I was testing my game today with a twitch stream opened in another chrome window , and the physics was running at correct speed. So here is my work around until the problem is fixed  :stuck_out_tongue:

Interesting. I don’t know how our internal timing is tied to a device’s screen refresh rate. But I’ll pass this on to the engineers.

Rob

Is there a URL to the game we can look at?

It is not a good idea to tie your game logic to a frame rate.  It is better to use an elapsed time and a preferred rate or period.

For example:

This is wrong/bad (movement rate will vary and not maintain an actual rate of 500 pixels per second):

local assumedFPS = 60 local speed = 500 local pixelsPerFrame = speed/assumedFPS local obj = display.newCircle( 10, 10, 10 ) function obj.enterFrame( self ) self.x = self.x + pixelsPerFrame end Runtime:addEventListener( "enteFrame", self )

This is correct/good:

local getTimer = system.getTimer local speed = 500 local obj = display.newCircle( 10, 10, 10 ) obj.lastT = getTimer() function obj.enterFrame( self ) local curT = getTimer() local dt = curT - self.lastT if( dt \<= 0 ) then return end self.lastT = curT local dx = speed \* dt/1000 self.x = self.x + dx end Runtime:addEventListener( "enteFrame", self )

Also, you can’t control enterFrame the way you want to.  The best you can do if you have too much code dependent on this is to write a wrapper that uses my proposed delta-time based fix that manually calls your old code when 16.67 ms has passed.

The issue is related to **window.requestAnimationFrame() .**The number of callbacks is usually 60 times per second, but generally match the display refresh rate in most web browsers as per W3C recommendation. 

Fix will come with next daily build.

Yes I know this roaminggamer but sometime I go that bad/wrong way because I need my game to be deterministic and I’m to lazy to code the best way  :stuck_out_tongue:

Also don’t forget that having a logic which depends on the time elapsed since the last call like you did is also a wrong/bad movement because it’s not deterministic (because your dt is never exactly the same and you can have approximation due to limited precision of floating point arithmetic).

The ideal solution (deterministic and framerate independant) is to have an engine which computes at a desired fixed deltaTime and having rendering part dissociated from computing the engine. But you have to interpolate rendering between the previous and current state of the engine (which is painfull to do). If I take your code, I would just add an accumulator coupled with a security like this:

function obj.enterFrame( self ) local curT = getTimer() local dt = curT - obj.lasT if dt \> SECURITY then --add a max to dt, so that it allows the engine to catch up during a lag dt = SECURITY end accumulator = accumulator + dt obj.lasT = curT while ( accumulator \>= PERIOD ) do local dx = speed \* PERIOD/1000 obj.x = obj.x + dx accumulator = accumulator - PERIOD end end

And for displaying the object, you have to interpolate between previous obj.x and current obj.x

By the way, for my problem, it was physic based game: http://honeyponey.fr/claw/

And I still notice the problem. The simulation is running too fast on my 120Hz screen even if there is no movement logic in onEnterFrame event.

So I guess there is something wrong as vitaly1 said.

Also, fun fact, I was testing my game today with a twitch stream opened in another chrome window , and the physics was running at correct speed. So here is my work around until the problem is fixed  :stuck_out_tongue: