0
\$\begingroup\$

I need to implement tickrate into my engine to handle timed events such as pushing out entity updates and I don't know where to start.

I have access to a timer which allows me get the time in milliseconds since the device has been initialized.

When I try to brainstorm on the correct approach to take one of the main things that I get stopped up on is that on the client side I should allow the framerate to run as fast as it can, however if I want the tickrate to run at 60 and the client FPS is less than 60 how can 60 ticks execute if the main loop wont run at least 60 times a second due to it being slowed down by the fps?

Can anyone explain how to properly implement tickrate? Thank you for your time.

\$\endgroup\$
2
\$\begingroup\$

The approach by Narrateur du chaos is commonly called the delta-t approach. But there is also another approach, the game-tick approach. In this approach you keep track of how long the game is running in real-time and how much time the game-world has processed. After each graphics frame you check how far the game world lacks behind the real world and do updates until it has catched up.

 MS_PER_TICK = 1000 / 60  // the time one game-tick represents

 PROCESSED_TIME = currentTimeInMs();     

 while game is running
      drawFrame()
      while (PROCESSED_TIME + MS_PER_TICK) < currentTimeInMs()
        updateGame()
        PROCESSED_TIME += MS_PER_TICK

Personally, I prefer this approach because it makes your update-functions a lot easier to write when you know it always represents a fixed timespan and don't have to take the delta-t into account for every single calculation.

\$\endgroup\$
  • \$\begingroup\$ +1, because I like this method far more than the delta one. Taking the time delta into account can be extremely difficult in some calculations. \$\endgroup\$ – Alexandre Desbiens Jul 17 '14 at 13:24
  • \$\begingroup\$ I like this since each tick is a fixed amount of time which helps stepping the physics however can you explain how this guarantees there will be no more or no less than 60 ticks a second? \$\endgroup\$ – KKlouzal Jul 17 '14 at 13:31
  • \$\begingroup\$ @KKLouzal It basically calculates 1/60th of a second and process. The only ways that could fail is if your clock is not calibrated or if the processor cannot handle the update process in 1/60th of a second. \$\endgroup\$ – Alexandre Desbiens Jul 17 '14 at 13:33
  • 3
    \$\begingroup\$ @KKlouzal When drawFrame takes very long, the while-loop will be executed several times, so game-ticks will be calculated until the game-state has caught up before another frame is rendered. When drawFrame is very fast, (PROCESSED_TIME + MS_PER_TICK) < currentTimeInMs() will likely still be false, so it will immediately render another frame without changing the state. \$\endgroup\$ – Philipp Jul 17 '14 at 13:37
  • 2
    \$\begingroup\$ @KKlouzal There's three performance cases 1) your machine can simulate all the requested ticks faster than time moves and it draws at least as many frames per second as you want; 2) your machine can simulate everything, but cuts down on render frames; 3) your machine cannot even keep up with simulation ticks in realtime. Case 3 is the bad one, as it will enter a death spiral never being able to catch up, and thus appear frozen. A common mitigation for that is to only simulate a particular number of ticks in a row before drawing, essentially ending up with game time running slower. \$\endgroup\$ – Lars Viklund Jul 17 '14 at 13:40
1
\$\begingroup\$

I'm not an experienced developer, but your question seems straightforward enough. Your main() must look like this:

int main(args)
{
    // Code, declarations, whatever
    MainClass game(arg1, arg2...);

    try
    {
          while (game.continue())
          {
               float ticks = timeSinceThatFunctionWasLastCalled();
               game.update(ticks);
          }

          return EXIT_SUCCESS
    }
    catch (err) { // Ideally, no exception must ever reach this point in
                  // the final version, or it means your game crashed, but
                  // whatever.
          return EXIT_FAILURE;
    }
}

Every class in your code whose instances must be altered every tick must then have some sort of function like void update(float ticks); that is called once every time game::update() is called.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.