public class BoxScreenHandler extends ScreenHandler { private final Inventory inventory; PropertyDelegate propertyDelegate; //This constructor gets called on the client when the server wants it to open the screenHandler, //The client will call the super constructor with an empty Inventory and the screenHandler will automatically //sync this empty inventory with the inventory on the server //Similar to the inventory, the client will allocate an empty propertyDelegate which will be synced with the Server automatically public BoxScreenHandler(int syncId, PlayerInventory playerInventory) { this(syncId, playerInventory, new SimpleInventory(9),new ArrayPropertyDelegate(1)); } //This constructor gets called from the BlockEntity on the server, the server knows the inventory of the container //and can therefore directly provide it as an argument. This inventory aswell as the propertyDelegate will then be synced to the Client public BoxScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory, PropertyDelegate propertyDelegate) { super(Test.BOX_SCREEN_HANDLER, syncId); checkSize(inventory, 9); this.inventory = inventory; this.propertyDelegate = propertyDelegate; //some inventories do custom logic when a player opens it. inventory.onOpen(playerInventory.player); //we need to tell the screenhandler about our propertyDelegate, otherwise it will not sync the data inside. this.addProperties(propertyDelegate); //This will place the slot in the correct locations for a 3x3 Grid. The slots exist on both server and client! [...] } //we provide this getter for the synced integer so the Screen can access this to show it on screen public int getSyncedNumber(){ return propertyDelegate.get(0); } @Override public boolean canUse(PlayerEntity player) { return this.inventory.canPlayerUse(player); } @Override public ItemStack transferSlot(PlayerEntity player, int invSlot) {[...]} }