Cannot load into world with bits in them. 1.20.4 Fabric - Chisels & Bits 1.4.155
Axelund opened this issue ยท 12 comments
Starting up a new world is fine and chiseling blocks and placing bits works. But when I exit the world and try and re-load the world it just stays at 100% loaded and never actually lets me into the world. Version 1.4.155 Chisel and Bits Fabric, Fabric api 0.97.0, Indium 1.0.30, Sodium Fabric 0.5.8. Please help!
I know it's not really a good "fix", but if you make sure just to not have any bits placed down when you save and exit it'll work fine when you rejoin, and you could put them back when you rejoin.
I'd try to find it myself, but without any error logs (since minecraft just freezes and nothing errors) it's kinda hard to trace.
Afraid not, that'd be more a question for the maintainer, I kinda just showed up to fix #1214 since I knew how.
Aww darn. It makes it almost impossible to play with the mod if nothing can be saved. Do you know when it might be fixed? Appreciate the help!
After upgrading Scena to version 1.0.141 and building jar for server, issue was solved for me, thanks!
@Firepup6500
I've found that
IBlockEntityPositionManager.getInstance().add(this);
in mod.chiselsandbits.block.entities.ChiseledBlockEntity#setLevel
causes infinite loop of tasks.
IBlockEntityPositionManager#add
tries to get chunk from level by calling LevelReader#getChunk
and it causes minecraft to load chunk that is not fully loaded and add futures again and again.
Solution:
If you carefully inspect minecraft codes, you will be noticed that BlockEntity#setLevel is always invoked by LevelChunk. And ChiseledBlockEntity#setLevel calls IBlockEntityPositionManager.getInstance().add(this), which calls getChunk. It will try to load itself(which is not fully loaded. note that BlockEntity#setLevel is called while loading chunk) and result in calling BlockEntity#setLevel again. It finally causes futures scheduled infinitely.
As a result, the solution may be write a mixin code that actually executes what IBlockEntityPositionManager#add does.
It varies which platform you are working on, but it quite easy. Just create LevelChunk mixin class and inject code to BlockEntity#setLevel in LevelChunk#setBlockEntity. The injected code will be fetching IFabricBlockEntityPositionHolder or IForgeBlockEntityPositionHolder and calling scena$add.
I tested it and it works perfect.
Also, Don't forget to remove IBlockEntityPositionManager#add in ChiseledBlockEntity#setLevel!
Codes below are I've used to test
`
@mixin(LevelChunk.class)
public abstract class MixinLevelChunk {
@Inject(method = "setBlockEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BlockEntity;setLevel(Lnet/minecraft/world/level/Level;)V"))
private void mod$manuallyAddToHolder(BlockEntity blockEntity, CallbackInfo ci){
IFabricBlockEntityPositionHolder holder = (IFabricBlockEntityPositionHolder) (Object) this;
holder.scena$add(blockEntity.getClass(), blockEntity.getBlockPos());
}
}
`
@singlerr Could you please create Pull Request for that? I have same issue.
If there's not a PR open for it later today, I'll test the fix and PR it myself if it works.
@Firepup6500 Maybe there is better way to do this? not using mixin. Anyway I'll open pr to fix the issue.