From 4e2c0e431b8198812937721f0a3ce146eeb37d3e Mon Sep 17 00:00:00 2001
From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Date: Wed, 8 Oct 2025 17:50:50 +1300
Subject: [PATCH] Fix MapLoaderSystem.SerializeEntitiesRecursive (#6246)
* Fix MapLoaderSystem.SerializeEntitiesRecursive
* a
* oops
---
RELEASE-NOTES.md | 1 +
.../EntitySerialization/EntitySerializer.cs | 36 +++++++++++++++++++
.../Systems/MapLoaderSystem.Save.cs | 9 ++---
3 files changed, 39 insertions(+), 7 deletions(-)
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index a5ef1d822..70d6412d8 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -45,6 +45,7 @@ END TEMPLATE-->
### Bugfixes
+* Fixed `MapLoaderSystem.SerializeEntitiesRecursive()` not properly serialising when given multiple root entities (e.g., multiple maps)
* Fixed yaml hot reloading throwing invalid path exceptions.
* The `EntityManager.CreateEntityUninitialized` overload that uses MapCoordinates now actually attaches entities to a grid if one is present at those coordinates, as was stated in it's documentation.
* Fixed physics joint relays not being properly updated when an entity is removed from a container.
diff --git a/Robust.Shared/EntitySerialization/EntitySerializer.cs b/Robust.Shared/EntitySerialization/EntitySerializer.cs
index eeb7031e1..36184f4f2 100644
--- a/Robust.Shared/EntitySerialization/EntitySerializer.cs
+++ b/Robust.Shared/EntitySerialization/EntitySerializer.cs
@@ -253,6 +253,42 @@ public sealed class EntitySerializer : ISerializationContext,
Truncate = EntityUid.Invalid;
}
+ ///
+ /// Serializes several entities and all of their children. Note that this will not automatically serialize the
+ /// entity's parents.
+ ///
+ public void SerializeEntityRecursive(HashSet roots)
+ {
+ if (roots.Count == 0)
+ return;
+
+ InitializeTileMap(roots.First());
+
+ HashSet allEntities = new();
+ List<(EntityUid Root, HashSet Children)> entities = new();
+
+ foreach(var root in roots)
+ {
+ if (!IsSerializable(root))
+ throw new Exception($"{EntMan.ToPrettyString(root)} is not serializable");
+
+ var ents = new HashSet();
+ RecursivelyIncludeChildren(root, ents);
+ entities.Add((root, ents));
+ allEntities.UnionWith(ents);
+ }
+
+ ReserveYamlIds(allEntities);
+
+ foreach (var (root, children) in entities)
+ {
+ Truncate = _xformQuery.GetComponent(root).ParentUid;
+ Truncated.Add(Truncate);
+ SerializeEntitiesInternal(children);
+ Truncate = EntityUid.Invalid;
+ }
+ }
+
#endregion
///
diff --git a/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.Save.cs b/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.Save.cs
index a0d6488e1..0afb8202c 100644
--- a/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.Save.cs
+++ b/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.Save.cs
@@ -16,7 +16,7 @@ public sealed partial class MapLoaderSystem
public event EntitySerializer.IsSerializableDelegate? OnIsSerializable;
///
- /// Recursively serialize the given entity and its children.
+ /// Recursively serialize the given entities and all of their children.
///
public (MappingDataNode Node, FileCategory Category) SerializeEntitiesRecursive(
HashSet entities,
@@ -41,12 +41,7 @@ public sealed partial class MapLoaderSystem
var serializer = new EntitySerializer(_dependency, opts);
serializer.OnIsSerializeable += OnIsSerializable;
-
- foreach (var ent in entities)
- {
- serializer.SerializeEntityRecursive(ent);
- }
-
+ serializer.SerializeEntityRecursive(entities);
var data = serializer.Write();
var cat = serializer.GetCategory();