Skip to content

About

A grid backup system for Magnetar

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

GridBackups

Magnetar server plugin for Space Engineers dedicated servers.

GridBackups exports ship/station grid blueprints on configurable backup triggers. Standalone servers keep backups in the Quasar data folder by default.

In a cluster, the plugin automatically uses PluginStorage.GetSharedDirectory regardless of UseQuasarConfigFolder. Each node backs up the grids it sees into the same plugin directory. Writes use temporary files and atomic rename; per-grid file locks coordinate daily backups and retention across nodes. Normal backup filenames include a unique suffix to avoid collisions across Hosts. An automatic backup is counted only after its file is written successfully; failed writes can be retried on the next scan. The shared filesystem must support advisory file locks and atomic rename. Quasar sets CLUSTER_SHARED_ROOT automatically for a single Host. A cluster on several Hosts needs one shared filesystem mounted at the same path on each; Quasar does not provision that mount. Without the shared root, the plugin fails to load instead of writing separate per-Host backups.

Configuration

The server plugin uses Magnetar PluginSdk configuration. Quasar can render the config UI from the schema generated by GridBackupsConfig. A GridBackups.cfg that fails to load is renamed to GridBackups.cfg.corrupted.<time>.txt and replaced by the defaults.

Important options:

  • Standalone storage root defaults to the Quasar data folder (QUASAR_DATA_DIR, derived from QUASAR_DS_CONFIG_PATH, or the platform default Quasar config directory). With UseQuasarConfigFolder off it is the server's data folder instead. Cluster storage uses the SDK shared root.
  • Minimum and maximum minutes since last backup.
  • Backup before concealment via public plugin entrypoint.
  • Backup when steady after a configured unchanged block-count duration.
  • Backup after a configured maximum block-count change.
  • Connected-grid grouping, owner folder naming, NPC/nobody grid inclusion, and retention limits.

Commands

  • !gridbackup list <PlayerName|SteamID|IdentityID> lists backed up grids for a player.
  • !gridbackup list <PlayerName|SteamID|IdentityID> <GridName|GridID|ListNumber> lists backup files for one grid.
  • !gridbackup list faction <FactionTag> lists backed up grids for a faction.
  • !gridbackup find <GridName|GridID> searches matching backed up grids across known owners.
  • !gridbackup restore <PlayerName|SteamID|IdentityID> <GridName|GridID|ListNumber> [backupNumber] [keepOriginalPosition] [force] restores a backup.
  • !gridbackup restore faction <FactionTag> <GridName|GridID|ListNumber> [backupNumber] [keepOriginalPosition] [force] restores from a faction member backup.
  • !gridbackup run starts a full backup scan.
  • !gridbackup status shows current backup service state.

Restore defaults to the latest backup, spawning near the caller. Console restores must use keepOriginalPosition=true. Use force=true to skip the occupation check.

External API

Other plugins can call:

bool BackupBeforeConcealment(List<MyObjectBuilder_CubeGrid> grids, long ownerIdentity);
bool BackupGridsManuallyWithBuilders(List<MyObjectBuilder_CubeGrid> grids, long ownerIdentity);

Build

Requirements:

  • Space Engineers Dedicated Server
  • Magnetar
  • .NET 10 SDK
  • .NET Framework 4.8.1 Developer Pack on Windows
  • Python 3.12 or newer, for setup.py

Build:

dotnet build GridBackups.sln --configuration Debug

Directory.Build.props auto-detects the Dedicated Server (Dedicated64) and the Magnetar installation (Magnetar). To override them, set them in Directory.Build.props.user, which is not committed. setup.py writes that file with the auto-detected Dedicated Server folder. The plugin version lives in Version.Build.props.

Development and deployment

Load the working copy through a Magnetar development folder: start Magnetar with -sources and add the repository with the Sources button. Magnetar then compiles the plugin from source.

Builds deploy nothing by default. To copy the build into <MagnetarData>/Local, set MagnetarData (the Magnetar config folder) in Directory.Build.props.user or pass -p:MagnetarData=... to the build.

Tests

tests/ holds the plugin's test suite. It runs on Linux only.

tests/unit has unit tests of the logic that needs no game: the storage root (Quasar data folder, the server's data folder, cluster storage), a broken config file, the backup triggers, retention, grid name matching and folder names. They build against the Dedicated Server and Magnetar like the plugin does:

dotnet test tests/unit

The rest is an in-game suite. It starts a Magnetar server with this working copy of the plugin, joins it with two headless game clients and drives them through the Remote plugin: player A is an administrator, player B has no rights. The tests run the chat commands and check the backup files, the plugin's log and the grids on the server. What it covers:

  • Backup triggers: the first scan, the minimum and maximum time since the last backup, a steady block count, a large block count change, and the entry points other plugins call, BackupBeforeConcealment among them (test_triggers.py)
  • What a backup holds and where it goes: grids joined by a rotor, owner folder names, NPC and nobody grids, the original owners, retention of normal, daily and old backups (test_contents.py)
  • The !gridbackup commands, their permissions and bad input (test_commands.py)
  • Restores: a restored grid matching the backup, near the caller or in place, backup numbers, faction restores, and the occupied-area check (test_restore.py)
  • The Quasar data folder from QUASAR_DATA_DIR, QUASAR_DS_CONFIG_PATH or the home folder, and a broken config file, each on a server of its own (test_storage.py)
  • Cluster storage: two servers started as cluster nodes that share one storage root (nodes.py), coordinating their backups through it (test_cluster.py)
  • Backups, config and listing across a server restart (test_restart.py)

The test world is the game's Empty World with the test players, a faction and a row of test grids, written fresh for every run. tests/probe is a test-only server plugin the servers load next to Grid Backups. It puts a new config into the running plugin, moves a grid's last backup back in time instead of waiting for minutes to pass, reports the state of grids, calls the public entry points, and runs chat commands as the console from a file, which is how the tests drive the servers that have no clients.

Running

You need the Space Engineers client and Dedicated Server from Steam, Magnetar and Pulsar installed, uv, and working copies of Remote and DirectTransport. The rig takes the ports, client ids and folders from a test slot of the se workspace (notes/parallel-test-work), and waits for free memory before each process it starts.

uv run pytest

Where GitHub's API rate limits Magnetar, export PULSAR_GITHUB_TOKEN for it to download its hub plugins with. A full run takes about 40 minutes, most of it starting servers; dotnet test tests/unit takes seconds. tests/rig.py lists the environment variables that point the rig at other installations and working copies.

To keep the server and clients running between runs while you work on a test:

uv run python tests/session.py start
GB_ATTACH=1 GB_KEEP=1 uv run pytest tests/test_commands.py
uv run python tests/session.py stop

Functionality is inspired by and reimplements the original Torch plugin GridBackup by LordTylus (license: Apache-2.0): https://github.com/LordTylus/SE-Torch-Plugin-ALE-GridBackup

About

A grid backup system for Magnetar

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages