Jump to content
  • Advertisement
Sollum

Competitive games and locked frame rates

Recommended Posts

Hello!

Recently i've been watching a lot of material on fighting and other competitive games. Most of serious fighting games have precise frame "timers".

Example:
5 frames for hit start animation
3 frames for still animation
5 frames for recovery animation

Games like Diablo 3 also have "Frame" counter.
But how do they go about precision? How do they ensure that frame A is equal to frame B and C?
I code games for Android and I switched to "time" based calculations instead of frame based long ago. But it turns out that frame precision is important in some cases.

How do big developers ensure that no frame skips happen and 1 frame is always the same length? 

At the moment, I imagine, they simply test if there is no lag in animations, and if there is, they work around it to make it smooth.
Not to mention, making it for a specific hardware.
How to go about in mobile and PC markets?

"Delta" time calculations are quite cool, but it gets awkward if you lag for 2 seconds and bullets go through wall, if no proper checking is done.

Share this post


Link to post
Share on other sites
Advertisement

This is done by decoupling simulation rate from frame rate. Generally when people talk about 3 frames for recovery, they are actually talking about 3 ticks/steps of game simulation, not the actual displayed frames (though these can be the same). There's a great article about this that you can find here.

Share this post


Link to post
Share on other sites

Thanks!

I had read that article before, and its exactly what pushed me to ditch frames and go for time. I will re read it again more carefully.

That article confused me once before. It mentions "partial states", as in 1/10 of physic done in frame/tick.
Does that mean you simulate 1/10 of a frame? I think its not a good idea.
Also i had this interesting bug, where due to "frame checking" on low end hardware i had 24 frames out of 60, as soon as i switched to delta time physics and stopped limiting it to frames it ran at 60 fps.

Share this post


Link to post
Share on other sites
38 minutes ago, Sollum said:

Does that mean you simulate 1/10 of a frame?

No. Generally your FPS will be higher than your simulation rate. Say you have a moving ball, in state 1 it's at x=0 and in state 2 it's at x=10. Now as you are accumulating to go to state 3, you can render the ball being somewhere between x=0 and x=10 by simply interpolating based on how much time there is left to the next state. If your halfway through to the next state, you render the ball at x=5.

To put it another way, say you simulate at 10Hz and render at 100fps, if all you do is render the result of one simulation, you'll be rendering the exact same thing 10 times over. This will look the same as rendering at 10fps. If instead you take the results of two states and interpolate between them, you'll see a smooth transition from one state to the other in a time period of 10 frames.

This does mean some delay is introduced (1 / simulation rate), since you need two states to interpolate.

Share this post


Link to post
Share on other sites
Posted (edited)
51 minutes ago, Mussi said:

No. Generally your FPS will be higher than your simulation rate. Say you have a moving ball, in state 1 it's at x=0 and in state 2 it's at x=10. Now as you are accumulating to go to state 3, you can render the ball being somewhere between x=0 and x=10 by simply interpolating based on how much time there is left to the next state. If your halfway through to the next state, you render the ball at x=5.

...

This does mean some delay is introduced (1 / simulation rate), since you need two states to interpolate.

I think i'd prefer to fill "do nothing" instead of interpolation if game is frame and sprite based.

I remembered the issue i was facing, i was trying to lock framerate to 60 fps and skipped game logic for frames, but in the end i was lossing framerate, since instead of waiting at the end, i tried to wait as soon as possible. From 60 fps it dropped to ~25.

Somehow i dislike the "half state", it makes no difference from time based logic in my eyes.

Edited by Sollum

Share this post


Link to post
Share on other sites

I'm sorry, I don't understand what you're saying. If you'd like, maybe you could explain it with some pseudo code? In any case, decoupling simulation from rendering should not drop your frame rate.

That being said, you don't have to use a fixed timestep, if variable deltas work for you then use that. However you mentioned the problem of tunneling in your op, if you want to prevent that you'll have to take special care for when your deltas become too large.

Share this post


Link to post
Share on other sites
1 hour ago, Sollum said:

I think i'd prefer to fill "do nothing" instead of interpolation if game is frame and sprite based.

I remembered the issue i was facing, i was trying to lock framerate to 60 fps and skipped game logic for frames, but in the end i was lossing framerate, since instead of waiting at the end, i tried to wait as soon as possible. From 60 fps it dropped to ~25.

Somehow i dislike the "half state", it makes no difference from time based logic in my eyes.

I'm also not sure what you're saying... Can you please elaborate more? You don't 'lock' frame rates with this type of a time step, nor do you ever use any 'sleep' commands. You can implement a frame limiter, so you're not running at 1000fps to reduce load, but you're not locking it down to 60fps. You also have to interpolate between those two states, otherwise your graphics will not be smooth.

Just to give you a quick break down, I personally use Fixed Time Steps with Variable Rendering on majority of my projects. Essentially you're running logic at a certain amount of ticks per second. If you set your tick count to 30 per second, then it will cycle through your logic every 0.033333 (repeating) of a second. During the "wait" time until the next tick is due, you're rendering frames as fast as possible, and repeating.

The two draw backs compared to variable would be input delay, and the requirement to interpolate in order to maintain smooth graphics (you'll be rendering a frame back). For me personally, the input delay doesn't effect me and isn't noticeable in my projects, and rendering a frame back to interpolate isn't noticeable in any negative fashion.

If you can show some code regarding your lost frames issue we can look into it.

As @Mussi stated, you can still use a Variable Time Step, just keep in mind the Pros and Cons as with any other Time Step.

Share this post


Link to post
Share on other sites

Sorry for not making much sense.

I think i figured out the issue i was facing before. Here is the code example.

public boolean timeToUpdate()
{
  if (TimeUtils.millis() > runActionAt)
  {
    runActionAt = TimeUtils.millis() + l_msForFrame;
    frameCounter++;
    return true;
  }

  return false;
}

 

It would check for "true" condition. If it returns true, game logic would update.
The idea was to check if current time is more than "next run time".
Where next run time is calculated by taking current time and adding time for one frame.

The result was that it would almost always check to soon and next check would happen a lot later, and that's why i was losing frames.
Calculating when the next update should happen was a bad idea.

I think i would find an answer to fix this problem in that article, i will check it a bit latter, lots of work at the moment.

But i hate the idea of those "interpolation" states, it can lead to very ugly rounding errors.

I plan to do some research tomorrow on this topic and i will get back to you.

Share this post


Link to post
Share on other sites
1 hour ago, Sollum said:

Sorry for not making much sense.

I think i figured out the issue i was facing before. Here is the code example.


public boolean timeToUpdate()
{
  if (TimeUtils.millis() > runActionAt)
  {
    runActionAt = TimeUtils.millis() + l_msForFrame;
    frameCounter++;
    return true;
  }

  return false;
}

 

It would check for "true" condition. If it returns true, game logic would update.
The idea was to check if current time is more than "next run time".
Where next run time is calculated by taking current time and adding time for one frame.

The result was that it would almost always check to soon and next check would happen a lot later, and that's why i was losing frames.
Calculating when the next update should happen was a bad idea.

I think i would find an answer to fix this problem in that article, i will check it a bit latter, lots of work at the moment.

But i hate the idea of those "interpolation" states, it can lead to very ugly rounding errors.

I plan to do some research tomorrow on this topic and i will get back to you.

I don't have too much time to get into great detail so I'll give a quick example. Your Time Step should be something like this (This example doesn't account for a frame skip, but it's not important right now):

while (game.isActive())
{

  while (clock.getTime().inMilliseconds() > nextTick)
  {

    // All Logic Here

    nextTick += 1000.f / ticksPerSecond;

  }
  
// Draw Here
}

 

1 hour ago, Sollum said:

But i hate the idea of those "interpolation" states, it can lead to very ugly rounding errors.

Can you provide some proof where you've seen this effect visual placement in a way that would create an issue? We're not talking about dealing with numbers in logic, but setting a draw position. Interpolation doesn't mess with logic, it simply takes two states and draws your image based on that calculation. You do not need 100% pin point accuracy for this when rounding.

There is a major difference between having numbers which are on going in a simulation and floating point errors could derail it, than setting and resetting draw positions. When I interpolate I have two positions of the object, and right before drawing the graphic I use the new value given to set the x, y of the image. The position you see on the screen isn't the actual position of the object in logic, it's just used to smooth out movement during rendering.

If I was to interpolate one object, it's only 3 lines of code, not counting the line of code needed to get the time value.

If you're already decided that you cannot interpolate states properly, then I would just forget Fixed Time Steps with Variable Rendering, and stick to Variable Time Steps, or another type that doesn't require the use of interpolation.

I should add that many online game use interpolation as well when dealing with server <-> client positions. This is not a new concept in the game industry.

Share this post


Link to post
Share on other sites

Keep in mind that interpolation is a blanket term that means different things in different contexts, not everything is interpolated. Rutin is specifically talking about linear interpolation between positions.

If you use a 2d sprite based game for example, animation is usually comprised of distinct sprite key frames, so a 2d fighting game could have character sprite positions interpolated(they would move slightly between frames even if the logic isn't updating) but their animations wouldn't change, and no game play effects would happen.

In reality games tend to vary a lot in how they handle updating, many run different logical updates at different rates as well (physics may be updated at a different rate than AI, or other systems.) Actions taking X amount of "frames" is likely just dependent on how the engine is set up, and may just be based on delta time.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!