#game #loop #frame #rate #independent

game-loop

A Rust crate that implements a frame-rate-independent game loop

4 releases (breaking)

✓ Uses Rust 2018 edition

0.4.0 Jan 10, 2020
0.3.0 Jan 5, 2020
0.2.0 Jan 4, 2020
0.1.0 Jan 4, 2020

#32 in Rendering

MIT license

125KB
140 lines

Game Loop

A Rust crate that implements a frame-rate-independent game loop. The code is based on "Fix Your Timestep!", it's extremely lightweight and supports both native execution and compilation to wasm.

Usage

use game_loop::game_loop;

fn main() {
  let game = YourGame::new();

  game_loop(game, 240, 0.1, |g| {
    g.game.your_update_function();
  }, |g| {
    g.game.your_render_function();
  });
}

The value 240 is the number of updates per second. It is not the frame rate. In web environments, the frame rate is controlled by requestAnimationFrame, otherwise render is called as quickly as possible, though you can slow it down with std::thread::sleep if you wish. This may be useful if vsync is enabled or to save power on mobile devices.

The value 0.1 is the maximum frame time which serves as an escape hatch if your functions can't keep up with 240 updates per second. Otherwise, your game would 'death spiral' falling further and further behind. For example, if your render function takes 0.5 seconds, only 24 updates would occur instead of 120. This slows your game down but that's better than crashing.

The g closure argument lets you access your game state which can be anything you like. You can also access the game loop's running time, how many updates there have been, etc. It also provides a blending_factor that you may use in your render function to interpolate frames and produce smoother animations. See the article above for more explanation.

In web environments, requestAnimationFrame only runs when the browser tab is active. Setting a maximum frame time ensures your game doesn't fall far behind on its updates and is effectively paused. Also, game_loop is asynchronous and returns immediately rather than blocking until g.exit() is called. Other than that, the interface is exactly the same.

Example

There's a Game of Life example that shows how to use the crate. You can run it with:

cargo run --example game_of_life

Game of Life

License

MIT

Dependencies

~0–325KB