promotional bannermobile promotional banner
premium banner
A useful mod for Minecraft servers and framework for mod developers.

Description

Custom Server Data

Version Loader Status

Overview

Custom Server Data is a Fabric server-side library mod that provides a structured, persistent global data framework for Minecraft 1.20.6. It allows mod developers (and the server itself) to store data.

Data is stored as human-readable JSON files inside the world save directory:

world/customserverdata/<modid>/<filename>.json

Each variable is defined with a type, default value, constraints, and nullability through a schema system, then read/written at runtime through a static API.

Developer Guide

1. Creating a Custom Type

Any custom object you want to store must implement IJsonSerializable:

import com.google.gson.JsonObject;
import fr.hdi.api.IJsonSerializable;

public class QuestData implements IJsonSerializable {
    private int nbPoints;
    private String status;

    public QuestData() {
        this.nbPoints = 0;
        this.status = "inactive";
    }

    public int getNbPoints() { return nbPoints; }
    public void setNbPoints(int nbPoints) { this.nbPoints = nbPoints; }

    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }

    @Override
    public JsonObject toJson() {
        JsonObject json = new JsonObject();
        json.addProperty("nb_points", nbPoints);
        json.addProperty("status", status);
        return json;
    }

    @Override
    public void fromJson(JsonObject json) {
        this.nbPoints = json.has("nb_points") ? json.get("nb_points").getAsInt() : 0;
        this.status = json.has("status") ? json.get("status").getAsString() : "inactive";
    }
}

2. Registering Data

Register your schemas in your mod's onInitialize method using ServerSchemaManager:

import fr.hdi.schema.DataType;
import fr.hdi.schema.ServerSchemaManager;
import fr.hdi.schema.VariableDefinition;
import net.fabricmc.api.ModInitializer;

public class MyMod implements ModInitializer {
    public static final String MOD_ID = "mymod";

    @Override
    public void onInitialize() {
        // Register an integer with min/max constraints
        ServerSchemaManager.register(MOD_ID, "quests",
            VariableDefinition.builder("nb_point")
                .type(DataType.INT)
                .defaultValue(10)
                .min(0)
                .max(1000)
                .build()
        );

        // Register a string
        ServerSchemaManager.register(MOD_ID, "quests",
            VariableDefinition.builder("status")
                .type(DataType.STRING)
                .defaultValue("active")
                .build()
        );

        // Register a boolean
        ServerSchemaManager.register(MOD_ID, "settings",
            VariableDefinition.builder("pvp_enabled")
                .type(DataType.BOOLEAN)
                .defaultValue(false)
                .build()
        );

        // Register a custom type
        ServerSchemaManager.register(MOD_ID, "quests",
            VariableDefinition.builder("quest_data", "QuestData")
                .type(DataType.CUSTOM)
                .customFactory(QuestData::new)
                .nullable(true)
                .build()
        );

        //Register a custom type List 
        ServerSchemaManager.register(MOD_ID, "warps",
                ServerVariableDefinition.builder("warps")
                        .type(ServerDataType.LIST)
                        .elementType(ServerDataType.CUSTOM)
                        .elementFactory(Warp::new)
                        .defaultValue(List.of())
                        .build()
        );
    }
}

This produces two JSON files on disk:

  • world/customserverdata/mymod/quests.json
  • world/customserverdata/mymod/settings.json

3. Reading / Writing Data

Use the static ServerDataStore API anywhere on the server thread:

import fr.hdi.store.ServerDataStore;

// Read values
int points = ServerDataStore.getInt("mymod", "quests", "nb_point");
String status = ServerDataStore.getString("mymod", "quests", "status");
boolean pvp = ServerDataStore.getBoolean("mymod", "settings", "pvp_enabled");

// Write values (validated against the schema)
ServerDataStore.setData("mymod", "quests", "nb_point", 42);
ServerDataStore.setData("mymod", "quests", "status", "completed");
ServerDataStore.setData("mymod", "settings", "pvp_enabled", true);

// Custom objects
QuestData quest = ServerDataStore.getCustom("mymod", "quests", "quest_data");
if (quest != null) {
    quest.setNbPoints(100);
    ServerDataStore.setData("mymod", "quests", "quest_data", quest);
}

List<Warp> warps = ServerDataStore.getList(EssentialsUtilsCommands.MOD_ID, "warps", "warps");
if (warps != null){
    warps.remove(1);
    ServerDataStore.setData(EssentialsUtilsCommands.MOD_ID, "warps","warps",warps);
}