Minecraftforge: [Future suggestion] setBlockState for range of blocks

Created on 14 Apr 2017  路  15Comments  路  Source: MinecraftForge/MinecraftForge

World can set single block state to new one.
But it's so slow for multi-update, because there is redundant actions that can be simplified to one-action when setting blocks range. Detailed, you can send all changes in a single packet when you update range, not separately cause it's really braked even for medium volumes.
I had to create my crutch to paste schematics faster and I even can't parallel it due #3841

Feature Stale

Most helpful comment

Not really an expert here, but wouldn't it potentially improve performance on sponge, as it could post just one event for mass block changes, instead of an event for every block? It could also allow to do far less chunk lookups, far less isValid checks, and these things do add up. Much less isAreaLoaded checks for lighting. While they are all inexpensive on their own, as I said it does add up to very noticable amount of time.

All 15 comments

Look at how /fill command does it, it seems fast enough for most people's usages.

Ok. I had tested on my mod and world.setBlockState(pos, state, 2); like in CommandFill and other features gives me drastically low performance. My method - changing ChunkBlockStorageArrays and after all send chunk to player is much more faster.

The problem with this is, that setBlockState does more than only changing an entry in ChunkBlockStorageArrays. There are some methods and events that are invoked when a block is changed. Most of them will effectively do nothing, but in some cases they do.
IIRC, multiple block changes are collected in a single network packet anyways.
World.setBlockState has to lookup the chunk for every call. This could be optimized by directly setting a whole range of blocks. But according to my benchmarks, this lookup is already relatively cheap, as it is only a lookup in a Long2ObjectHashmap (or however it is called).

As I suppose, the most part of calculations consumes light recalculations. Ticking and notifying are slow also because of light. Why there is no special optimized method to re-render light in range?
I believe that calculating single-block lightnings are touching it's neighbours in a big radius. If so there is possibility to optimize that process for block-volume.

This issue has been automatically marked as stale because it has not had activity in a long time, and will be closed if no further activity occurs. If this issue was overlooked, forgotten, or should remain open for any other reason, please reply here to call attention to it and remove the stale status. Thank you for your contributions.

Since the light calc one is dead, we may still expose some api for batch block changing.

@liach What exactly do you want to optimize with that?

Update blocks after the batch operation instead of one by one in the original method.

Which updates are you referring to? I'm not sure if there are many things that can actually profit from delaying some updates.
If you mean the light updates, I wouldn't advise doing that, because of the Vanila bug I described here. This bug applies in general to situations where large areas of light sources are updated before the lighting engine is issued, eg. by placing some lava lakes in a batch operation and running the lighting engine afterwards.

We also need to update neighbor states in batch so that blocks within the volume don't need to update neighbor states too many times.

if it's not light, I honestly don't think it's worth the complexity to batch anything. Neighbor updates are not expensive, the light updates that they bring are

Honestly, we need normal command to paste schematic or common world fragment with tile entities (ideally with mob-entities, particles, etc), including arguments for rotation (x,y,z), and flipping (x, y, z). And it should calculate the light properly and fast as possible. My mod - structpro do that thing, so it's not impossible. Yes, default forge tools for changing blocks really expensive and really slow for big batch updates.

Not really an expert here, but wouldn't it potentially improve performance on sponge, as it could post just one event for mass block changes, instead of an event for every block? It could also allow to do far less chunk lookups, far less isValid checks, and these things do add up. Much less isAreaLoaded checks for lighting. While they are all inexpensive on their own, as I said it does add up to very noticable amount of time.

This issue has been automatically marked as stale because it has not had activity in a long time. If this issue is still relevant and should remain open, please reply with a short explanation (e.g. "I have checked the code and this issue is still relevant because ___." or "Here's a screenshot of this issue on the latest version"). Thank you for your contributions!

This issue has been automatically closed because it has not had activity in a long time. Please feel free to reopen it or create a new issue.

Was this page helpful?
0 / 5 - 0 ratings