Fix MV Scene_Boot hang: measureText was font-agnostic, breaking Graphics.isFontLoaded - #1152
Merged
Merged
Conversation
…ics.isFontLoaded MV's classic font-ready check (Scene_Boot.isGameFontLoaded, via Graphics.isFontLoaded) measures '40px GameFont, sans-serif' against '40px sans-serif' and waits for the two widths to diverge. Our measureText (mruby-mvjs/src/mvcanvas.cxx) backed every font shorthand with the same loaded game font regardless of the requested family, so those two measurements were always identical and the check never passed -- Scene_Boot would hang until its own 20s timeout and throw "Error: Failed to load GameFont", on any project whose corescript takes this path rather than the newer FontFaceSet path our document.fonts stand-in already covers. Found against a real, downloaded RPG Maker MV release (an Enigma Virtual Box-packed single-file distributable, unpacked with evbunpack to reach its www/ project) that never got past Scene_Boot. Fixed by having measureText/fillText/strokeText parse whether the font shorthand actually names "GameFont" and route anything else through the same rough per-character estimate already used when no game font is loaded at all -- guaranteed to differ from the real metrics. Verified: the same real game now reaches Scene_Title, New Game and Scene_Map. data/Lunatic-Core and data/mv-sample both happen to use a corescript build that takes the FontFaceSet path already, which is why this stayed hidden until a different real release exercised the older one. Adds a regression test in mruby-mvjs/test/canvas_test.rb (asserts the exact fallback value for a non-"GameFont" shorthand, independent of whether a real font happens to be loaded in the test environment) and documents the root cause in docs/TODO.md's M5 section. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RmARb1uB2F9rXRg6tQsGgR
CI's clang-format pre-commit hook reflows the font_text_width signature and a comment block differently than my by-hand wrapping. Reformatted to the tool's own output (verified locally: clang-format -i now produces no diff). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RmARb1uB2F9rXRg6tQsGgR
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.
Summary
Scene_Boot.isGameFontLoaded, viaGraphics.isFontLoaded) measures'40px GameFont, sans-serif'against'40px sans-serif'and waits for the two widths to diverge. OurmeasureText(mruby-mvjs/src/mvcanvas.cxx) backed every font shorthand with the same loaded game font regardless of the requested family, so those two measurements were always identical and the check never passed —Scene_Bootwould hang until its own 20s timeout and throwError: Failed to load GameFont, on any project whose corescript takes this path rather than the newer FontFaceSet path ourdocument.fontsstand-in already covers.evbunpackto reach itswww/project) that never got pastScene_Boot.measureText/fillText/strokeTextparse whether the font shorthand actually names"GameFont"and route anything else through the same rough per-character estimate already used when no game font is loaded at all — guaranteed to differ from the real metrics.data/Lunatic-Coreanddata/mv-sampleboth happen to use a corescript build that takes the FontFaceSet path already, which is why this stayed hidden until a different real release exercised the older one.Test plan
Scene_Boot → Scene_Title → New Game → Scene_Map(previously stuck atScene_Bootforever)rake test(mrbtest): 1842 OK, 0 KO, 0 Crash — includes a new regression test inmruby-mvjs/test/canvas_test.rbthat asserts the exact fallback value for a non-"GameFont"shorthand, independent of whether a real font happens to be loaded in the test environmentLunatic-Coreandmz-sample: all still green, no regressions🤖 Generated with Claude Code
https://claude.ai/code/session_01RmARb1uB2F9rXRg6tQsGgR
Generated by Claude Code