Yo Odin ยท Chapter 1

Chapter 1: Yo, Odin: setup and a first look

This chapter: install and verify the Odin toolchain, set up your editor, compile and run a first program, and see the road ahead.


1.1 What we're building

Destroids, an Asteroids clone. You fly a vector ship in a wrap-around field of drifting rocks; shoot them and they split into smaller, faster pieces; clear the wave for a bigger one; you get three lives and a risky hyperspace jump. The finished game has:

  • a twinkling starfield of ~380 points;
  • a ship with thrust, inertia, and a flickering flame;
  • rotating polygon asteroids that bounce off each other;
  • sparks, spinning debris, shockwave rings, and screen shake on every hit;
  • a HUD (score, wave, lives), plus intro, pause, and game-over screens;
  • live-synthesised sound, no audio files;
  • a high score saved across reloads.

All of it is canvas lines and rectangles, one WebAssembly module, three static files. No engine, no assets, no dependencies.

Why the constraints? When you can't reach for a sprite sheet or a physics library, you have to understand what a sprite and a collision actually are, and that understanding transfers to whatever you build next.

1.2 Why Odin, why WebAssembly

Odin is a compiled, statically typed, manually memory-managed language in the C tradition, by Ginger Bill. Four things make it a good fit here:

  • It targets WebAssembly directly: odin build -target:js_wasm32, no plumbing.
  • Array programming is built in: a [2]f32 behaves like a vector (add, scale, swizzle), which is exactly what 2D maths wants.
  • No hidden garbage collector: allocation is explicit, which matters in a 60 fps loop.
  • It's small: you can learn the parts we need in one chapter.

WebAssembly runs compiled code at near-native speed inside a web page, reachable by anyone with a browser and no install step. Odin + WASM + Canvas is a dependency-free game target.

1.3 What you need

A desktop (macOS, Linux, or Windows), a terminal, a text editor, and a recent desktop browser. Destroids is keyboard-controlled, so it's a desktop game.

1.4 Installing Odin

Follow the official, always-current guide:

https://odin-lang.org/docs/install/

Odin builds on LLVM, so its one dependency is a matching LLVM/Clang, which that page pins per platform. In short:

  • macOS: brew install odin (Homebrew), or build from source against Homebrew's LLVM.
  • Linux: install the specified LLVM, clone Odin, run build_odin.sh.
  • Windows: install the Visual Studio Build Tools, then use a prebuilt release or build from source.

Verify:

odin version      # prints e.g. "odin version dev-2026-07"
odin report       # diagnostics, paste this when asking for help

Odin note. Odin moves quickly and most people track a recent build. I use only long-stable parts of the language here, so any current Odin compiles it; Appendix D notes the few places most likely to drift.

1.5 Editor setup

Any editor works, but syntax highlighting and a language server, **ols**, give you autocomplete, and inline errors. The ols README has per-editor setup (VS Code, Neovim, Emacs, Sublime, anything with an LSP client).

The command you'll run most needs no editor:

odin check <directory>   # type-check only, no binary: "did I just break something?"

1.6 Hello, Odin

// hello/main.odin
package main

import "core:fmt"

main :: proc() {
	fmt.println("Yo, Odin!")
}

Run it from the folder containing hello:

odin run hello
# => Yo, Odin!

The essentials, unpacked properly in Chapter 2:

  • package main: a directory is a package; an executable's package is main.
  • import "core:fmt": core: is the bundled standard library; fmt prints.
  • main :: proc() { โ€ฆ }: Odin declares with name :: value; here the value is a procedure.
  • fmt.println(โ€ฆ): call println from fmt.

Odin note. Three verbs: odin run (build + run), odin build (build only), and odin check (type-check only). You'll use all three.

That was a native binary for your machine. Soon we'll compile other code to WebAssembly: same compiler, different -target, and by the end you'll routinely build two targets from one project: the game to WASM, and the server that serves it to native.

1.7 The road ahead

Twelve chapters, each ending somewhere runnable:

  1. Setup and a first look (here)
  2. Enough Odin to be dangerous
  3. Odin meets the browser (WebAssembly)
  4. Serving the game (an Odin web server)
  5. The renderer, part 1: command buffer + bridge
  6. The renderer, part 2: canvas, loop, input
  7. The game takes shape: loop, state, ship
  8. Rocks and bullets: asteroids, shooting, collisions
  9. Juice: particles, debris, shake, starfield, hyperspace
  10. HUD, state, and a persistent high score
  11. A voice: synthesised sound
  12. Determinism, build, and ship

Then appendices: Odin quick-reference, full source listings, extending the renderer, troubleshooting, links, and changelog.

The project's final shape (don't create it yet):

yo-odin/
โ”œโ”€โ”€ batch/          renderer library (Ch. 5โ€“6)
โ”œโ”€โ”€ web/batch.js    its JavaScript glue
โ”œโ”€โ”€ src/            the game (Ch. 7โ€“11)
โ”œโ”€โ”€ server/         the Odin web server (Ch. 4)
โ”œโ”€โ”€ index.html      the host page
โ”œโ”€โ”€ dist/           build output (three shipped files)
โ”œโ”€โ”€ build.sh
โ””โ”€โ”€ run.sh

Checkpoint

odin version works, you know the three verbs, your editor understands Odin, and you've run your first program.

Exercises

  1. Add a second fmt.println line and re-run.
  2. Use odin build hello instead of run; find and run the binary. What differs?
  3. Break the program (drop a brace) and read what odin check hello says.

Further reading