Skip to content

Prevent NPE for weightless contraptions#965

Closed
lap2ka wants to merge 2 commits into
ryanhcode:mainfrom
lap2ka:fix478
Closed

Prevent NPE for weightless contraptions#965
lap2ka wants to merge 2 commits into
ryanhcode:mainfrom
lap2ka:fix478

Conversation

@lap2ka

@lap2ka lap2ka commented May 19, 2026

Copy link
Copy Markdown
Contributor

Fix #457, fix #478, fix #851, fix #882, fix #906, fix #909
lotta duplicates here

Copilot AI review requested due to automatic review settings May 19, 2026 23:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets a recurring server crash in the Create compatibility layer where MassTracker.getCenterOfMass() can be null for certain “weightless” / non-solid contraptions, leading to a NullPointerException during contraption initialization.

Changes:

  • Adds a null-check before translating floating block cluster origins using the contraption center of mass.
  • Adds a null-check before adding the contraption to the physics pipeline.
Comments suppressed due to low confidence (1)

neoforge/src/main/java/dev/ryanhcode/sable/neoforge/mixin/compatibility/create/contraptions/AbstractContraptionEntityMixin.java:175

  • This null-guard prevents the immediate NPE, but leaves sable$massTracker in a state where getCenterOfMass() is null. Several call sites assume a non-null center of mass (e.g., KinematicContraption.sable$getLocalPose() and this mixin's sable$getPosition()), so if this contraption is added to a plot or the physics pipeline later it can still crash. Consider treating a null centerOfMass as an invalid MassTracker and explicitly skipping/removing the contraption from any physics/plot collections (or providing a safe fallback center of mass) to keep invariants consistent.
        assert this.sable$localBounds != null;
        this.sable$massTracker = MassTracker.build(this.sable$blockGetter(), this.sable$localBounds);
        final Vector3dc centerOfMass = this.sable$massTracker.getCenterOfMass();
        if (centerOfMass != null) {
            final Vector3d temp = centerOfMass.negate(new Vector3d()).add(0.5, 0.5, 0.5);
            for (final FloatingBlockCluster cluster : this.sable$floatingClusterContainer.clusters) {
                cluster.getBlockData().translateOrigin(temp);
            }
        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 99 to 106
if (!this.sable$added && this.level() instanceof final ServerLevel serverLevel) {
this.sable$buildProperties();
this.sable$addToPlot();
this.sable$addToPipeline(serverLevel);
if (this.sable$massTracker.getCenterOfMass() != null) {
this.sable$addToPipeline(serverLevel);
}
this.sable$added = true;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shi the AI overlord is right

@lap2ka

lap2ka commented May 19, 2026

Copy link
Copy Markdown
Contributor Author
image

@Ocelot5836

Copy link
Copy Markdown
Collaborator

Fixed in latest

@Ocelot5836 Ocelot5836 closed this Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment