Skip to main content

Crate gasm

Crate gasm 

Source
Expand description

Rust bindings for the gasm game ABI v0 — see spec/ABI.md.

ⓘ
struct MyGame { t: u32 }
impl gasm::Game for MyGame {
    fn init() -> Result<Self, String> { gasm::set_frame_rate(60.0); Ok(MyGame { t: 0 }) }
    fn frame(&mut self) { self.t += 1; /* simulate, draw */ }
}
gasm::game!(MyGame);

Build with --target wasm32-unknown-unknown and crate-type = ["cdylib"]. On native targets the same code links against an in-process stub host (native) for tests and benchmarks.

Re-exports§

pub use sys::keys;

Modules§

audio
clipboard
Text on the system clipboard (gasm:clipboard, optional: check clipboard::available). Copying is always allowed; pasted text is readable only during the frame that carries the player’s paste key press (Ctrl+V, Cmd+V on macOS).
fetch
HTTP requests made by the runner (gasm:fetch, TLS included): start one, then poll it each frame. Runners may deny requests (natively: --allow-net, optionally a host list; browsers: the page, and CORS). Probe [available] first.
files
Files for the player (gasm:files, optional: check files::available): save hands the runner a copy to keep where the player finds it (Pictures// for images, Downloads// otherwise, a download in browsers). The game never learns the path.
gfx
GPU rendering through gasm:gfx (a WebGPU subset; descriptors are JSON).
gles
The OpenGL ES 3.0 C API on gasm:gl, for Rust guests: the same functions as the C SDK’s gasm_gl.c (there is no libc to link it), with C signatures, so GL loaders can use them through get_proc_address. glow’s native backend runs on them (sdk/glow, design/gasm-gl.md):
input
Raw keyboard, pointer and gamepads (next to the virtual pads).
main_loop
Games that keep their own main loop (loop { update(); draw(); wait_frame(); }) instead of implementing Game. Same mechanism as the C SDK’s gasm_loop.h: main_loop! exports the entry points and runs your function on the first frame; main_loop::wait_frame suspends it until the next frame: with Binaryen’s Asyncify inside the module (gasm_frame, any runner), or by the runner itself when it switches stacks (gasm_run). Build, then post-process the .wasm:
media
Audio streams the runner plays (internet radio, tracks), mixed after the game’s own audio (gasm:media). The game needs the player’s yes: "media": true in its manifest (manifest!) and the runner’s question, or --allow-media.
native
In-process stub host for running a guest natively (non-wasm targets).
net
Message connections through gasm:net (WebSocket semantics, non-blocking).
storage
Persistent per-game key/value store (gasm:storage): saves, settings, scores.
sync
Locks for crate::thread’s cooperative threads, shaped like std::sync: Mutex, Condvar, Semaphore. A wait lets the other threads run; time is the frame’s. Without the threaded loop there is only the calling thread: locks always succeed, waits with a timeout time out at once, waits without one trap (nothing else could ever wake them).
sys
Raw ABI. On wasm32 these are the real imports (see spec/ABI.md). On other targets they are backed by crate::native, an in-process stub host used for native parity tests and benchmarks.
thread
Cooperative threads for games with their own loop (design/threads.md), the Rust side of the C SDK’s gasm_thread.h: the same scheduler, the same rules.

Macros§

game
Export the gasm entry points for a Game type.
log
format!-style logging: gasm::log!("x = {x}").
main_loop
Export the gasm entry points for a game with its own main loop (see [main_loop]).
manifest
Embed the game’s capabilities manifest (the gasm.manifest custom section): what it requires, the hosts it reaches and whether it saves files, which runners check and ask about once before it starts. Once per game, with a JSON string:
threaded_main_loop
Like main_loop!, with cooperative threads (thread, sync): main runs as the first thread, thread::spawn starts more. The frame driver is the thread scheduler. Asyncify only (no gasm_run export): run wasm-opt --asyncify --pass-arg=asyncify-removelist@gasm_frame,gasm_loop_frame on the module.
title
The game’s built-in title (custom section gasm.title): runners show it (and launchers list it) before the game runs and while it hasn’t called set_title. Use once, at the top level: gasm::title!("Sumo");

Structs§

Buttons
Virtual gamepad buttons (bit positions per spec/ABI.md).

Constants§

ABI_VERSION

Traits§

Game
A gasm game. init runs once; frame runs at the configured frame rate.

Functions§

asset
Read a whole asset (it must fit in memory: under 2 GiB).
asset_names
All asset names, sorted (by UTF-8 bytes). Folder entries keep their on-disk case.
asset_read_at
Read up to buf.len() bytes of an asset starting at offset (for streaming large assets). Returns bytes read (0 at the end), or None if missing.
asset_size
Size of an asset in bytes (any size), or None if it doesn’t exist.
asset_version
An asset’s version, or None if it doesn’t exist: 0 for assets given at launch, a new, larger number each time the embedder replaces it while the game runs. Poll it to notice new data. Older runners: always 0.
exit
End the game (WASI proc_exit). Runners treat code 0 as a clean exit.
has
Does the runner provide an import? A module ("gasm:gfx") or a function in one ("gasm.asset_size64", "gasm:gfx.destroy"). Calling an import the runner lacks traps, so probe optional features first.
is_fullscreen
Whether the game is shown fullscreen now (set_fullscreen, or the player’s own keys: F11, Alt+Enter); always false in headless runs.
log
max_threads
The player’s time zone now: minutes east of UTC, daylight saving included (120 for CEST). 0 in headless runs, and on older runners without it. How many worker threads this run allows at once (wasi-threads guests size their pool from it; 0 in headless runs and browsers).
pad
Buttons held on virtual pad player (0..=3) this frame.
param
Launch parameter (--param k=v natively, ?k=v in the browser).
present
Present an RGBA8 frame (stride bytes per row; 1-4096 pixels each way).
set_frame_rate
Rate at which the runner calls frame(). Default 60.
set_fullscreen
Ask to show the game fullscreen (true) or in its window, after this frame. Returns whether this runner can show it fullscreen at all (a window, the browser player; not headless runs or runners without it): what the game got is is_fullscreen, a frame or more later. Going fullscreen needs a key press or click in the last 5 seconds (as browsers require), so ask from the frame that handled the player’s choice; leaving always works.
set_title
Name the game’s window or browser tab (runners add their own suffix, e.g. “DOOM — gasm”). Control characters are dropped, at most 256 bytes are kept, and "" restores the default (the file name). Does nothing on runners without it.
text_input
Text typed since the previous frame ('\u{8}' = backspace, '\n' = enter), or None if the runner has no keyboard.
time_ms
Monotonic milliseconds (virtual, frame-derived time in headless runs).
utc_offset_minutes
video_set_aspect
Show video_present frames at display aspect num:den (e.g. 4:3 for a 320×200 game drawn for a CRT) instead of square pixels; (0, 0) resets. Returns false on runners without it: the game then corrects the aspect itself (or accepts square pixels). Display only: hashes don’t change.