Preface
This is the advanced book on the shelf. It doesn't teach you Odin: it assumes you already know it, ideally from finishing Yo Odin or Odin't Know That, or from equivalent comfort with structs, arrays, pointers, context and calling conventions. What it teaches instead is a skill most programmers never get a proper run at, because most day-to-day work never asks for it: how to build a real programming language, by hand, from an empty directory, in a systems language, and embed it inside a larger program so that other code, code you didn't write and won't recompile, can drive your program's behaviour.
By the last page you'll have built Muspel: a lexer, a recursive-descent parser, structured data (structs, enums, fixed-capacity arrays), a tree-walking interpreter (built deliberately, then deliberately outgrown), a bytecode compiler, a resumable stack-based virtual machine, a multi-file module system, and a host-embedding layer, all from scratch, all in Odin, all using nothing the Odin compiler doesn't already ship with. You'll finish by watching Embers, a small arcade game built alongside the language, change its own boss fight's timing while it's running, because you edited a text file and saved it.
Who this is for
An Odin programmer who has built at least one non-trivial project already, comfortable with pointers, manual memory layout, and reading a grammar. Nobody needs prior compiler or interpreter experience; this book teaches parsing and bytecode design from first principles, just not Odin from first principles. If the sentence "walk the AST and evaluate each node" doesn't yet mean anything to you, that's fine: it will by Chapter 8, and structs, enums, and arrays as a Muspel script sees them will make sense two chapters before that. If the words context, defer, or "fixed-capacity array" are unfamiliar, go and finish one of the other two books first; this one assumes you're past that.
What you'll build
Two things, kept deliberately separate: muspel/, a standalone scripting-language package that never imports a game, and Embers, a small top-down arcade host whose entire enemy-wave and boss behaviour layer is .mus script files, not compiled game logic. The separation is itself the lesson: a scripting layer entangled with its first host was never actually reusable.
Along the way you get musc, a command-line tool that lexes, parses, checks, compiles, disassembles and runs a .mus file, so every layer of the language has a satisfying, runnable checkpoint long before Embers exists to embed it in anything.
The ground rules
- Odin's own standard library only.
core:,base:,vendor:packages, nothing else. No parser-generator, no existing bytecode-VM framework, no third-party anything: the entire point is that you build a lexer, parser, compiler and VM by hand and understand every line of it. - Zero binary assets. Embers is drawn with canvas or shape primitives exactly like the rest of the shelf; no images, no audio files.
- Self-contained. No chapter assumes code fetched from outside this book.
- Every design decision gets a "why," not just a "how." Wherever the language could reasonably have been built a different way, stack machine or register machine, tree-walk or bytecode-first, OS threads or a flat resumable loop, this book names the alternatives, states the trade-off, and states the choice, in a recurring Design decision callout. The goal is that you finish able to make different choices confidently for your own language, not just recite this one's.
- British English throughout.
How to read it
Build along, using musc from Chapter 2 onwards as your test bench. This book is considerably longer than its two siblings, because a real language implementation genuinely has seven separate engineering layers, lexing, parsing, structuring data, tree-walking, compiling and executing, modularising, embedding, and compressing any one of them would leave you with a book that describes an interpreter rather than one you actually built and could defend in an interview. Take it a part at a time; each of the six parts ends somewhere real and demoable.
Three kinds of callout recur, one of them new to this book:
Design decision: a real fork in the road. States the alternatives considered, the trade-off, and the choice made, and why.
Why: the reasoning behind something with only one reasonable answer, not a real fork.
Gotcha: a real trap the author hit, told so you don't have to hit it too.
Where this book sits, and where to go from here
This book's structure owes a considerable debt to Robert Nystrom's freely available *Crafting Interpreters*, the modern reference this book's approach rhymes with throughout, credited generously wherever that's true. What this book adds beyond it is doing all of it in Odin, structured data (structs, enums, fixed-capacity arrays) and a qualified-import module system alongside the language core, and going further into the specific, practical problem of embedding: a resumable VM that never blocks a game's frame loop, fault isolation against a script that misbehaves, and live hot-reload of running bytecode. Where this book's baseline implementation stops short (full closures with upvalues, a static type system, a JIT; though optional copying GC and map extensions are documented in Appendix G), it says so plainly and points you to Crafting Interpreters, at Lua, and at Wren for the next steps.
The other two volumes on the shelf are Yo Odin (https://nofuss.co.za/yo_odin/), building Destroids for the browser in WebAssembly, and Odin't Know That (https://nofuss.co.za/odint_know_that/), building the native desktop runner Sköll with raylib. Either is the right place to start if you haven't yet; this book is where you go once you have.
Acknowledgements are due to Ginger Bill and the Odin community for the language, and to Robert Nystrom for writing the book that made an entire generation of programmers, this author included, believe that building a language from scratch was something they could actually do.
Right. Let's build a language.