User Tools

Site Tools


tutorial:blockentity_modify_data

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
tutorial:blockentity_modify_data [2025/04/01 12:48] – [Some notes about NbtCompound] solidblocktutorial:blockentity_modify_data [2025/06/11 16:07] (current) – update solidblock
Line 52: Line 52:
 ===== Serializing Data ===== ===== Serializing Data =====
  
-If you want to store any data in your ''BlockEntity'', you will need to save and load it, or it will only be held while the ''BlockEntity'' is loaded, and the data will reset whenever you come back to it. Luckily, saving and loading is quite simple - you only need to override ''writeNbt()'' and ''readNbt()''+If you want to store any data in your ''BlockEntity'', you will need to save and load it, or it will only be held while the ''BlockEntity'' is loaded, and the data will reset whenever you come back to it. Luckily, saving and loading is quite simple - you only need to override ''writeNbt()''/''writeData()'' and ''readNbt()''/''readData()''
  
-''writeNbt()'' modifies the parameter ''nbt'', which should contain all of the data in your block entity. It usually does not modify the block entity object itself. The NBT is saved to the disk, and if you need to sync your block entity data with clients, also sent through packets.+''writeNbt()''/''writeData()'' modifies the parameter ''nbt'', which should contain all of the data in your block entity. It usually does not modify the block entity object itself. The NBT is saved to the disk, and if you need to sync your block entity data with clients, also sent through packets.
  
 In older versions, it was very important to call ''super.writeNbt'', which saves the position and id of the block entity to the nbt. Without this, any further data you try and save would be lost as it is not associated with a position and ''BlockEntityType''. However, latest versions do not require it, as they will be handled through ''createNbt()'' method. In older versions, it was very important to call ''super.writeNbt'', which saves the position and id of the block entity to the nbt. Without this, any further data you try and save would be lost as it is not associated with a position and ''BlockEntityType''. However, latest versions do not require it, as they will be handled through ''createNbt()'' method.
Line 60: Line 60:
 Knowing this, the example below demonstrates saving an integer from your ''BlockEntity'' to the nbt. In the example, the integer is saved under the key ''"number"'' - you can replace this with any string, but you can only have one entry for each key in your nbt, and you will need to remember the key in order to read the data later. Knowing this, the example below demonstrates saving an integer from your ''BlockEntity'' to the nbt. In the example, the integer is saved under the key ''"number"'' - you can replace this with any string, but you can only have one entry for each key in your nbt, and you will need to remember the key in order to read the data later.
  
 +//For versions 1.21.5 and before://
 <code java DemoBlockEntity.java> <code java DemoBlockEntity.java>
 public class DemoBlockEntity extends BlockEntity { public class DemoBlockEntity extends BlockEntity {
Line 74: Line 75:
     public void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registries) {     public void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registries) {
         // Save the current value of the number to the nbt         // Save the current value of the number to the nbt
-        nbt.putInt("number", number); 
- 
         super.writeNbt(nbt, registries);         super.writeNbt(nbt, registries);
 +        nbt.putInt("number", number);
     }     }
 } }
 </code> </code>
  
-In order to read the data, you will also need to override ''readNbt''This method is the opposite of ''writeNbt'' - instead of saving your data to a ''NBTCompound'', you are given the nbt data which you saved earlier, enabling you to retrieve any data that you need. It modifies the block entity object itself, instead of the ''nbt''To read the number we saved earlier in the nbtsee the example below.+//For versions 1.21.6 and after:// 
 +<code java> 
 +    @Override 
 +    public void writeData(WriteView view) { 
 +        super.writeData(view); 
 +        // Save the current value of the number to the nbt 
 +        view.putInt("number"number); 
 +    }
  
 +</code>
 +
 +In order to read the data, you will also need to override ''readNbt''/''readData''. This method is the opposite of ''writeNbt''/''writeData'' - instead of saving your data to a ''NBTCompound'', you are given the nbt data which you saved earlier, enabling you to retrieve any data that you need. It modifies the block entity object itself, instead of the ''nbt''. To read the number we saved earlier in the nbt, see the example below.
 +
 +//For versions 1.21.5 and before://
 <code java> <code java>
     // Deserialize the BlockEntity     // Deserialize the BlockEntity
Line 90: Line 102:
                  
         number = nbt.getInt("number", 0);         number = nbt.getInt("number", 0);
 +    }
 +</code>
 +
 +//For versions 1.21.6 and after://
 +<code java>
 +    @Override
 +    public void readData(ReadView view) {
 +        super.readData(ReadView view);
 +        
 +        number = view.getInt("number", 0);
     }     }
 </code> </code>
Line 111: Line 133:
  
   @Override   @Override
-  public NbtCompound toInitialChunkDataNbt(RegistryWrapper.WrapperLookup registryLookup) { +  public NbtCompound toInitialChunkDataNbt(RegistryWrapper.WrapperLookup registries) { 
-    return createNbt(registryLookup);+    return createNbt(registries);
   }   }
 </code> </code>
Line 125: Line 147:
     }     }
    
 +    // The following two methods are changed since 1.21.6, see the examples above.
     @Override     @Override
     public void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registries) {     public void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registries) {
 +        super.writeNbt(nbt, registries);
         nbt.putInt("number", number);         nbt.putInt("number", number);
-  
-        super.writeNbt(nbt, registries); 
     }     }
          
Line 225: Line 247:
   }   }
  
 +  // For versions 1.21.5 and before:
   @Override   @Override
   public void removeFromCopiedStackNbt(NbtCompound nbt) {   public void removeFromCopiedStackNbt(NbtCompound nbt) {
     nbt.remove("number");     nbt.remove("number");
 +  }
 +  
 +  // For versions 1.21.6 and after:
 +  @Override
 +  public void removeFromCopiedStackData(WriteView view) {
 +    view.remove("number");
   }   }
 </code> </code>
  
-The usage of ''removeFromCopiedStackNbt'' is, when copying item stacks, as the components are already copied, the nbts are no longer needed. If you pick stack (which means press the mouse wheel to the block write pressing ''Ctrl''), the components will be transferred to the stack. If you need to transfer the components when pick blocks even if you do not hold ''Ctrl'' (like the behavior of vanilla banner blocks), see [[blockentity_sync_itemstack]].+The usage of ''removeFromCopiedStackNbt''/''removeFromCopiedStackData'' is, when copying item stacks, as the components are already copied, the nbts are no longer needed. If you pick stack (which means press the mouse wheel to the block write pressing ''Ctrl''), the components will be transferred to the stack. If you need to transfer the components when pick blocks even if you do not hold ''Ctrl'' (like the behavior of vanilla banner blocks), see [[blockentity_sync_itemstack]].
tutorial/blockentity_modify_data.txt · Last modified: 2025/06/11 16:07 by solidblock