Chisels & Bits - For Forge

Chisels & Bits - For Forge

108M Downloads

Cannot load into world with bits in them. 1.20.4 Fabric - Chisels & Bits 1.4.155

Axelund opened this issue ยท 12 comments

commented

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!

CandBissue
commented

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.

commented

This is the same issue as #1210 (if anyone is curious), it's just easier to find out about now that the bug that #1214 fixed is fixed

commented

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.

commented

Afraid not, that'd be more a question for the maintainer, I kinda just showed up to fix #1214 since I knew how.

commented

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!

commented

After upgrading Scena to version 1.0.141 and building jar for server, issue was solved for me, thanks!

commented

@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());
}

}

`

commented

@singlerr Could you please create Pull Request for that? I have same issue.

commented

If there's not a PR open for it later today, I'll test the fix and PR it myself if it works.

commented

@Firepup6500 Maybe there is better way to do this? not using mixin. Anyway I'll open pr to fix the issue.

commented

Is this an issue with just Sodium?
Or also without it?

commented

has nothing to do with sodium. It happens without sodium