# Fixed Timestep Loops Fixed Timestep game play loops allow us to run update for game or application logic in fixed timesteps such as 60 frames per second while running draw operations at an unlimited capacity. Running your updates in fixed intervals allows you to not tax the computation of the system and get a smooth update logic for things such as physics or AI operations. ## Python Example Fixed timestep example in Python. Supports an `update()` and `draw()` but does not pass delta time into the methods. ```python timer = 0 actualTime = pygame.time.get_ticks() # ms FPS = 60 dt = int(1 / FPS * 1000) # 60 fps in ms updateCounter = 0 drawCounter = 0 while True: # UPDATE at fixed intervals newTime = pygame.time.get_ticks() # ms frameTime = newTime - actualTime if frameTime > 250: fameTime = 250 # avoid spiral of death timer += frameTime while timer >= dt: # TODO pass delta time in seconds update() updateCounter += 1 timer -= dt draw() drawCounter += 1 actualTime = newTime # ms ``` ## C++ Example without Draw Example C++ game class with a loop that does not have a Draw method. This is useful for a server processing game or application logic. This example has elements of SFML in it. ```cpp class Game { public: Game(); void run(); virtual void update(sf::Time &gameTime); protected: sf::Clock clock; float FPS; float actualTime; float dt; float timer; }; ``` ```cpp Game::Game() { actualTime = clock.getElapsedTime().asSeconds(); timer = 0.0f; FPS = 60.0f; dt = 1.0f / FPS; } void Game::run() { registerStates(); // Game loop running = true; while (running) { // UPDATE at fixed intervals float newTime = clock.getElapsedTime().asSeconds(); float frameTime = newTime - actualTime; if(frameTime > 0.25f) { frameTime = 0.25f; // Avoid spiral of death } timer += frameTime; // Run update in dt sized chunks while(timer >= dt) { sf::Time gtu = sf::seconds(dt); update(gtu); timer -= dt; } actualTime = newTime; } } void Game::update(sf::Time &gameTime) { // Update various managers and components for(unsigned int i=0; iupdate(gameTime); } // Quit if no states if(stateStack->empty()) { quit(); } } ``` ## C++ Example Extension with Draw Call This is an extending class of the above example, adding in the draw routine logic. ```cpp class VideoGame : public Game { public: VideoGame(); void run(); virtual void update(sf::Time &gameTime); virtual void draw(sf::RenderWindow &window, sf::Time &gameTime); }; ``` ```cpp bit::VideoGame::VideoGame() : bit::Game() { // not a bad idea to take the window width, height, build the window here etc } void bit::VideoGame::run() { // Game loop running = true; while (running) { // Freshen draw clearWindow(); // UPDATE at fixed intervals float newTime = clock.getElapsedTime().asSeconds(); float frameTime = newTime - actualTime; if(frameTime > 0.25f) { frameTime = 0.25f; // Avoid spiral of death } timer += frameTime; // Run update in dt sized chunks while(timer >= dt) { // Window listening for input events in this spot is a good idea sf::Time gtu = sf::seconds(dt); update(gtu); timer -= dt; } // draw in timechunks remaining draw(*renderWindow, gtd); actualTime = newTime; } } void bit::VideoGame::update(sf::Time &gameTime) { bit::Game::update(gameTime); } void bit::VideoGame::draw(sf::RenderWindow &window, sf::Time &gameTime) { // Draw logic } ```