4
\$\begingroup\$

I've implemented Glenn Fiedler's Fix Your Timestep! quite a few times in single-threaded games.

Now I'm facing a different situation: I'm trying to do this in JavaScript. I know JS is single-threaded, but I plan on using requestAnimationFrame for the rendering part.

This leaves me with two independent fake threads: simulation and rendering. Timing in these threads is independent too: dt for simulation and render is not the same.

If I'm not mistaken, simulation should be up to Fiedler's while loop end. After the while loop, accumulator < dt so I'm left with some unspent time (accumulator) in the simulation thread.

The problem comes in the draw/interpolation phase:

const double alpha = accumulator / dt;
State state = currentState*alpha + previousState * ( 1.0 - alpha );
render( state );

In my render callback, I have the current timestamp to which I can subtract the last-simulated-in-physics-timestamp to have a dt for the current frame.

Should I just forget about this dt and draw using the physics thread's accumulator? It seems weird, since, well, I want to interpolate for the unspent time between simulation and render too, right?

Of course, I want simulation and rendering to be completely independent, but I can't get around the fact that in Glenn's implementation the renderer produces time and the simulation consumes it in discrete dt sized chunks.

A similar question was asked in Semi Fixed-timestep ported to javascript but the question doesn't really get to the point, and answers there point to removing physics from the render thread (which is what I'm trying to do) or just keeping physics in the render callback too (which is what I'm trying to avoid.)

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

How much time does the game logic update take? If your's like most games use very little resources for the game logic there is no need to run multiple virtual threads.

Interpolation takes a lot of extra code, you shouldn't waste your time on it unless you have to. Running your logic at a rate that gives a whole number of updates per screen update should give smooth animation without interpolation, since 60 Hz is pretty much the standard these days that is pretty easy to do, your logic rate should be a multiple of 60. A more brutal approach is to simply run the logic at a very high rate, thus limiting the amount that any frame can be off, a high enough logic rate will make the animation smooth irrespective of any synchronization issues. If it isn't too much of a CPU strain on any target platform I'd combine the two methods and run at least at 120 Hz. Otherwise try 60 Hz.

function update(){
    var advance=(+new Date()-startTime)*logicRate
    while(stepCount*1000<advance){
        doLogic()
        stepCount++
    }
    render()
}

One thing to remember is that input should be applied to the correct update, put keyboard and mouse events in a buffer and apply them only as you do the logic step where they belong.

I wouldn't remove the game logic update from the render call, it's a great place to have it in order to ensure that the logic is up to date, but you could make a separate routine that most likely get the job done beforehand:

function updateLogic(){
    var advance=(+new Date()-startTime)*logicRate
    if(stepCount*1000<advance){
        doLogic()
        stepCount++
    }
}
setInterval(updateLogic,1)

It won't make any real difference unless the logic update takes a significant amount of time.

\$\endgroup\$
2
  • \$\begingroup\$ I appreciate your effort but this doesn't answer my question. The issue here is that I NEED separate threads because my game steps are fixed (online game + reproducibility) and requestAnimationFrame steps are not. Case closed :P \$\endgroup\$
    – kaoD
    Dec 2, 2012 at 18:21
  • \$\begingroup\$ You DO GET perfect reproducibility this way, doLogic() runs exactly logicRate times per second. If you get fewer frames the code will simply do more updates per frame and vice versa. \$\endgroup\$ Dec 3, 2012 at 15:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .