Aller au contenu

Tutorial: Metadata Storage

Aprende a usar el Meta System para almacenar datos personalizados.

Objetivo

Crear un sistema de estadísticas de jugador que persiste entre sesiones.

Paso 1: Crear MetaRegistry

public class PlayerStats {
    private static final MetaRegistry<Player> REGISTRY =
        new MetaRegistry<>();

    // Datos persistentes
    public static final MetaKey<Integer> KILLS =
        REGISTRY.registerMetaObject(
            p -> 0,
            true,
            "player_kills",
            Codec.INT
        );

    public static final MetaKey<Integer> DEATHS =
        REGISTRY.registerMetaObject(
            p -> 0,
            true,
            "player_deaths",
            Codec.INT
        );

    public static final MetaKey<Long> PLAY_TIME =
        REGISTRY.registerMetaObject(
            p -> 0L,
            true,
            "player_playtime",
            Codec.LONG
        );

    // Datos temporales
    public static final MetaKey<Long> SESSION_START =
        REGISTRY.registerMetaObject(
            p -> System.currentTimeMillis()
        );
}

Paso 2: Usar MetaKeys

public class StatsManager {

    public void onPlayerKill(Player player) {
        int kills = player.getMetaObject(PlayerStats.KILLS);
        player.putMetaObject(PlayerStats.KILLS, kills + 1);

        player.sendMessage("Kills: " + (kills + 1));
    }

    public void onPlayerDeath(Player player) {
        int deaths = player.getMetaObject(PlayerStats.DEATHS);
        player.putMetaObject(PlayerStats.DEATHS, deaths + 1);
    }

    public void onPlayerJoin(Player player) {
        long sessionStart = player.getMetaObject(PlayerStats.SESSION_START);
        System.out.println("Sesión iniciada: " + sessionStart);
    }

    public void onPlayerLeave(Player player) {
        // Calcular tiempo de juego
        long sessionStart = player.getMetaObject(PlayerStats.SESSION_START);
        long sessionTime = System.currentTimeMillis() - sessionStart;

        long totalPlayTime = player.getMetaObject(PlayerStats.PLAY_TIME);
        player.putMetaObject(PlayerStats.PLAY_TIME, totalPlayTime + sessionTime);
    }

    public void showStats(Player player) {
        int kills = player.getMetaObject(PlayerStats.KILLS);
        int deaths = player.getMetaObject(PlayerStats.DEATHS);
        long playTime = player.getMetaObject(PlayerStats.PLAY_TIME);

        double kd = deaths > 0 ? (double) kills / deaths : kills;

        player.sendMessage("=== Estadísticas ===");
        player.sendMessage("Kills: " + kills);
        player.sendMessage("Deaths: " + deaths);
        player.sendMessage("K/D: " + String.format("%.2f", kd));
        player.sendMessage("Tiempo de juego: " + formatTime(playTime));
    }

    private String formatTime(long millis) {
        long hours = millis / 3600000;
        long minutes = (millis % 3600000) / 60000;
        return hours + "h " + minutes + "m";
    }
}

Paso 3: Datos Complejos

Para tipos personalizados, crear un Codec:

public class PlayerProfile {
    public String rank;
    public List<String> achievements;
    public Map<String, Integer> questProgress;

    public static final Codec<PlayerProfile> CODEC = ...;
}

// Registrar
public static final MetaKey<PlayerProfile> PROFILE =
    REGISTRY.registerMetaObject(
        p -> new PlayerProfile(),
        true,
        "player_profile",
        PlayerProfile.CODEC
    );

Siguiente