Skip to content

NPE in extractWaypointBoxes when a waypoint is set and a portal is rendered #11

Description

@koolBEANS829

Summary

WaypointRenderingHelper.extractWaypointBoxes assumes
LevelExtractionContext#levelState is non-null. Mods that run a second level
extraction pass for a different world make it null — Immersive Portals does exactly
this when drawing a portal's destination — and the game crashes with an NPE.

The crash only happens once the current world has at least one waypoint, because
extractWaypointBoxes returns early on the empty waypoint map before it ever reaches
levelState(). With no waypoints set you can play next to portals indefinitely; add
one and look at a portal and it crashes immediately.

Versions

SimpleWaypoints 1.4.0 (bundled inside clientcommands 2.15.1 as a JiJ dependency)
Minecraft 26.2
Fabric Loader 0.19.3
Fabric API 0.156.0+26.2
Seamless Portals 1.0.0 (com.warwa.seamlessportals, Immersive Portals engine)

Crash

Description: Render Frame

java.lang.NullPointerException: Cannot invoke
  "net.minecraft.client.renderer.state.level.LevelRenderState.setData(
     net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey, Object)"
  because the return value of
  "net.fabricmc.fabric.api.client.rendering.v1.level.LevelExtractionContext.levelState()"
  is null
	at knot//dev.xpple.simplewaypoints.impl.WaypointRenderingHelper.extractWaypointBoxes(WaypointRenderingHelper.java:208)
	at knot//net.fabricmc.fabric.api.client.rendering.v1.level.LevelExtractionEvents.lambda$static$3(LevelExtractionEvents.java:72)
	at knot//net.minecraft.client.renderer.extract.LevelExtractor.handler$bdh000$fabric-rendering-v1$afterExtractLevel(LevelExtractor.java:1665)
	at knot//net.minecraft.client.renderer.extract.LevelExtractor.extract(LevelExtractor.java:230)
	at knot//qouteall.imm_ptl.core.render.SecondaryWorldRenderCore.renderDestWorld(SecondaryWorldRenderCore.java:761)
	at knot//qouteall.imm_ptl.core.render.MyGameRenderer.switchAndRenderTheWorld(MyGameRenderer.java:392)
	at knot//qouteall.imm_ptl.core.render.MyGameRenderer.renderWorldNew(MyGameRenderer.java:220)
	at knot//qouteall.imm_ptl.core.render.renderer.PortalRenderer.invokeWorldRendering(PortalRenderer.java:356)
	at knot//qouteall.imm_ptl.core.render.renderer.RendererUsingStencil.renderPortals(RendererUsingStencil.java:155)
	at knot//com.warwa.seamlessportals.fabric.SeamlessPortalsClientFabric.lambda$onInitializeClient$0(SeamlessPortalsClientFabric.java:144)
	...

Steps to reproduce

  1. Minecraft 26.2 + Fabric, with SimpleWaypoints and any Immersive Portals–based mod
  2. Load a world containing a portal
  3. /sw:waypoint add test
  4. Look at the portal → instant crash

Cause

Immersive Portals calls LevelExtractor.extract a second time for the portal's
destination world from SecondaryWorldRenderCore.renderDestWorld. That pass has no
level render state, so context.levelState() returns null at
WaypointRenderingHelper.java:208.

Fix

Returning early when there is no level state is enough — waypoints simply aren't
collected for the secondary pass, and still render normally in the main view. The only
visible consequence is that waypoints don't draw inside a portal view.

     private static void extractWaypointBoxes(LevelExtractionContext context) {
+        // Mods that render a secondary world (e.g. Immersive Portals' portal
+        // destination pass) run extraction with no level render state.
+        if (context.levelState() == null) {
+            return;
+        }
+
         String worldIdentifier = SimpleWaypointsImpl.INSTANCE.getWorldIdentifier(Minecraft.getInstance());

I built 1.4.0 with just this change and confirmed the crash is gone with a waypoint set
and portals on screen. Verified the rebuild is otherwise identical to the released jar —
only WaypointRenderingHelper*.class differ.

I left renderWaypointBoxes alone: it dereferences LevelRenderContext#levelState
unguarded at line 212, but I could never get that one to return null, including across
tens of thousands of portal render passes. Happy to guard it too if you'd rather be
defensive.

Related

Same root cause, reported to clientcommands (which bundles this mod):
Earthcomputer/clientcommands#811 / Earthcomputer/clientcommands#812.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions