fix(simulation): address PR #12 review — z-level filter, visible tile dedup, version bump

- Filter remembered entities by z-level (Hoshe + Tyre warning)
- Skip remembered ghosts on currently visible tiles (Hoshe warning)
- Bump ObserverSnapshot version to 3 (Tyre suggestion)
- Add edge case tests: visible tile collision, different z-level,
  knowledge without position (Hoshe suggestion)
- Regenerate msgpack fixtures for v3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-12 01:47:35 +01:00
co-authored by Claude Opus 4.6
parent 8c802a2412
commit 22de6c714f
13 changed files with 179 additions and 26 deletions
+1 -1
View File
@@ -33,7 +33,7 @@ fn snapshot_roundtrip_over_unix_socket() {
let bridge = LocalBridge::accept(&server_path).expect("failed to accept");
let snapshot = ObserverSnapshot {
version: 2,
version: 3,
tick: 42,
game_time: GameTime {
day: 0,
+1 -1
View File
@@ -19,7 +19,7 @@ fn snapshot_roundtrip_over_tcp() {
let bridge = TcpBridge::accept_on(listener).expect("failed to accept");
let snapshot = ObserverSnapshot {
version: 2,
version: 3,
tick: 42,
game_time: GameTime {
day: 0,
+1 -1
View File
@@ -61,7 +61,7 @@ fn player_moves_north_through_full_pipeline() {
rmp_serde::from_slice(&response).expect("deserialize snapshot");
// Snapshot captures state at end of tick 0 (before advance_tick increments to 1)
assert_eq!(snapshot.version, 2);
assert_eq!(snapshot.version, 3);
assert_eq!(snapshot.tick, 0);
assert_eq!(snapshot.entities.len(), 1);
+2 -2
View File
@@ -18,7 +18,7 @@ fn write_fixture(name: &str, bytes: &[u8]) {
/// Helper to create a minimal v2 snapshot for fixtures
fn fixture_snapshot(tick: u64, entities: Vec<VisibleEntity>) -> ObserverSnapshot {
ObserverSnapshot {
version: 2,
version: 3,
tick,
game_time: GameTime {
day: 0,
@@ -150,7 +150,7 @@ fn generate_msgpack_fixtures() {
// v2 snapshot with visible_tiles and game_time populated
let snapshot_v2_full = ObserverSnapshot {
version: 2,
version: 3,
tick: 500,
game_time: GameTime {
day: 1,
+5 -5
View File
@@ -7,7 +7,7 @@ use std::fs;
/// Helper to create a minimal v2 snapshot for tests
fn test_snapshot(tick: u64, entities: Vec<VisibleEntity>) -> ObserverSnapshot {
ObserverSnapshot {
version: 2,
version: 3,
tick,
game_time: GameTime {
day: 0,
@@ -40,7 +40,7 @@ fn observer_snapshot_roundtrip() {
let bytes = rmp_serde::to_vec_named(&snapshot).expect("serialize");
let decoded: ObserverSnapshot = rmp_serde::from_slice(&bytes).expect("deserialize");
assert_eq!(decoded.version, 2);
assert_eq!(decoded.version, 3);
assert_eq!(decoded.tick, 42);
assert_eq!(decoded.entities.len(), 1);
assert_eq!(decoded.entities[0].entity_id, 1);
@@ -178,7 +178,7 @@ fn all_entity_kind_variants_roundtrip() {
#[test]
fn snapshot_v2_fields_roundtrip() {
let snapshot = ObserverSnapshot {
version: 2,
version: 3,
tick: 100,
game_time: GameTime {
day: 3,
@@ -216,7 +216,7 @@ fn snapshot_v2_fields_roundtrip() {
let bytes = rmp_serde::to_vec_named(&snapshot).expect("serialize");
let decoded: ObserverSnapshot = rmp_serde::from_slice(&bytes).expect("deserialize");
assert_eq!(decoded.version, 2);
assert_eq!(decoded.version, 3);
assert_eq!(decoded.game_time.day, 3);
assert_eq!(decoded.game_time.time_of_day, 720);
assert_eq!(decoded.game_time.day_phase, DayPhase::Evening);
@@ -244,7 +244,7 @@ fn all_facing_direction_variants_roundtrip() {
for dir in directions {
let snapshot = ObserverSnapshot {
version: 2,
version: 3,
tick: 0,
game_time: GameTime {
day: 0,