wyrd-for-games 0.4.0

Engine-neutral signal-graph game logic for Wyrd
Documentation

wyrd-for-games

wyrd-for-games provides engine-neutral signal-graph game logic: author and validate a Weave, bind it to dense runtime ids, settle it once per frame, and apply its output in your game host.

The library target is named wyrd:

cargo add wyrd-for-games --rename wyrd

Start with the complete, compile-checked A01: Hello, invert lesson, then follow the tier links in Rustdoc.

Use wyrd::core, wyrd::graph, and wyrd::runtime when you want an explicit layer namespace. The crate supports no_std plus alloc, signal-f32 (default) or signal-i32, optional serde codecs, and an opt-in schema feature for std + serde JSON Schema tooling.

Choose an authoring surface

weave! is the declarative choice for fixed topology. pattern! is the same validated lowering for a reusable fragment with named inputs and outputs. Both create the immutable graph values used by bind; they do not introduce a parallel runtime representation.

Implement Recipe when a graph is a reusable host contract. Its associated Ports type resolves dense runtime handles once after bind, and RecipeInstance keeps those typed ports with the owning runtime. Use Scenario::<MyRecipe>::run for deterministic, closure-scoped frames and assertions in tests or executable examples.

For topology generated by code, call Weave::compose. Its Composer exposes Bool, Level, and Count wires for common operations. Composer::knot, input, output, and thread remain available for every WeaveBuilder operation, so generation never loses access to the catalog or its diagnostics.

Recipe::manifest returns a deterministic summary of host signal and command endpoints. Enable schema when tools need schemars::JsonSchema for graph and recipe manifest types; default and no_std builds do not pull in schema dependencies.

Host loop

let mut runtime = Runtime::bind(weave, BindOpts::default())?;
// Once: resolve SenseId / HostPathId for the hot path.

// Each frame:
runtime.begin_frame(HostTime { tick });
{
    let mut ports = runtime.port_writer();
    ports.set_sense(plate_id, value)?; // SenseId — never a string on the hot path.
}
runtime.loom();
for signal in runtime.outbox().signals() {
    // signal.path: HostPathId → runtime.path_name(signal.path) when needed.
}
for command in runtime.outbox().emits() {
    // command.cmd: CmdId
}

Steady-state loom does not allocate topology: inbound edges and slots are precomputed during bind. Keep active Weaves scoped to a room or puzzle island and bind them on load, not once per frame.

Stability and continuation snapshots

Wyrd 0.4 is pre-1.0. Minor 0.x releases may make breaking public-API changes; patch releases preserve the public Rust API unless the changelog calls out a required correction.

Runtime::snapshot captures the mutable state needed to continue one bound runtime deterministically. Runtime::restore validates the snapshot format, numeric path, executable fingerprint, and buffer shape before changing the runtime. Use Runtime::snapshot_into when repeated captures should reuse owned buffers.

RuntimeState is opaque in Rust but serializable through the optional serde feature as Wyrd's versioned checkpoint contract. Capture it after loom and after the host has applied that frame's outbox, before the next begin_frame; outbox effects are intentionally not saved or replayed. Games own their wider save schema and host effects. Use Runtime::bind_restored to load into a fresh runtime and RuntimePreset / bind_with_preset for authored named Flag, Counter, and SignalIn starting values. Persist game progress in a host-owned format. Use a runtime snapshot only with the same bound executable contract; do not assume compatibility across minor releases or different Weaves.

Tiered examples

The wyrd::examples module provides Tier A foundations, Tier B first Weaves, Tier C game-logic patterns, and Tier D chamber composition. Each named lesson is human-readable Rustdoc backed by a complete, compile-checked doctest. Tier D combines host-owned observations into a latched gate, continuous mover target, and edge-triggered room-transition request.

cargo test -p wyrd-for-games --doc --no-default-features \
  --features "std,signal-f32,serde-ron,serde-json,schema" --locked