45 lines
1.8 KiB
Rust
45 lines
1.8 KiB
Rust
//! Bundle round-trip: a game folder → one JSON document → a fully working
|
|
//! World with NO filesystem. This is exactly how a wasm build boots, so it
|
|
//! gets a native test.
|
|
|
|
use mrpci_core::{Command, GameState, World, WorldBundle};
|
|
|
|
fn game_dir() -> Option<String> {
|
|
for p in ["games/neon-precinct", "../games/neon-precinct"] {
|
|
if std::path::Path::new(p).join("game.json").exists() {
|
|
return Some(p.to_string());
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
#[test]
|
|
fn bundle_round_trip_boots_without_fs() {
|
|
let Some(dir) = game_dir() else {
|
|
eprintln!("demo game not generated; skipping");
|
|
return;
|
|
};
|
|
let world = World::load_game(dir);
|
|
let json = serde_json::to_string(&world.to_bundle()).expect("bundle serializes");
|
|
let bundle: WorldBundle = serde_json::from_str(&json).expect("bundle parses");
|
|
assert_eq!(bundle.rooms.len(), 3, "all three demo rooms travel");
|
|
assert!(bundle.scripts.len() >= 4, "main.rhai + room scripts travel");
|
|
assert!(bundle.sprites.contains_key("keycard"), "art travels");
|
|
|
|
let mut sprites: Vec<_> = bundle.sprites.clone().into_iter().collect();
|
|
sprites.sort_by(|a, b| a.0.cmp(&b.0));
|
|
let world2 = World::from_memory(bundle.manifest, bundle.rooms, bundle.scripts, sprites);
|
|
let mut gs = GameState::new(world2);
|
|
gs.apply(Command::NewGame { room: None });
|
|
|
|
// The world is really alive: art cooked, scripts compiled, sim ticking.
|
|
assert!(gs.world.cel("keycard").is_some(), "sprites quantized from bundle art");
|
|
let snap = gs.snapshot();
|
|
assert_eq!(snap.room_name, "Neon Row");
|
|
assert!(!snap.props.is_empty());
|
|
gs.apply(Command::Tick { n: 60 });
|
|
let frame = gs.render_indices(true);
|
|
assert_eq!(frame.len(), 320 * 190);
|
|
assert!(frame.iter().any(|&p| p != 0), "frame isn't blank");
|
|
}
|