From 924c79b0ad06885d793d477bfc9d129da676d62b Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 18 Jan 2026 22:38:24 +0000 Subject: [PATCH] Persist generated map across skirmish settings. --- OpenRA.Game/GameInformation.cs | 2 +- OpenRA.Game/Map/MapGenerationArgs.cs | 8 ++++---- OpenRA.Game/Network/GameSave.cs | 2 +- .../ServerTraits/SkirmishLogic.cs | 18 +++++++++++++++--- .../Widgets/Logic/Lobby/LobbyLogic.cs | 4 +++- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/OpenRA.Game/GameInformation.cs b/OpenRA.Game/GameInformation.cs index 04e9bbed66..7ff72430e6 100644 --- a/OpenRA.Game/GameInformation.cs +++ b/OpenRA.Game/GameInformation.cs @@ -115,7 +115,7 @@ namespace OpenRA nodes.Add(new MiniYamlNode($"Player@{i}", FieldSaver.Save(Players[i]))); if (MapGenerationArgs != null) - nodes.Add(new MiniYamlNode("MapGenerationArgs", new MiniYaml("", MiniYaml.FromString(MapGenerationArgs.Serialize(), "MapGenerationArgs")))); + nodes.Add(new MiniYamlNode("MapGenerationArgs", new MiniYaml("", MapGenerationArgs.Serialize()))); return nodes.WriteToString(); } diff --git a/OpenRA.Game/Map/MapGenerationArgs.cs b/OpenRA.Game/Map/MapGenerationArgs.cs index 0d6e6b1d39..acfac1dbb1 100644 --- a/OpenRA.Game/Map/MapGenerationArgs.cs +++ b/OpenRA.Game/Map/MapGenerationArgs.cs @@ -41,10 +41,10 @@ namespace OpenRA return yaml.NodeWithKey("Settings").Value; } - public string Serialize() + public List Serialize() { - return new List() - { + return + [ new("Uid", Uid), new("Generator", Generator), new("Tileset", Tileset), @@ -52,7 +52,7 @@ namespace OpenRA new("Settings", Settings), new("Title", Title), new("Author", Author) - }.WriteToString(); + ]; } } } diff --git a/OpenRA.Game/Network/GameSave.cs b/OpenRA.Game/Network/GameSave.cs index d1a9b6889c..c2608ecc46 100644 --- a/OpenRA.Game/Network/GameSave.cs +++ b/OpenRA.Game/Network/GameSave.cs @@ -314,7 +314,7 @@ namespace OpenRA.Network .ToList(); file.WriteLengthPrefixedString(Encoding.UTF8, slotClientNodes.WriteToString()); - file.WriteLengthPrefixedString(Encoding.UTF8, MapGenerationArgs?.Serialize() ?? string.Empty); + file.WriteLengthPrefixedString(Encoding.UTF8, MapGenerationArgs?.Serialize().WriteToString() ?? string.Empty); var traitDataOffset = file.Length; file.Write(TraitDataMarker); diff --git a/OpenRA.Mods.Common/ServerTraits/SkirmishLogic.cs b/OpenRA.Mods.Common/ServerTraits/SkirmishLogic.cs index 9259b2abc0..e92e60685f 100644 --- a/OpenRA.Mods.Common/ServerTraits/SkirmishLogic.cs +++ b/OpenRA.Mods.Common/ServerTraits/SkirmishLogic.cs @@ -76,8 +76,19 @@ namespace OpenRA.Mods.Common.Server // Only set players and options if the map is available if (server.LobbyInfo.GlobalSettings.Map != mapNode.Value.Value) { - var map = server.ModData.MapCache[mapNode.Value.Value]; - if (map.Status != MapStatus.Available || !server.InterpretCommand($"map {map.Uid}", conn)) + var preview = server.ModData.MapCache[mapNode.Value.Value]; + if (preview.Status != MapStatus.Available) + { + if (mapNode.Value.Nodes.Length == 0) + return false; + + var args = FieldLoader.Load(mapNode.Value); + preview.UpdateFromGenerationArgs(args); + preview.Generate(); + server.GeneratedMapData = mapNode.Value.Nodes.WriteToString(); + } + + if (!server.InterpretCommand($"map {preview.Uid}", conn)) return false; } @@ -157,9 +168,10 @@ namespace OpenRA.Mods.Common.Server return; var playerClient = server.LobbyInfo.NonBotClients.First(); + var map = server.ModData.MapCache[server.LobbyInfo.GlobalSettings.Map]; var nodes = new List { - new("Map", server.LobbyInfo.GlobalSettings.Map), + new("Map", server.LobbyInfo.GlobalSettings.Map, map.GenerationArgs?.Serialize() ?? []), new("Options", new MiniYaml("", server.LobbyInfo.GlobalSettings.LobbyOptions .Select(kv => new MiniYamlNode(kv.Key, kv.Value.Value)))), new("Player", new SkirmishSlot(playerClient).ToYaml()), diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs index 86b761cf58..a1f8cb2a3d 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs @@ -263,7 +263,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic return; lastGeneratedMap = args; - orderManager.IssueOrder(Order.FromTargetString("GenerateMap", args.Serialize(), true)); + orderManager.IssueOrder(Order.FromTargetString("GenerateMap", args.Serialize().WriteToString(), true)); orderManager.IssueOrder(Order.Command("map " + args.Uid)); Game.Settings.Server.Map = args.Uid; Game.Settings.Save(); @@ -703,6 +703,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic return; map = modData.MapCache[uid]; + if (map.GenerationArgs != null) + lastGeneratedMap = map.GenerationArgs; // Tell the server that we have the map mapAvailable = map.Status == MapStatus.Available;