Fix infobook crash when hovering the top-left corner on recipe pages - #237
Merged
rubensworks merged 1 commit intoSep 2, 2026
Merged
Conversation
Buttons for empty recipe slots never have their element set, and are never positioned either, so they keep sitting at (0, 0) with a null element. RecipeAppendix#renderToolTips calls renderTooltip on all buttons regardless, so as soon as the mouse entered the top-left 16x16 pixels of the screen while a recipe appendix with an empty slot was shown, ItemButton and FluidButton dereferenced that null element and crashed the game. Almost every recipe appendix has empty slots: any crafting recipe that does not fill the whole 3x3 grid, and any drying basin or squeezer recipe without a fluid input or output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kzc5LxSaedCXCK4pynhJV3
rubensworks
force-pushed
the
fix/infobook-empty-recipe-slot-tooltip-crash
branch
from
September 1, 2026 16:45
4130d09 to
32e3118
Compare
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Found while working on CyclopsMC/IntegratedTerminals#213.
Retargeted from
master-1.21-ltstomaster-1.20-lts, since the bug is present there too.The crash
Moving the mouse into the top-left 16x16 pixels of the screen while any infobook page with a recipe appendix that has an empty slot is open crashes the game:
and the
FluidStackvariant of the same:Cause
renderItemForButtonandrenderFluidForButtononly callbutton.update(...)when the stack is non-empty, so a button for an empty recipe slot never gets an element and is never positioned either: it keepsAdvancedButton's initial(0, 0)position with anullelement.renderToolTipsthen callsrenderTooltipon every button inrenderItemHoldersregardless, andrenderItemTooltip/renderFluidTooltipcheck the mouse bounds before the empty check:So the bounds check passes for a button stuck at
(0, 0)as soon as the mouse is in the top-left corner, and thenullelement is dereferenced.This affects almost every recipe appendix, since empty slots are the norm rather than the exception: any crafting recipe that does not fill the whole 3x3 grid, and any drying basin or squeezer recipe without a fluid input or output.
Fix
ItemButton#renderTooltipandFluidButton#renderTooltipnow return early when there is no element. Anullelement is already an expected state elsewhere inElementButton(bothupdateandisVisiblehandle it), so this only brings the tooltip path in line with the rest of the class.I kept it to that rather than also positioning the buttons of empty slots, since the latter would change which button ends up in
renderItemHoldersfor appendices that render the same button enum more than once per frame, and this is enough to fix the crash.Testing
Please note that this change is not verified against this branch locally — see below. It is the same change that was verified on
master-1.21-lts, where the two classes are structurally identical (sameElementButtoncontract, samegetElement(), same two overrides).The crash was originally hit and the fix verified on 1.21.1: with a patched build published to mavenLocal and Integrated Dynamics' infobook opened in a dev client, both reproducers —
Terminals -> Storage Terminal -> Craftingpage 2/3 (Drying Basin appendices without an output fluid, theFluidButtonvariant) and page 3/3 (a shaped crafting recipe with empty grid cells, theItemButtonvariant) — crashed within a frame of the mouse being parked at 10,10 before the change, and survived it after../gradlew buildand./gradlew runGameTestServerpassed there.On this branch I could not get ForgeGradle's MCP setup to run in my environment (
extractServerdies withIllegalStateException: ProjectScopeServices has been closedwhile requesting a toolchain launcher), which is unrelated to this change but blocks the build, so I am relying on CI for the build check here.No automated test either way: the classes are
@OnlyIn(Dist.CLIENT)Buttonsubclasses that need aGuiGraphics, which neither the unit tests nor the game tests can provide.Other branches
master-1.19-ltshas the same unguardedrenderTooltipoverrides (with the olderPoseStacksignature), andmaster-1.21-ltsand newer do too, so this presumably wants upmerging forward and possibly one more backport.