From d0f05e56226aa95b7cc58461888db1963962d343 Mon Sep 17 00:00:00 2001 From: autocommit Date: Mon, 18 May 2026 20:10:30 -0700 Subject: [PATCH] =?UTF-8?q?feat(simulator):=20=E2=9C=A8=20Introduce=20visi?= =?UTF-8?q?on=20event=20types=20for=20replay=20data=20processing=20in=20ev?= =?UTF-8?q?ent.rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- src/simulator/crates/mc-replay/src/event.rs | 50 +++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/simulator/crates/mc-replay/src/event.rs b/src/simulator/crates/mc-replay/src/event.rs index c6dd62ed..f98a038d 100644 --- a/src/simulator/crates/mc-replay/src/event.rs +++ b/src/simulator/crates/mc-replay/src/event.rs @@ -241,6 +241,53 @@ pub enum TurnEvent { /// Catalog kind of the destroyed unit (e.g. `"worker"`). unit_kind: UnitKind, }, + /// Communications Phase 1: first-contact event. Fires exactly once per + /// ordered `(discoverer, discovered)` pair the first turn `discoverer` + /// observes any unit or city of `discovered` in their VISIBLE set. + /// Contact is symmetric, so a single meeting emits two `PlayerDiscovered` + /// events (one per direction) — the replay viewer can dedupe by pair. + PlayerDiscovered { + /// Turn the event fired on. + turn: u32, + /// Clan that did the seeing. + discoverer: ClanId, + /// Clan whose unit/city was seen. + discovered: ClanId, + /// Tile that triggered the contact (the seen unit/city centre). + at_hex: TileCoord, + }, + /// Communications Phase 1: a foreign city centre entered the observer's + /// VISIBLE set for the first time. Fires once per (observer, city_id) + /// pair across the whole game (not re-fired on re-sighting). + CitySpotted { + /// Turn the event fired on. + turn: u32, + /// Clan that did the spotting. + observer: ClanId, + /// Owning clan of the spotted city. + city_owner: ClanId, + /// Stable city id. Phase 1 uses the synthesised `city__` + /// scheme also used by `CityBuildingCompleted`. + city_id: CityName, + /// Tile the city sits on. + at_hex: TileCoord, + }, + /// Communications Phase 1: a foreign unit was sighted. Debounced — fires + /// on first sighting OR on re-sighting after ≥3 turns out of vision. + /// The (observer, unit_id) debounce state is owned by `PlayerVision`, + /// not by this crate. + UnitSpotted { + /// Turn the event fired on. + turn: u32, + /// Clan that did the spotting. + observer: ClanId, + /// Owning clan of the spotted unit. + unit_owner: ClanId, + /// Unit catalog id (e.g. `"dwarf_warrior"`). + archetype: UnitKind, + /// Tile the unit was sighted on. + at_hex: TileCoord, + }, /// p2-48: the game has ended. Emitted at most once per game, at the tail /// of `TurnProcessor::step` when `end_conditions::evaluate_conditions` /// returns `Some`. @@ -296,6 +343,9 @@ impl TurnEvent { | Self::UnitCaptured { turn, .. } | Self::UnitRansomOffered { turn, .. } | Self::CivilianDestroyed { turn, .. } + | Self::PlayerDiscovered { turn, .. } + | Self::CitySpotted { turn, .. } + | Self::UnitSpotted { turn, .. } | Self::GameOver { turn, .. } => turn, } }