Jump to content

Is it OK to call p2's update function directly?


Mehow
 Share

Recommended Posts

Is it OK to call p2's update function directly?

And if not, is there another good way to force phaser to update its logic/physics faster than in the core game loop?
 
My issue is I have an old game state (say 100ms old) and some newer inputs.
I want to force phaser to update the old state repeatedly and as fast as possible to simulate the missing 100ms, then display the new up-to-date state. 
 
The reason I ask is for extrapolating client-side a state received from a server in a real-time game. Because due to latency, the state sent by the server will be X milliseconds old by the time the client-receives it.
 
My initial thought was to repeatedly call:

game.physics.p2.update()

Alternatively, reading the source code in game.js for phasers core update loop suggested mimicking:

this.updateLogic(1.0 / this.time.desiredFps);//  Sync the scene graph after _every_ logic update to account for moved game objectsthis.stage.updateTransform();

Both seem to work, but I have no idea if either causes subtle issues I'm not aware of (plus the second method uses methods labelled as 'internal').
So which, if either would be the preferred method?
And if neither, then what's the best alternative?

Similar issue to: http://www.html5gamedevs.com/topic/6996-phaser-update-speed/

Link to comment
Share on other sites

Interestingly, the p2.world.step function takes a second parameter that is the "time since last called". P2 then tries to do fixed steps from that time until it gets to now.

 

Unfortunately, p2.update() calls world.step without that second parameter and there's no "mainstream" way to supply that parameter.

 

You can actually set p2's frameRate variable, and it will step the world according to that rate, not the actual rate that the update method is being called (which will still be called at the actual game framerate by the main game loop). Bigger time steps will cause physics artifacts, though, and you'll almost certainly get the wrong result, though they may be close.

 

I'd probably override p2.update() to call world.step with the other parameter if necessary. I don't think there's a way to do it strictly using the public-facing API.

Link to comment
Share on other sites

Thanks for that, I ended up writing some tests to compare world.step with 1 vs 2 parameters.
2 parameters gave inconsistent end positions, where as 1 parameter (via p2.update) gave consistent results, which where the exact same as those given by running the game live.
 
I do suspect this might be my dodgy implementation for the 2 parameter case, but any advantages between the two methods are so small it didn't seem worth thinking about much more. (differences could also of been due to p2 using interpolation when given 2 parameters?).
 
In case anyones interested, the logic I've chosen for using p2.update runs like this:

var demoInputs = [{inputSample: {...}, time: 0},    {inputSample: {...}, time: 500}];var serverStateTimeStamp = 0;var fakeCurrentTime = 520;function extrapolate() {    var inputElement = 0;    var simulatedTime = 0;    while (serverStateTimeStamp + simulatedTime < fakeCurrentTime) {        simulatedTime += 1000 * (1.0 / game.time.desiredFps);//*1000 for milliseconds        if (serverStateTimeStamp + simulatedTime > demoInputs[inputElement].time) {            var inputToUse = demoInputs[inputElement];            inputElement++;            proccessInput(inputToUse.inputSample);        }        game.physics.p2.update();    }    //really there should be a check here to make sure that processing the step hasn't taken longer then the time step.    //p2.world.step with 2 parameters has this check built in}

The logic for world.step with extra parameters is similar:

function extrapolate(){    var simulatedTime = serverStateTimeStamp;    for(var input of demoInputs){        var timeToSimulate = input.time - simulatedTime;        game.physics.p2.world.step(1.0/game.time.desiredFps, timeToSimulate, 1000);        simulatedTime = input.time;        proccessInput(input.inputSample);    }    //all inputs simulated, now catch up from last input to current time    timeToSimulate = fakeDateNow - simulatedTime;    game.physics.p2.world.step(1.0/game.time.desiredFps, timeToSimulate, 1000);};

 
The fact that my tests gave the exact same positions as actually running the game is enough that I'm happy to assume calling p2.update directly doesn't screw stuff up (for now anyway...).

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...