Jump to content

How many models is too many?


Jay Avery

Recommended Posts

My mod has a bunch of custom building blocks (walls etc) with lots of adaptivity, which means loads of multipart models. The Forge loading screen now shows ~110,000 models in the ModelLoader baking stage, and it runs out of memory if it has less than about 4G of RAM allocated. I'm just wondering, how worried should I be about this? It obviously puts a bit of a limit on who will be able to run the mod, because low-spec computers won't have enough RAM to spare. Is there anything (other than hugely reducing the number of models I use obviously) that I can do to make this process easier or less memory intensive? Or should I just accept that my mod is a bit intensive to start up and stop worrying about it? I'm pretty sure that my multipart models are put together such that there are none (or at least very few) which are never used, so i don't think a custom state mapper (?) would make much difference.

Edited by Jay Avery
Link to comment
Share on other sites

2 Methods I can recommend (used booth by myself with blocks having 2000+ Models and safed each time up to 500mb RAM)

 

Nr. 1:

Create Separate Models for all possible Combinations (if you have really so much it might be the best to create a tool on your own)

 

Nr. 2:

In case you use Minecrafts Multipart Models you should really switch to Forge's Blockstate format, that saves a bunch of RAM.

 

In each case I haven't tested booth methods equally so I cannot say you which one is better.
But for the RAM it seems pretty similar, even though Forge's Blockstate model has a longer loading time.

Link to comment
Share on other sites

Do you really need all of them to be baked at once?
Why not have a custom IBakedModel render the block.
If the wanted model is cached (stored already) then simply return the BakedQuad's for that.
If not, create the wanted model, cache the BakedQuads, and return the BakedQuads for the model from the cache.

This way, only the "needed" models are in memory (which should only be a shadow of what you got now), and if they are not, it creates them from scratch, AS they are needed.
This should shave off a significant amount of RAM requirement.

  • Like 1

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

2 hours ago, Matryoshika said:

Do you really need all of them to be baked at once?
Why not have a custom IBakedModel render the block.
If the wanted model is cached (stored already) then simply return the BakedQuad's for that.
If not, create the wanted model, cache the BakedQuads, and return the BakedQuads for the model from the cache.

This way, only the "needed" models are in memory (which should only be a shadow of what you got now), and if they are not, it creates them from scratch, AS they are needed.
This should shave off a significant amount of RAM requirement.

They don't necessarily all need to be baked at once, that's a good point. But if I use a cache system, won't that have negative performance implications during the running of the game as they get baked on the fly? Might it just postpone the out of memory error to some unpredictable time during gameplay, instead of getting it out of the way during start-up?

Link to comment
Share on other sites

4 minutes ago, Jay Avery said:

They don't necessarily all need to be baked at once, that's a good point. But if I use a cache system, won't that have negative performance implications during the running of the game as they get baked on the fly? Might it just postpone the out of memory error to some unpredictable time during gameplay, instead of getting it out of the way during start-up?

No player, will likely ever going to have more than 10% of your models loaded in memory at any given time. If they have more than that, they goddamned tried their best to soak up their own memory.

Yes, framerates may stutter, but most of the time, no-one will notice. I create baked models on the fly to create Menger fractals, and only notice anything at iteration 4, or loop number 20⁴ as that amounts up to.
It all depends on how efficient you are when it comes to "creating" the models.

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

I would recommend TheGreyGhost's Minecraft By Example MBE04.
Though he uses IPerspectiveAwareModel (Which extends IBakedModel).
However, don't do anything with the ModelBakeEvent. Just create an ICustomModelLoader, have it accept the resourcelocation(s) for these models, point those resourcelocation(s) to a custom IModel that immediately points to the IBakedModel.

I do this in my ongoing project Echo, but it's quite messy right now and I haven't uploaded the latest changes yet. You can take a look, but wait a few hours for me to upload the current stuff, as most things get shoved around a bit, or right out removed.

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

I've been doing some research from those links and other sources. I think I have a rough idea of how to override the default models with a custom IBakedModel. But I'm still really confused about exactly what to do in my special model.

  • For a new (not cached) state, how do I turn the IBlockState into a List<BakedQuad> that's made from multiple json-defined parts like a vanilla multipart? I've been digging through the vanilla code but it goes through so many stages and I don't know if following vanilla is the best approach anyway. And the other mod examples I've seen use more complicated models rather than simple json ModelResourceLocations.
  • What is the process for caching a model? How do I store them and how do I check whether it's already stored? Can I just use a Map<IBlockState, IBakedModel> and add to it as models get baked? Or do I need some more sophisticated approach?
Edited by Jay Avery
Link to comment
Share on other sites

I use a model-cache for Menger fractal inspired blocks, which require me to store them per iteration, per state, per facing, so I use a multi-dimensional map: Map<Byte,Map<IBlockState,Map<EnumFacing,ArrayList<BakedQuad>>>>.
If any of these are null (get(byte), or get(byte).get(state)....) then the BakedQuads have not been calculated yet.

You need to figure out how you should store your IBakedModels, or better yet, their List<BakedQuad> depending on what side is being rendered (EnumFacing).
If nothing else, assign each multipart to a string, and use that string as a key.
As for the conversion between IBlockState -> List<BakedQuad>
You will need to use IExtendedBlockState to provide information for the model.
IExtendedBlockState can carry more information (and any type!) than a normal IBlockState, but that data will not get serialized to meta-data.
Now, store the multiparts in your IExtendedBlockState, and read from the IExtendedBlockState in the getQuads of your IBakedModel
Pseudo-code V

List<BakedQuad> model = new ArrayList<BakedQuad>();

List<String> wantedMultiparts = YourBlocksExtendedState.getValue(WANTEDMP);
	if(wantedMultiparts.contains("multipart_a")){
  		if(Cache.get("multipart_a") != null && Cache.get("multipart_a").get(facing) != null)
  			model.add(Cache.get("multipart_a").get(facing));
  		else{
  			<Get the List<BakedQuad> from IModel->IBakedModel->getQuads()...>
  		}
  	]
  		

As for how you are supposed to get the multi-parts from JSON, I don't know, sadly.

 

Here are some examples though, for what I've talked about.
Cache

Block implementing IExtendedBlockState

(You also want to write the IExtendedState to NBT so that the Item can render exactly the same (You need to override getOverrides in IBakedModel to return a similar IBakedModel))
Getting values from IExtendedBlockState

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

Thanks for all the help. I now have a working delayed-baking system! (I just pushed my latest changes here). The model baking bar has dropped from 110,000+ to about 4,000 models, and only takes about 1.5G RAM at the most. And I'm not noticing any performance issues in the game when I place the blocks in question, but all the models are looking as they should. :D

 

If anyone has feedback on the approach I've taken, please do tell. I've never done anything so complicated with block models before. But it all seems to be working so I'm pretty pleased.

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.