Language Overview

Lux is a Lua 5.1 / GLua superset for GMod development. It keeps Lua's direct imperative style while moving module loading, public APIs, realm checks, macros, and host transforms into the compiler.

Examples use the code switcher in the top-right corner. Read the Lux source, then switch to generated Lua to see the runtime shape.

Parsesyntax, macros, and host transform hooks
Resolvemodule directories, part files, imports, and exports
Checkrealms, externs, ordering, and public API rules
EmitLua artifacts, loaders, source maps, and diagnostics

A Complete Small Example

This client HUD snippet shows the main Lux style: explicit imports, small functions, enums, match, guards, arrow callbacks, template strings, and explicit exports.

Client HUD snippet
import { arr } from "@lux/std"

enum Tier repr number {
  Guest = 0,
  Regular = 1,
  Veteran = 2,
}

fn tierForExp(exp) {
  stopif exp == nil, Tier.Guest
  stopif exp < 5, Tier.Guest
  stopif exp < 25, Tier.Regular
  Tier.Veteran
}

client fn drawPlayerList(players) {
  local names = arr.map(players, (ply) => {
    local tier = tierForExp(ply:GetNWInt("lux_exp"))
    local label = match tier {
      Tier.Guest => "guest"
      Tier.Regular => "regular"
      Tier.Veteran => "veteran"
    }
    `${ply:Nick()} (${label})`
  })

  draw.SimpleText(table.concat(names, ", "), "DermaDefault", 16, 16)
}

export client { drawPlayerList }

Core Feature Checklist

Lux adds syntax and compiler behavior in a few focused areas:

  • fn declarations with expression bodies, block bodies, default parameters, implicit tail returns, and top-level function hoisting.
  • Guard statements such as stopif and stopifn for early returns and loop control.
  • Arrow functions for short callbacks and method-friendly callback assignment.
  • Optional access and ?? for nil-safe expression composition without losing false.
  • Destructuring, table spread, compound assignment, pipelines, do expressions, and template strings.
  • Directory modules made from multiple part files that share one module-private scope.
  • Explicit import/export syntax where exported names form the public API.
  • Realm-aware declarations and blocks for client, server, and shared GMod artifacts.
  • Scalar and table enums with checked match expressions.
  • Compile-time macros and host transforms for domain-specific lowering.

Relationship to Lua

Lux is not trying to hide Lua. Generated code is intended to be readable enough for stack traces, code review, and debugging in a live GMod server.

The compiler follows these principles:

  • preserve Lua evaluation order;
  • emit direct functions, tables, branches, and loops where possible;
  • avoid generated closures for ordinary match and conditional expressions;
  • keep source maps and optional source comments usable;
  • report deterministic diagnostics before generating Lua that GMod would reject.

When Lux syntax maps to a tricky Lua rule, the docs show both sides in the same code block switcher.

Terms Used in the Docs

module: a logical Lux module, usually a directory under the source root.

part: one .lux file inside a module. All parts in a module share module scope, but imports are part-local.

realm: one of client, server, or shared. Realms affect availability, imports, exports, and generated artifacts.

exported name: the public API name visible to other modules.

binding: the internal module-scope name created by a declaration.

extern: a declaration or config entry that tells Lux the realm of an external symbol outside Lux's known module graph.

host transform: a package-provided compile-time rewrite attached to imports from a specific runtime module.

Reading Order

Read the language reference in this order:

  1. Functions and Control Flow
  2. Modules and Parts
  3. Imports and Exports
  4. Realms
  5. Enums and Match
  6. Macros and Host Transforms

Then move to GMod backend and Generated Lua to understand how Lux projects become addon artifacts.