User Tools

Site Tools


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
Last revisionBoth sides next revision
tutorial:persistent_states [2023/09/28 05:37] – Add missing imports jmanc3tutorial:persistent_states [2024/01/11 06:44] – typo jmanc3
Line 104: Line 104:
 import net.minecraft.world.PersistentStateManager; import net.minecraft.world.PersistentStateManager;
 import net.minecraft.world.World; import net.minecraft.world.World;
-import net.minecraft.datafixer.DataFixTypes; 
  
 public class StateSaverAndLoader extends PersistentState { public class StateSaverAndLoader extends PersistentState {
Line 147: Line 146:
  
     // ... (Previously written code)     // ... (Previously written code)
 +
 +    private static Type<StateSaverAndLoader> type = new Type<>(
 +            StateSaverAndLoader::new, // If there's no 'StateSaverAndLoader' yet create one
 +            StateSaverAndLoader::createFromNbt, // If there is a 'StateSaverAndLoader' NBT, parse it with 'createFromNbt'
 +            null // Supposed to be an 'DataFixTypes' enum, but we can just pass null
 +    );
  
     public static StateSaverAndLoader getServerState(MinecraftServer server) {     public static StateSaverAndLoader getServerState(MinecraftServer server) {
Line 155: Line 160:
         // 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);
-        // (Note: 'DataFixTypes.LEVEL' is used as it's a required parameter but the decision to use 'DataFixTypes.LEVEL' specifically is arbitrary.) +
-        StateSaverAndLoader state = persistentStateManager.getOrCreate( +
-                new Type<>(StateSaverAndLoader::new, StateSaverAndLoader::createFromNbt, DataFixTypes.LEVEL), +
-                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 181: Line 182:
 import net.minecraft.world.PersistentStateManager; import net.minecraft.world.PersistentStateManager;
 import net.minecraft.world.World; import net.minecraft.world.World;
-import net.minecraft.datafixer.DataFixTypes; 
  
 public class StateSaverAndLoader extends PersistentState { public class StateSaverAndLoader extends PersistentState {
Line 198: Line 198:
         return state;         return state;
     }     }
 +
 +    private static Type<StateSaverAndLoader> type = new Type<>(
 +            StateSaverAndLoader::new, // If there's no 'StateSaverAndLoader' yet create one
 +            StateSaverAndLoader::createFromNbt, // If there is a 'StateSaverAndLoader' NBT, parse it with 'createFromNbt'
 +            null // Supposed to be an 'DataFixTypes' enum, but we can just pass null
 +    );
  
     public static StateSaverAndLoader getServerState(MinecraftServer server) {     public static StateSaverAndLoader getServerState(MinecraftServer server) {
Line 206: Line 212:
         // 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);
-        // (Note: 'DataFixTypes.LEVEL' is used as it's a required parameter but the decision to use 'DataFixTypes.LEVEL' specifically is arbitrary.) +
-        StateSaverAndLoader state = persistentStateManager.getOrCreate( +
-                new Type<>(StateSaverAndLoader::new, StateSaverAndLoader::createFromNbt, DataFixTypes.LEVEL), +
-                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 457: Line 459:
 import net.minecraft.world.PersistentStateManager; import net.minecraft.world.PersistentStateManager;
 import net.minecraft.world.World; import net.minecraft.world.World;
-import net.minecraft.datafixer.DataFixTypes; 
  
 import java.util.HashMap; import java.util.HashMap;
Line 501: Line 502:
         return state;         return state;
     }     }
 +
 +    private static Type<StateSaverAndLoader> type = new Type<>(
 +            StateSaverAndLoader::new, // If there's no 'StateSaverAndLoader' yet create one
 +            StateSaverAndLoader::createFromNbt, // If there is a 'StateSaverAndLoader' NBT, parse it with 'createFromNbt'
 +            null // Supposed to be an 'DataFixTypes' enum, but we can just pass null
 +    );
  
     public static StateSaverAndLoader getServerState(MinecraftServer server) {     public static StateSaverAndLoader getServerState(MinecraftServer server) {
Line 509: Line 516:
         // 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);
-        // (Note: 'DataFixTypes.LEVEL' is used as it's a required parameter but the decision to use 'DataFixTypes.LEVEL' specifically is arbitrary.) +
-        StateSaverAndLoader state = persistentStateManager.getOrCreate( +
-                new Type<>(StateSaverAndLoader::new, StateSaverAndLoader::createFromNbt, DataFixTypes.LEVEL), +
-                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 538: Line 541:
 Running the client now, all our player-specific data is correctly saved. Running the client now, all our player-specific data is correctly saved.
  
-  Note: each time you restart the minecraft client with fabric, you're assigned a new UUID, so it may seem like it'not working, but that'just because of the developer environment(If you run the fabric multiplayer server, 'Minecraft Server' and use authme, you could verify it does indeed work as it's supposed to.)+==== Important Caveat ==== 
 + 
 +  Each time you restart the minecraft client with fabric, you're assigned a new random UUID each launch, so it may seem like our code is not working because it'pulling data for a new UUID never before seen. If you want to verify everything is working correctlydownload [[https://www.curseforge.com/minecraft/mc-mods/auth-me|AuthMe]] and drop the ''AuthMe.jar'' into run/mods. Login to your Minecraft account from the multiplayer screen. This will now change the random UUID to your actual UUID and therefore you can test if the data is correctly saved and associated with one UUID even across restarts. (You don't have to keep doing this, once you've verified once that, if the UUID is the same across launches, the data is correctly saved, you can just develop the mod normally safe in the knowledge that your data will be saved)
  
 Just remember if you add new fields to ''**PlayerData**'' or ''**StateSaveAndLoader**'' you need to correctly do the work of writing and loading those fields in the ''**writeNbt**'' and ''**createFromNbt**'' functions //always//. If you forget this step, your data won't be properly saved or loaded from disk. Just remember if you add new fields to ''**PlayerData**'' or ''**StateSaveAndLoader**'' you need to correctly do the work of writing and loading those fields in the ''**writeNbt**'' and ''**createFromNbt**'' functions //always//. If you forget this step, your data won't be properly saved or loaded from disk.
Line 643: Line 648:
   * Note: The ''**playerData**'' we created isn't the up-to-date one that lives on the server. We simply create our own copy of ''**PlayerData**'' client-side and update it as we receive packets. Since it's ''**public static**'' that means you can access it from anywhere on the client.   * Note: The ''**playerData**'' we created isn't the up-to-date one that lives on the server. We simply create our own copy of ''**PlayerData**'' client-side and update it as we receive packets. Since it's ''**public static**'' that means you can access it from anywhere on the client.
  
-  Note: each time you restart the minecraft client with fabric, you're assigned a new UUID, so it may seem like it'not working, but that'just because of the developer environment(If you run the fabric multiplayer server, 'Minecraft Server' and use authme, you could verify it does indeed work as it's supposed to.)+==== Important Caveat ==== 
 + 
 +  Each time you restart the minecraft client with fabric, you're assigned a new random UUID each launch, so it may seem like our code is not working because it'pulling data for a new UUID never before seen. If you want to verify everything is working correctlydownload [[https://www.curseforge.com/minecraft/mc-mods/auth-me|AuthMe]] and drop the ''AuthMe.jar'' into run/mods. Login to your Minecraft account from the multiplayer screen. This will now change the random UUID to your actual UUID and therefore you can test if the data is correctly saved and associated with one UUID even across restarts. (You don't have to keep doing this, once you've verified once that, if the UUID is the same across launches, the data is correctly saved, you can just develop the mod normally safe in the knowledge that your data will be saved)
  
 ====== More Involved Player Data ====== ====== More Involved Player Data ======
Line 674: Line 681:
 import net.minecraft.world.PersistentStateManager; import net.minecraft.world.PersistentStateManager;
 import net.minecraft.world.World; import net.minecraft.world.World;
-import net.minecraft.datafixer.DataFixTypes; 
  
 import java.util.HashMap; import java.util.HashMap;
Line 735: Line 741:
         return state;         return state;
     }     }
 +
 +    private static Type<StateSaverAndLoader> type = new Type<>(
 +            StateSaverAndLoader::new, // If there's no 'StateSaverAndLoader' yet create one
 +            StateSaverAndLoader::createFromNbt, // If there is a 'StateSaverAndLoader' NBT, parse it with 'createFromNbt'
 +            null // Supposed to be an 'DataFixTypes' enum, but we can just pass null
 +    );
  
     public static StateSaverAndLoader getServerState(MinecraftServer server) {     public static StateSaverAndLoader getServerState(MinecraftServer server) {
Line 743: Line 755:
         // 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);
-        // (Note: 'DataFixTypes.LEVEL' is used as it's a required parameter but the decision to use 'DataFixTypes.LEVEL' specifically is arbitrary.) +
-        StateSaverAndLoader state = persistentStateManager.getOrCreate( +
-                new Type<>(StateSaverAndLoader::new, StateSaverAndLoader::createFromNbt, DataFixTypes.LEVEL), +
-                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.
tutorial/persistent_states.txt · Last modified: 2024/04/25 14:06 by mayaqq