Jump to content

World NBT data [Forge 1.19.3]


BaRiBoD

Recommended Posts

I know that with this you can save a data in nbt data of a player
 

player.getPersistentData().putInt("value", 0);

Is there any way to save this data in nbt data world instead of nbt data player?

Edited by BaRiBoD
Link to comment
Share on other sites

  • BaRiBoD changed the title to World NBT data [Forge 1.19.3]

ok. you have "your" storage. where you keep data. let's say this is it:

public class OurMap
{
	private HashMap<String, Integer> internal;
	// getter, setter, etc.
}

now a Saved data class. before 1.18, it had save and load methods. as of 1.18 load is done in constructor. i don't like it but it is how it is.
again, you do not tell the game to save anything. save will happen when it happens.

public class OurWorldSavedData extends SavedData
{
	private final OurMap map = new OurMap(100);

	public OurWorldSavedData()
	{
	}

	public OurWorldSavedData(CompoundTag root)  // load method is now this
	{
		if (root.contains(Constants.MODID))
		{
			ListTag list = root.getList(Constants.MODID, 10);
			CompoundTag current;
			for (Tag nbt : list)
			{
				current = (CompoundTag) nbt;
				this.map.init(current.getString("key"), current.getInt("val"));
			}
		}
	}


	@Override
	public CompoundTag save(CompoundTag root)
	{
		ListTag list = new ListTag();
		foreach (String k, int v) in map do something like this(
		{
			CompoundTag c = new CompoundTag();
			c.putString("key", k);
			c.putInt("val", v);
			list.add(c);
		} );
		root.put(Constants.MODID, list);
		return root;
	}


	public OurMap getMap()
	{
		return this.map;
	}
}

last part may sound cringy but there are many ways to do this and i can't list them all (and this isn't how i prefer to do it).
maybe you'll have the class just expose the internal structure and have the rest of the mod write to it. or you'll provide getters and setters in SavedData. or keep them separate. doesn't matter much.

important part - hooking it to work:

this is my FoodManager class. don't worry about the logic. also implementation isn't elegant (i have separate map and saved data) but focus on the last part - i attach a single instance of saved data to overworld:

public class FoodDataManager
{
	private static OurMap foodMap = null;
	private static OurWorldSavedData data = null;
	private static final Logger LOGGER = LogManager.getLogger();


	public static int increase(Player player, ItemStack item)
	{
		if (!(player.level instanceof ServerLevel))
		{
			return -1;
		}

		VerifyInitialized(player.level);

		int result = foodMap.increase(player, item.getItem());
		data.setDirty();
		return result;
	}



	private static void VerifyInitialized(Level currentWorld)
	{
		if (foodMap == null)
		{
			data = currentWorld.getServer().overworld().getDataStorage().computeIfAbsent(OurWorldSavedData::new, OurWorldSavedData::new, Constants.MODID);
			foodMap = data.getMap();
		}
	}
}

 

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.