A language forged for games

Iron compiles to C and produces native binaries with zero runtime overhead. Manual memory control, first-class concurrency, and game-dev primitives — all with clean, readable syntax.

Latest: v0.0.1-alpha · Apache 2.0
game.iron
import raylib

object Player {
  var pos:   Vec2
  var hp:    Int
  val speed: Float
  val name:  String
}

func Player.update(dt: Float) {
  if is_key_down(.RIGHT) { self.pos.x += self.speed * dt }
  if is_key_down(.LEFT)  { self.pos.x -= self.speed * dt }
}

func main() {
  val window = init_window(800, 600, "My Game")
  defer close_window(window)

  var player = Player(vec2(0.0, 0.0), 100, 200.0, "Victor")

  while not window_should_close() {
    player.update(get_frame_time())
    draw {
      clear(DARKGRAY)
      player.draw()
    }
  }
}

Built for developers who ship games

Iron gives you the performance of C with a modern syntax that stays out of your way.

Performance

Compiles to C and produces native binaries. No garbage collector, no VM, no interpreter overhead. Just raw speed.

Control

You manage memory explicitly — stack, heap, reference counting — with compiler-assisted safety nets. No borrow checker, no hidden magic.

Game-Dev First

Thread pools, parallel loops, draw {} blocks, and concurrency primitives are first-class language features, not library afterthoughts.

Legible

No operator overloading, no implicit conversions, no hidden control flow. When you read Iron code, you know exactly what it does.

Features

Power where you need it

Iron gives you fine-grained control without boilerplate.

Memory, your way

Choose the right strategy for each allocation. Stack by default, heap when you need it, reference counting for shared ownership. The compiler tracks escapes and auto-frees when safe.

  • Stack allocation by default — zero overhead
  • Escape analysis auto-frees heap values that don't leave scope
  • Opt-in rc for shared ownership
  • defer for deterministic resource cleanup
  • leak for intentional permanent allocations
memory.iron
-- stack: default, auto-freed at scope exit
val pos = vec2(10.0, 20.0)

-- heap: auto-freed when value doesn't escape
val enemies = heap [Enemy; 64]

-- reference counted: shared ownership
val sprite = rc load_texture("hero.png")
var other = sprite  -- ref count = 2

-- deterministic cleanup
val file = open_file("save.dat")
defer close_file(file)

-- intentional permanent allocation
val atlas = heap load_texture("atlas.png")
leak atlas

First-class concurrency

Named thread pools, typed channels, mutexes, and parallel loops are built into the language. No external threading libraries, no callback pyramids.

  • Named thread pools with CPU pinning
  • Typed channels for safe message passing
  • parallel loops with automatic work distribution
  • Compiler prevents mutable captures in parallel blocks
concurrency.iron
val compute = pool("compute", 4)
val io = pool("io", 1)

-- background work on a specific pool
val handle = spawn("load-assets", io) {
  return load_texture("hero.png")
}
val tex = await handle

-- typed channels
val ch = channel[Texture](8)
ch.send(load_texture("hero.png"))
val tex = ch.recv()

-- parallel loops across cores
for i in range(len(particles)) parallel(compute) {
  particles[i].update(dt)
}

Compile-time evaluation

Any pure function can run at compile time. Build lookup tables, embed files, precompute values — all baked into the binary with zero runtime cost.

  • Call any pure function with comptime
  • Embed files directly into the binary
  • Build lookup tables at compile time
  • Same function works at runtime and compile time
comptime.iron
func build_sin_table() -> [Float; 360] {
  var table = [Float; 360]
  for i in range(360) {
    table[i] = sin(Float(i) * 3.14159 / 180.0)
  }
  return table
}

-- evaluated at compile time, zero cost
val SIN_TABLE = comptime build_sin_table()

-- embed files directly
val SHADER = comptime read_file("main.glsl")

-- same function also works at runtime
val dynamic = build_sin_table()

Get started in seconds

Clone, build, and run your first Iron program.

1
git clone https://github.com/victorl2/iron-lang.git
2
cd iron-lang && cmake -B build && cmake --build build
3
./build/iron run examples/hello.iron
hello.iron
func main() {
  println("Hello, Iron!")
}