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
- Minecraft 26.2 + Fabric, with SimpleWaypoints and any Immersive Portals–based mod
- Load a world containing a portal
/sw:waypoint add test
- 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.
Summary
WaypointRenderingHelper.extractWaypointBoxesassumesLevelExtractionContext#levelStateis non-null. Mods that run a second levelextraction 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
extractWaypointBoxesreturns early on the empty waypoint map before it ever reacheslevelState(). With no waypoints set you can play next to portals indefinitely; addone and look at a portal and it crashes immediately.
Versions
com.warwa.seamlessportals, Immersive Portals engine)Crash
Steps to reproduce
/sw:waypoint add testCause
Immersive Portals calls
LevelExtractor.extracta second time for the portal'sdestination world from
SecondaryWorldRenderCore.renderDestWorld. That pass has nolevel render state, so
context.levelState()returnsnullatWaypointRenderingHelper.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*.classdiffer.I left
renderWaypointBoxesalone: it dereferencesLevelRenderContext#levelStateunguarded 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.