From 1135e499d709624e51e182c06e3a20f6938f635b Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 07:05:13 -0700 Subject: [PATCH] fix(zone): scrub NaN/inf manifest floats at save time Mirrors the load-side sanitize. nlohmann throws on NaN/inf, so a corrupted in-memory baseHeight or volume would abort the manifest save and lose all zone-level settings (flags, audio config, etc.). --- tools/editor/zone_manifest.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/editor/zone_manifest.cpp b/tools/editor/zone_manifest.cpp index 8a94af65..c7732b83 100644 --- a/tools/editor/zone_manifest.cpp +++ b/tools/editor/zone_manifest.cpp @@ -20,7 +20,9 @@ bool ZoneManifest::save(const std::string& path) const { j["displayName"] = displayName; j["mapId"] = mapId; j["biome"] = biome; - j["baseHeight"] = baseHeight; + // Scrub before serialization — nlohmann throws on NaN/inf, which would + // wipe the entire manifest save and lose all zone settings. + j["baseHeight"] = std::isfinite(baseHeight) ? baseHeight : 100.0f; j["hasCreatures"] = hasCreatures; j["description"] = description; j["editorVersion"] = "1.0.0"; @@ -60,8 +62,10 @@ bool ZoneManifest::save(const std::string& path) const { if (!musicTrack.empty()) audio["music"] = musicTrack; if (!ambienceDay.empty()) audio["ambienceDay"] = ambienceDay; if (!ambienceNight.empty()) audio["ambienceNight"] = ambienceNight; - audio["musicVolume"] = musicVolume; - audio["ambienceVolume"] = ambienceVolume; + audio["musicVolume"] = std::isfinite(musicVolume) + ? std::clamp(musicVolume, 0.0f, 1.0f) : 0.7f; + audio["ambienceVolume"] = std::isfinite(ambienceVolume) + ? std::clamp(ambienceVolume, 0.0f, 1.0f) : 0.5f; j["audio"] = audio; }