{"id":21028869,"url":"https://github.com/chamons/game-hotreload-example","last_synced_at":"2026-04-28T10:05:31.411Z","repository":{"id":244898439,"uuid":"816540173","full_name":"chamons/game-hotreload-example","owner":"chamons","description":"An example project which uses web assembly to power hotreload of a trivial game","archived":false,"fork":false,"pushed_at":"2024-12-27T17:25:23.000Z","size":626,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-01T07:22:26.619Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chamons.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-18T00:43:18.000Z","updated_at":"2024-12-27T17:25:26.000Z","dependencies_parsed_at":"2025-03-13T19:16:18.436Z","dependency_job_id":"f90b0d36-1aa5-4549-a3e4-b4ad20310e4c","html_url":"https://github.com/chamons/game-hotreload-example","commit_stats":null,"previous_names":["chamons/game-hotreload-example"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/chamons/game-hotreload-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chamons%2Fgame-hotreload-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chamons%2Fgame-hotreload-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chamons%2Fgame-hotreload-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chamons%2Fgame-hotreload-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chamons","download_url":"https://codeload.github.com/chamons/game-hotreload-example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chamons%2Fgame-hotreload-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32375700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T09:24:15.638Z","status":"ssl_error","status_checked_at":"2026-04-28T09:24:15.071Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T11:59:25.321Z","updated_at":"2026-04-28T10:05:31.395Z","avatar_url":"https://github.com/chamons.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Game Hotreload Example\n\nThis repository is an example project using the power of [Web Assembly](https://developer.mozilla.org/en-US/docs/WebAssembly) and the [WebAssembly Component Model](https://component-model.bytecodealliance.org/) to create a hot reloadable game development experience.\n\n## Screenshot\n![Screen Shot](./docs/screenshot.png)\n\n## Getting Started\n\n0. `rustup target add wasm32-wasip1 \u0026\u0026 cargo install wasm-tools`\n1. Install [Just](https://github.com/casey/just)\n2. In one terminal window run `just watch` to start compiling the game assembly on every change\n3. In another terminal window, run `just hotreload`\n4. Make a change in `game/src/lib.rs` to some text or a color, save the file, and watch the logic\n5. Click to increment the counter, and hotreload with another change to see that the state survives\n5. Run `just run` to run the project without wasmtime or hotreloading\n\n## How does it work?\n\nThe project is split up into two crates:\n\n- Game (A simple library) - Contains all of the core logic describing the scene to be drawn, how to interact with keyboard/mouse, etc. \n- Launcher (A macroquad game binary) - A uncommonly changed shell which forwards UX interactions and draws to the screen as requested\n\nThe launcher contains a feature flag `hotreload` which changes how the launcher consumers the game crate:\n\nWithout `hotreload` the `Launcher` has a direct hard library dependency on `Game` and nothing special happens.\n\nWith `hotreload` however the Launcher loads up a web assembly packaged version of the launcher crate via wasmtime. A simple file watcher then waits for the assembly file to change, and then reloads it before processing the next frame. Before this reload, the entire state of the game is serialized via Serde which is then restored inside the new web assembly instance.\n\n## How does the host launcher communicate with the game?\n\nThere is a WebAssembly Component Interface file (`wit/interface.wit`) which contains a simple stateless interface to a portion of macroquad. Each frame is passed the state of the mouse and keyboard and calls draw instructions on an imported screen resources. These instructions are then executed within the launcher host.\n\nAs we want to arbitrarily reload the game, the global state of the graphics stack and window must not be lost. This is why the Game does not directly use macroquad.\n\n## Why not just use hot-lib-reloader-rs\n\n[hot-lib-reloader-rs](https://github.com/rksm/hot-lib-reloader-rs) is an impressive crate, but in my experience was never stable enough to actually save me much time. About 1 in 5 times my projects would crazy, so I had to setup a relaunch script, which would occasionally go haywire and need to be manually killed.\n\nAny use of any thread local storage, or function pointers (dyn traits) would caused it to misbehave. This applied significant design pressure to how the project needed to be laid out to be \"binary reload friendly\".\n\nSo far WASM hot reloading has been completely stable in my experience.\n\n## Areas for improvement\n\n### Unnecessary Dependency\n\nThe launcher binary uses a feature flag to enable hot reload goodness. Unfortunately it is not possible to remove a dependency, so there is an \"unnecessary\" hard link from game to launcher even in the hotreload case. The launcher is written to never use the game dependency in hotreload contexts, but if it did those portions would not be hotreloaded (or you would get a compile error).\n\nIt is possible to use two inverse feature flags (hotreload and direct), but that is discouraged behavior. I have not looked into this much yet. In the past the crate hierarchy was more complex and feature unification prevented from being an option.\n\n### WIT interface interactions with VSCode\n\nAs the WIT interface used between the worlds is code generated, it is not always trivial to see the final rust interface, as you can not jump to definition. The `rust-analyzer: Expand macro recursively at caret` feature can be useful, but it is not an ideal user experience.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchamons%2Fgame-hotreload-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchamons%2Fgame-hotreload-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchamons%2Fgame-hotreload-example/lists"}