Index: binaries/data/mods/public/globalscripts/utility.js =================================================================== --- binaries/data/mods/public/globalscripts/utility.js +++ binaries/data/mods/public/globalscripts/utility.js @@ -115,6 +115,14 @@ } /** + * Check if the data is contained in its stringification. + */ +function isEqualToStringified(data) +{ + return deepCompare(data, JSON.parse(JSON.stringify(data))); +} + +/** * Removes prefixing path from a path or filename, leaving just the file's name (with extension) * * ie. a/b/c/file.ext -> file.ext Index: binaries/data/mods/public/gui/session/AutoFormation.js =================================================================== --- binaries/data/mods/public/gui/session/AutoFormation.js +++ binaries/data/mods/public/gui/session/AutoFormation.js @@ -56,7 +56,7 @@ */ getDefault() { - return this.defaultFormation == NULL_FORMATION ? undefined : this.defaultFormation; + return this.defaultFormation == NULL_FORMATION ? null : this.defaultFormation; } /** @@ -65,6 +65,6 @@ getNull() { let walkOnly = Engine.ConfigDB_GetValue("user", "gui.session.formationwalkonly") === "true"; - return walkOnly ? NULL_FORMATION : undefined; + return walkOnly ? NULL_FORMATION : null; } } Index: binaries/data/mods/public/simulation/ai/common-api/entity.js =================================================================== --- binaries/data/mods/public/simulation/ai/common-api/entity.js +++ binaries/data/mods/public/simulation/ai/common-api/entity.js @@ -928,7 +928,7 @@ }, "tradeRoute": function(target, source) { - Engine.PostCommand(PlayerID, { "type": "setup-trade-route", "entities": [this.id()], "target": target.id(), "source": source.id(), "route": undefined, "queued": false, "pushFront": false }); + Engine.PostCommand(PlayerID, { "type": "setup-trade-route", "entities": [this.id()], "target": target.id(), "source": source.id(), "route": null, "queued": false, "pushFront": false }); return this; }, @@ -983,7 +983,7 @@ "autocontinue": false, "queued": false, "pushFront": false, - "metadata": metadata // can be undefined + "metadata": metadata // TODO filter out undefineds here }); return this; }, Index: binaries/data/mods/public/simulation/helpers/Commands.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Commands.js +++ binaries/data/mods/public/simulation/helpers/Commands.js @@ -4,6 +4,12 @@ function ProcessCommand(player, cmd) { + // Commands can only contain stringifiable data. If things cannot be + // stringified, this can yield an OOS on replay, since the replay uses + // stringified commands. + if (!isEqualToStringified(cmd)) + error("Found order containing non-stringifiable data: " + JSON.stringify(cmd)); + let cmpPlayer = QueryPlayerIDInterface(player); if (!cmpPlayer) return;