Jump to content

[1.12.x] Keeping track of entity data


NovaViper

Recommended Posts

I'm trying to figure out how to get a player's Doggy Talents dogs and have all of their information saved on a separate file on the machine; and finally, when the player use the whistle item to call their dogs, it should (basically) recreate the dog using the data that was saved previously and have the 'new' dog spawn around the either the dog's owner or whoever used the whistle. However, there is some issues i need addressed, which are the following below:

  • What would be the best and most reasonable way of doing this
  • How can I actually save what is inside the dog's inventory, as the dogs do possess the ability to carry things (if they have the talent of course), in the same manner as the vanilla Donkey/Horse does.
  • How often this should save, as to avoid data lost in case a player accidentally calls the dog before the data was saved or if the dog despawns
  • How should this method deal with non-owner players (those whom do not own the dog, but the owner has allowed the dog to be manipulated by others.

I did in a previous attempt make a way to call the dogs, but it did not account for despawning due to the chunk where the dog is located at being despawned. Here is the repo in 1.12.2: https://github.com/ProPercivalalb/DoggyTalents/tree/master/src-mc-universal

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

Well, Minecraft is just Java so all the file I/O libraries are available. So you could just come up with your own file format. But you could also hook into some of the built-in formats to help you. For example, if you have the data in NBT already then there are already methods for writing and reading NBT.

 

But do you really need to store these in a separate file? Because you can also put all this stuff into a world save data instance and have that saved together with the regular game saves. Thanks to diesieben07 for this tip.

 

There is are built in classes for saving data: WorldSavedData. How you do it depends if you want to store it per-dimension (different data for e.g. nether and overworld, these are two World instances in the code) or per save-file (same data for all dimensions).  For the former use world.perWorldStorage, otherwise use world.mapStorage.

Warning: Be sure to always call markDirty() on your data when you change a value, otherwise Minecraft will not save it.
 

You can see diesieben07's simple example here: WorldSaveData example cod

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

16 minutes ago, jabelar said:

Well, Minecraft is just Java so all the file I/O libraries are available. So you could just come up with your own file format. But you could also hook into some of the built-in formats to help you. For example, if you have the data in NBT already then there are already methods for writing and reading NBT.

 

But do you really need to store these in a separate file? Because you can also put all this stuff into a world save data instance and have that saved together with the regular game saves. Thanks to diesieben07 for this tip.

 

There is are built in classes for saving data: WorldSavedData. How you do it depends if you want to store it per-dimension (different data for e.g. nether and overworld, these are two World instances in the code) or per save-file (same data for all dimensions).  For the former use world.perWorldStorage, otherwise use world.mapStorage.

Warning: Be sure to always call markDirty() on your data when you change a value, otherwise Minecraft will not save it.
 

You can see diesieben07's simple example here: WorldSaveData example cod

I feel the best way to store the data per-dimension basis.

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

3 minutes ago, NovaViper said:

I feel the best way to store the data per-dimension basis.

Well, it depends on how your mod works. If you store it per-dimension then if you whistle for your dog while in the Nether you will only get dogs saved in the Nether.

 

In any case, the point is that is it very simple to save additional custom data to the world save file. NBT format is quite suitable for that. So then you just need to write the methods to take the data and put it into NBT and read it back. For the most part it should be fairly easy, although sometimes using NBT with lots of compounds and lists can be a bit confusing. So just work through it carefully. The concept is simple, but the details are important when dealing with files.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

  • 6 months later...

I know it has been a while since I've commented on this, but this is what the main developer has came up with so far. However, he hasn't been able to finish the implementation of the WorldSave data class, so I'm trying to pick up on where he left off. So far, he got the dog's location to actually save, but I haven't been able to figure out how the remove the location data when the dog dies or the owner untames it. I'm also trying to figure out what would be the best possible way to basically create a dog that contains all of the data of the original dog (with all the talent data, and the data that's within the talent, PackPuppy since it actually creates a Container to store items like a chest).

This gist contains all of the files of the current progress so far: https://gist.github.com/NovaViper/5364aebd06bb9c2f704e89f1a2878512

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

9 hours ago, diesieben07 said:

Death: EntityLivingBase#onDeath.

Untaming: Well, just do it when you run the untaming code, I don't know where you do that.

I mean I'm not sure how to actually remove the data out of the storage all together, I did create a piece of code, but because I never really messed around with storing data and such in Minecraft, I'm not exactly sure where to start off with it:

 

	public void removeDog(EntityDog dog) {
		DogLocation temp = new DogLocation(dog);

/*		for (int i = 0; i < this.locations.size(); i++) {
			DogLocation loc = this.locations.get(i);

			if (loc.equals(temp)) {
				this.locations.remove(i);
				this.markDirty();
				return;
			}
		}*/

		this.locations.remove(temp);
		this.markDirty();
	}

 

--Edit--

Nevermind, I just got the code working. Now my issue is trying to figure out how to actually store all of the data that the dog has in the NBT (from the talents to its storage containers that is created from the talents).

Edited by NovaViper

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

Hm.. strangely enough, whenever the dog dies, it doesn't get removed from the World Storage.. as the debug item I'm using (the radar item) checks the queue size (it should start off as 0) seems to have it stored (it says 1 entry is stored instead of 0) while when I untame the dog, the dog gets purged from the storage

 

https://gist.github.com/NovaViper/5364aebd06bb9c2f704e89f1a2878512

 

--Edit--

I figured out it. I discovered that because the LivingUpdate method is almost constantly running, even when the dog died, the LivingUpdate section ran (which loaded the dog's data again)

Edited by NovaViper

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

@diesieben07 I made several changes (following your advice with using the uniqueID method instead of the former) since earlier today and this warning starting coming up.

[17:32:04] [Server thread/WARN] [minecraft/EntityDataManager]: defineId called for: class doggytalents.entity.EntityDog from class doggytalents.entity.DogDataTracker

 

Also, whenever the dogs end up being sent to another dimension (say the nether or the end) while I remain in the original dimension they were in, I get this error when trying to use the radar item to locate them:

 

[17:42:42] [Server thread/FATAL] [minecraft/MinecraftServer]: Error executing task
java.util.concurrent.ExecutionException: java.lang.NullPointerException
	at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[?:1.8.0_191]
	at java.util.concurrent.FutureTask.get(FutureTask.java:192) ~[?:1.8.0_191]
	at net.minecraft.util.Util.runTask(Util.java:54) [Util.class:?]
	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:798) [MinecraftServer.class:?]
	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:743) [MinecraftServer.class:?]
	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192) [IntegratedServer.class:?]
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:592) [MinecraftServer.class:?]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_191]
Caused by: java.lang.NullPointerException
	at doggytalents.helper.DogLocationManager$DogLocation.getDog(DogLocationManager.java:173) ~[DogLocationManager$DogLocation.class:?]
	at doggytalents.item.ItemRadar.onItemRightClick(ItemRadar.java:43) ~[ItemRadar.class:?]
	at net.minecraft.item.ItemStack.useItemRightClick(ItemStack.java:234) ~[ItemStack.class:?]
	at net.minecraft.server.management.PlayerInteractionManager.processRightClick(PlayerInteractionManager.java:384) ~[PlayerInteractionManager.class:?]
	at net.minecraft.network.NetHandlerPlayServer.processTryUseItem(NetHandlerPlayServer.java:796) ~[NetHandlerPlayServer.class:?]
	at net.minecraft.network.play.client.CPacketPlayerTryUseItem.processPacket(CPacketPlayerTryUseItem.java:43) ~[CPacketPlayerTryUseItem.class:?]
	at net.minecraft.network.play.client.CPacketPlayerTryUseItem.processPacket(CPacketPlayerTryUseItem.java:9) ~[CPacketPlayerTryUseItem.class:?]
	at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:21) ~[PacketThreadUtil$1.class:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_191]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_191]
	at net.minecraft.util.Util.runTask(Util.java:53) ~[Util.class:?]
	... 5 more

 

 

Here are the changes I made: https://gist.github.com/NovaViper/5364aebd06bb9c2f704e89f1a2878512/51d0950e50f956d4db5b6e2ce49965e42c7961d1

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

2 minutes ago, diesieben07 said:

Your code is not even syntax-highlighted... But for something complicated like this I would need a working Git repository to actually debug this. Which you should also do, by the way. The debugger works wonders.

Alrighty, here's the link to the specific commit I just added to Github: https://github.com/percivalalb/DoggyTalents/commit/6590b944d4656f0e284d336a838d1cf4f752fc38

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

I noticed another strange issue, whenever the dog gets sent to another dimension, it ends up adding itself twice to the location manager list, and its AI seems to respond at a slowed rate than before (sometimes its AI doesn't execute at all)

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

Have you stepped through the execution with the debugger?

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

The debugger is an essential and amazingly powerful tool.

http://www.vogella.com/tutorials/EclipseDebugging/article.html

place a breakpoint and then step through the execution

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

23 hours ago, Cadiboo said:

The debugger is an essential and amazingly powerful tool.

http://www.vogella.com/tutorials/EclipseDebugging/article.html

place a breakpoint and then step through the execution

It didn't really help me that much trying to debug it

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

Hm.. I am noticing that the debugger is throwing this error after removing one of the dogs:

 

locationManager.locations.get(1) = {IndexOutOfBoundsException@10226} Method threw 'java.lang.IndexOutOfBoundsException' exception.
 detailMessage = "Index: 1, Size: 1"
 cause = {IndexOutOfBoundsException@10226} "java.lang.IndexOutOfBoundsException: Index: 1, Size: 1"
 stackTrace = {StackTraceElement[18]@10389} 
 suppressedExceptions = {Collections$UnmodifiableRandomAccessList@10386}  size = 0

 And this one whenever I use the radar item at all:

Cannot find local variable 'loc'

 

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.