Skip to content

Fixed a failed font load leaving the text renderer destroyed - #6627

Closed
dekrom wants to merge 1 commit into
MeteorDevelopment:masterfrom
dekrom:fix/font-load-failure
Closed

Fixed a failed font load leaving the text renderer destroyed#6627
dekrom wants to merge 1 commit into
MeteorDevelopment:masterfrom
dekrom:fix/font-load-failure

Conversation

@dekrom

@dekrom dekrom commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Type of change

  • Bug fix
  • New feature

Description

Fonts#load destroys the current renderer before it has a replacement:

if (RENDERER != null) {
    if (RENDERER.fontFace.equals(fontFace)) return;
    else RENDERER.destroy();
}

try {
    RENDERER = new CustomTextRenderer(fontFace);

If the constructor throws, the catch falls back to load(DEFAULT_FONT). That recursive call
sees RENDERER != null and compares RENDERER.fontFace against DEFAULT_FONT. FontFace does
not override equals and FontFamily#get hands back the same stored instance, so when the font
you were already on was the default, that check passes and the call returns immediately.
RENDERER is left pointing at the renderer that was destroyed a few lines earlier, with all
five of its textures closed.

Every Meteor text draw after that throws out of CustomTextRenderer#end when
getTextureView() is called on a closed texture, so the whole gui is unusable until a restart.
CustomFontChangedEvent is never posted either, so anything caching a font holder keeps the
dead one.

Hitting it only takes picking a system font whose file has been moved or deleted since the
startup scan, which is normal enough after a font package update.

Building the new renderer first and only destroying the old one once that succeeded also makes
the early return correct rather than dangerous: on the fallback path RENDERER is still the
live renderer, so returning early because it is already the default font is exactly right.

Related issues

None that I found.

How Has This Been Tested?

Not reproduced in game yet. The path is easy to follow though: the recursive load(DEFAULT_FONT)
hits the identity check against a renderer that was already destroyed, since FontFace does not
override equals. Builds clean against current master.

Checklist:

  • My code follows the style guidelines of this project.
  • I have added comments to my code in more complex areas.
  • I have tested the code in both development and production environments.

@crosby-moe

Copy link
Copy Markdown
Collaborator

the reasoning here is incorrect, a recursive Fonts#load would always either change the FontFace to a different instance or throw an irrecoverable exception

also, Fonts.DEFAULT_FONT is packaged inside the jar and would not be affected by external file changes

@crosby-moe crosby-moe closed this Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants