tutorial:persistent_states

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorial:persistent_states [2025/03/12 17:18] – added bac comments lakazatongtutorial:persistent_states [2025/03/13 14:52] (current) – world.getServer() only once, harmonized MOD_ID lakazatong
Line 119: Line 119:
 <code java> <code java>
 import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
 +import net.minecraft.registry.RegistryWrapper;
 import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
 +import net.minecraft.server.world.ServerWorld;
 import net.minecraft.world.PersistentState; import net.minecraft.world.PersistentState;
-import net.minecraft.world.PersistentStateManager; 
 import net.minecraft.world.World; import net.minecraft.world.World;
  
Line 129: Line 130:
  
     @Override     @Override
-    public NbtCompound writeNbt(NbtCompound nbt) {+    public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registries) {
         nbt.putInt("totalDirtBlocksBroken", totalDirtBlocksBroken);         nbt.putInt("totalDirtBlocksBroken", totalDirtBlocksBroken);
         return nbt;         return nbt;
Line 152: Line 153:
         return state;         return state;
     }     }
-    +
     public static StateSaverAndLoader createNew() {     public static StateSaverAndLoader createNew() {
         StateSaverAndLoader state = new StateSaverAndLoader();         StateSaverAndLoader state = new StateSaverAndLoader();
Line 174: Line 175:
     // ... (Previously written code)     // ... (Previously written code)
  
-    private static Type<StateSaverAndLoader> type = new Type<>(+    private static final Type<StateSaverAndLoader> type = new Type<>(
             StateSaverAndLoader::createNew, // If there's no 'StateSaverAndLoader' yet create one and refresh variables             StateSaverAndLoader::createNew, // If there's no 'StateSaverAndLoader' yet create one and refresh variables
             StateSaverAndLoader::createFromNbt, // If there is a 'StateSaverAndLoader' NBT, parse it with 'createFromNbt'             StateSaverAndLoader::createFromNbt, // If there is a 'StateSaverAndLoader' NBT, parse it with 'createFromNbt'
Line 182: Line 183:
     public static StateSaverAndLoader getServerState(MinecraftServer server) {     public static StateSaverAndLoader getServerState(MinecraftServer server) {
         // (Note: arbitrary choice to use 'World.OVERWORLD' instead of 'World.END' or 'World.NETHER' Any work)         // (Note: arbitrary choice to use 'World.OVERWORLD' instead of 'World.END' or 'World.NETHER' Any work)
-        PersistentStateManager persistentStateManager = server.getWorld(World.OVERWORLD).getPersistentStateManager();+        ServerWorld serverWorld = server.getWorld(World.OVERWORLD)
 +        assert serverWorld != null;
  
         // The first time the following 'getOrCreate' function is called, it creates a brand new 'StateSaverAndLoader' and         // The first time the following 'getOrCreate' function is called, it creates a brand new 'StateSaverAndLoader' and
         // stores it inside the 'PersistentStateManager'. The subsequent calls to 'getOrCreate' pass in the saved         // stores it inside the 'PersistentStateManager'. The subsequent calls to 'getOrCreate' pass in the saved
         // 'StateSaverAndLoader' NBT on disk to our function 'StateSaverAndLoader::createFromNbt'.         // 'StateSaverAndLoader' NBT on disk to our function 'StateSaverAndLoader::createFromNbt'.
-        StateSaverAndLoader state = persistentStateManager.getOrCreate(type, ExampleMod.MOD_ID);+        StateSaverAndLoader state = serverWorld.getPersistentStateManager().getOrCreate(type, ExampleMod.MOD_ID);
  
         // If state is not marked dirty, when Minecraft closes, 'writeNbt' won't be called and therefore nothing will be saved.         // If state is not marked dirty, when Minecraft closes, 'writeNbt' won't be called and therefore nothing will be saved.
Line 205: Line 207:
 <code java> <code java>
 import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
 +import net.minecraft.registry.RegistryWrapper;
 import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
 +import net.minecraft.server.world.ServerWorld;
 import net.minecraft.world.PersistentState; import net.minecraft.world.PersistentState;
-import net.minecraft.world.PersistentStateManager; 
 import net.minecraft.world.World; import net.minecraft.world.World;
  
Line 215: Line 218:
  
     @Override     @Override
-    public NbtCompound writeNbt(NbtCompound nbt) {+    public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registries) {
         nbt.putInt("totalDirtBlocksBroken", totalDirtBlocksBroken);         nbt.putInt("totalDirtBlocksBroken", totalDirtBlocksBroken);
         return nbt;         return nbt;
Line 225: Line 228:
         return state;         return state;
     }     }
-    +
     public static StateSaverAndLoader createNew() {     public static StateSaverAndLoader createNew() {
         StateSaverAndLoader state = new StateSaverAndLoader();         StateSaverAndLoader state = new StateSaverAndLoader();
Line 232: Line 235:
     }     }
  
-    private static Type<StateSaverAndLoader> type = new Type<>(+    private static final Type<StateSaverAndLoader> type = new Type<>(
             StateSaverAndLoader::createNew, // If there's no 'StateSaverAndLoader' yet create one and refresh variables             StateSaverAndLoader::createNew, // If there's no 'StateSaverAndLoader' yet create one and refresh variables
             StateSaverAndLoader::createFromNbt, // If there is a 'StateSaverAndLoader' NBT, parse it with 'createFromNbt'             StateSaverAndLoader::createFromNbt, // If there is a 'StateSaverAndLoader' NBT, parse it with 'createFromNbt'
Line 240: Line 243:
     public static StateSaverAndLoader getServerState(MinecraftServer server) {     public static StateSaverAndLoader getServerState(MinecraftServer server) {
         // (Note: arbitrary choice to use 'World.OVERWORLD' instead of 'World.END' or 'World.NETHER' Any work)         // (Note: arbitrary choice to use 'World.OVERWORLD' instead of 'World.END' or 'World.NETHER' Any work)
-        PersistentStateManager persistentStateManager = server.getWorld(World.OVERWORLD).getPersistentStateManager();+        ServerWorld serverWorld = server.getWorld(World.OVERWORLD)
 +        assert serverWorld != null;
  
         // The first time the following 'getOrCreate' function is called, it creates a brand new 'StateSaverAndLoader' and         // The first time the following 'getOrCreate' function is called, it creates a brand new 'StateSaverAndLoader' and
         // stores it inside the 'PersistentStateManager'. The subsequent calls to 'getOrCreate' pass in the saved         // stores it inside the 'PersistentStateManager'. The subsequent calls to 'getOrCreate' pass in the saved
         // 'StateSaverAndLoader' NBT on disk to our function 'StateSaverAndLoader::createFromNbt'.         // 'StateSaverAndLoader' NBT on disk to our function 'StateSaverAndLoader::createFromNbt'.
-        StateSaverAndLoader state = persistentStateManager.getOrCreate(type, ExampleMod.MOD_ID);+        StateSaverAndLoader state = serverWorld.getPersistentStateManager().getOrCreate(type, ExampleMod.MOD_ID);
  
         // If state is not marked dirty, when Minecraft closes, 'writeNbt' won't be called and therefore nothing will be saved.         // If state is not marked dirty, when Minecraft closes, 'writeNbt' won't be called and therefore nothing will be saved.
Line 264: Line 268:
 import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
 import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents; import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
-import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
-import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;+
 import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
 import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
-import net.minecraft.network.PacketByteBuf; 
 import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
-import net.minecraft.util.Identifier; 
  
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
  
-    public static final String MOD_ID = "your_unique_mod_id_change_me_please";+    public static final String MOD_ID = "examplemod";
  
-    public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID"dirt_broken");+    public void onInitialize() { 
 +        PayloadTypeRegistry.playS2C().register(DirtBrokenPayload.IDDirtBrokenPayload.CODEC);
  
-    @Override 
-    public void onInitialize() { 
         PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {         PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {
             if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) {             if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) {
-                StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(world.getServer()); 
-                // Increment the amount of dirt blocks that have been broken 
-                serverState.totalDirtBlocksBroken += 1; 
- 
                 // Send a packet to the client                 // Send a packet to the client
                 MinecraftServer server = world.getServer();                 MinecraftServer server = world.getServer();
 +                assert server != null;
  
-                PacketByteBuf data PacketByteBufs.create(); +                // Increment the amount of dirt blocks that have been broken 
-                data.writeInt(serverState.totalDirtBlocksBroken);+                StateSaverAndLoader serverState StateSaverAndLoader.getServerState(server); 
 +                serverState.totalDirtBlocksBroken += 1;
  
                 ServerPlayerEntity playerEntity = server.getPlayerManager().getPlayer(player.getUuid());                 ServerPlayerEntity playerEntity = server.getPlayerManager().getPlayer(player.getUuid());
                 server.execute(() -> {                 server.execute(() -> {
-                    ServerPlayNetworking.send(playerEntity, DIRT_BROKEN, data);+                    assert playerEntity != null; 
 +                    ServerPlayNetworking.send(playerEntity, new DirtBrokenPayload(serverState.totalDirtBlocksBroken));
                 });                 });
             }             }
Line 379: Line 378:
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
  
-    public static final String MOD_ID = "your_unique_mod_id_change_me_please";+    public static final String MOD_ID = "examplemod";
  
     public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, "dirt_broken");     public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, "dirt_broken");
Line 387: Line 386:
         PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {         PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {
             if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) {             if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) {
-                StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(world.getServer());+                // Send a packet to the client 
 +                MinecraftServer server = world.getServer(); 
 +                assert server != null; 
 +                 
 +                StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(server);
                 // Increment the amount of dirt blocks that have been broken                 // Increment the amount of dirt blocks that have been broken
                 serverState.totalDirtBlocksBroken += 1;                 serverState.totalDirtBlocksBroken += 1;
Line 393: Line 396:
                 PlayerData playerState = StateSaverAndLoader.getPlayerState(player);                 PlayerData playerState = StateSaverAndLoader.getPlayerState(player);
                 playerState.dirtBlocksBroken += 1;                 playerState.dirtBlocksBroken += 1;
- 
-                // Send a packet to the client 
-                MinecraftServer server = world.getServer(); 
  
                 PacketByteBuf data = PacketByteBufs.create();                 PacketByteBuf data = PacketByteBufs.create();
Line 614: Line 614:
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
  
-    public static final String MOD_ID = "your_unique_mod_id_change_me_please";+    public static final String MOD_ID = "examplemod";
  
     public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, "dirt_broken");     public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, "dirt_broken");
Line 633: Line 633:
         PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {         PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {
             if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) {             if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) {
-                StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(world.getServer());+                // Send a packet to the client 
 +                MinecraftServer server = world.getServer(); 
 +                assert server != null; 
 +                 
 +                StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(server);
                 // Increment the amount of dirt blocks that have been broken                 // Increment the amount of dirt blocks that have been broken
                 serverState.totalDirtBlocksBroken += 1;                 serverState.totalDirtBlocksBroken += 1;
Line 639: Line 643:
                 PlayerData playerState = StateSaverAndLoader.getPlayerState(player);                 PlayerData playerState = StateSaverAndLoader.getPlayerState(player);
                 playerState.dirtBlocksBroken += 1;                 playerState.dirtBlocksBroken += 1;
- 
-                // Send a packet to the client 
-                MinecraftServer server = world.getServer(); 
  
                 PacketByteBuf data = PacketByteBufs.create();                 PacketByteBuf data = PacketByteBufs.create();
Line 881: Line 882:
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
  
-    public static final String MOD_ID = "your_unique_mod_id_change_me_please";+    public static final String MOD_ID = "examplemod";
  
     public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, "dirt_broken");     public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, "dirt_broken");
Line 900: Line 901:
         PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {         PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {
             if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) {             if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) {
-                StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(world.getServer());+                // Send a packet to the client 
 +                MinecraftServer server = world.getServer(); 
 +                assert server != null; 
 +                 
 +                StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(server);
                 // Increment the amount of dirt blocks that have been broken                 // Increment the amount of dirt blocks that have been broken
                 serverState.totalDirtBlocksBroken += 1;                 serverState.totalDirtBlocksBroken += 1;
Line 906: Line 911:
                 PlayerData playerState = StateSaverAndLoader.getPlayerState(player);                 PlayerData playerState = StateSaverAndLoader.getPlayerState(player);
                 playerState.dirtBlocksBroken += 1;                 playerState.dirtBlocksBroken += 1;
- 
-                // Send a packet to the client 
-                MinecraftServer server = world.getServer(); 
  
                 PacketByteBuf data = PacketByteBufs.create();                 PacketByteBuf data = PacketByteBufs.create();
tutorial/persistent_states.1741799907.txt.gz · Last modified: 2025/03/12 17:18 by lakazatong