Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor map loading & saving #5572

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7b8c790
Refactor map loading & saving
ElectroJr Dec 22, 2024
cb170ed
test fixes
ElectroJr Dec 22, 2024
530783e
ISerializationManager tweaks
ElectroJr Dec 23, 2024
2074ac3
Fix component composition
ElectroJr Dec 23, 2024
eee3756
Try fix entity deserialization component composition
ElectroJr Dec 23, 2024
9ee0293
comments
ElectroJr Dec 23, 2024
043ac1a
CL
ElectroJr Dec 23, 2024
75b6ebd
error preinit
ElectroJr Dec 23, 2024
0de702b
a
ElectroJr Dec 23, 2024
164cb1a
cleanup
ElectroJr Dec 23, 2024
3a6da59
error if version is too new
ElectroJr Dec 23, 2024
a3ab32a
Add AlwaysPushSerializationTest
ElectroJr Dec 24, 2024
3afb6ba
Add auto-inclusion test
ElectroJr Dec 24, 2024
a77bc88
Better categorization
ElectroJr Dec 24, 2024
416a2f5
Combine test components
ElectroJr Dec 24, 2024
9d71807
Save -> TrySave
ElectroJr Dec 24, 2024
db9d0e3
Create new partial class for map loading
ElectroJr Dec 24, 2024
9eddbe1
Add OrphanSerializationTest
ElectroJr Dec 24, 2024
4930f2a
Include MapIds in BeforeSerializationEvent
ElectroJr Dec 24, 2024
4c7522f
Addd LifetimeSerializationTest
ElectroJr Dec 24, 2024
66e4ebb
Add TestMixedLifetimeSerialization
ElectroJr Dec 24, 2024
fb03472
Add CategorizationTest
ElectroJr Dec 24, 2024
a47bdc3
explicitly serialize list of nullspace entities
ElectroJr Dec 25, 2024
4f7ff86
Add backwards compatibility test
ElectroJr Dec 25, 2024
1221931
Version comments
ElectroJr Dec 25, 2024
b8313f3
add MapMergeTest
ElectroJr Dec 27, 2024
5530625
Add NetEntity support
ElectroJr Dec 27, 2024
e095689
Merge branch 'master' of https://github.com/space-wizards/RobustToolb…
ElectroJr Jan 12, 2025
aecbdbb
Merge branch 'master' of https://github.com/space-wizards/RobustToolb…
ElectroJr Jan 12, 2025
652b476
update notes
ElectroJr Jan 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,30 @@ END TEMPLATE-->

### Breaking changes

*None yet*
* `ITileDefinitionManager.AssignAlias` and general tile alias functionality has been removed. `TileAliasPrototype` still exist, but are only used during entity deserialization.
* `IMapManager.AddUninitializedMap` has been removed. Use the map-init options on `CreateMap()` instead.
* Re-using a MapId will now log a warning. This may cause some integration tests to fail if they are configured to fail
when warnings are logged.
* The minimum supported map format / version has been increased from 2 to 3.
* The server-side `MapLoaderSystem` and associated classes & structs has been moved to `Robust.Shared`, and has been significantly modified.
* The`TryLoad` and `Save` methods have been replaced with grid, map, generic entity variants. I.e, `SaveGrid`, `SaveMap`, and `SaveEntities`.
* Most of the serialization logic and methods have been moved out of `MapLoaderSystem` and into new `EntitySerializer`
and `EntityDeserializer` classes, which also replace the old `MapSerializationContext`.
* The `MapLoadOptions` class has been split into `MapLoadOptions`, `SerializationOptions`, and `DeserializationOptions`
structs.

### New features

*None yet*
* The current map format/version has increased from 6 to 7 and now contains more information to try support serialization of maps with null-space entities and full game saves.
* `IEntitySystemManager` now provides access to the system `IDependencyCollection`.

### Bugfixes

*None yet*
* Fixed entity deserialization for components with a data fields that have a AlwaysPushInheritance Attribute

### Other

*None yet*
* `MapChangedEvent` has been marked as obsolete, and should be replaced with `MapCreatedEvent` and `MapRemovedEvent.

### Internal

Expand Down
2 changes: 1 addition & 1 deletion Robust.Client/GameObjects/EntitySystems/MapSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protected override MapId GetNextMapId()
{
// Client-side map entities use negative map Ids to avoid conflict with server-side maps.
var id = new MapId(--LastMapId);
while (MapManager.MapExists(id))
while (MapExists(id) || UsedIds.Contains(id))
{
id = new MapId(--LastMapId);
}
Expand Down
95 changes: 43 additions & 52 deletions Robust.Server/Console/Commands/MapCommands.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using System.Linq;
using System.Numerics;
using Robust.Server.GameObjects;
using Robust.Server.Maps;
using Robust.Shared.Console;
using Robust.Shared.ContentPack;
using Robust.Shared.EntitySerialization;
using Robust.Shared.EntitySerialization.Systems;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Utility;

namespace Robust.Server.Console.Commands
{
Expand Down Expand Up @@ -42,7 +43,7 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

_ent.System<MapLoaderSystem>().Save(uid, args[1]);
_ent.System<MapLoaderSystem>().TrySaveGrid(uid, new ResPath(args[1]));
shell.WriteLine("Save successful. Look in the user data directory.");
}

Expand All @@ -63,7 +64,6 @@ public override CompletionResult GetCompletion(IConsoleShell shell, string[] arg
public sealed class LoadGridCommand : LocalizedCommands
{
[Dependency] private readonly IEntitySystemManager _system = default!;
[Dependency] private readonly IMapManager _map = default!;
[Dependency] private readonly IResourceManager _resource = default!;

public override string Command => "loadgrid";
Expand Down Expand Up @@ -91,13 +91,14 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

if (!_map.MapExists(mapId))
var sys = _system.GetEntitySystem<SharedMapSystem>();
if (!sys.MapExists(mapId))
{
shell.WriteError("Target map does not exist.");
return;
}

var loadOptions = new MapLoadOptions();
Vector2 offset = default;
if (args.Length >= 4)
{
if (!float.TryParse(args[2], out var x))
Expand All @@ -112,9 +113,10 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

loadOptions.Offset = new Vector2(x, y);
offset = new Vector2(x, y);
}

Angle rot = default;
if (args.Length >= 5)
{
if (!float.TryParse(args[4], out var rotation))
Expand All @@ -123,9 +125,10 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

loadOptions.Rotation = Angle.FromDegrees(rotation);
rot = Angle.FromDegrees(rotation);
}

var opts = DeserializationOptions.Default;
if (args.Length >= 6)
{
if (!bool.TryParse(args[5], out var storeUids))
Expand All @@ -134,10 +137,11 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

loadOptions.StoreMapUids = storeUids;
opts.StoreYamlUids = storeUids;
}

_system.GetEntitySystem<MapLoaderSystem>().Load(mapId, args[1], loadOptions);
var path = new ResPath(args[1]);
_system.GetEntitySystem<MapLoaderSystem>().TryLoadGrid(mapId, path, out _, opts, offset, rot);
}

public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
Expand All @@ -149,7 +153,6 @@ public override CompletionResult GetCompletion(IConsoleShell shell, string[] arg
public sealed class SaveMap : LocalizedCommands
{
[Dependency] private readonly IEntitySystemManager _system = default!;
[Dependency] private readonly IMapManager _map = default!;
[Dependency] private readonly IResourceManager _resource = default!;

public override string Command => "savemap";
Expand Down Expand Up @@ -189,29 +192,29 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
if (mapId == MapId.Nullspace)
return;

if (!_map.MapExists(mapId))
var sys = _system.GetEntitySystem<SharedMapSystem>();
if (!sys.MapExists(mapId))
{
shell.WriteError(Loc.GetString("cmd-savemap-not-exist"));
return;
}

if (_map.IsMapInitialized(mapId) &&
if (sys.IsInitialized(mapId) &&
( args.Length < 3 || !bool.TryParse(args[2], out var force) || !force))
{
shell.WriteError(Loc.GetString("cmd-savemap-init-warning"));
return;
}

shell.WriteLine(Loc.GetString("cmd-savemap-attempt", ("mapId", mapId), ("path", args[1])));
_system.GetEntitySystem<MapLoaderSystem>().SaveMap(mapId, args[1]);
_system.GetEntitySystem<MapLoaderSystem>().TrySaveMap(mapId, new ResPath(args[1]));
shell.WriteLine(Loc.GetString("cmd-savemap-success"));
}
}

public sealed class LoadMap : LocalizedCommands
{
[Dependency] private readonly IEntitySystemManager _system = default!;
[Dependency] private readonly IMapManager _map = default!;
[Dependency] private readonly IResourceManager _resource = default!;

public override string Command => "loadmap";
Expand Down Expand Up @@ -267,61 +270,49 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

if (_map.MapExists(mapId))
var sys = _system.GetEntitySystem<SharedMapSystem>();
if (sys.MapExists(mapId))
{
shell.WriteError(Loc.GetString("cmd-loadmap-exists", ("mapId", mapId)));
return;
}

var loadOptions = new MapLoadOptions();

float x = 0, y = 0;
if (args.Length >= 3)
float x = 0;
if (args.Length >= 3 && !float.TryParse(args[2], out x))
{
if (!float.TryParse(args[2], out x))
{
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[2])));
return;
}
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[2])));
return;
}

if (args.Length >= 4)
float y = 0;
if (args.Length >= 4 && !float.TryParse(args[3], out y))
{

if (!float.TryParse(args[3], out y))
{
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[3])));
return;
}
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[3])));
return;
}
var offset = new Vector2(x, y);

loadOptions.Offset = new Vector2(x, y);

if (args.Length >= 5)
float rotation = 0;
if (args.Length >= 5 && !float.TryParse(args[4], out rotation))
{
if (!float.TryParse(args[4], out var rotation))
{
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[4])));
return;
}

loadOptions.Rotation = new Angle(rotation);
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[4])));
return;
}
var rot = new Angle(rotation);

if (args.Length >= 6)
bool storeUids = false;
if (args.Length >= 6 && !bool.TryParse(args[5], out storeUids))
{
if (!bool.TryParse(args[5], out var storeUids))
{
shell.WriteError(Loc.GetString("cmd-parse-failure-bool", ("arg", args[5])));
return;
}

loadOptions.StoreMapUids = storeUids;
shell.WriteError(Loc.GetString("cmd-parse-failure-bool", ("arg", args[5])));
return;
}

_system.GetEntitySystem<MapLoaderSystem>().TryLoad(mapId, args[1], out _, loadOptions);
var opts = new DeserializationOptions {StoreYamlUids = storeUids};

var path = new ResPath(args[1]);
_system.GetEntitySystem<MapLoaderSystem>().TryLoadMapWithId(mapId, path, out _, out _, opts, offset, rot);

if (_map.MapExists(mapId))
if (sys.MapExists(mapId))
shell.WriteLine(Loc.GetString("cmd-loadmap-success", ("mapId", mapId), ("path", args[1])));
else
shell.WriteLine(Loc.GetString("cmd-loadmap-error", ("path", args[1])));
Expand Down
Loading
Loading