Skip to content

Repository files navigation

tua

Typed Lua source-to-source tooling for LuaJIT and LOVE projects.

Documentation · GitHub Releases · VS Code Extension

Tua starts with normal Lua syntax, adds erased type syntax and a small amount of LuaJIT-safe sugar, then emits readable Lua 5.1-compatible code. It is built for projects that want stronger editor feedback, static checks, and build tooling without leaving the normal Lua and LOVE workflow.

local controls = input({
  controls = {
    left = { "key:left", "key:a" },
    right = { "key:right", "key:d" },
    up = { "key:up", "key:w" },
    down = { "key:down", "key:s" },
    collect = { "key:space", "button:a" },
    pause = { "key:escape", "button:start" },
  },
  pairs = {
    move = { "left", "right", "up", "down" },
  },
})

local game = store({
  score = 0,
  player = vec2(80, 120),
})

local flow = stateMachine({
  initial = "playing",
  events = {
    { name = "pause", from = "playing", to = "paused" },
    { name = "resume", from = "paused", to = "playing" },
  },
})

local events = signal()
events:on("coin.collected", function(points: number)
  game:update(function(state)
    state.score += points
  end)
end)

function love.update(dt: number)
  controls:update()

  if controls:pressed("pause") then
    if flow.current == "playing" then flow:pause() else flow:resume() end
  end

  if flow.current ~= "playing" then return end

  local moveX, moveY = controls:get("move")
  game:update(function(state)
    state.player.x += moveX * 180 * dt
    state.player.y += moveY * 180 * dt
  end)

  if controls:pressed("collect") then
    events:emit("coin.collected", 10)
  end
end

function love.draw()
  local state = game:get()
  love.graphics.circle("fill", state.player.x, state.player.y, 16)
  love.graphics.print("Score: " .. tostring(state.score), 16, 16)
end

This repository contains the compiler core, CLI, language server, VS Code extension, documentation site, and bundled example projects.

What Tua Provides

  • Erased local, function, alias, table-shape, optional-field, and union types.
  • Readable Lua 5.1-compatible output for LuaJIT and LOVE 11.x.
  • A CLI for init, check, fmt, lint, build, traceback, watch, and lsp.
  • A compiler-backed language server and VS Code extension with diagnostics, completion, hover, signature help, rename, references, semantic tokens, inlay hints, document/workspace symbols, and more.
  • LOVE-aware helpers, API catalogs, callback guidance, and asset-path validation for both Tua helpers and native LOVE constructors.
  • Opt-in built-in helpers such as Vec2, spriteSheet({...}), Baton-backed typed input, signal buses, state stores, state machines, ECS, and object pools.
  • Mixed-source builds where .tua files compile to .lua, while plain .lua files and assets are copied into the build output for runnable LOVE folders.

What You Can Do With It

  • Write typed gameplay code that still ships as ordinary Lua source.
  • Keep existing Lua modules and gradually adopt .tua where stronger tooling helps.
  • Build LOVE projects with editor-aware assets, generated-Lua/source-map navigation, source-mapped Lua debugging, and project graphs for modules, signals, state machines, ECS, and object pools.
  • Use one versioned toolchain across the CLI, language server, release VSIXs, and documentation.

VS Code Extension

The extension lives in editors/vscode and is distributed through GitHub release VSIXs plus registry publishing for Visual Studio Marketplace and Open VSX. Published VSIX packages bundle the matching tua server binary for each platform, so extension installs do not download a server at activation time.

It provides compiler-backed Tua editing, LOVE-aware completion and diagnostics, generated Lua inspection, project commands for running or debugging LOVE, and source-linked explorers for assets, modules, signals, state machines, ECS, and object pools.

Experimental local Ollama ghost-text completion is opt-in and compiler validated before display. Trusted local tools can also explicitly start the read-only tua api --stdio JSON-RPC session or tua mcp --stdio; neither service opens a network socket or starts automatically.

Learn More

Development

Pending contributor priorities are tracked in ROADMAP.md.

cargo test --workspace
cargo run -p tua-cli -- --help

Useful local workflows:

make build-features
make editor-regression-smoke
make extension-package

GitHub Linguist support materials live in support/github-linguist/.

Serve the documentation site locally:

make docs

Examples

  • examples/features is a buildable tour of the v1 language and LSP features.
  • examples/linter intentionally breaks every currently emitted standard lint rule and is expected to fail tua lint.
  • examples/love-minimal is a small LÖVE smoke-test project.
  • examples/love-full is a larger LÖVE conversion example with Lua interop.
  • examples/love-tua is a mixed Tua/Lua bullet-hell showcase combining ECS, object pools, stores, state machines, typed input, and vendored Feel feedback.

About

tua is a typed Lua superset that compiles to plain Lua 5.1-compatible source for LuaJIT and LÖVE projects.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages