Skip to content

Fix crashes from modules ticking without a world, half-built screens and missing textures - #6734

Open
Awokein wants to merge 1 commit into
MeteorDevelopment:masterfrom
Awokein:fix-null-crashes
Open

Awokein wants to merge 1 commit into
MeteorDevelopment:masterfrom
Awokein:fix-null-crashes

Conversation

@Awokein

@Awokein Awokein commented Oct 17, 2026 •

Copy link
Copy Markdown

Type of change

  • Bug fix
  • New feature

Description

Reworked after review: instead of null checks this fixes why things were null, and adds one safety net so a broken module doesn't take the whole game down.

Modules ticking without a world (#6599)
Module listeners are only managed by GameJoinedEvent/GameLeftEvent, so anything that loses the world or player without a leave event (crash recovery mods returning to the title screen, the world still loading after join) left modules ticking with mc.player == null. Modules.updateModuleSubscriptions() now runs before every tick and removes module listeners while there's no world or player, then adds them back once both exist. No onActivate/onDeactivate calls since there's no player to use in them.

Half-built screens (#6360)
WidgetScreen.init() set firstInit = false before initWidgets(), so if building the widgets threw once the screen was never rebuilt and kept rendering a half-initialised window (the triangle NPE in WWindow$WHeader). It's now only marked as built after initWidgets() succeeds, so a failure shows its real error instead.

Built-in textures fail fast (#6722)
Texture.readResource returned null for a missing or unreadable resource, which then crashed later in the GUI renderer. It now throws with the path and the decode error, and the empty spawn egg texture is loaded at startup in GuiRenderer.init() instead of lazily when the entity list opens.

Safety net
MeteorEventBus extends orbit's EventBus: if an exception comes from a module's event handler, that module is disabled, the full error is logged and the user gets a chat message saying which module crashed. Exceptions that don't come from a module are rethrown as before, so nothing else is silently swallowed.

Closes #6599
Closes #6360
Closes #6722

@crosby-moe

Copy link
Copy Markdown
Collaborator

i think this is all setting a bad precedent

instead of adding null checks everywhere we should tighten the code to prevent nullness altogether:

  • it makes no sense for a module without runInMainMenu to be ticking when the logical world is still being loaded
  • it makes no sense to be rendering a gui element that hasn't been initiaized

#6722 should be fixed in a different way, if built-in assets have issues loading we should be failing fast rather than silently ignoring it

@Awokein Awokein changed the title Fix null pointer crashes in InvUtils, section headers and GUI textures Fix crashes from modules ticking without a world, half-built screens and missing textures Oct 18, 2026
@Awokein

Awokein commented Oct 18, 2026

Copy link
Copy Markdown
Author

fair, reworked it. the null checks are gone and it fixes the actual causes now (also my #6360 change was in the wrong class, the crash was WWindow's header not WMeteorSection):

  • modules get their listeners removed before a tick if there's no world/player and added back once there is, so they never tick while the world's loading or after crash recovery skips GameLeft
  • WidgetScreen only marks itself initialised after initWidgets succeeds, so a failed build shows the real error instead of rendering a half-built window
  • built-in textures throw with the path if they fail to load, and the spawn egg one loads at startup

but i don't think it should be all or nothing, so i kept one safety net: if a module's event handler throws, that module gets disabled, the full error is logged and the user gets told in chat which module crashed. anything not from a module still crashes like before, so nothing gets silently swallowed. lmk if you'd rather that be its own pr

@crosby-moe

Copy link
Copy Markdown
Collaborator

your WidgetScreen changes appear to completely negate the entire reason the firstInit variable existed in the first place

also the modules/event bus changes should be done by a human rather than a machine

@crosby-moe

Copy link
Copy Markdown
Collaborator

should clarify, the modules/event bus changes as-is are bad, you want the added friction of the game closing in the case where a crash would happen otherwise the error and subsequent debug information goes ignored and unreported

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

Labels

None yet

Projects

None yet

2 participants