Working with Data

Managing Large Save Files

How do professional games handle really large save files, like open world games with lots of player progress?

Abstract art representing computer programming

Professional games use several strategies to handle large amounts of save data efficiently:

Incremental Saving

Instead of saving everything at once, games often save different components independently:

#include <chrono>

using namespace std::chrono;
class SaveManager {
  steady_clock::time_point LastInventorySave;
  steady_clock::time_point LastQuestSave;

 public:
  void Update() {
    auto Now = steady_clock::now();

    // Save inventory every 5 minutes
    if (Now - LastInventorySave > minutes(5)) {
      SaveInventory();
      LastInventorySave = Now;
    }

    // Save quests every 10 minutes
    if (Now - LastQuestSave > minutes(10)) {
      SaveQuests();
      LastQuestSave = Now;
    }
  }

  void SaveInventory() {
    // Only save items that changed since last save
    for (const auto& Item : PlayerInventory) {
      if (Item.HasChanged) {
        WriteItemToFile(Item);
      }
    }
  }
};

Chunked World Data

Open world games typically divide the world into chunks and only save active areas:

struct WorldChunk {
  static constexpr int SIZE = 64;
  std::array<std::array<Tile, SIZE>, SIZE>
    Tiles;
  bool IsModified{false};
};

class World {
  std::vector<std::vector<WorldChunk>> Chunks;

  void SaveActiveChunks() {
    const int PlayerChunkX = PlayerPos.X /
      WorldChunk::SIZE;
    const int PlayerChunkY = PlayerPos.Y /
      WorldChunk::SIZE;

    // Save chunks near player
    for (int dx = -1; dx <= 1; ++dx) {
      for (int dy = -1; dy <= 1; ++dy) {
        SaveChunkIfModified(PlayerChunkX + dx,
                            PlayerChunkY + dy);
      }
    }
  }
};

Compression

Large save files are typically compressed before writing to disk:

#include <zlib.h>
#include <vector>

std::vector<char> CompressSaveData(
  const std::vector<char>& Data) {
  std::vector<char> CompressedData;
  z_stream Stream{};

  // Initialize zlib
  deflateInit(&Stream, Z_BEST_COMPRESSION);

  // Compress data in chunks
  const int CHUNK_SIZE = 16384;
  char OutBuffer[CHUNK_SIZE];

  // Compression code here...

  deflateEnd(&Stream);
  return CompressedData;
}

Reference Data

Instead of saving full copies of common objects, save references to shared data:

struct Item {
  int TemplateId; // Reference to item template
  int Count; // Instance-specific data
  
  // Don't save template data like name, description, icon...
};

This combination of techniques allows games to manage massive amounts of save data while maintaining reasonable file sizes and save/load times.

Answers to questions are automatically generated and may not have been reviewed.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 75 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2025 - All Rights Reserved