Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

Hi

 

I'm trying to save a custom object, holding only primitive values, to a chunk. It adds more information to the chunk that I need for my mod.

The values are simple numbers that show the amount of player made pollution.
What I did was putting all the chunks into a hashmap (the chunk's coordinates converted to a string and my custom object as a value), then convert that hashmap to json and save it with NBT on the world map.

 

I soon found out that the string is simply too long to store and it won't load the objects. I also think this way is a bit too devious and that there must be an easier way.

 

I'm looking for a way so I can add a value to a chunk, this would be the best manner ,I think, and also save it to the chunk in the same way chunks are saved.

Or is there an easier way to save the hashmap I have to NBT?

 

I'm just not entirely sure how to go at this. If anyone could point me in the right direction, that'd be great.

 

Thanks

Edited by Viperdream

  • Author

Ok, that should work.

Just a few questions. How do I make the ChunkPos the key of the NBTTag? Since it requires a string? Or do I somehow use the hashcode I can generate with that?

 

Also, I tried out a different method which seems to be working partly. But for some reason the NBT data doesn't persist when I restart Minecraft.

I've based myself on your Questology mod for the WorldSavedData extension class (thanks for that).

 

public class ChunkEcoValuesData extends WorldSavedData{
	
	private static final String IDENTIFIER = EcoBalance.MODID;
	
	private static String coords;
	private String jsonCv;
	
	public ChunkEcoValuesData(){
		super(IDENTIFIER);
	}
	public ChunkEcoValuesData(String id){
		super(id);
	}
	
	@Override
	public void readFromNBT(NBTTagCompound nbt) {
		jsonCv = nbt.getString(coords);
	}
	@Override
	public void writeToNBT(NBTTagCompound nbt) {
		System.out.println("[EcoBalance]: Saving to NBT...");
		nbt.setString(coords, jsonCv);
	}
	
	public String getJson(){
		System.out.println("Getting this json string: " + jsonCv);
		return jsonCv;
	}
	
	public void setJson(String json){
		this.jsonCv = json;
		System.out.println("Setting this json string: " + jsonCv);
		markDirty();
	}
	
	public void setCoords(String nCoords){
		coords = nCoords;
	}
	
	public static ChunkEcoValuesData get (World w, String chunkCoords){
		coords = chunkCoords;
		System.out.println("[EcoBalance] Getting data with coords: " + coords);
		
		ChunkEcoValuesData data = (ChunkEcoValuesData)w.perWorldStorage.loadData(ChunkEcoValuesData.class, IDENTIFIER);
		if(data == null){
			System.out.println("[EcoBalance] Data is null ");
			data = new ChunkEcoValuesData(coords);
			w.perWorldStorage.setData(IDENTIFIER, data);
		}
		return data;
	}

}

 

I'm a bit clueless here, because every time I set the value I mark it dirty. Shouldn't it save it then? I can see in the console that it passes the correct variable through, but yet it returns null when I restart Minecraft.

  • Author

Ok, if I understand this right. Should something like this work?

 

	@SubscribeEvent
	public void onChunkSave(ChunkDataEvent.Save e){
		NBTTagCompound nbt = e.getData();
		nbt.setDouble("value1", 1);
		nbt.setDouble("val2", 1);
	}

 

So once the event launches I can get the NBTTagCompound from the chunk and then I simply add my values to the NBT tag? Will it save automatically with the chunk without me having to do anything else?

And to get the values I simply use the ChunkDataEvent.Load and call upon the NBTTagCompound to find my values?

 

Sorry for all the questions, you've been a great help so far. I've been at this for a day now trying out various methods.

  • Author

This works like a charm, thanks a ton.

 

If anyone is wondering how my code looks like, here it is

 

	/**This saves the ChunkEcoValues object to the NBTTagCompound to its corresponding chunk
	 */
	@SubscribeEvent
	public void onChunkDataSave(ChunkDataEvent.Save e){
		NBTTagCompound nbt = e.getData();
		Chunk c = e.getChunk();
		ChunkEcoValues cv = Pollution.pollutedChunks.get(c);
		
		if(cv.getPassiveFactor() == null){
			cv.initDefault(c);
		}
		nbt.setDouble(passiveFactor, cv.getPassiveFactor());
		nbt.setDouble(originalPassive, cv.getActivePollution());
		nbt.setDouble(activePollution, cv.getActivePollution());
		nbt.setDouble(activeEco, cv.getActiveEco());
	}
	/**This loads the ChunkEcoValues from the NBTTagCompound from the chunk
	 */
	@SubscribeEvent
	public void onChunkDataLoad(ChunkDataEvent.Load e){ 
		if(!Pollution.pollutedChunks.containsKey(e.getChunk())){
			Chunk c = e.getChunk();
			NBTTagCompound nbt = e.getData();
			ChunkEcoValues cv = new ChunkEcoValues();
			
			cv.setChunk(c);
			cv.setPassiveFactor(nbt.getDouble(passiveFactor));
			cv.setOriginalPassive(nbt.getDouble(originalPassive));
			cv.setActivePollution(nbt.getDouble(activePollution));
			cv.setActiveEco(nbt.getDouble(activeEco));
			
			Pollution.pollutedChunks.put(c, cv);
		}else{	
			Chunk c = e.getChunk();
			ChunkEcoValues cv;
			
			cv.initDefault(c);
			
			Pollution.pollutedChunks.put(c, cv);
		}
	}

 

Or more clearly:

ChunkDataEvent.Save - save your data to NBT

ChunkDataEvent.Load - load your data from NBT

ChunkEvent.Unload - remove unused data from your runtime storage (likely a Map)

 

You need to do all three.  Save can happen any time, so it's not safe to purge runtime data at that point, and ChunkEvent.Load doesn't give you access to the NBT data.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

I have an example of something similar here, here and here.

 

I use a World capability (IChunkEnergyHolder) to store a Map containing the IChunkEnergy (which stores a single integer) for each chunk of the World. I use ChunkDataEvent.Load to read the IChunkEnergy from the chunk's NBT and store it in the Map, ChunkEvent.Load to create a default IChunkEnergy for the chunk if it doesn't have one and store it in the MapChunkDataEvent.Save to save the IChunkEnergy to the chunk's NBT and ChunkEvent.Unload to remove the IChunkEnergy from the Map.

 

The capability doesn't actually save any data itself, it only exists to hold the Map at runtime.

 

I use ChunkWatchEvent.Watch to send the IChunkEnergy to the client when a player starts watching a chunk. Whenever an IChunkEnergy's stored value changes, it's sent to all players watching the chunk.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

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...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.