Jump to content

[1.15.2] Is it possible to store data in normal blocks?


HappyHippo77

Recommended Posts

So I've got a really cool idea for a system for a mod of mine. Basically, it's a magic mod, and there will be two kinda of energy (mana), natural and personal. Natural energy exists in every natural block in the game, to different extents depending on the block itself. Personal energy is from the player themselves. By depleting personal energy too far you'll begin to experience negative effects, but if you don't give an area enough time to "recharge" after performing more magic there and trying again, the energy might be completely depleted from the blocks and they might die, rendering the area useless. Thus, you'd have to balance between using personal and natural energy in order to keep your casting areas alive.

 

I really want to implement this system, but I've run into a massive barrier. I don't know how I would be able to store information, not only in normal vanilla blocks, but in EVERY natural block which has been depleted from its default energy in some way.. I've seen other mods do things somewhat similar to this, so I get the feeling it's possible, I just have no idea how to do it myself. Would I use Capabilities? Or is there a better system?

Edited by HappyHippo77
Link to comment
Share on other sites

Hi

I don't think it's possible to directly add this information to vanilla blocks.  If it were your own blocks, you could have blockstates for each one (say 16 levels) or a tileentity.

However it's certainly possible to maintain a parallel data structure of your own which stores the energy level for every block (or perhaps more efficiently - every partially depleted block) - you can store it in WorldSavedData, and can update it regularly using server world tick.  You may need to be careful about chunks loading in or out (not trying to update information for chunks which have been unloaded because the player is a long way away, for example) but it wouldn't be particularly difficult.

 

If there are other mods which seem to do something similar, you could look at their source code too.

-TGG

 

 

  • Thanks 1
Link to comment
Share on other sites

41 minutes ago, TheGreyGhost said:

Hi

I don't think it's possible to directly add this information to vanilla blocks.  If it were your own blocks, you could have blockstates for each one (say 16 levels) or a tileentity.

However it's certainly possible to maintain a parallel data structure of your own which stores the energy level for every block (or perhaps more efficiently - every partially depleted block) - you can store it in WorldSavedData, and can update it regularly using server world tick.  You may need to be careful about chunks loading in or out (not trying to update information for chunks which have been unloaded because the player is a long way away, for example) but it wouldn't be particularly difficult.

 

If there are other mods which seem to do something similar, you could look at their source code too.

-TGG

 

 

Thanks for the response! So to do this, would I basically need to add a value for every modified block containing the location and energy values (and potentially the block type as well) of each block?

Edited by HappyHippo77
Link to comment
Share on other sites

Hi

>Thanks for the response! So to do this, would I basically need to add a value for every modified block containing the location and energy values (and potentially the block type as well) of each block?

Yeah, pretty much.

 

You might use (say) a HashMap of BlockPos vs energy value for all blocks which are are partially depleted.  The block type is stored already (in the World) so you don't need to store that.

You might also need some sort of second datastructure (eg HashSet) for blocks which are permanently depleted.

 

I think you also need to decide how the game should react if the data structures get too big and you need to cull them from memory.  What's your game mechanic for that?  eg

Do you strip out the depleted blocks which are a long way away? ("Natural energy regenerates instantly when there are no spellcasters within X radius")

If too many blocks get fully depleted in an area, does it destroy the entire chunk? ("If the flow of natural energy is sufficiently disturbed, then all natural energy in the area sickens and dies")

 

If those have an unacceptable game impact, you might need to split your data structure into chunks and store them in parallel with normal world data.  i.e. hook into the chunk loading and unloading events, and load+unload your own datastructures in parallel with those.  WorldSavedData might not be suitable for storing large amounts of data (I'm not sure); you may need to write your own datastructures on disk similar to how the chunk system does it, i.e. allows you to modify chunks within the file without having to rewrite the entire file.

That would be more complicated but it would still work if you're careful. 

 

-TGG

 

 

 

  • Thanks 1
Link to comment
Share on other sites

15 hours ago, TheGreyGhost said:

Yeah, pretty much.

 

You might use (say) a HashMap of BlockPos vs energy value for all blocks which are are partially depleted.  The block type is stored already (in the World) so you don't need to store that.

You might also need some sort of second datastructure (eg HashSet) for blocks which are permanently depleted.

I'm relatively new to Forge, so all of this is very complicated and out of my league, but I'm good at learning, so I'll try. Do you know of any resources for this kind of thing?

 

15 hours ago, TheGreyGhost said:

I think you also need to decide how the game should react if the data structures get too big and you need to cull them from memory.  What's your game mechanic for that?  eg

Do you strip out the depleted blocks which are a long way away? ("Natural energy regenerates instantly when there are no spellcasters within X radius")

If too many blocks get fully depleted in an area, does it destroy the entire chunk? ("If the flow of natural energy is sufficiently disturbed, then all natural energy in the area sickens and dies")

Well, once the blocks "die", they'd probably be replaced with separate blocks from the mod which would have a more "dead" appearance, and no ability to receive energy (and may have lesser value drops), so I don't think I'd need that kind of thing too much (the energy will restore naturally over time, and not an overly long time, so it shouldn't ever get too full of data).

Link to comment
Share on other sites

1 hour ago, HappyHippo77 said:

Do you know of any resources for this kind of thing?

This is a very complicated thing and almost no one does it because its complicated and a pain in the ass because vanilla doesn't support it directly.

This is the best example I have, but doesn't store data at the block level, but rather in 16x16x8 block-groups. Mind, its old code.

Edited by Draco18s

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.

Link to comment
Share on other sites

3 hours ago, Draco18s said:

This is a very complicated thing and almost no one does it because its complicated and a pain in the ass because vanilla doesn't support it directly.

This is the best example I have, but doesn't store data at the block level, but rather in 16x16x8 block-groups. Mind, its old code.

Thanks for the help, sorry I keep asking so many questions. Where would I use this hashmap? In a class which extends WorldSavedData?

Edited by HappyHippo77
Link to comment
Share on other sites

I haven't messed with it in a while. I'm not sure how I'd handle it today.

(I need to figure that out at some point, but I'm blocked by other things that need to be available first)

Edited by Draco18s

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.

Link to comment
Share on other sites

WorldSavedData uses its read and write methods to save and load things with the NBT format. NBT has no built-in data types for BlockPos, nor an easy way of storing the key-value pairs that maps use. Still, look at how vanilla uses NBT to figure out how to work with it.

If you're using integers for the energy values, you could save them all as a single integer array with NBT. Basically, every four integers in the array would be your x y z and energy values. There are other ways of doing this of course.

I'm eager to learn and am prone to mistakes. Don't hesitate to tell me how I can improve.

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.