Posted November 20, 20213 yr This is my capability provider. public class MyCapabilityProvider implements ICapabilitySerializable<INBT> { @CapabilityInject(IMyCapability.class) public static Capability<IMyCapability> My_CAPABILITY = null; private final LazyOptional<IMyCapability> lazyOptional = LazyOptional.of(MyCapability::new); @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction side) { if (capability == My_CAPABILITY) { return lazyOptional.cast(); } return LazyOptional.empty(); } @Override public INBT serializeNBT() { return My_CAPABILITY.getStorage().writeNBT(My_CAPABILITY, lazyOptional.orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!")), null); } @Override public void deserializeNBT(INBT nbt) { My_CAPABILITY.getStorage().readNBT(My_CAPABILITY, lazyOptional.orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!")), null, nbt); } } The issue is that the values written to the disk are the default values for my capability data. I added some logging to the storage class, and this confirms it. Why is that happening?
November 20, 20213 yr Author 3 minutes ago, diesieben07 said: Show where you are changing the values. I am actually changing it in many places. My interface accesses the capability on the player to draw it. This is where it gets updated on the server: public static void handlePacket(ClientSyncOverlayMessage message, Supplier<NetworkEvent.Context> ctx) { LogManager.getLogger().info("Got sync overlay message! Selected: " + message.getSelectedTechnique().getId() + " nature: " + message.getSelectedTechnique().getNature()); ServerPlayerEntity playerEntity = ctx.get().getSender(); playerEntity.getCapability(TechniqueCapabilityProvider.Technique_CAPABILITY).ifPresent(TechniqueCapability -> { TechniqueCapability.setSelectedTechniqueFor(message.getSelectedTechnique().getNature(), message.getSelectedTechnique()); LOGGER.info("Updated selected Technique to " + message.getSelectedTechnique().getId() + ", power level: " + message.getSelectedTechnique().getPower()); LOGGER.info("PW after update: " + TechniqueCapability.getSelectedTechniqueFor(TechniqueCapability.getSelectedNatureOrDefault()).getPower()); }); } P.S i renamed the capability to TechniqueCapability in this example. Edited November 20, 20213 yr by matthew123
November 21, 20213 yr Author 12 hours ago, diesieben07 said: Examples are not useful, as the issue is with your code, not with some example. Is this code executed? Does it do the correct thing? The code above is used to synchronize the capability on the server. The correct values are printed out by the logger, but when I check the values with NBTExplorer, they are the default ones. Thus, when re-joining the singleplayer world, the capability has the default values.
November 21, 20213 yr Author 1 hour ago, diesieben07 said: Are your NBT writing and reading methods called? Of course. But the logging i added to them indicates that default values are being written.
November 21, 20213 yr Author 1 hour ago, diesieben07 said: Are your NBT writing and reading methods called? To clarify, I added logging to the storage class (where writeNBT and readNBT are being called).
November 21, 20213 yr Author 17 hours ago, diesieben07 said: Show where you are changing the values. private static int executeCommand(CommandContext<CommandSource> commandContext) throws CommandSyntaxException { Entity entity = commandContext.getSource().getEntity(); TranslationTextComponent finalText = new TranslationTextComponent("chat.type.announcement", commandContext.getSource().getDisplayName(), new StringTextComponent("ok")); commandContext.getSource().getServer().getPlayerList().broadcastMessage(finalText, ChatType.CHAT, entity.getUUID()); ServerPlayerEntity playerEntity = commandContext.getSource().getPlayerOrException(); playerEntity.getCapability(AbilityCapabilityProvider.Ability_CAPABILITY).ifPresent(AbilityData -> { AbilityData.addAbility(NatureTypes.A, new AbilityData(NatureTypes.A, "mymod:a", 0, 0, 1)); AbilityData.addAbility(NatureTypes.A, new AbilityData(NatureTypes.A, "mymod:b", 0, 0, 1)); AbilityData.addAbility(NatureTypes.B, new AbilityData(NatureTypes.B, "mymod:c", 0, 0, 1)); AbilityData.addAbility(NatureTypes.B, new AbilityData(NatureTypes.B, "mymod:d", 0, 0, 1)); AbilityData.addAbility(NatureTypes.D, new AbilityData(NatureTypes.D, "mymod:e", 0, 0, 1)); AbilityData.addAbility(NatureTypes.E, new AbilityData(NatureTypes.E, "mymod:f", 0, 0, 1)); ModNetwork.sendTo(new ServerSyncAbilityMessage(AbilityData), playerEntity); ModNetwork.sendTo(new ServerSyncPowerMessage(42, 42), playerEntity); }); return 1; }
November 21, 20213 yr 5 minutes ago, matthew123 said: Would a git repo of my mod do any better? yes definitely
November 21, 20213 yr Author 12 minutes ago, Luis_ST said: yes definitely https://github.com/empireu/NarutoMod
November 22, 20213 yr Author 12 hours ago, diesieben07 said: From what I can tell it functions correctly. Your NBT format is absolutely bizarre though: Why on earth is "Selected Nature" in the same compound tag as all the Jutsu data? Why are you using spaces in the keys? Why on earth did you decide that putting "[SELECTED] " in front of the key was a good way to mark an entry as selected instead of just... you know... a boolean? Why on earth does JutsuData.serialize / deserialize use a random ad-hoc string format instead of, you know, serializing its values to a NBT compound tag? I am not sure how to serialize all of it to NBT. When my data was only using integers, I used an integer array, but that is not possible now. Could you show me how? Also, do you have recommendations on the capability? I believe that my current approach is very messy.
November 22, 20213 yr Author I think I am onto something! I started analyzing ItemStackHandler, and I found that they were using ListNBT. This satisfies all my needs. I guess vanilla code is the best learning resource.
November 23, 20213 yr Author 21 hours ago, diesieben07 said: Use a compound tag and put the individual values in individual keys. It looked fine except for the serialization... Is this better?
November 23, 20213 yr Author An issue still persists. It appears as if the power level is the only thing that is not serializing. The selected nature AND selected jutsu seems to be synchronizing fine, but the power level does not, even though it is clearly updated: The selected jutsu seems to work fine, as indicated by that bool and in-game testing. Thus, I added logging in the exact place the jutsu serializes it's power level: And then after updating values: What the hell is going on?! I am at a loss. Why is everything else working but that integer?
November 23, 20213 yr Author 8 hours ago, diesieben07 said: Why did you delete your Git repository? Why are you using random logger statements instead of the debugger? It is 2021, Java has had an extremely powerful debugger for ages. Use it! https://github.com/empireu/NarutoMod
November 23, 20213 yr Author 35 minutes ago, matthew123 said: https://github.com/empireu/NarutoMod It was never an issue with serialization, networking, ... . It was an issue with the capability class! It was updating only ONE of the 2 collections here: We both missed it.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.