pylon-shard-guest crate and
compile it to WebAssembly. The pylon binary loads the module at boot. You
do not build a custom server binary, so the same app runs on pylon dev,
pylon start, a Docker image, and Stack0 Cloud.
The complete example is examples/shard-arena.
Set up
Install the WebAssembly target once:shards/arena:
shards/arena/Cargo.toml
[workspace] table so
the crate builds on its own.
Write the simulation
ImplementShard and export it with export_shard!:
shards/arena/src/lib.rs
auth carries user_id, is_admin, roles, tenant_id, and the verified
ticket. Read ticket claims with auth.claim("realm").
The module has no clock, no random source, and no I/O. Put a seed in
params when the game needs random numbers. The same inputs then give the
same state, which a replay needs. pylon_shard_guest::log(Level::Info, "…")
writes to the server log.
Declare the shard kind
Add the kind tobuildManifest in app.ts:
app.ts
Build the module
cargo build --release --target wasm32-unknown-unknown for
each kind with a crate, and copies the module to its wasm path.
pylon dev runs the same build at start. It builds again and restarts the
server when a .rs file or Cargo.toml in the crate changes.
Commit the .wasm file. pylon build copies it into the artifact, and
pylon deploy uploads it even when .gitignore lists it. When cargo is on
the path, pylon deploy builds the crates first. A GitHub deploy uses the
committed file, because the Cloud builder has no Rust toolchain.
Start a shard and join it
An action starts a shard and gives the player a ticket:functions/joinArena.ts
ctx.shards has these calls:
A shard id is 1 to 128 letters, digits,
-, _, ., or :.
The client connects with the ticket:
/shard on the app’s own origin, so it needs no
extra port or proxy rule. See React client
for acks, rejections, and custom decoders.
Limits and failures
- A tick that runs past
tickBudgetMsstops the shard. - A module that grows past
memoryMbstops the shard. - A panic stops the shard. The server log shows the panic message.
ctx.shards.get(id)returns the reason inerroruntil the host removes the stopped shard (within a few seconds).- A module may import only
pylon.log. The server refuses a module built for WASI or with any other import, and the boot fails. - Shard state is in memory. A restart or a deploy ends every shard.
Hosted on Stack0 Cloud
Stack0 Cloud runs shards with no extra setup. Clients connect towss://your-app.stack0.app/shard, or to /shard on your custom domain.
- An open shard connection keeps the app’s machine running.
- A machine with autostop on can stop when no client is connected. Its shards end, like on any restart.