• Forums

Navigation

  • Home
  • Contributing to the Docs
  • Getting Started
    • Introduction
    • Structuring Your Mod
    • Versioning
  • Core Concepts
    • Registries
    • Sides
    • Events
    • Mod Lifecycle
    • Resources
    • Internationalization
  • Blocks
    • Introduction
    • Block States
  • Items
    • Introduction
    • BlockEntityWithoutLevelRenderer
  • Networking
    • Introduction
    • SimpleImpl
    • Synchronizing Entities
  • Block Entities
    • Introduction
    • BlockEntityRenderer
  • Game Effects
    • Particles
    • Sounds
  • Data Storage
    • Capabilities
    • Saved Data
      • Declaration
      • Attaching to a Level
  • Rendering
    • Model Loaders
      • Introduction
      • Baked Model
      • Perspective
      • Item Overrides
  • Resources
    • Client Assets
      • Introduction
      • Models
        • Introduction
        • Texture Tinting
        • Item Properties
    • Server Data
      • Introduction
      • Recipes
        • Introduction
        • Custom Recipes
        • Ingredients
        • Non-Datapack Recipes
      • Loot Tables
      • Global Loot Modifiers
      • Tags
      • Advancements
      • Conditionally-Loaded Data
  • Data Generation
    • Introduction
    • Client Assets
      • Model Providers
      • Language Providers
      • Sound Providers
    • Server Data
      • Recipe Providers
      • Loot Table Providers
      • Tag Providers
      • Advancement Providers
      • Global Loot Modifier Providers
  • Miscellaneous Features
    • Configuration
    • Game Tests
    • Forge Update Checker
    • Debug Profiler
  • Advanced Topics
    • Access Transformers
  • Contributing to Forge
    • Introduction
    • Pull Request Guidelines
  • Legacy Versions
    • Introduction
    • Porting to This Version

Saved Data

The Saved Data (SD) system is an alternative to level capabilities that can attach data per level.

Declaration

Each SD implementation must subtype the SavedData class. There are two important methods to be aware of:

  • save: Allows the implementation to write NBT data to the level.
  • setDirty: A method that must be called after changing the data, to notify the game that there are changes that need to be written. If not called, #save will not get called and the existing data will persist.

Attaching to a Level

Any SavedData is loaded and/or attached to a level dynamically. As such, if one is never created on a level, then it will not exist.

SavedDatas are created and loaded from the DimensionDataStorage, which can be accessed by either ServerChunkCache#getDataStorage or ServerLevel#getDataStorage. From there, you can get or create an instance of your SD by calling DimensionDataStorage#computeIfAbsent. This will attempt to get the current instance of the SD if present or create a new one and load all available data.

DimensionDataStorage#computeIfAbsent takes in three arguments: a function to load NBT data into a SD and return it, a supplier to construct a new instance of the SD, and the name of the .dat file stored within the data folder for the implemented level.

For example, if a SD was named “example” within the Nether, then a file would be created at ./<level_folder>/DIM-1/data/example.dat and would be implemented like so:

// In some class
public ExampleSavedData create() {
  return new ExampleSavedData();
}

public ExampleSavedData load(CompoundTag tag) {
  ExampleSavedData data = this.create();
  // Load saved data
  return data;
}

// In some method within the class
netherDataStorage.computeIfAbsent(this::load, this::create, "example");

To persist a SD across levels, a SD should be attached to the Overworld, which can be obtained from MinecraftServer#overworld. The Overworld is the only dimension that is never fully unloaded and as such makes it perfect to store multi-level data on.

Built with MkDocs using a custom theme. Hosted by Read the Docs.
Enable Dark Theme