pub trait Runtime {
// Required methods
fn start(&mut self, game: &mut Game);
fn update(&mut self, game: &mut Game);
fn end(&mut self, game: &mut Game);
}Expand description
The lifecycle trait for game logic.
Implement this trait to hook your application into the engine’s event
loop. Pass an instance to Game::new or Game::run and the engine
drives the three lifecycle methods automatically.
| Method | Called | Purpose |
|---|---|---|
start | Once, before the first frame | One-time setup |
update | Every frame | Input, logic, rendering |
end | Once, on shutdown | Cleanup |
Each method receives &mut Game, giving you access to the renderer,
camera, window, events, and time.
§Example
use optic_loop::{Game, Runtime};
struct FpsCounter {
frames: u64,
}
impl Runtime for FpsCounter {
fn start(&mut self, _game: &mut Game) {
println!("Starting...");
}
fn update(&mut self, game: &mut Game) {
self.frames += 1;
if self.frames % 60 == 0 {
let fps = game.time.fps();
println!("FPS: {:.1}", fps);
}
game.renderer.clear();
// ... draw scene ...
}
fn end(&mut self, _game: &mut Game) {
println!("Rendered {} frames total", self.frames);
}
}
Game::run(FpsCounter { frames: 0 });§Why three methods?
Separating start from update avoids re-initialising assets every
frame. Separating end from drop gives you a predictable point to
save state before the engine tears down subsystems.
Required Methods§
Sourcefn start(&mut self, game: &mut Game)
fn start(&mut self, game: &mut Game)
Called once before the first frame.
Use this for one-time initialisation:
- Load meshes, textures, and shaders via [
GPU::ship_*] - Set up initial game state
- Connect to a server (see [
Game::enable_networking])
The window is not yet visible when start runs. The engine calls
start, makes the window visible, then immediately enters the
update loop.
Sourcefn update(&mut self, game: &mut Game)
fn update(&mut self, game: &mut Game)
Called every frame.
This is the main game loop body. Do all per-frame work here:
- Poll input — check
game.eventsfor keyboard, mouse, gamepad - Update logic — move entities, run physics, check collisions
- Render — clear the screen, bind shaders, draw meshes
Use Game::exit to stop the loop from within update.
Sourcefn end(&mut self, game: &mut Game)
fn end(&mut self, game: &mut Game)
Called once on shutdown.
Triggered by Game::exit, window close, or SIGINT. Use this to:
- Save persistent state (scores, settings)
- Disconnect from servers
- Release non-GPU resources
The GPU and window are still alive during end; they are destroyed
after it returns.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".