Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Best way to store non-volatile data in a custom entity


squidlex
 Share

Recommended Posts

I was wondering what the best way to store persistent data in an entity is.

Right now, I'm attaching a custom capability to my entity and attempting to store the capability's data in EntityDataAccessors  every time the Entity is constructed.

This isn't working, and I was wondering if there was a better way of doing this?

Thank you!

 

Edit: By non-volatile I mean saves the data to the specific instance of the entity even when the game is restarted

Edited by squidlex
Clarification
Link to comment
Share on other sites

EntityDataAccessor is for syncing to the client. You can also only use it for your own entities. Do not attempt to use it for other entities, you will break things even if it might not seem so if only your mod is installed.

For making capability data persistent, you need to implement INBTSerializable on your attached ICapabilityProvider. Its methods will then be called to save and restore any persistent data.

  • Like 2
Link to comment
Share on other sites

Thank you for your help! I'm only using the accessors for my own Entity and I'm implementing INBTSerializable in my provider so this shouldn't cause any issues.

I'm trying to access my capability in my Entity's constructor but it isn't working, however it works if I try to access it in another method such as interactAt(). Do you know if there is a way I can access my attached capability when my entity is being constructed? Thanks again.

 

Link to comment
Share on other sites

Thanks for the tip! I've now got:

	@Override
	public void readAdditionalSaveData(CompoundTag pCompound) {
		super.readAdditionalSaveData(pCompound);
		this.nameId = pCompound.getInt("nameId");
	}
	
	@Override
	public void addAdditionalSaveData(CompoundTag pCompound) {
		super.addAdditionalSaveData(pCompound);
		pCompound.putInt("nameId", this.nameId);
	}

but this is not saving correctly. Do I need to call these methods myself?

Link to comment
Share on other sites

Sorry, I should have been more clear.

I am checking my field on the client side in an interaction result, where if they are their default value of -1 I randomly generate a new value:

	@Override
	public InteractionResult interactAt(Player player, Vec3 position, InteractionHand hand) {
		if (level.isClientSide()) {
			if(this.nameId < 0) {
			this.nameId = level.random.nextInt(10);
		}
			GuiWrapper.openGUI(level, player, this);
			System.out.println("Client: " + this.nameId); // I know this is inefficient but just for testing purposes
		} 
		
		return super.interactAt(player, position, hand);
	}

And here is the field:

	private int nameId = -1;

The issue is that every time I close and open the world, they reset to -1 and a new value is generated.

Link to comment
Share on other sites

Data storage is server side only by default. Your interactAt method should be server side. You should then send a packet with the current value to the client, which then opens the GUI based on that new value.

Another alternative would be using SynchedEntityData, which keeps a data point synced with the client at all times. Note however that you should only do this if you really need the up to date value on the client at all time.

  • Thanks 1
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
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.

 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.