Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Changing code while the game runs

Edit a system, save, and the running game uses the new code from the next frame on. Nothing restarts: every entity, resource, the camera and the tick count stay where they were. With a battle half fought, you can retune how units pick targets and watch the same fight continue.

This uses subsecond, the hot-patching engine from the Dioxus project, run by Dioxus’s CLI dx.

Setup

Install the CLI once:

cargo install dioxus-cli@0.7.10

(dx is also the name of a Deno tool; if that one comes first on your PATH, call this one as ~/.cargo/bin/dx.)

Give your game a hotpatch feature that turns on the engine’s:

[dependencies]
ponko = "0.0.1"

[features]
hotpatch = ["ponko/hotpatch"]

Then start the game through dx instead of cargo run:

dx serve --hot-patch --features hotpatch

Edit any system in your game’s crate and save. The console says Hot-patching: src/main.rs took 349ms, then ponko: code patched, and the system runs its new code.

Try it

examples/hotpatch.rs spins a few crabs and prints the first one’s rotation every second:

#![allow(unused)]
fn main() {
fn spin(ctx: &mut Ctx) {
    let dt = ctx.dt();
    for t in ctx.world.query::<&mut Transform2D>().iter() {
        t.rotation += -6.0 * dt;
    }
}
}

Change += 1.5 to -= 3.0 and save. The printed rotation turns around from wherever it had got to:

tick  4200  rotation   66.40
tick  4260  rotation   63.40
tick  4320  rotation   60.40

What can change

ChangePatched live?
A system’s body, and any function it callsyes
Constants and literals in them (speeds, colors, ranges)yes
New helper functions called from a systemyes
Adding or removing systems (.sim_system(...) in main)no: main already ran; restart
A component’s or resource’s fields (its size or layout)no: restart (the old values in memory have the old layout)
Code outside your game’s crate (the engine, other crates in a workspace)no: only the crate with main is patched

Code that changes a type’s layout and runs anyway can crash, so restart after changing struct fields. For tuning numbers without code at all, see data files; for looking at and editing the running world, the inspector.

Cost

Without the hotpatch feature, systems are plain calls, as before. With it, each system call looks itself up in a table, which is negligible (one lookup per system per frame, not per entity), and only in debug builds; release builds call directly even with the feature on.

The engine’s own systems (draw_sprites, camera_controls, …) can’t be patched, since they’re outside your crate.

C and C++

Not available: hot patching works on Rust code compiled by dx. C and C++ games can keep their game data in data files, which reload when saved.