2

I'm currently working on a Java MMO with a pretty solid start, but I've come across an issue I need a little help with.

I'm working on player positions. Meaning their X/Y on the screen, if the PlayerA has a higher FPS (Frames Per Second) than other players, the resulting action will be that PlayerA will move faster than everyone else. I know the reasoning for this, it's because when the game draws I just use x++.

What would a better method be?

famousgarkin
  • 688
  • 7
  • 23
Matthew Auld
  • 123
  • 3

2 Answers2

7

Sounds like you might want to start using a delta time and a time-based movement speed. It could be a little difficult considering that it looks like you could be using a tile-based engine, but if you use a delta-time, your movement equation will look something like this:

x += unitsPerSecond * deltaTime;

Where x is a floating point variable (float or double), unitsPerSecond is how fast you want your characters to move per second, and deltaTime is in fractional seconds. Having your position as a floating-point value is key.

John McDonald
  • 6,746
  • 2
  • 31
  • 45
  • Seriously, why make him take a detour through that horrible principle? Fixed step is so much easier to get working nicely. http://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step – aaaaaaaaaaaa Nov 14 '11 at 21:03
  • @eBusiness, I would probably do both, but yes, you are correct. A fixed time step would probably fix all of his problems – John McDonald Nov 14 '11 at 21:04
  • 1
    @eBusiness, I too prefer fixed-step, but you can do most things perfectly fine with delta-time systems, and indeed many games in history have done just that. You only really start to see problems when you perform integration, like gravity and other physics. But feel free to post an alternative answer. :) – Kylotan Nov 14 '11 at 21:12
  • @Kylotan 24 seconds ahead of you ;-) And yes, variable step has it's place, especially in the more processing power constricted past. That is not to say that it will have no place in the future, but fixed step really should be the default choice, and is thus the obvious place for a beginner to start. – aaaaaaaaaaaa Nov 14 '11 at 21:25
5

Basically, you need to repeat performing multiple different tasks at independent intervals. In pseudocode that will typically look something like this:

updateTime=1000/120
nextUpdate=time()
repeat{
    while(nextUpdate<time()){
        updatePlayerPositionPhysicsAndStuff()
        nextUpdate+=updateTime
    }
    render()
}

So updatePlayerPositionPhysicsAndStuff will run exactly 120 times per second, while render will take up all the leftover computing power running as often as there is time for.

aaaaaaaaaaaa
  • 8,892
  • 1
  • 21
  • 35
  • This sounds logical, I'll try this out and hopefully it works. Thanks. – Matthew Auld Nov 14 '11 at 21:48
  • 1
    Just keep in mind that simple implementations like the example code can do bad things whenever there's lag or delay in processing; it can result in a "spiral of death." You generally want to use a time delta combined with fixed interval, with a cap on the delta. In other words, calculate the time delta since the last update, cap that at some reasonable value (1/20th of a second, say), add that to an accumulator, and then do fixed timesteps draining from the accumulator. The accumulator also then gives you "left over" time at the end of an update loop to do interpolation for smoothness. – Sean Middleditch Nov 15 '11 at 00:14
  • @seanmiddleditch More complicated, and ditches an important feature, that of determinism. – aaaaaaaaaaaa Nov 15 '11 at 06:30
  • @eBusiness: it's more complicated by all of three lines, allows interpolation which is important if you want the rendering to look good at lower interval values, runs no risk of the spiral of death, and your comment about determinism just confuses me; can you explain further? – Sean Middleditch Nov 15 '11 at 08:13
  • Determinism: If I run the same code with the same input twice I get the same results. That feature breaks if you don't use fixed steps, for any multiplayer game that is a pretty big deal, for single player games it can still be a nice feature to keep. I presume that by "spiral of death" you mean the situation where the computer can't keep up with the requirement of doing a specific number of updates. You obviously have to scale the requirement to a sensible level, in most games that will not be a problem. – aaaaaaaaaaaa Nov 15 '11 at 13:43
  • @eBusiness: I clearly said to still use fixed timesteps. What I suggested was to simply to change how you're calculating the "when should I run the fixed-timestep update" logic. Exact same results, except instead of spiraling out of control you get a worst case where the simulation just goes into "slow motion" (e.g., your fixed 60Hz physics update is only being called at 30Hz). The delta you have also then can be used by graphics to smoothly interpolate between "current" and "previous" physics states, so you can just always run physics at a lower Hz and still have a smooth-looking game. – Sean Middleditch Nov 16 '11 at 08:51
  • I guess you meant something different than I read. Which when I reread your words and think about is not that surprising. Your explanation is holed, I tried to mentally fill in the gaps and came out with variable steps with an upper cap on delta time. I still don't get what problem you are trying to solve, except that you have given it the name "spiral of death" or "spiral out of control", which does nothing to explain what you are talking about. I get that you also want to interpolate for rendering, which is fine for the advanced audience, but the rest remains a mystery. – aaaaaaaaaaaa Nov 16 '11 at 09:57