Concurrency-safe save synchronization for alternating dedicated-server hosts, with a stable Palworld release and an experimental Valheim adapter on main.
Status:
v2.2.2remains the stable Palworld reference release.mainadditionally contains the experimental Valheim 1.0 adapter, managed-computer authorization and the modularized backend introduced after that release. Those development-tree features are not part of thev2.2.2support promise. A broader multi-game / device-sync product is still outside this repository.
Development note: the current development tree contains an experimental Valheim 1.0 Windows adapter. It reuses the generic backend contract but is not part of the
v2.2.2stable release and should not be used on the only copy of a real world before its four-host acceptance test passes.
Website · Wiki · Docs · Releases · Discussions
Spanish documentation: the repository itself is maintained in English. The Wiki keeps a complete Spanish section alongside the English pages.
Palworld is a trademark of Pocketpair, Inc. This community project is not affiliated with, sponsored by or endorsed by Pocketpair. It does not distribute game files or save content.
A shared ZIP, network folder or cloud directory does not establish a single source of truth. Two hosts can start divergent copies, timestamps can change while files are copied, and a perfectly valid directory may belong to a different world.
Save Sync separates the game server from the authoritative save store. The diagram below shows the stable Palworld v2.2.2 flow:
flowchart LR
A[Host PC A] -->|HTTPS + Bearer| API[Save Sync]
B[Host PC B] -->|HTTPS + Bearer| API
API --> DB[(SQLite WAL)]
API --> FS[(Versioned ZIPs)]
API -. optional backup .-> EXT[(restic / external storage)]
A -->|localhost REST| PA[PalServer]
B -->|localhost REST| PB[PalServer]
The active gaming PC runs the selected dedicated server. Save Sync keeps the authoritative version, arbitrates the session lock and rejects stale uploads or saves from another world. The stable v2.2.2 workflow uses Palworld; the experimental Valheim workflow on main uses the same backend contract with a game-specific client adapter.
- backend-assigned monotonically increasing integer versions;
- optimistic concurrency through
baseVersion; - exclusive lock with
sessionId, TTL and heartbeat; - adapter-defined save identity; Palworld uses
worldGuid, while experimental Valheim uses its signed 64-bitworldUid; - server-side SHA-256 verification;
- defensive ZIP validation against path traversal, symlinks, entry floods and ZIP bombs;
- immutable publication before SQLite moves the authoritative pointer;
- restore creates a new version instead of rewriting history;
- Bearer tokens stored only as hashes, with optional per-computer binding for managed-host games;
- Windows DPAPI for client-side secrets;
- configurable per-slot retention;
- durable external-backup queue supervised outside Gunicorn, with timeout, retry and audit trail;
- backup status that reports what is actually known instead of pretending a remote snapshot was checked live.
Save Sync does not merge divergent worlds. If two copies were independently modified, one must be chosen explicitly.
For production, use the same product release for the client and backend. Do not deploy the moving tip of main on a real world.
Requirements:
- Docker Engine + Docker Compose v2;
- HTTPS;
- private filesystem storage;
- Traefik + ForwardAuth/AuthentiK for the private panel, or API-only mode.
git clone --branch v2.2.2 --depth 1 https://github.com/Ayerdi/dedicated-server-save-sync.git
cd dedicated-server-save-sync
config/deploy.sh --init-envReview .env, then deploy:
config/deploy.shTo validate the stack locally without a reverse proxy, domain or PalServer:
bash scripts/local-e2e.sh- Download
dedicated-server-save-sync-client-v2.2.2.zipand its.sha256file from Releases. - Verify the checksum before extracting the archive.
- Copy
client/config.example.jsontoclient/config.json. - Configure the public URL, PalServer path and
Adapter=palworld. - Run
client/Configure-Secrets.cmd. - Run
client/Test-Connection.cmd. - Start sessions through
client/Start-PalworldSync.cmd.
The older Spanish command filenames remain in the package as compatibility aliases, so existing installations and scripts do not break.
PowerShell checksum verification:
$zip = 'dedicated-server-save-sync-client-v2.2.2.zip'
$expected = ((Get-Content "$zip.sha256") -split '\s+')[0].ToLowerInvariant()
$actual = (Get-FileHash $zip -Algorithm SHA256).Hash.ToLowerInvariant()
if ($actual -ne $expected) { throw 'Client SHA-256 mismatch.' }Normal session flow:
status → lock → download if needed → start → heartbeat
→ REST save/shutdown → ZIP/SHA-256 → upload
The client verifies the real worldGuid through Palworld's local REST API before starting and before publishing. Do not expose Palworld's REST port through your router.
Read client/README.md and docs/OPERATIONS.md before first production use. For development-tree Valheim testing, use docs/VALHEIM.md and the dedicated four-host acceptance checklist; do not treat the experimental adapter as part of the stable release.
SAVE_SYNC_RETENTION_PER_SLOT limits operational versions per host/slot.
SAVE_SYNC_POST_PUBLISH_COMMAND defines an external backup after a confirmed publication. The web process only queues the work in SQLite; a separate backup-supervisor service executes it, applies the timeout, audits the result and retains the row for retry if the supervisor crashes before recording a final outcome.
A version with a pending backup stays protected from retention. Physical ZIP deletion occurs only after retention metadata is committed and current references are revalidated.
GET /backup-status and the panel distinguish current backup configuration from historical results. latestVersionBackedUp=true means the configured hook reported success for the current version; it does not mean the restic repository was queried live.
Never publish real .env, client configuration/secrets, tokens, passwords, saves, ZIP archives, SQLite databases, complete logs, production paths, GUIDs, IPs, domains or personal names.
CI runs Ruff, pytest with an 85% coverage floor, pip-audit, Docker E2E —including supervisor crash/restart—, Pester and Gitleaks over Git history.
Use SECURITY.md for vulnerabilities. Use GitHub Discussions or issues for non-sensitive support.
The backend retains generic primitives (gameKey, saveIdentity, adapters), and the repository keeps technical documentation for that design. However, the stable product in this repository supports Palworld.
An experimental Valheim adapter now exists on main behind the same isolation boundary. It requires its own gameKey, database and storage root, uses folder-based Valheim 1.0 saves plus intrinsic worldUid, and does not change Palworld's legacy API/REST behavior.
The development backend also includes schema-4 web management for authorized users and physical host PCs behind the per-game managedHosts capability. It is enabled for the experimental Valheim deployment and disabled for Palworld. Authentik remains the identity provider; Save Sync stores roles, registered ClientId values and optional computer-bound sync tokens. This supports groups where several distinct computers may take turns hosting one authoritative save while the global lock prevents simultaneous writers. Computer-bound tokens are sync-only and cannot perform administrative operations.
A broader product covering multi-game installations, automatic save discovery, multiple server instances, device-to-device cloud save synchronization and a cross-platform agent is intentionally outside this repository's maintenance scope.
python3 -m venv .venv
. .venv/bin/activate
pip install --require-hashes -r requirements-dev.txt
bash -n scripts/*.sh config/*.sh
ruff check save_sync tests wsgi.py scripts/check-docs.py
python scripts/check-docs.py
python -m pytest -q
pip-audit -r requirements.txt --progress-spinner=off
docker compose config --quiet
bash scripts/run-gitleaks.sh
bash scripts/local-e2e.shWindows client tests:
Import-Module Pester -RequiredVersion 5.9.0
Invoke-Pester -Path .\client -CI- Documentation index
- Architecture and invariants
- HTTP API
- Operations
- Local development
- Migrations
- Multi-game design reference
- Release process
- Publication checklist
- Maintainer guide
- Security
- Support
- Contributing
Code and documentation: Apache License 2.0.