ChiselsAndBits / Chisels-and-Bits

A Minecraft mod about chiseling and designing custom blocks in game.
https://algorithmx2.github.io/Chisels-and-Bits/
MIT License
222 stars 81 forks source link

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

Open Axelund opened 6 months ago

Axelund commented 6 months ago

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
Firepup6500 commented 6 months ago

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

Firepup6500 commented 6 months ago

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.

Axelund commented 6 months ago

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!

Firepup6500 commented 6 months ago

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

Firepup6500 commented 6 months ago

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.

singlerr commented 5 months ago

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

}

`

BondarenkoArtur commented 5 months ago

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

Firepup6500 commented 5 months ago

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

singlerr commented 5 months ago

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

marchermans commented 5 months ago

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

singlerr commented 5 months ago

has nothing to do with sodium. It happens without sodium

BondarenkoArtur commented 5 months ago

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