Posted November 22, 20222 yr I'm trying to understand capabilities but since the "system" got recently renewed I can't find any tutorial about it and the forge documentation doesn't give me the info I need. As I understood there is an interface for the capability and a "handler" class which implements the interface. I got the following: interface: Spoiler @AutoRegisterCapability public interface IQuestStatus { /** * Saves values from a HashMap as NBT data * @param nbt */ public void saveNBTData(CompoundTag nbt); /** * Writes the saved NBT data into a HashMap * @param nbt */ public void loadNBTData(CompoundTag nbt); } handler: Spoiler public class QuestStatusHandler implements IQuestStatus, INBTSerializable<CompoundTag> { private HashMap<String, Boolean> questStatus = new HashMap<String, Boolean>(); private int questsInTotal = 1; public void saveNBTData(CompoundTag nbt) { /* the NBTData is structured like this: * (String questID, boolean value) * * value == true: quest is accepted * * value == false: quest is not accepted */ for(int i = 0; i < questStatus.size(); i++) { nbt.putBoolean("quest_"+i, questStatus.get("quest_"+i)); } } public void loadNBTData(CompoundTag nbt) { for(int i = 0; i < questsInTotal; i++) questStatus.put("quest_"+i, nbt.getBoolean("quest_"+i)); } @Override public CompoundTag serializeNBT() { CompoundTag nbt = new CompoundTag(); saveNBTData(nbt); return nbt; } @Override public void deserializeNBT(CompoundTag nbt) { loadNBTData(nbt); } } Now, first I wanna know how to load the NBT data when a Player connects and second, how to save the NBT data when a Player disconnects. Also I only need to change a value saved in the HashMap questStatus then, which is from player to player different right? If so is there any specific way I have to use or can I somehow access it from the player? Edited November 27, 20222 yr by Ezio214
November 22, 20222 yr https://forge.gemwire.uk/wiki/Capabilities Boilerplate: If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one. If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install Large files should be posted to a file sharing site like https://gist.github.com You should also read the support forum sticky post.
November 22, 20222 yr Author I don't get it. So I have my own capability interface and that needs to have the @AutoRegisterCapability annotation so the capability gets registered. My "Handler" class is the Implementation class of my own capability interface. Do I need now a Capability Provider (Persistent Provider) to access the values I stored or how do I do that?
November 22, 20222 yr Relook at that link. The information is there, including a whole worked example at the bottom on how to attach to an entity and store a "damageDealt" field. You don't need the first part if you are using the annotation for capability registration. There's also a separate page on that same wiki: https://forge.gemwire.uk/wiki/Capabilities/Attaching Boilerplate: If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one. If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install Large files should be posted to a file sharing site like https://gist.github.com You should also read the support forum sticky post.
November 24, 20222 yr Author So after looking again at the post and at the code example I got to something. I just didn't use the attach-method they have. Instead I used the following SubscribeEvent: Spoiler @SubscribeEvent public static void onAttachCapabilities(AttachCapabilitiesEvent<Entity> event) { if(event.getObject() instanceof Player) { if(!event.getObject().getCapability(QuestStatusProvider.INSTANCE).isPresent()) { System.out.println("[DEBUG]: >>>> attached QuestStatus-Capability to Player <<<<"); event.addCapability(QuestStatusProvider.IDENTIFIER, new QuestStatusProvider()); } } } which works. Thank you for that What I dont understand is how I can save the NBT-data and how I can modify it. Edited November 24, 20222 yr by Ezio214
November 24, 20222 yr Author After a very long (around 4 hours) brainstorm and trying out code without really understanding it, I found the answer. To anyone courios about how to modify NBT-data or even read it: // somewhere in your code where you need to read/modify the capability // for class structure see here: https://gist.github.com/TheCurle/6db954d680f6f067dcdc791355c32c89 player.getCapability(CustomCapabilityProvider.INSTANCE).ifPresent(capability -> { // change or read your capability here }; Still I dont know how to save the NBT-data when the player leaves his world/server. As soon as I know I'll let you all know. Edited November 24, 20222 yr by Ezio214
November 25, 20222 yr Author Found out that capabilities are saved automatically, I just didn't see that because my client and my server don't seem to synchronize. [12:44:08] [Server thread/INFO] [co.tu.MODID/]: [MODID_DEBUG] :: questStatus quest_0 from player is 1 [12:44:08] [Render thread/INFO] [co.tu.MODID/]: [MODID_DEBUG] :: questStatus quest_0 from player is 0 The Logger gives me this info when I right click my villager to open a Screen only if questStatus equals 0. As soon as I press a button on that Screen both, client and server, are set to 1 -> that works. But it seems like the nbt-data gets only loaded server-side. How can I load the same values for client-side?
November 25, 20222 yr Why do you keep asking questions that are answered in links to docs that have already been posted? https://forge.gemwire.uk/wiki/Capabilities/Attaching#Synchronizing_Data_with_Clients It makes me think I am wasting my time being your search engine, if you don't read the links I give you. 🙂 Your question has also been answered maybe a hundred times in this forum in various forms depending upon the use case. Boilerplate: If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one. If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install Large files should be posted to a file sharing site like https://gist.github.com You should also read the support forum sticky post.
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.