Fyrox Savegame

Save Slots, Versioning & Encryption — a game-oriented save/load system for the Fyrox Rust game engine. Not just a serde wrapper.

Fyrox 1.0+ Rust 1.87+ MIT (Free) LZ4 / Zstd AES-256-GCM (Pro) Atomic Writes
Get Pro on itch.io GitHub (Free)

Core Features

💾

Named Slots + Quick Save

Save to named slots ("slot_1", "manual_save") or use quick_save()/quick_load() for one-button save/load.

📋

Rich Metadata

Timestamp, total playtime, description, thumbnail (PNG bytes), and custom key-value pairs. Display save info without loading the full file.

🔄

Version Migration

MigrationRegistry runs upgrade functions in order (v1 → v2 → v3). Old saves always load, even after major updates.

📦

LZ4 Compression

Fast LZ4 compression reduces save file size with minimal CPU overhead. Pro adds Zstd for higher compression ratios.

🔒

CRC32 Checksums

Every save file includes a CRC32 checksum. Detect corruption on load before deserializing. Pro adds SHA-256 for stronger integrity.

⚛️

Atomic Writes

Write to a temp file, then rename over the target. If the game crashes mid-save, the previous file stays intact.

🔐

AES-256-GCM (Pro)

Encrypt save files to prevent tampering and cheating. Authenticated encryption ensures both confidentiality and integrity.

Async Saving (Pro)

Non-blocking saves via tokio. The game keeps running while save data is compressed, encrypted, and written to disk.

Save File Format

Magic FXSG (4 bytes)
Header Version + flags
Metadata bincode encoded
Payload bincode → LZ4
Checksum CRC32 (4 bytes)

Pro: Payload can use Zstd instead of LZ4, and the entire payload+checksum block can be wrapped in AES-256-GCM encryption.

Dependencies

Free

serdeSerialization framework
bincodeBinary encoding
thiserrorError types
crc32fastCRC32 checksums
lz4_flexLZ4 compression

Pro (additional)

sha2SHA-256 integrity
aes-gcmAES-256-GCM encryption
zstdZstd compression
tokioAsync runtime

Free vs Pro

Free MIT

  • Named slots + quick save/load
  • Metadata (timestamp, playtime, description, thumbnail, custom KV)
  • MigrationRegistry for version upgrades
  • LZ4 compression
  • CRC32 checksums
  • Atomic writes (temp file + rename)
  • Format: Magic FXSG + bincode + LZ4 + CRC32
  • Full serde integration

Pro Paid

  • Everything in Free
  • SHA-256 integrity verification
  • AES-256-GCM encryption (anti-cheat)
  • Zstd compression (higher ratio)
  • Async saving via tokio (non-blocking)
  • Auto-save rotation (timer + rotating slots)
  • ProSaveConfig for pro_encode()/pro_decode()
  • Priority support

Quick Start Example

use fyrox_savegame::*;

#[derive(serde::Serialize, serde::Deserialize)]
struct GameState {
    player_hp: i32,
    level: u32,
    position: [f32; 3],
    inventory: Vec<String>,
}

// Save
let state = GameState { player_hp: 85, level: 7, position: [10.0, 0.0, -5.0], inventory: vec!["sword".into()] };
let meta = Metadata::new()
    .description("Entered the forest dungeon")
    .playtime(Duration::from_secs(3600))
    .custom("chapter", "3");

SaveManager::save("slot_1", &state, &meta)?;

// Load
let (state, meta): (GameState, Metadata) = SaveManager::load("slot_1")?;
println!("HP: {}, Playtime: {:?}", state.player_hp, meta.playtime());

// Quick save/load
SaveManager::quick_save(&state, &meta)?;
let (state, meta): (GameState, Metadata) = SaveManager::quick_load()?;

// Version migration
let mut registry = MigrationRegistry::new();
registry.register(1, 2, |data: Value| {
    // Add new "stamina" field with default
    data["stamina"] = Value::from(100);
    Ok(data)
});
registry.register(2, 3, |data: Value| {
    // Rename "hp" to "player_hp"
    data["player_hp"] = data["hp"].clone();
    Ok(data)
});

Pro: Encrypted Async Save

use fyrox_savegame_pro::*;

let config = ProSaveConfig {
    compression: Compression::Zstd { level: 3 },
    encryption: Some(EncryptionConfig {
        algorithm: EncryptionAlgorithm::Aes256Gcm,
        key: load_key_from_secure_storage()?,
    }),
    integrity: Integrity::Sha256,
};

// Non-blocking save (returns immediately)
let handle = pro_encode_async("autosave_1", &state, &meta, &config).await?;

// Auto-save rotation: keeps last 3 saves, rotates every 5 minutes
let auto_saver = AutoSave::new()
    .interval(Duration::from_secs(300))
    .slots(3)  // autosave_0, autosave_1, autosave_2
    .config(config);
auto_saver.start(); // runs in background via tokio

FAQ

Why not just use serde directly?

Plain serde gives you serialization, but not game save features. Fyrox Savegame adds named save slots, metadata (timestamps, playtime, thumbnails), version migration so old saves load after updates, LZ4 compression, CRC32 integrity checks, and atomic writes to prevent corruption. It is a complete save system, not just a serialization wrapper.

Is it crash-safe?

Yes. Saves use atomic writes: data is written to a temporary file first, then renamed over the target. If the game crashes mid-write, the previous save remains intact. CRC32 checksums detect any file corruption on load.

How does version migration work?

Register migration functions in the MigrationRegistry, keyed by version numbers. When loading a save from an older version, the system runs each migration in order (v1 to v2, v2 to v3, etc.) to upgrade the data. You never break backward compatibility.

What is the save file format?

Magic bytes (FXSG) + version header + metadata (bincode) + payload (game state serialized with bincode, compressed with LZ4, CRC32 appended). Pro can substitute Zstd compression and wrap the payload in AES-256-GCM encryption.

Why AES-256-GCM for anti-cheat?

AES-256-GCM provides authenticated encryption: players cannot read or modify save data without the key. The GCM authentication tag ensures any tampering is detected on load. This prevents save editors and cheat tools from modifying game state.

Does async saving block the game?

No. Pro's async saving (via tokio) serializes, compresses, and encrypts the data on a background thread. The game loop continues running. You receive a completion handle to check status or await the result.

Never lose a player's progress

Crash-safe saves with compression, integrity, encryption, and migration — built for games.

Get Pro on itch.io GitHub (Free)