Disclosure: This article was generated with AI for the FrameSprite team, which has a commercial interest in FrameSprite. It received a separate AI editorial review against the cited sources. Executed synthetic fixtures are identified with their runtime and limits; no other editor, engine, production or performance test is implied.
Iterate Unicode code points when a bitmap-font descriptor identifies supplementary-plane glyphs by their full character ID. A JavaScript loop over UTF-16 code units can split one symbol into two lookups. Both halves then appear missing even though the complete glyph is in the atlas.
Key takeaway: A missing glyph lookup can be a string-iteration bug. Expanding the atlas will not help if the consumer never asks for the correct ID.
Use a symbol that cannot hide the mistake
The original fixture string is A🎲B. Its code points are 65, 127922 and 66. Its UTF-16 units are 65, 55356, 57266 and 66. The two middle units represent one character, not two independently drawable glyph IDs.
The BMFont binary-v3 notes describe the expanded character-ID field. Confirm that your descriptor exporter and importer actually support the range you need before debugging the rendering layer.
Keep the character whole during lookup
JavaScript's string iterator yields code-point strings. An explicit lookup can therefore use:
const ids = [];
for (const character of 'A🎲B') {
ids.push(character.codePointAt(0));
}
// Expected: [65, 127922, 66]
By contrast, indexing the string and calling charCodeAt for every numeric position exposes its UTF-16 units. That may be useful for an encoding diagnostic, but it is the wrong boundary for this glyph-ID lookup.
Do not replace the two surrogate halves with a generic fallback independently. That produces two fallback symbols for one missing character and can also double the layout advance. Decide fallback after the complete code point has been looked up.
Reproduce the encoding distinction without an engine
The fixture input and executed output record both sequences. Python 3.12.10 ran three assertions in the checker, using explicit UTF-16 little-endian encoding to expose the units. The JavaScript snippet above is a source-based adaptation; that snippet was not the code executed by the Python fixture.
The Cyotek BMFont consumer is another implementation reference when examining supported descriptor forms. It does not establish the capabilities of a particular game's text stack.
In your project, log the numeric glyph IDs requested for a three-character sample. If the supplementary symbol produces two requests, fix iteration first. If it produces one correct request but still fails, inspect coverage, page resolution and the target importer's supported range.
Code points still are not shaped text
This repair does not implement grapheme clustering, ligatures, bidirectional ordering or emoji sequences. A family emoji or a combining-mark sequence can contain multiple code points that form one visual unit. Use a suitable shaping/text system when your interface allows that content; a simple bitmap glyph loop should have an explicit supported-character contract.
For absent descriptor entries, run the font coverage and fallback check. For filenames that look identical but compare differently, use the Unicode normalization guide. For a fixed image strip, confirm the SpriteFont character map rather than assuming every runtime supports arbitrary Unicode IDs.
Acceptance check
Render one supported supplementary symbol, one deliberately unsupported code point and the same string on two lines. Record the number of glyph lookups and advances. The result should preserve supported IDs and produce the fallback behavior you documented, without silently changing the source string.
Editorial ownership
Prepared by the workflow team, which has a commercial relationship with this site. This guide was drafted with AI assistance; independent editorial review is recorded separately. Report a technical correction with the relevant input, tool version and observed result.
Top comments (0)