Hacker News Viewer

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

by 4RH1T3CT0R on 4/6/2026, 7:25:39 PM

TrueType fonts have a hinting VM that grid-fits glyphs. It has a stack, storage area, conditionals, function calls, and it turns out it&#x27;s Turing-complete. So I built a raycasting engine in the hinting bytecode.<p>The glyph &quot;A&quot; in the font has 16 vertical bar contours. The hinting program reads player coordinates from font variation axes via GETVARIATION, does DDA ray marching against a tile map in the storage area, and repositions bar heights with SCFS. It ends up looking like a crude Wolfenstein-style view.<p>Small visuzlization: <a href="https:&#x2F;&#x2F;github.com&#x2F;4RH1T3CT0R7&#x2F;ttf-doom&#x2F;blob&#x2F;main&#x2F;docs&#x2F;media&#x2F;transform.gif" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;4RH1T3CT0R7&#x2F;ttf-doom&#x2F;blob&#x2F;main&#x2F;docs&#x2F;media...</a><p>About 6.5 KB of bytecode total - 13 functions, 795 storage slots, sin&#x2F;cos lookup tables.<p>JS handles movement, enemies, and shooting, then passes the coordinates to the font through CSS font-variation-settings. The font is basically a weird GPU.<p>The weirdest parts: - TrueType MUL does (a<i>b)&#x2F;64, not a</i>b. So 1*4=0. The DIV instruction is equally cursed. - No WHILE loops. Everything compiles to recursive FDEFs. FreeType limits call depth to ~64 frames. - SVTCA[0] is Y, SVTCA[1] is X. Of course.<p>There&#x27;s a small compiler behind this - lexer, parser, codegen - that turns a C-like DSL into TT assembly.<p>Demo GIF: <a href="https:&#x2F;&#x2F;github.com&#x2F;4RH1T3CT0R7&#x2F;ttf-doom&#x2F;blob&#x2F;main&#x2F;docs&#x2F;media&#x2F;demo.gif" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;4RH1T3CT0R7&#x2F;ttf-doom&#x2F;blob&#x2F;main&#x2F;docs&#x2F;media...</a><p>Live demo: <a href="https:&#x2F;&#x2F;4rh1t3ct0r7.github.io&#x2F;ttf-doom&#x2F;" rel="nofollow">https:&#x2F;&#x2F;4rh1t3ct0r7.github.io&#x2F;ttf-doom&#x2F;</a> (Chrome&#x2F;Edge, WASD+arrows, Space to shoot, Tab for debug overlay)<p>This is a DOOM-style raycaster, not a port of the original engine - similar to DOOMQL and the Excel DOOM. The wall rendering does happen in the font&#x27;s hinting VM though. Press Tab in the demo to watch the font variation axes change as you move.

https://github.com/4RH1T3CT0R7/ttf-doom

Comments

by: emanuele-em

Ok the MUL workaround got me. MUL does (a<i>b)&#x2F;64 so you have to DIV first to get a</i>64, then MUL finally gives you a*b. And recursive FDEFs because there&#x27;s no WHILE? All in 6.5KB? What kind of frame rate do you actually get out of this?

4/6/2026, 9:12:47 PM


by: tadfisher

You are (or I suspect your LLM is) not correct about Doom using a raycasting engine. Wolfenstein fits that description, yes. Doom rather famously introduced BSP for level data and it draws sorted polygons front-to-back without ray-marching.

4/6/2026, 11:11:07 PM


by: tombert

I tried playing the demo, and it was just green bars for me. The walls didn&#x27;t scale up or shrink, it was just a bunch of solid static green bars.<p>The enemies did scale up and shrink as I got closer, and the minimap worked.<p>Tried with Brave on Linux, and Google Chrome on macOS.

4/6/2026, 11:00:40 PM