MTAX — Lua Modding
Write Lua 5.4 mods for MTAX without leaving the editor. Two layers sit behind everything here. A Lua 5.4 parser with scope resolution, written for this extension, drives navigation, the outline, rename and semantic highlighting — so clicking a name finds the binding, not other text that happens to match. An API snapshot knows the 1,059 native functions, the 172 events, the OOP API
(26 classes plus 14 static classes), the sandbox and the Table of contents
FeaturesLanguage supportEverything a Lua editor is expected to do, answered from the syntax tree:
Scope stops at the resource. Each MTAX resource runs in its own Lua VM, so a global defined in resource A genuinely does not exist in resource B — and navigation refuses to jump across that line, unlike a general-purpose Lua server that would treat the whole folder as one scope. ColourNames are coloured for what they are — native, event, OOP class, local, parameter, property,
method, label — rather than all alike. A native called from the wrong side is marked
Two layers share the work, and they do not overlap. A TextMate injection grammar generated
from the API owns the MTAX identity — natives, engine globals, OOP classes and event names get
their own The split matters, because a semantic token silently replaces the scope underneath it: claiming
The MTAX APICompletion that knows which side the file runs onAs you type in a script, natives show up with their signature, description and example.
The ones that do not exist on that side are still offered — flagged with
The side comes from the manifest: a file listed in Event names where event names belongInside the Hover and signature helpHovering shows the signature, parameters with type and default, the return value, the OOP
equivalent and a link to the wiki. While you type the arguments, the current parameter is
highlighted — and when a native has both a server and a client variant ( All of it in English or Portuguese, following the VS Code display language or the
Problems the server would reject
Every rule carries its own severity and can be turned off. The ones worth fixing
automatically offer a quick fix (
A real
|
| Command | Shortcut | What it does |
|---|---|---|
MTAX: New Resource… |
— | Creates the folder with a manifest and scripts. Five layouts: server + client, server only, client only, with NUI, loading screen |
MTAX: New Script… |
— | Creates the script and declares it in the right manifest list |
MTAX: Search the API… |
Ctrl+Alt+M |
Searches the 1,059 natives; inserts the call or opens the documentation |
MTAX: Open documentation… |
Ctrl+Alt+D |
Opens the wiki page for the symbol under the cursor |
MTAX: Convert meta.xml… |
— | Converts a legacy MTA resource to mtaxmanifest.lua |
MTAX: Set up lua-language-server |
— | Points sumneko at the MTAX definitions |
MTAX: Set the side of the current file |
— | Pins client / server / shared when inference gets it wrong |
MTAX: Regenerate the API… |
— | Regenerates everything from the local MTAX-Purple/ and wiki/ |
On macOS the shortcuts are Cmd+Alt+M and Cmd+Alt+D.
lua-language-server (optional)
The extension ships generated LuaCATS files (definitions/) with the 1,059 natives
annotated, the OOP classes with their inheritance, and Vector2/3/4 and Matrix. If
sumneko.lua is installed, the
extension offers to point it at those definitions — giving you real type inference layered on top
of everything described above. It also disables io, package and debug in sumneko's
completion, since the MTAX sandbox does not have those libraries.
None of this is required: without sumneko, the extension works on its own.
Configuration
| Key | Default | What it controls |
|---|---|---|
mtax.enable |
true |
Turns the whole language layer on or off |
mtax.docsLanguage |
auto |
auto, en or pt in hovers and completion |
mtax.semanticHighlighting |
true |
Colour names for what they are, not all alike |
mtax.diagnostics.enable |
true |
Turns problem reporting on |
mtax.diagnostics.syntax |
error |
Lua syntax errors from the built-in parser |
mtax.diagnostics.wrongSide |
warning |
Native from one side called from the other |
mtax.diagnostics.sharedSideCalls |
off |
The same, but inside a shared script |
mtax.diagnostics.unknownNative |
warning |
Function shaped like a native that does not exist in MTAX |
mtax.diagnostics.typos |
warning |
Name one or two characters away from a real native |
mtax.diagnostics.sandbox |
error |
require, io, package, os.execute… |
mtax.diagnostics.manifest |
true |
Validation of mtaxmanifest.lua |
mtax.diagnostics.deprecatedMeta |
true |
Points out meta.xml files and offers to convert them |
mtax.completion.oop |
true |
Suggest the OOP API alongside the plain natives |
mtax.completion.snippets |
true |
Expand a native into a call with its arguments as tab stops |
mtax.luals.autoConfigure |
ask |
ask, always or never for configuring sumneko |
mtax.statusBar |
true |
Show the file side in the status bar |
mtax.author |
"" |
Name written to resource_author when scaffolding a resource |
mtax.sourceRoot |
"" |
Folder holding MTAX-Purple/ and wiki/, used to regenerate the API |
Where the data comes from
data/api.json, definitions/*.lua and syntaxes/*.json are generated, never edited by hand:
| Source | What comes out of it |
|---|---|
Shared/src/lua_api/catalog/functions.h |
the 1,059 natives, with side and confidence level |
Shared/src/lua_api/oop/oopclasses.h |
OOP classes, methods, properties, inheritance |
Shared/src/lua_api/sandbox/policy.h |
open libraries, removed globals, restricted os fields |
Shared/src/lua_api/prelude/prelude.h |
pure-Lua helpers (bit*, utf*, split, inspect, ref…) |
Server/src/modules/resources/manifest.cpp |
the manifest keys and the validation rules |
wiki/src/content/docs/{en,pt} |
descriptions, signatures, parameters, returns, examples and events |
Out of those come the API snapshot the extension reads at runtime, the LuaCATS definition files, and the TextMate injection grammars that colour the API.
To regenerate after changing the engine or the wiki:
npm run generate # searches upwards for MTAX-Purple/ and wiki/
npm run generate -- --root "D:/Projetos MTAX"
Or, from inside VS Code, run MTAX: Regenerate the API from local MTAX sources.
Current coverage: 1,059 / 1,059 signatures and 1,058 / 1,059 descriptions.
Developing the extension
npm install
npm run generate # data/api.json + definitions/
npm run compile # bundle into dist/
npm run watch # rebuild on save
npm test # 67 tests: parser, scopes, manifest, API, grammar and end-to-end activation
npm run package # produces the .vsix
F5 in VS Code opens a window with the extension loaded.
The tests run against the real bundle with a stub of the VS Code API, so a hang on activation or a broken provider shows up before packaging. The colouring is checked against the actual TextMate engine layered over VS Code's own Lua grammar, because an injection selector is easy to get subtly wrong and impossible to eyeball.
Project layout
tools/generate-api.mjs reads engine + wiki, writes data/, definitions/ and syntaxes/
src/lua/lexer.ts Lua 5.4 tokens, long brackets, escapes, BOM and shebang
src/lua/parser.ts error-tolerant recursive descent -> syntax tree
src/lua/analyze.ts scopes, bindings, references, dotted paths, the outline
src/lua/index.ts per-file and per-resource caches
src/api/model.ts loads and indexes the API snapshot
src/manifest/ parsing, path rules, globs, side resolution
src/features/ completion, hover, signature help, diagnostics, quick fixes,
navigation, semantic tokens, links, status bar, commands,
scaffolding, luals
The parser never throws. A file is re-read on every keystroke, so half-typed code is the normal
case: what it cannot understand is recorded, the token is skipped, and the walk continues — an
unfinished if at the bottom of a file does not cost you the outline of everything above it.
It is checked against the real thing: 618 Lua files from the server's own resources/ folder,
6.6 MB, parse with zero errors — the only three failures are MTXA-protected script
containers, which are not Lua at all.
License
Released under the MIT License. Copyright (c) 2026 CMR Services.