//! `wai.world.model` SHARED / multi-agent — **convergence on a generated world**. //! Two actors interleave signed action ops over one world; the merged log replays //! (canonical total order, ANY arrival) to one session hash, and the integer world //! model renders that to one BYTE-EXACT frame sequence. So N participants driving a //! *generative* interactive world converge on the identical world + hash — the //! generative analog of the multiplayer-worlds convergence, the thing the float //! world-model field (streaming non-reproducible pixels) cannot offer. Composes //! `world_model::replay` ∘ `int_world::decode_deltas`. Never skips (committed model). #![cfg(all(feature = "world_model", feature = "world_int"))] use std::path::PathBuf; use ed25519_dalek::SigningKey; use wai::int_hyper_synth::IntModel; use wai::int_world::decode_deltas; use wai::world::CausalOp; use wai::world_model::{hex32, replay, sign_action, ModelHeader}; fn key(s: u8) -> SigningKey { SigningKey::from_bytes(&[s; 32]) } fn vdir() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/vectors/int_world") } fn header() -> ModelHeader { ModelHeader { model_id: [7u8; 32], seed: 0x00C0FFEE, width: 64, height: 64, fps: 24 } } /// Replay a (possibly out-of-order) multi-actor op set and render the generated /// world; returns (session_hash hex, clip_hash hex, per-frame bytes). fn run(ops: &[CausalOp], t: &IntModel, gs: &IntModel, z0: &[i64], c: usize, lat: usize) -> (String, String, Vec>) { let s = replay(&header(), ops, true).expect("replay verifies + orders"); let deltas: Vec<(i64, i64)> = s.actions.iter().map(|a| (a.dx as i64, a.dy as i64)).collect(); let clip = decode_deltas(t, gs, z0, &deltas, c, lat).expect("the merged log renders"); (hex32(&s.session_hash), format!("{:016x}", clip.clip_hash()), clip.frames) } #[test] fn two_actors_converge_on_one_byte_exact_generated_world() { let t = IntModel::from_bytes(&std::fs::read(vdir().join("world_T.bin")).unwrap()).unwrap(); let gs = IntModel::from_bytes(&std::fs::read(vdir().join("world_gs.bin")).unwrap()).unwrap(); let j: serde_json::Value = serde_json::from_slice(&std::fs::read(vdir().join("world.json")).unwrap()).unwrap(); let c = j["c"].as_u64().unwrap() as usize; let lat = j["lat"].as_u64().unwrap() as usize; let z0: Vec = j["z0"].as_array().unwrap().iter().map(|v| v.as_i64().unwrap()).collect(); // Two actors co-drive one world; their action ops interleave by effect tick. let (a, b) = (key(1), key(2)); let ops = vec![ sign_action(&a, 1, 1, 1, 0, 0, b""), // A: +x sign_action(&b, 1, 1, 0, 1, 0, b""), // B: +y (same tick → serialized by actor) sign_action(&a, 2, 2, 1, 0, 0, b""), // A: +x sign_action(&b, 2, 3, -1, 0, 0, b""), // B: −x sign_action(&a, 3, 4, 0, 1, 0, b""), // A: +y ]; let (sh, ch, frames) = run(&ops, &t, &gs, &z0, c, lat); assert_eq!(frames.len(), ops.len() + 1, "one frame per merged action + initial"); // CONVERGENCE: a peer that received the ops in a different order renders the // identical world — same session hash, same clip hash, same frame bytes. No // tolerance, no "eventually": the generated world is byte-equal. let mut shuffled = ops.clone(); shuffled.rotate_left(2); shuffled.swap(0, 3); let (sh2, ch2, frames2) = run(&shuffled, &t, &gs, &z0, c, lat); assert_eq!(sh, sh2, "session hash converges regardless of arrival order"); assert_eq!(ch, ch2, "the GENERATED world converges byte-exact"); assert_eq!(frames, frames2, "every generated frame is byte-identical across peers"); // Portable pins (deterministic Ed25519 + canonical order + integer render). println!("shared world: session {sh} clip {ch}"); assert_eq!(sh, "c61a6595d23980656d8ff326f3d1f327654f4afb364c233946e0f49fde78c4c0", "shared session hash"); assert_eq!(ch, "b7039d73a08de906", "shared world clip hash"); }