Files
Verbatim/tests/integration.rs
T
Emil 9fe7137e45 feat: bigger characters (16 sub-bodies), wider terminal viewport
- Entity: 16 sub-bodies (was 7), radius 0.7 (was 0.4), full humanoid
  shape: head, shoulders, torso, arms, hips, legs, feet
- Terminal: viewport up to 250x80 (was 120x50), uses full terminal size
- Camera: uses renderer viewport dimensions instead of hardcoded values
- Physics: constraint correction clamped to 0.5 cells max, 8 substeps
  (was 4), gravity 0.04 (was 0.08), collision pass after each constraint
  iteration to prevent tunneling with larger bodies
- Player: move_speed 0.3, jump_force 1.2 for bigger body
- Spawn: 6 cells above surface (was 4) for taller body
2026-06-20 21:27:11 +03:00

109 lines
3.8 KiB
Rust

use verbatim::ai::GameSession;
use verbatim::ai::AiAction;
use verbatim::ai::{ReplayRecorder, ReplayPlayer};
#[test]
fn replay_deterministic() {
let mut s1 = GameSession::new_seeded(123);
s1.init();
s1.set_recording(true);
s1.perform_action(&AiAction::MoveRight);
s1.step(10);
s1.perform_action(&AiAction::Jump);
s1.step(10);
let state1 = s1.get_state();
s1.save_replay("/tmp/verbatim_test_replay.json").expect("save replay");
let player = ReplayPlayer::load("/tmp/verbatim_test_replay.json").expect("load replay");
let s2 = player.play();
let state2 = s2.get_state();
assert_eq!(state1.tick, state2.tick, "ticks should match");
if let (Some(p1), Some(p2)) = (&state1.player, &state2.player) {
assert_eq!(p1.health, p2.health, "player health should match");
assert!((p1.pos[0] - p2.pos[0]).abs() < 0.01, "player x should match: {} vs {}", p1.pos[0], p2.pos[0]);
assert!((p1.pos[1] - p2.pos[1]).abs() < 0.01, "player y should match: {} vs {}", p1.pos[1], p2.pos[1]);
}
}
#[test]
fn replay_play_until_tick() {
let mut s = GameSession::new_seeded(999);
s.init();
s.set_recording(true);
s.perform_action(&AiAction::MoveRight);
s.step(5);
s.perform_action(&AiAction::MoveLeft);
s.step(5);
s.perform_action(&AiAction::Jump);
s.step(10);
s.save_replay("/tmp/verbatim_test_replay2.json").expect("save");
let player = ReplayPlayer::load("/tmp/verbatim_test_replay2.json").expect("load");
let s_half = player.play_until_tick(5);
assert_eq!(s_half.tick(), 5, "should stop at tick 5, got {}", s_half.tick());
let s_full = player.play();
assert_eq!(s_full.tick(), 20, "full replay should reach tick 20, got {}", s_full.tick());
}
#[test]
fn same_seed_same_state() {
let mut s1 = GameSession::new_seeded(42);
s1.init();
s1.step(30);
let state1 = s1.get_state();
let mut s2 = GameSession::new_seeded(42);
s2.init();
s2.step(30);
let state2 = s2.get_state();
assert_eq!(state1.tick, state2.tick);
if let (Some(p1), Some(p2)) = (&state1.player, &state2.player) {
assert!((p1.pos[0] - p2.pos[0]).abs() < 0.01, "x mismatch: {} vs {}", p1.pos[0], p2.pos[0]);
assert!((p1.pos[1] - p2.pos[1]).abs() < 0.01, "y mismatch: {} vs {}", p1.pos[1], p2.pos[1]);
}
}
#[test]
fn pipe_protocol_init_and_step() {
use std::io::Write;
use std::process::{Command, Stdio};
let mut child = Command::new(env!("CARGO_BIN_EXE_verbatim"))
.arg("--mode").arg("pipe")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::null())
.spawn()
.expect("failed to start process");
let stdin = child.stdin.as_mut().expect("failed to open stdin");
writeln!(stdin, "{{\"cmd\":\"init\",\"seed\":42}}").expect("write init");
stdin.flush().expect("flush");
let mut output = String::new();
let stdout = child.stdout.as_mut().expect("failed to open stdout");
use std::io::Read;
let mut buf = [0u8; 65536];
let n = stdout.read(&mut buf).expect("read");
output.push_str(&String::from_utf8_lossy(&buf[..n]));
let json: serde_json::Value = serde_json::from_str(output.trim()).expect("parse response");
assert_eq!(json["ok"], true, "init should succeed: {}", output);
writeln!(stdin, "{{\"cmd\":\"step\",\"n\":10}}").expect("write step");
stdin.flush().expect("flush");
let n = stdout.read(&mut buf).expect("read");
let output2 = String::from_utf8_lossy(&buf[..n]).to_string();
let json2: serde_json::Value = serde_json::from_str(output2.trim()).expect("parse step response");
assert_eq!(json2["ok"], true);
assert_eq!(json2["state"]["tick"], 10, "tick should be 10 after stepping 10");
writeln!(stdin, "{{\"cmd\":\"quit\"}}").expect("write quit");
stdin.flush().expect("flush");
child.wait().expect("wait");
}