logo
Kurashizu Blogwhere ideas flow
  • Home
  • News
  • Blog
  • About
  • Home
  • News
  • Blog
  • About

© 2026 Kurashizu. All rights reserved.

Admin·New Post·Service Status
Powered by Cloudflare·05.11.26
← Back to news

56,000 lines of DOOM, in a language I made up

Original article
betlang.dev|16 points|12 comments|by ghuntley|Jul 16, 2026

56,000 Lines of DOOM: Written in a Language I Invented

Overview: What is betlang?

bet (v0.1.0) is a legitimate programming language that wears a mask of irony. On the surface, it utilizes slang keywords that resemble a modern group chat, but beneath that facade lies a professional-grade compiler.

Key Technical Capabilities:

  • Backend: Compiles to native machine code via LLVM.
  • Memory: Features a custom memory management system.
  • Self-Hosting: The language is capable of compiling its own source.
  • Proven: It successfully runs the original DOOM.

The Motivation: Beyond the "Product"

I developed bet during a hiatus from the grind of creating commercial software. I craved a project with a definitive boundary—something I could actually complete. Building a compiler had been a long-term ambition, and the "joke language" angle provided the perfect excuse to blend absurdity with rigorous engineering.

"A joke language gave me the excuse: keywords that read like a group chat, wrapped around a compiler that had to genuinely work."

I intentionally avoided researching existing projects during the early stages because I didn't want external influence to stifle the creative spark. I later discovered that Geoffrey Huntley had already explored this territory.


Engineering the "Crib": Memory Management

A language that only changes syntax is merely a "costume." To make bet a real tool, I gave it a specific architectural purpose. In game development, the overhead of manual free() calls or the unpredictable pauses of Garbage Collection (GC) can destroy a frame budget.

bet solves this using Arenas. Instead of tracking individual objects, you allocate memory into a scope and discard the entire scope at once. This is similar to the arena allocators found in Zig or the temp-allocators in Odin.

The Logic of crib and evict

In bet, this is a first-class citizen of the language:

  1. crib: Create an arena scoped to the current frame.
  2. evict: Wipe the entire arena in constant time.

The time complexity for clearing a frame is O(1)\text{O}(1)O(1).

Example Implementation:

frame.bet 
crib wave // Initialize arena for this frame
squad e in spawn(wave) { 
    e.tick() 
} 
evict wave // Entire scope is deleted instantly

The Development Process: Architect vs. Agent

I wanted to test the limits of AI coding agents on a complex, well-defined project. I stepped back from the implementation and acted solely as the Architect.

My Workflow:

  • Define the problem.
  • Establish strict acceptance criteria.
  • Enforce a "no-shortcut" policy.

No code was merged without verification. A change only shipped if it:

  • Passed all unit tests.
  • Met the architectural requirements.
  • Cleared the existing corpus.

The Compiler Pipeline


The Ultimate Stress Test: DOOM

To prove bet wasn't just a toy, I ported the original id Software C source code. This included the renderer, game logic, audio, and WAD loading.

The Scale of the Port:

  • Lines of Code: 56,000+56,000+56,000+
  • Precision: Utilizes fixed-point math.
  • Accuracy: The simulation is bit-for-bit identical to the reference C build.

If the math drifted by even a single step, the player would walk into walls. By replaying original recorded inputs in lockstep, I verified that bet could handle professional-grade software without shortcuts.

DOOM in betlang


Project Completion & Timelog

bet is finished. There is no "Version 2" and no roadmap. It served its purpose as an experiment in learning and a testament to my ability to finish what I start.

Active Effort Tracking: Note: The "Porting Games" row is inflated by ~12 hours due to AI agent usage limits.

TaskDescriptionTime Spent
Porting GamesDOOM, Oregon Trail, Pong18h
Self-HostingCompiling bet with bet4h
SecurityReviewing cwage issues #30–#483h
Infra/ToolingCI, Docker, Docs, Site3h
FrontendLexer, Parser, Grammar2h
LanguageTypes, Keywords, Containers2h
LLVM BackendThe core engineering1h
Arena Memorycrib and evict logic29m
TotalTracked Active Effort≈34h\approx 34\text{h}≈34h

Prior Art

Credit is due to Geoffrey Huntley, who created cursed. He utilized a similar approach: a slang-based language compiled via LLVM and directed by AI.

  • Original Write-up: ghuntley.com/cursed
  • Follow: @GeoffreyHuntley on 𝕏