Back to graph

Topic analysis

Show HN: TTF-DOOM – A raycaster running inside TrueType font hinting

A DOOM-style raycaster that runs inside a TrueType font's hinting program. TrueType fonts have a built-in virtual machine for grid-fitting glyphs. It's got a stack, storage slots, arithmetic, conditionals, function calls - and it turns out it's Turing-complete. I wanted to see if I could get it to render 3D graphics. The font file contains a DDA raycasting engine written in TrueType bytecode. The glyph "A" has 16 vertical bar contours, and the hinting program raycasts against a 16x16 tile map and repositions those bars using SCFS instructions to form a 3D perspective view. The whole thing is 6.5 KB. JS handles movement, enemies, and shooting, then passes coordinates to the font through font-variation-settings . The font does the raycasting and wall rendering. Canvas overlay draws enemies, weapon, and HUD on top. I wrote a small compiler that takes a custom DSL and outputs TrueType hinting assembly. The DSL looks like a stripped-down C: This compiles to TT bytecode - FDEF , CALL , RS , WS , SCFS , etc. - and gets injected into a .ttf file along with sin/cos lookup tables and the map data. The compiler handles variable allocation (everything goes into TT storage slots), function definitions (FDEF/ENDF), and a few other things like fixed-point math. The pipeline: doom.doom -> lexer -> parser -> codegen -> doom.ttf MUL does (a*b)/64 . Not a*b . Everything is F26Dot6 fixed-point internally. So 1 * 4 = 0 . I lost probably two days to this before I found a workaround: DIV(a, 1) returns a * 64 (DIV is equally broken), then MUL(a*64, b) = (a*64*b)/64 = a*b . There's no WHILE instruction either. Loops compile to recursive FDEFs, and FreeType caps the call stack at ~64 frames. 16 columns x 14 ray steps barely fits. return inside a recursive-while doesn't exit. It pushes a value and keeps going. Everything had to be rewritten with hit flags. SCFS takes F26Dot6 pixel coordinates, not font units - took me a while to figure out why every bar was a tiny speck. Chrome caches hinted glyphs and sometimes skips re-hinting when axes change - fixed with per-frame jitter. SVTCA[0] selects Y, [1] selects X. The font just renders walls. JS does everything else. Player position and angle go into three font variation axes ( MOVX , MOVY , TURN ). JS stuffs coordinates into font-variation-settings every frame. Browser re-hints the glyph. Shape changes. Press Tab in the demo to see what's going on under the hood: Open http://localhost:8765/hosts/browser/index.html in Chrome or Edge. WASD to move, arrows to turn, Space to shoot. Press Tab for a debug overlay showing the font variation axes in real-time. llama.ttf also runs computation in a font, but it uses HarfBuzz's WASM shaper - basically a WebAssembly runtime bolted onto font shaping. TTF-DOOM uses the actual TrueType hinting bytecode that Apple shipped in 1991 for grid-fitting glyphs. Different VM entirely.

Heat score

1

Sources

1

Platforms

1

Relations

0
First seen
Apr 7, 2026, 3:25 AM
Last updated
Apr 7, 2026, 8:00 AM

Why this topic matters

Show HN: TTF-DOOM – A raycaster running inside TrueType font hinting is currently shaped by signals from 1 source platforms. This page organizes AI analysis summaries, 1 timeline events, and 0 relationship edges so search engines and AI systems can understand the topic's factual basis and propagation arc.

News

Keywords

7 tags
raycasterrunninginsidefonthintingstyleruns

Source evidence

1 evidence items

Show HN: TTF-DOOM – A raycaster running inside TrueType font hinting

News · 1
Apr 7, 2026, 3:25 AMOpen original source

Timeline

Show HN: TTF-DOOM – A raycaster running inside TrueType font hinting

Apr 7, 2026, 3:25 AM

Related topics

No related topics have been aggregated yet, but this page still preserves the AI summary, source links, and timeline.