fix(simulation): fix triangle state save/load and persist contamination

Three save/load bugs fixed:
- ContaminationActive not persisted in SaveStateV1 — caused double-fire
  of contamination pressure on reload after tick 300.
- Loaded triangle entities missing ActiveSim marker — made them
  invisible to escalation and contamination systems after any load.
- Existing triangle entities not despawned before load — created
  duplicates, doubling tension escalation per tick.

Also: HashSet → BTreeSet for D-010 compliance, defensive event queue
reset on load, and three regression tests for triangle roundtrip.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 23:24:56 +01:00
co-authored by Claude Opus 4.6
parent 70de959ac3
commit 339f112c8f
4 changed files with 160 additions and 6 deletions
+8
View File
@@ -105,6 +105,12 @@ pub struct SaveStateV1 {
/// DLC can populate it without a save format migration.
#[serde(default)]
pub modifications: Vec<Modification>,
/// Whether contamination has already activated (#254).
/// Persisted to prevent double-firing on save/load — without this,
/// reloading a save after tick 300 would re-trigger contamination
/// and apply a duplicate tension delta to all ActiveFork triangles.
#[serde(default)]
pub contamination_active: bool,
}
/// Per-NPC state snapshot for `SaveStateV1`.
@@ -418,6 +424,7 @@ mod tests {
triangle_states: vec![],
open_doors: vec![],
modifications: vec![],
contamination_active: false,
}
}
@@ -816,6 +823,7 @@ mod tests {
triangle_states: vec![],
open_doors: vec![],
modifications: vec![],
contamination_active: false,
};
let bytes = save.to_bytes().expect("serialize");