garbage collection does need to be implemented, but I was looking at this code and found so many fucking bugs I decided it wasn't worth the effort of fixing.
I don't know why this would be missing, but in some cases it is, as seen in the crash archive. Whatever the case, we shouldn't be shitting the bed because of this.
this was observable by planting a sapling underneath an existing tree and punching it with bone meal.
This change will also prevent trees generating too close together.
since this is an internal method, it doesn't make sense to force a single parameter that requires potentially constructing a separate object just for the parameters, so we pass primitives instead, which are also easier to typehint against.
this doesn't fix shit but it at least doesn't crash. Fixing this properly can't be effectively done any other way without backwards compatibility breaks. Fortunately it's not common practice to grow trees at the top of the world.
calculating dynamic states in some cases requires getting properties from neighbouring blocks, but getting these blocks also causes their dynamic states to be calculated, leading to a bouncing recursion.
This change allows retrieving blocks without calculating dynamic state information, if the call was generated by calculating dynamic state information.
Since these blocks are incomplete, they should not be cached and are only used to allow another adjacent block to complete its state. It is therefore not possible for a block's dynamic states to depend on another block's dynamic states.
This recursion bug was observable by running /gc and walking into a door, which would cause the server to freeze and crash.
This was the cause of many inconsistency and broken world bugs. In the future (once we switch to paletted chunks) this won't be possible anyway. For now, some temporary API is provided to allow modifying chunkdata directly, but it is required that **both** must be provided.