Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

FNT Bitmap Font File Format

Chunked bitmap-font format with per-file palette and per-glyph indexed image data.

.FNT stores UI/dialog font glyphs as palette-indexed bitmaps. Each file embeds its own palette (not scene COL palettes), then stores glyph records in ASCII order. For palette structure background, see COL.md.

Top-Level Layout

The file is a sequence of named chunks, followed by an end marker:

  1. FNHD (always present)
  2. BPAL or FPAL (always present)
  3. FBMP (always present)
  4. RDAT (optional)
  5. END marker

Common chunk orders:

  • FNHD -> BPAL -> FBMP -> END
  • FNHD -> BPAL -> FBMP -> RDAT -> END
  • FNHD -> FPAL -> FBMP -> END (ARIALVS.FNT only)

Chunk Header

Each chunk begins with an 8-byte header:

Chunk-length fields are big-endian.

OffsetSizeTypeNameDescription
0x004[u8; 4]tagChunk name (FNHD, BPAL, FPAL, FBMP, RDAT)
0x044u32lengthChunk payload size in bytes

END is a 4-byte marker tag with no payload. ARIALVS.FNT has 4 additional trailing zero bytes after END .

FNHD Chunk (56 bytes)

FNHD payload is always 56 bytes.

Numeric fields are little-endian.

OffsetSizeTypeNameDescription
0x0032[u8; 32]descriptionFont/tool description string; may contain NUL padding or multiple NUL-terminated fragments
0x202u16unknown_24Not read at runtime — overwritten during glyph loading. Known values: 0, 1, 3. Export-tool metadata.
0x222u16has_rdat1 if RDAT chunk present; 0 otherwise. Not checked at runtime — the engine never searches for RDAT.
0x242u16reserved_28Always 0. Not read at runtime.
0x262u16reserved_2aAlways 0. Not read at runtime.
0x282u16reserved_2cAlways 0. Not read at runtime.
0x2A2u16max_widthExport-tool hint (range 11–23). Not read at runtime — overwritten with the width of glyph ‘W’ during loading.
0x2C2u16line_heightUsed by the engine for text layout and baseline positioning. Values: 9, 10, 12, 14, 16, 22, 25, 26.
0x2E2u16character_startFirst encoded codepoint; always 32 (0x20, space). Not read at runtime — engine assumes fixed start.
0x302u16character_countUsed by the engine as the glyph loop bound (clamped to 256). Number of glyph records in FBMP. Values: 95, 97, 98, 104, 112, 208.
0x322u16reserved_36Always 0. Overwritten to 0xFF during glyph loading.
0x342u16reserved_38Always 0. Overwritten to 0xFF during glyph loading.
0x362u16has_paletteUsed by the engine to control palette loading. Non-zero = allocate 768-byte palette and search for FPAL/BPAL chunk. Always 1.

BPAL / FPAL Chunk (Palette)

Palette payload is always 768 bytes (256 RGB triplets).

OffsetSizeTypeNameDescription
0x00768[u8; 768]rgb_triplets256 entries x 3 bytes (R, G, B), palette indices referenced by FBMP pixel bytes

Notes:

  • BPAL is the normal tag.
  • FPAL appears in ARIALVS.FNT with the same 768-byte payload shape.
  • These palettes are local to each font file, independent of scene palettes in COL.md.

FBMP Chunk (Glyph Records)

FBMP payload contains character_count glyph records in sequential codepoint order starting at character_start.

Each glyph record:

Numeric fields are little-endian.

OffsetSizeTypeNameDescription
0x002u16enabled0 = disabled/unrendered glyph; non-zero = active glyph
0x022i16offset_leftHorizontal draw offset in pixels
0x042i16offset_topVertical draw offset in pixels
0x062u16widthGlyph bitmap width in pixels
0x082u16heightGlyph bitmap height in pixels
0x0Awidth*height[u8]pixelsRow-major palette indices

Value ranges:

  • offset_left: 0..5
  • offset_top: 0..19
  • width: 1..22
  • height: 1..25

FBMP payload length equals the sum of all glyph record sizes (10-byte header + width * height pixels each).

RDAT Chunk (Optional, 173 bytes)

RDAT is optional and always 173 bytes when present.

Layout (partially decoded):

Numeric fields are little-endian.

OffsetSizeTypeNameDescription
0x00136[u8; 136]source_nameNUL-padded source/tool string
0x884u32unknown_90Non-zero metadata field
0x8C4u32unknown_94Non-zero metadata field
0x904u32unknown_98Always 0
0x944u32unknown_9cUsually 0; value 2 in ARIALBG.FNT
0x984u32unknown_a0Near max_width-like values
0x9C4u32unknown_a4Near line_height-like values
0xA04u32unknown_a8Small enum-like values (1..3)
0xA44u32unknown_acSmall enum-like values (1..2)
0xA84u32unknown_b0Always 0
0xAC1u8unknown_b4Always 0

RDAT is metadata. The font loader uses FNHD, FPAL/BPAL, and FBMP; it does not parse RDAT payload data.

External References