Skip to content

Commit 7b6f0f1

Browse files
Prevent crashes during collision shape baking
Wrapped collision shape retrieval in defensive error handling so problematic block states do not crash collider baking. This also ensures the temporary block getter state is reset after shape retrieval and treats failed or null shapes as empty collision data.
1 parent d3808e8 commit 7b6f0f1

1 file changed

Lines changed: 20 additions & 8 deletions

File tree

sable_rapier/src/main/java/dev/ryanhcode/sable/physics/impl/rapier/collider/RapierVoxelColliderBakery.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import net.minecraft.world.level.BlockGetter;
1414
import net.minecraft.world.level.block.Blocks;
1515
import net.minecraft.world.level.block.state.BlockState;
16+
import net.minecraft.world.phys.shapes.Shapes;
1617
import net.minecraft.world.phys.shapes.VoxelShape;
1718
import org.jetbrains.annotations.NotNull;
1819
import org.jetbrains.annotations.Nullable;
@@ -66,17 +67,28 @@ public RapierVoxelColliderBakery(@NotNull final BlockGetter blockGetter) {
6667
return entry;
6768
}
6869

69-
final VoxelShape shape;
70+
VoxelShape shape = Shapes.empty();
7071

71-
this.level.setup(childState);
72-
if (childState.getBlock() instanceof final BlockSubLevelCollisionShape extension) {
73-
shape = extension.getSubLevelCollisionShape(this.level, childState);
74-
} else {
75-
shape = childState.getCollisionShape(this.level, BlockPos.ZERO, SableCollisionContext.get());
72+
// if mods have complicated multiblocks, we catch it
73+
try {
74+
this.level.setup(childState);
75+
76+
if (childState.getBlock() instanceof final BlockSubLevelCollisionShape extension) {
77+
shape = extension.getSubLevelCollisionShape(this.level, childState);
78+
} else {
79+
shape = childState.getCollisionShape(this.level, BlockPos.ZERO, SableCollisionContext.get());
80+
}
81+
} catch (Exception e) {
82+
System.err.println("[Sable] Failed to get collision shape for block "
83+
+ childState.getBlock().getDescriptionId()
84+
+ ". Defaulting to empty shape to prevent crash.");
85+
e.printStackTrace();
86+
shape = Shapes.empty();
87+
} finally {
88+
this.level.setup(Blocks.AIR.defaultBlockState());
7689
}
77-
this.level.setup(Blocks.AIR.defaultBlockState());
7890

79-
if (shape.isEmpty()) {
91+
if (shape == null || shape.isEmpty()) {
8092
return RapierVoxelColliderData.EMPTY;
8193
}
8294

0 commit comments

Comments
 (0)