@thigasdevelopment/luam 0.13.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -562
- package/luam.mjs +7068 -1617
- package/package.json +1 -1
- package/template/luam.manifest +0 -4
package/README.md
CHANGED
|
@@ -18,137 +18,69 @@
|
|
|
18
18
|
<img alt="License" src="https://img.shields.io/badge/license-MIT-blue">
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`meta.xml` — a resource your server can start as-is.
|
|
21
|
+
Write `.luam` files with types, classes, enums and template strings. The
|
|
22
|
+
compiler checks them and emits readable **Lua 5.1** plus a generated `meta.xml` —
|
|
23
|
+
a resource your MTA server can start as-is.
|
|
25
24
|
|
|
26
|
-
It is *typed Lua*, not TypeScript. Blocks still end with `end
|
|
27
|
-
still `~=`,
|
|
25
|
+
It is *typed Lua*, not TypeScript. Blocks still end with `end`, inequality is
|
|
26
|
+
still `~=`, and comments use `#` and `#* ... *#`.
|
|
28
27
|
|
|
29
28
|
```lua
|
|
30
|
-
|
|
29
|
+
enum Target { LUA_51, MTA }
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
class Luam {
|
|
32
|
+
version: string
|
|
33
|
+
target: Target = Target.LUA_51
|
|
34
|
+
files: number = 0
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
constructor = function (version: string)
|
|
37
|
+
self.version = version
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
compile = function (source: string): string
|
|
41
|
+
self.files += 1
|
|
42
|
+
|
|
43
|
+
return `Luam ${self.version} compiled ${source} to plain Lua 5.1`
|
|
44
|
+
end
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
local luam = new Luam('0.15.6')
|
|
48
|
+
|
|
49
|
+
outputServerLog(luam:compile('src/server/main.luam'))
|
|
37
50
|
```
|
|
38
51
|
|
|
39
52
|
Annotations are erased at build time. `dxDrawText` in a server file, a typo in an
|
|
40
|
-
MTA function name, a `string`
|
|
41
|
-
|
|
53
|
+
MTA function name, a `string` where a `number` belongs — all build errors, before
|
|
54
|
+
the server starts. A build with any error writes nothing.
|
|
42
55
|
|
|
43
56
|
---
|
|
44
57
|
|
|
45
58
|
## Install
|
|
46
59
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
> · [Instalação](https://thigasdevelopment.github.io/luam/pt-br/guide/installation)
|
|
50
|
-
|
|
51
|
-
You need [Node.js](https://nodejs.org/) 20 or newer and an
|
|
52
|
-
[MTA:SA](https://multitheftauto.com/) 1.5+ server. No Lua toolchain — the
|
|
53
|
-
compiler emits Lua text, it never runs it.
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
node --version # must print v20.x or newer
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### 1. Install the CLI
|
|
60
|
+
Needs [Node.js](https://nodejs.org/) 20+ and an [MTA:SA](https://multitheftauto.com/)
|
|
61
|
+
1.5+ server. No Lua toolchain.
|
|
60
62
|
|
|
61
63
|
```bash
|
|
62
64
|
npm install --global @thigasdevelopment/luam
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
That gives you one command, `luam`. Check it:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
65
|
luam --version
|
|
69
66
|
```
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
| --- | --- |
|
|
73
|
-
| Install | `npm install --global @thigasdevelopment/luam` |
|
|
74
|
-
| Update to the latest | `npm update --global @thigasdevelopment/luam` |
|
|
75
|
-
| Install a specific version | `npm install --global @thigasdevelopment/luam@0.1.1` |
|
|
76
|
-
| Uninstall | `npm uninstall --global @thigasdevelopment/luam` |
|
|
77
|
-
| Run once, without installing | `npx @thigasdevelopment/luam <command>` |
|
|
78
|
-
|
|
79
|
-
`npx @thigasdevelopment/luam build` works anywhere and caches the download, which is handy in CI or
|
|
80
|
-
on a machine you would rather not install into.
|
|
81
|
-
|
|
82
|
-
<details>
|
|
83
|
-
<summary><b><code>luam: command not found</code> after installing</b></summary>
|
|
84
|
-
|
|
85
|
-
npm put the binary in its global bin directory and that directory is not on your
|
|
86
|
-
`PATH`. Find it:
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
npm config get prefix
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
- **Windows** — add that folder itself to your user `PATH`
|
|
93
|
-
(*Settings → System → About → Advanced system settings → Environment
|
|
94
|
-
Variables*), then open a **new** terminal.
|
|
95
|
-
- **macOS / Linux** — add `<prefix>/bin` to your `PATH` in `~/.zshrc` or
|
|
96
|
-
`~/.bashrc`, then run `source ~/.zshrc`.
|
|
97
|
-
|
|
98
|
-
Nothing to configure if you would rather not: `npx @thigasdevelopment/luam <command>` needs no
|
|
99
|
-
`PATH` entry at all.
|
|
100
|
-
|
|
101
|
-
</details>
|
|
102
|
-
|
|
103
|
-
<details>
|
|
104
|
-
<summary><b>Install from source instead</b></summary>
|
|
105
|
-
|
|
106
|
-
For contributing, or to run a change that is not released yet. Needs
|
|
107
|
-
[pnpm](https://pnpm.io/) 9+.
|
|
68
|
+
Then install the VS Code extension — it runs the same checker as the CLI:
|
|
108
69
|
|
|
109
70
|
```bash
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
pnpm install
|
|
113
|
-
pnpm install:cli
|
|
71
|
+
luam setup # detects your editors and asks before installing
|
|
72
|
+
luam doctor # verifies CLI, editors and extension
|
|
114
73
|
```
|
|
115
74
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
bin directory is not on your `PATH`.
|
|
120
|
-
|
|
121
|
-
</details>
|
|
122
|
-
|
|
123
|
-
### 2. Install the editor extension
|
|
124
|
-
|
|
125
|
-
The VS Code extension gives you types, completion and errors while you type —
|
|
126
|
-
from the same checker the CLI runs, so the editor and the build never disagree.
|
|
127
|
-
Let the CLI detect supported editors and ask before changing each one:
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
luam setup
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
For an unattended development-machine setup, approve every detected editor:
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
luam setup --yes
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Run `luam doctor` afterward to check the CLI, detected editors, and extension.
|
|
140
|
-
See [Editor support](#editor-support) for the compatibility matrix and manual installation.
|
|
75
|
+
> [Installation](https://thigasdevelopment.github.io/luam/en/guide/installation)
|
|
76
|
+
> · [Instalação](https://thigasdevelopment.github.io/luam/pt-br/guide/installation)
|
|
77
|
+
> — `PATH` troubleshooting, `npx`, install from source, manual `.vsix`.
|
|
141
78
|
|
|
142
79
|
---
|
|
143
80
|
|
|
144
81
|
## Quick start
|
|
145
82
|
|
|
146
|
-
|
|
147
|
-
> **[Quick start](https://thigasdevelopment.github.io/luam/en/guide/quick-start)**
|
|
148
|
-
> · [Início rápido](https://thigasdevelopment.github.io/luam/pt-br/guide/quick-start)
|
|
149
|
-
|
|
150
|
-
**1. Scaffold.** `init` writes exactly one file, `.luam.manifest`. No framework, no
|
|
151
|
-
example tree, nothing to delete.
|
|
83
|
+
**1. Scaffold.** `init` writes exactly one file, `.luam.manifest`.
|
|
152
84
|
|
|
153
85
|
```bash
|
|
154
86
|
mkdir my-resource && cd my-resource
|
|
@@ -156,8 +88,7 @@ luam init
|
|
|
156
88
|
```
|
|
157
89
|
|
|
158
90
|
**2. Write some Luam.** Create the source tree yourself — **the folder decides
|
|
159
|
-
the environment**: `src/server
|
|
160
|
-
`src/shared` is both.
|
|
91
|
+
the environment**: `src/server`, `src/client`, `src/shared`.
|
|
161
92
|
|
|
162
93
|
```
|
|
163
94
|
my-resource/
|
|
@@ -168,32 +99,6 @@ my-resource/
|
|
|
168
99
|
└── client/hud.luam
|
|
169
100
|
```
|
|
170
101
|
|
|
171
|
-
```lua
|
|
172
|
-
-- src/shared/config.luam
|
|
173
|
-
function formatPlayerName(name: string): string
|
|
174
|
-
return 'Player: ' .. name
|
|
175
|
-
end
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
```lua
|
|
179
|
-
-- src/server/main.luam
|
|
180
|
-
addEventHandler('onPlayerJoin', root, function()
|
|
181
|
-
outputChatBox(formatPlayerName(getPlayerName(source)), root)
|
|
182
|
-
end)
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
```lua
|
|
186
|
-
-- src/client/hud.luam
|
|
187
|
-
local caption: string = `HUD ${RESOURCE_NAME:demo}`
|
|
188
|
-
|
|
189
|
-
addEventHandler('onClientRender', root, function()
|
|
190
|
-
dxDrawText(caption, 10, 10)
|
|
191
|
-
end)
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
The compiler already knows `formatPlayerName` is shared, so the server file may
|
|
195
|
-
call it — and that `dxDrawText` from `main.luam` would be an error.
|
|
196
|
-
|
|
197
102
|
**3. Build.**
|
|
198
103
|
|
|
199
104
|
```bash
|
|
@@ -208,15 +113,11 @@ src/client/hud.luam:4:5 error check-environment-api: API "outputChatBox" is serv
|
|
|
208
113
|
```
|
|
209
114
|
|
|
210
115
|
**4. Run it.** Copy `build/my-resource` into
|
|
211
|
-
`<MTA Server>/mods/deathmatch/resources/`, then
|
|
212
|
-
|
|
213
|
-
```
|
|
214
|
-
refresh
|
|
215
|
-
start my-resource
|
|
216
|
-
```
|
|
116
|
+
`<MTA Server>/mods/deathmatch/resources/`, then `refresh` and
|
|
117
|
+
`start my-resource` in the server console.
|
|
217
118
|
|
|
218
119
|
**5. Iterate.** Point `.luam.manifest` at your server and let `dev` build, sync,
|
|
219
|
-
restart
|
|
120
|
+
restart and stream logs on every save:
|
|
220
121
|
|
|
221
122
|
```luam
|
|
222
123
|
name = 'my-resource'
|
|
@@ -225,322 +126,80 @@ serverPath = 'C:/MTA Server'
|
|
|
225
126
|
|
|
226
127
|
```bash
|
|
227
128
|
luam dev
|
|
129
|
+
luam dev --start-server # also starts and owns the local MTA process
|
|
228
130
|
```
|
|
229
131
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
## The CLI
|
|
233
|
-
|
|
234
|
-
> Every command, option and exit code:
|
|
235
|
-
> **[CLI commands](https://thigasdevelopment.github.io/luam/en/tooling/cli)**
|
|
236
|
-
> · [Comandos da CLI](https://thigasdevelopment.github.io/luam/pt-br/tooling/cli)
|
|
237
|
-
|
|
238
|
-
Project commands read `.luam.manifest` from the current directory or from `--cwd`.
|
|
239
|
-
`setup`, `doctor`, and `init` do not require an existing project.
|
|
240
|
-
|
|
241
|
-
### `luam init`
|
|
242
|
-
|
|
243
|
-
Scaffolds `.luam.manifest` and stops. The resource name comes from `--name`, or from
|
|
244
|
-
the directory you are in.
|
|
245
|
-
|
|
246
|
-
```bash
|
|
247
|
-
luam init --name gamemode-race
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
An existing `.luam.manifest` is kept and reported — pass `--force` to overwrite it.
|
|
251
|
-
|
|
252
|
-
### `luam setup`
|
|
253
|
-
|
|
254
|
-
Detects supported editor commands on `PATH`, asks for consent, and installs the
|
|
255
|
-
Luam extension. It tries the editor's marketplace first and falls back to the
|
|
256
|
-
official `.vsix` from the GitHub release that matches the CLI version.
|
|
257
|
-
|
|
258
|
-
```bash
|
|
259
|
-
luam setup
|
|
260
|
-
luam setup --yes
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
The command never installs into an editor silently. In CI or another
|
|
264
|
-
non-interactive terminal, pass `--yes` explicitly.
|
|
265
|
-
|
|
266
|
-
### `luam doctor`
|
|
267
|
-
|
|
268
|
-
Reports the running CLI and Node.js versions, every supported editor detected
|
|
269
|
-
on `PATH`, and whether that editor has the Luam extension.
|
|
270
|
-
|
|
271
|
-
```bash
|
|
272
|
-
luam doctor
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### `luam check`
|
|
276
|
-
|
|
277
|
-
Compiles everything and prints diagnostics. **Writes nothing.** This is the
|
|
278
|
-
command to put in CI and in a pre-commit hook.
|
|
279
|
-
|
|
280
|
-
```bash
|
|
281
|
-
luam check
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
```
|
|
285
|
-
src/server/main.luam:11:23 error check-type-mismatch: Variable "total" expects "number" but received "string".
|
|
286
|
-
Build failed: 1 error, 0 warnings in 4 ms.
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
### `luam build`
|
|
290
|
-
|
|
291
|
-
Compiles and writes the bundled production resource into `<outDir>/<name>`, plus
|
|
292
|
-
`<outDir>/<name>.luam-map.json` for resolving production error positions. Pass
|
|
293
|
-
`--no-bundle` for tree output or `--no-map` to suppress the map.
|
|
294
|
-
|
|
295
|
-
```bash
|
|
296
|
-
luam build
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
```
|
|
300
|
-
Discovery: done in 1 ms.
|
|
301
|
-
Compile: 3 files in 12 ms.
|
|
302
|
-
Assembly: done in 0 ms.
|
|
303
|
-
Manifest: done in 1 ms.
|
|
304
|
-
Write: 7 files in 2 ms.
|
|
305
|
-
Build passed: 3 files, 0 errors, 0 warnings in 16 ms.
|
|
306
|
-
Wrote 7 files to "build/my-resource".
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
A build that reports any error writes nothing, so a resource that worked is
|
|
310
|
-
never replaced with partial output.
|
|
311
|
-
|
|
312
|
-
### `luam dev`
|
|
313
|
-
|
|
314
|
-
Runs the `ensure` build, server sync, restart, and watch loop while following
|
|
315
|
-
`<serverPath>/mods/deathmatch/logs/server.log`. It starts at the end of the file,
|
|
316
|
-
so existing history is not printed.
|
|
317
|
-
|
|
318
|
-
```bash
|
|
319
|
-
luam dev
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
Server records attributed to the active resource and relayed client
|
|
323
|
-
`outputDebugString` calls share one stable stream:
|
|
324
|
-
|
|
325
|
-
```
|
|
326
|
-
[14:22:07][server][info] Resource started
|
|
327
|
-
[14:22:09][client][warn] Missing vehicle model
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
The client call still reaches the MTA debug console. `dev` adds a validated,
|
|
331
|
-
rate-limited MTA event relay only to the synchronized server resource. `build`
|
|
332
|
-
and `ensure` never include these development helpers. Engine output without a
|
|
333
|
-
resource identity may appear as plain server output; records attributed to
|
|
334
|
-
other resources are ignored.
|
|
335
|
-
|
|
336
|
-
### `luam ensure`
|
|
337
|
-
|
|
338
|
-
The loop you leave running while you work. It builds, mirrors the resource into
|
|
339
|
-
your MTA server, restarts it, and repeats all of that on every save.
|
|
340
|
-
|
|
341
|
-
```bash
|
|
342
|
-
luam ensure
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
How much it does depends on what `.luam.manifest` gives it:
|
|
346
|
-
|
|
347
|
-
| Configured | What `ensure` does |
|
|
348
|
-
| --- | --- |
|
|
349
|
-
| nothing | Builds into `<outDir>/<name>` and watches |
|
|
350
|
-
| `serverPath` | Also mirrors the resource into the server. You restart it |
|
|
351
|
-
| `serverPath` + `transport` | Also refreshes and restarts the resource for you |
|
|
352
|
-
|
|
353
|
-
To get the restart, add an `http` transport pointing at a resource on your server
|
|
354
|
-
that exports `refreshResources` and `restartResource`:
|
|
355
|
-
|
|
356
|
-
```luam
|
|
357
|
-
name = 'my-resource'
|
|
358
|
-
serverPath = 'C:/MTA Server'
|
|
359
|
-
|
|
360
|
-
transport = {
|
|
361
|
-
kind = 'http',
|
|
362
|
-
host = '127.0.0.1',
|
|
363
|
-
port = 22005,
|
|
364
|
-
resource = 'luam-sync',
|
|
365
|
-
username = 'luam',
|
|
366
|
-
passwordEnv = 'LUAM_MTA_PASSWORD',
|
|
367
|
-
}
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
```bash
|
|
371
|
-
set LUAM_MTA_PASSWORD=... # Windows
|
|
372
|
-
export LUAM_MTA_PASSWORD=... # macOS / Linux
|
|
373
|
-
luam ensure
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
Use `passwordEnv`, which names an environment variable, rather than an inline
|
|
377
|
-
`password` — no log line or diagnostic ever prints the value. MTA's HTTP
|
|
378
|
-
interface has no TLS, so keep `host` on `127.0.0.1` and tunnel over SSH instead
|
|
379
|
-
of exposing the port.
|
|
132
|
+
> [Quick start](https://thigasdevelopment.github.io/luam/en/guide/quick-start)
|
|
133
|
+
> · [Início rápido](https://thigasdevelopment.github.io/luam/pt-br/guide/quick-start)
|
|
380
134
|
|
|
381
|
-
|
|
382
|
-
whose content changed. If the build reports an error, nothing is synced and the
|
|
383
|
-
running server keeps the last version that compiled. `Ctrl+C` ends the watch;
|
|
384
|
-
`--no-watch` runs the whole cycle exactly once, which is what an editor task or
|
|
385
|
-
a deploy script wants.
|
|
135
|
+
---
|
|
386
136
|
|
|
387
|
-
|
|
137
|
+
## Commands
|
|
388
138
|
|
|
389
|
-
|
|
|
139
|
+
| Command | What it does |
|
|
390
140
|
| --- | --- |
|
|
391
|
-
|
|
|
392
|
-
|
|
|
393
|
-
|
|
|
394
|
-
|
|
|
395
|
-
|
|
|
396
|
-
|
|
|
397
|
-
|
|
|
398
|
-
|
|
|
399
|
-
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
| `1` | The build reported errors |
|
|
408
|
-
| `2` | The command line or the configuration is invalid |
|
|
409
|
-
|
|
410
|
-
Progress is painted on stderr and the report goes to stdout, so redirecting
|
|
411
|
-
stdout captures the report alone. Output drops all escape sequences when the
|
|
412
|
-
stream is not a terminal — a CI log stays readable.
|
|
413
|
-
|
|
414
|
-
### `.luam.manifest`
|
|
415
|
-
|
|
416
|
-
Only `name` is required.
|
|
417
|
-
|
|
418
|
-
| Field | Default | Meaning |
|
|
419
|
-
| --- | --- | --- |
|
|
420
|
-
| `name` | required | Names the output folder and the resource `ensure` restarts. MTA reads the resource name from the folder, so it never reaches `meta.xml` |
|
|
421
|
-
| `author`, `version`, `description` | unset | `meta.xml` info attributes |
|
|
422
|
-
| `compilerOptions` | `strict` on, the rest off | How the checker reads the project: `strict`, `oop`, `noUnusedLocals`, `noUnusedParameters`, `warningsAsErrors` |
|
|
423
|
-
| `sources` | `src/<side>/**/*.luam` | Patterns per side. The side that matches a file is its environment, unless a directive overrides it |
|
|
424
|
-
| `assets` | `{ }` | `{ from, to }` mappings. Only what a mapping names is copied and declared `<file>` |
|
|
425
|
-
| `dependencies` | `{ }` | Resources written as `<include resource="..." />` |
|
|
426
|
-
| `engine.minVersion` | `"latest"` | Becomes `min_mta_version`. An explicit version keeps the build network-free |
|
|
427
|
-
| `environment` | `.env`, `.env.local` | Which files declare and override the keys behind `env` and `process.env` |
|
|
428
|
-
| `outDir` | `"build"` | Receives `<outDir>/<name>` |
|
|
429
|
-
| `loadOrder` | `[]` | Source paths pinned ahead of their group in `meta.xml`. An entry matching no file fails the build |
|
|
430
|
-
| `output.bundle` | `true` | Default `build` layout; command flags override it |
|
|
431
|
-
| `output.map` | `true` | Generate source position maps; only `build` writes one to disk |
|
|
432
|
-
| `output.minify` | `true` | Write each generated script on one line during `build`; `dev` and `ensure` never minify |
|
|
433
|
-
| `helpers` | `[]` | Runtime helpers to copy even when no feature requires them |
|
|
434
|
-
| `serverPath` | unset | MTA server root, for `ensure` |
|
|
435
|
-
| `resourcesDir` | `"mods/deathmatch/resources"` | Resource directory relative to `serverPath` |
|
|
436
|
-
| `transport` | `{ "kind": "none" }` | How `ensure` restarts the resource |
|
|
437
|
-
| `development.logs` | disabled, safe limits | Client relay message length and rate limits used by `dev` |
|
|
438
|
-
|
|
439
|
-
Paths must stay inside their base directory — an absolute path or a `..` segment
|
|
440
|
-
is rejected. A pattern accepts `*`, `**`, and `?` only. `oop`, `sourceDirs`,
|
|
441
|
-
`assetDirs`, and `mta` were removed; each reports `config-removed-field` and
|
|
442
|
-
names its replacement.
|
|
443
|
-
|
|
444
|
-
Every field, the transport in detail, `.env` handling and declaration files:
|
|
445
|
-
**[.luam.manifest](https://thigasdevelopment.github.io/luam/en/tooling/luam-manifest)**
|
|
446
|
-
and
|
|
447
|
-
[Configuration fields](https://thigasdevelopment.github.io/luam/en/reference/configuration-fields)
|
|
448
|
-
· [.luam.manifest](https://thigasdevelopment.github.io/luam/pt-br/tooling/luam-manifest)
|
|
449
|
-
· also in [`packages/cli/README.md`](packages/cli/README.md).
|
|
141
|
+
| `luam init` | Scaffolds `.luam.manifest` and stops |
|
|
142
|
+
| `luam check` | Compiles and prints diagnostics. Writes nothing — this is the CI command |
|
|
143
|
+
| `luam build` | Writes the bundled resource into `<outDir>/<name>`, plus a source map |
|
|
144
|
+
| `luam dev` | Build, sync, restart and watch, while following the server log |
|
|
145
|
+
| `luam ensure` | Build, sync and restart on every save |
|
|
146
|
+
| `luam server` | Run an existing local MTA server in the foreground |
|
|
147
|
+
| `luam trace` | Resolves a production error position back to the authored file |
|
|
148
|
+
| `luam setup` | Installs the editor extension |
|
|
149
|
+
| `luam doctor` | Reports CLI, Node.js, detected editors and extension status |
|
|
150
|
+
|
|
151
|
+
Exit codes: `0` success, `1` build errors, `2` invalid command line or
|
|
152
|
+
configuration. Progress goes to stderr and the report to stdout.
|
|
153
|
+
|
|
154
|
+
> [CLI commands](https://thigasdevelopment.github.io/luam/en/tooling/cli)
|
|
155
|
+
> · [Comandos da CLI](https://thigasdevelopment.github.io/luam/pt-br/tooling/cli)
|
|
156
|
+
> — every option and exit-code details.
|
|
450
157
|
|
|
451
158
|
---
|
|
452
159
|
|
|
453
160
|
## The language
|
|
454
161
|
|
|
455
|
-
> Every feature, with emitted Lua and the errors it catches:
|
|
456
|
-
> **[The language](https://thigasdevelopment.github.io/luam/en/language/)**
|
|
457
|
-
> · [A linguagem](https://thigasdevelopment.github.io/luam/pt-br/language/)
|
|
458
|
-
|
|
459
|
-
```lua
|
|
460
|
-
local name: string = 'Thigas'
|
|
461
|
-
local player: Player? = nil # optional
|
|
462
|
-
local id: string | number = 1 # union
|
|
463
|
-
local names: string[] = {} # array
|
|
464
|
-
|
|
465
|
-
type PlayerId = number # alias
|
|
466
|
-
|
|
467
|
-
enum GameState { LOBBY, PLAYING } # GameState.LOBBY is 0
|
|
468
|
-
|
|
469
|
-
interface Command { # compile-only, never emitted
|
|
470
|
-
name: string
|
|
471
|
-
execute(player: Player): void
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
class VIPPlayer extends Player implements Command {
|
|
475
|
-
level: number = 1
|
|
476
|
-
|
|
477
|
-
constructor = function (name: string, level: number)
|
|
478
|
-
self:super(name)
|
|
479
|
-
self.level = level
|
|
480
|
-
end
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
local vip = new VIPPlayer('Thigas', 2)
|
|
484
|
-
```
|
|
485
|
-
|
|
486
162
|
| Feature | Notes |
|
|
487
163
|
| --- | --- |
|
|
488
164
|
| Type annotations | Optionals, unions, arrays, aliases, generics, `fun(string): void` — all erased |
|
|
489
|
-
| Classes | `extends`, `implements`, `constructor`, `
|
|
490
|
-
| Decorators | `@Getter` and `@Setter` generate typed
|
|
165
|
+
| Classes | `extends`, `implements`, `constructor`, `super(...)`, `new` |
|
|
166
|
+
| Decorators | `@Getter` and `@Setter` generate typed accessors |
|
|
491
167
|
| Interfaces | Verified by the checker, never reach the generated Lua |
|
|
492
168
|
| Enums | Zero-based, checked members, erased when unused |
|
|
493
169
|
| Template strings | `` `Hi ${name:Guest}` `` — scope-checked, with defaults |
|
|
494
|
-
|
|
|
495
|
-
|
|
|
496
|
-
|
|
|
497
|
-
| Object extensions | `items.count` → `table.size(items)`, `name.trim`, `ratio.clamp(a, b)` |
|
|
170
|
+
| Operators | `+=`, `-=`, `*=`, `/=`, `..=`, and `score++` / `score--` as statements |
|
|
171
|
+
| Comments | `# line` and `#* block *#`; length without a space is `#items` |
|
|
172
|
+
| Object extensions | `items.count`, `name.trim`, `ratio.clamp(a, b)` |
|
|
498
173
|
| Multi-return | `local x, y, z = getElementPosition(el)` — typed from the MTA catalog |
|
|
499
|
-
| `export` | Erased from the Lua, written into `meta.xml`
|
|
500
|
-
| Native libraries | `sleep` plus
|
|
501
|
-
|
|
|
502
|
-
|
|
|
503
|
-
| Deployment values | `.env` keys typed and reachable as `env.SERVER_NAME`, server-only |
|
|
174
|
+
| `export` | Erased from the Lua, written into `meta.xml` |
|
|
175
|
+
| Native libraries | `sleep` plus `Threads`, `Async` and `Dotenv`, injected only when named |
|
|
176
|
+
| MTA OOP classes | `Player.getRandom()`, `File.exists(path)`, callable constructors |
|
|
177
|
+
| Deployment values | `.env` keys typed as `env.SERVER_NAME`, server-only |
|
|
504
178
|
| Strictness | `#!strict` (default), `#!nonstrict`, `#!nocheck` per file |
|
|
505
179
|
|
|
506
180
|
`class`, `constructor`, `declare`, `enum`, `export`, `extends`, `implements`,
|
|
507
|
-
`interface`, `new` and `type` are **reserved
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
Reach for `#!nocheck` when porting existing Lua: rename to `.luam` and the build
|
|
513
|
-
passes while you annotate module by module.
|
|
181
|
+
`interface`, `new` and `type` are **reserved** on top of the Lua 5.1 keywords.
|
|
182
|
+
Property names still work (`config.type`), and `type(value)` keeps working.
|
|
183
|
+
Porting existing Lua? Rename to `.luam`, add `#!nocheck`, and annotate module by
|
|
184
|
+
module.
|
|
514
185
|
|
|
515
186
|
### Environments
|
|
516
187
|
|
|
517
188
|
Every file is `server`, `client` or `shared` — from its folder, or from a `#!`
|
|
518
|
-
directive. That decides which MTA APIs resolve
|
|
519
|
-
|
|
520
|
-
```lua
|
|
521
|
-
#!client
|
|
522
|
-
|
|
523
|
-
dxDrawText('hud', 10, 10) # ok
|
|
524
|
-
outputChatBox('hi', player) # error: server API in a client file
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
`server` and `client` files may use `shared` declarations; `shared` may use only
|
|
528
|
-
`shared`; `server` and `client` never see each other. Events are scoped the same
|
|
529
|
-
way. A name the catalog does not know stays `any`, so a missing API never blocks
|
|
530
|
-
a build.
|
|
189
|
+
directive. That decides which MTA APIs resolve: `dxDrawText` in a client file is
|
|
190
|
+
fine, `outputChatBox` in the same file is a build error.
|
|
531
191
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
`"oop": true`.
|
|
192
|
+
`server` and `client` may use `shared` declarations; `shared` may use only
|
|
193
|
+
`shared`; `server` and `client` never see each other. A name the catalog does
|
|
194
|
+
not know stays `any`, so a missing API never blocks a build.
|
|
536
195
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
196
|
+
> [The language](https://thigasdevelopment.github.io/luam/en/language/)
|
|
197
|
+
> · [A linguagem](https://thigasdevelopment.github.io/luam/pt-br/language/)
|
|
198
|
+
> — every feature, with the emitted Lua and the errors it catches.
|
|
540
199
|
|
|
541
200
|
---
|
|
542
201
|
|
|
543
|
-
##
|
|
202
|
+
## Output
|
|
544
203
|
|
|
545
204
|
```
|
|
546
205
|
build/
|
|
@@ -556,139 +215,64 @@ build/
|
|
|
556
215
|
└── client.lua
|
|
557
216
|
```
|
|
558
217
|
|
|
559
|
-
`build` ships at most one bundle per non-empty environment
|
|
560
|
-
and assets
|
|
561
|
-
|
|
562
|
-
Use `luam trace src/server.lua:42` with the matching map to recover the authored
|
|
563
|
-
file, line, and symbol. See [output layouts and source maps](https://thigasdevelopment.github.io/luam/en/reference/output-layouts).
|
|
218
|
+
`build` ships at most one bundle per non-empty environment; `config.lua`, `.env`
|
|
219
|
+
and assets stay at their own paths, and the map stays outside the resource.
|
|
220
|
+
`ensure` defaults to a mirrored tree and `dev` always uses one.
|
|
564
221
|
|
|
565
|
-
|
|
566
|
-
with no network and no cache it is omitted with a warning, and the build still
|
|
567
|
-
succeeds.
|
|
222
|
+
> [Output layouts and source maps](https://thigasdevelopment.github.io/luam/en/reference/output-layouts)
|
|
568
223
|
|
|
569
224
|
---
|
|
570
225
|
|
|
571
|
-
##
|
|
572
|
-
|
|
573
|
-
> Compatibility matrix, manual `.vsix` install, settings:
|
|
574
|
-
> **[Editors](https://thigasdevelopment.github.io/luam/en/tooling/editors)**
|
|
575
|
-
> · [Editores](https://thigasdevelopment.github.io/luam/pt-br/tooling/editors)
|
|
576
|
-
|
|
577
|
-
The **Luam** extension for VS Code starts a language server built on the same
|
|
578
|
-
frontend the CLI uses, so the editor and the build never disagree about a file.
|
|
579
|
-
|
|
580
|
-
| You get | Details |
|
|
581
|
-
| --- | --- |
|
|
582
|
-
| Syntax highlighting | `.luam` files, including type annotations and template strings |
|
|
583
|
-
| Diagnostics | On open and on every keystroke, cleared when you fix the file |
|
|
584
|
-
| Completion | Scope symbols, workspace globals, MTA APIs scoped to the file's environment, keywords |
|
|
585
|
-
| Member completion | `.` completes fields and static methods; `:` completes instance methods, including inherited MTA members |
|
|
586
|
-
| Hover | Declared or inferred type, function signature, and the environment of an MTA API |
|
|
587
|
-
| Navigation | Go to definition, find references, rename — across files for globals |
|
|
588
|
-
|
|
589
|
-
Completion is scoped exactly like the checker: `dxDrawText` never appears in a
|
|
590
|
-
server file, `kickPlayer` never appears in a client file.
|
|
591
|
-
|
|
592
|
-
### Installing it
|
|
226
|
+
## Configuration
|
|
593
227
|
|
|
594
|
-
|
|
595
|
-
whose launchers are on `PATH` and asks before installing:
|
|
228
|
+
`.luam.manifest` — only `name` is required.
|
|
596
229
|
|
|
597
|
-
```
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
| Editor | Launcher detected | Automatic installation | Distribution path |
|
|
602
|
-
| --- | --- | --- | --- |
|
|
603
|
-
| Visual Studio Code | `code` | Yes | Marketplace, then release `.vsix` fallback |
|
|
604
|
-
| Visual Studio Code Insiders | `code-insiders` | Yes | Marketplace, then release `.vsix` fallback |
|
|
605
|
-
| Cursor | `cursor` | Yes | Editor marketplace, then release `.vsix` fallback |
|
|
606
|
-
| VSCodium | `codium` | Yes | Open VSX when available, then release `.vsix` fallback |
|
|
607
|
-
| Windsurf | `windsurf` | Yes | Editor marketplace, then release `.vsix` fallback |
|
|
608
|
-
|
|
609
|
-
Other VS Code-compatible forks can usually install the release `.vsix`
|
|
610
|
-
manually, but `luam setup` does not claim support until their launcher and
|
|
611
|
-
extension APIs are stable. JetBrains IDEs need a separate plugin and are not
|
|
612
|
-
supported by this VS Code extension. Neovim, Zed, and Sublime Text need their
|
|
613
|
-
own LSP adapter or extension and are not currently supported.
|
|
614
|
-
|
|
615
|
-
**From a release.** Download `luam-<version>.vsix` from the
|
|
616
|
-
[Releases page](https://github.com/ThigasDevelopment/luam/releases), then use
|
|
617
|
-
the launcher for your editor:
|
|
618
|
-
|
|
619
|
-
```bash
|
|
620
|
-
code --install-extension luam-0.1.1.vsix
|
|
621
|
-
cursor --install-extension luam-0.1.1.vsix
|
|
622
|
-
codium --install-extension luam-0.1.1.vsix
|
|
623
|
-
windsurf --install-extension luam-0.1.1.vsix
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
In a compatible editor, you can also open **Extensions**, choose **Install from
|
|
627
|
-
VSIX**, and select the downloaded file. Reload the window when prompted.
|
|
628
|
-
|
|
629
|
-
**From source.** Build the VSIX yourself:
|
|
630
|
-
|
|
631
|
-
```bash
|
|
632
|
-
git clone https://github.com/ThigasDevelopment/luam.git
|
|
633
|
-
cd luam
|
|
634
|
-
pnpm install
|
|
635
|
-
pnpm --filter luam bundle
|
|
636
|
-
npx --yes @vscode/vsce package --no-dependencies --skip-license --out luam.vsix
|
|
637
|
-
code --install-extension luam.vsix
|
|
638
|
-
```
|
|
639
|
-
|
|
640
|
-
**To hack on the extension**, skip packaging and launch a development host
|
|
641
|
-
instead — it reloads on rebuild:
|
|
642
|
-
|
|
643
|
-
```bash
|
|
644
|
-
pnpm --filter luam bundle
|
|
645
|
-
code --extensionDevelopmentPath=packages/vscode
|
|
230
|
+
```luam
|
|
231
|
+
name = 'my-resource'
|
|
232
|
+
serverPath = 'C:/MTA Server'
|
|
646
233
|
```
|
|
647
234
|
|
|
648
|
-
|
|
649
|
-
|
|
235
|
+
Optional fields cover `meta.xml` info, `compilerOptions`, `sources`, `assets`,
|
|
236
|
+
`dependencies`, `engine.minVersion`, `environment`, `outDir`, `loadOrder`,
|
|
237
|
+
`output`, `helpers`, `resourcesDir`, `development.logs` and
|
|
238
|
+
`development.server.executable`.
|
|
650
239
|
|
|
651
|
-
|
|
240
|
+
> [.luam.manifest](https://thigasdevelopment.github.io/luam/en/tooling/luam-manifest)
|
|
241
|
+
> and [Configuration fields](https://thigasdevelopment.github.io/luam/en/reference/configuration-fields)
|
|
242
|
+
> · [.luam.manifest](https://thigasdevelopment.github.io/luam/pt-br/tooling/luam-manifest)
|
|
652
243
|
|
|
653
|
-
|
|
654
|
-
| --- | --- | --- |
|
|
655
|
-
| **Luam: Ensure Resource** | `Ctrl+Alt+E` (`Cmd+Alt+E`) | Runs `luam ensure` in a terminal for the current project |
|
|
656
|
-
| **Luam: Restart Language Server** | — | Restarts the server when it gets confused |
|
|
244
|
+
---
|
|
657
245
|
|
|
658
|
-
|
|
659
|
-
| --- | --- | --- |
|
|
660
|
-
| `luam.cliPath` | `"luam"` | Command used to run the CLI. Point it at a bundle to test an unreleased build |
|
|
661
|
-
| `luam.ensureWatch` | `true` | Pass `--watch` when the ensure command runs |
|
|
662
|
-
| `luam.trace.server` | `"off"` | Trace the LSP traffic. Set to `"verbose"` when reporting a bug |
|
|
246
|
+
## Editor support
|
|
663
247
|
|
|
664
|
-
|
|
248
|
+
The **Luam** VS Code extension runs a language server built on the same frontend
|
|
249
|
+
as the CLI, so the editor and the build never disagree: syntax highlighting,
|
|
250
|
+
diagnostics on every keystroke, scoped completion, hover types, go to
|
|
251
|
+
definition, find references and rename.
|
|
665
252
|
|
|
666
|
-
|
|
667
|
-
|
|
253
|
+
Supported and auto-installed by `luam setup`: VS Code, VS Code Insiders, Cursor,
|
|
254
|
+
VSCodium and Windsurf. The language server itself is editor-agnostic and speaks
|
|
255
|
+
`--stdio` to any LSP client.
|
|
668
256
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
```
|
|
257
|
+
> [Editors](https://thigasdevelopment.github.io/luam/en/tooling/editors)
|
|
258
|
+
> · [Editores](https://thigasdevelopment.github.io/luam/pt-br/tooling/editors)
|
|
259
|
+
> — compatibility matrix, manual `.vsix` install, commands and settings.
|
|
673
260
|
|
|
674
261
|
---
|
|
675
262
|
|
|
676
263
|
## Known limitations
|
|
677
264
|
|
|
678
|
-
> With the workaround for each:
|
|
679
|
-
> **[Limitations](https://thigasdevelopment.github.io/luam/en/reference/limitations)**
|
|
680
|
-
> · [Limitações](https://thigasdevelopment.github.io/luam/pt-br/reference/limitations)
|
|
681
|
-
|
|
682
265
|
- **No type narrowing.** `if value ~= nil then` does not refine `string?`.
|
|
683
|
-
- **Declaration order matters for classes within a file.**
|
|
684
|
-
|
|
685
|
-
- **The MTA catalog can lag a release.** It comes from a pinned snapshot; a newer
|
|
686
|
-
function stays `any` rather than erroring.
|
|
266
|
+
- **Declaration order matters for classes within a file.**
|
|
267
|
+
- **The MTA catalog can lag a release** — a newer function stays `any`.
|
|
687
268
|
- **No static members, declared metamethods, or generic classes.**
|
|
688
269
|
- **The editor does not re-check an open file when another one changes.**
|
|
689
|
-
Cross-module violations surface in `luam check`.
|
|
690
270
|
- **An export is named, never verified** against the side that calls it.
|
|
691
271
|
|
|
272
|
+
> [Limitations](https://thigasdevelopment.github.io/luam/en/reference/limitations)
|
|
273
|
+
> · [Limitações](https://thigasdevelopment.github.io/luam/pt-br/reference/limitations)
|
|
274
|
+
> — with the workaround for each.
|
|
275
|
+
|
|
692
276
|
---
|
|
693
277
|
|
|
694
278
|
## Contributing
|
|
@@ -698,39 +282,25 @@ The repo is a pnpm workspace: `compiler`, `cli`, `lsp`, `vscode`, `runtime`,
|
|
|
698
282
|
|
|
699
283
|
```bash
|
|
700
284
|
pnpm install
|
|
701
|
-
pnpm typecheck
|
|
702
|
-
pnpm test
|
|
285
|
+
pnpm typecheck
|
|
286
|
+
pnpm test
|
|
703
287
|
pnpm build
|
|
704
288
|
```
|
|
705
289
|
|
|
706
290
|
Branch from `develop`, add a fixture and a snapshot for new language behaviour,
|
|
707
|
-
and run `pnpm typecheck && pnpm test` before opening a pull request.
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
The user-facing manual lives in [`docs/`](docs/) and is published to
|
|
721
|
-
[thigasdevelopment.github.io/luam](https://thigasdevelopment.github.io/luam/).
|
|
722
|
-
|
|
723
|
-
```bash
|
|
724
|
-
pnpm docs:dev # local preview with hot reload
|
|
725
|
-
pnpm docs:verify # locale parity, snippet checks, and a full build
|
|
726
|
-
```
|
|
727
|
-
|
|
728
|
-
English is the source locale and pt-BR is translated from it; every page exists in
|
|
729
|
-
both, and CI fails when one is missing. Code samples are real files under
|
|
730
|
-
`docs/snippets/`, verified with `luam check` on every documentation build, and
|
|
731
|
-
rendered into both locales from the same source — so a sample cannot drift. See
|
|
732
|
-
the [documentation changelog](https://thigasdevelopment.github.io/luam/en/changelog)
|
|
733
|
-
for the conventions.
|
|
291
|
+
and run `pnpm typecheck && pnpm test` before opening a pull request. House style:
|
|
292
|
+
TypeScript only, strict, no `any`, no comments inside code, 4-space indentation,
|
|
293
|
+
single quotes, kebab-case file names, path aliases instead of `../` imports, no
|
|
294
|
+
barrel files, everything in English.
|
|
295
|
+
|
|
296
|
+
The manual lives in [`docs/`](docs/) — `pnpm docs:dev` to preview,
|
|
297
|
+
`pnpm docs:verify` before pushing. English is the source locale and pt-BR is
|
|
298
|
+
translated from it; CI fails when a page is missing from one.
|
|
299
|
+
|
|
300
|
+
Per-package docs: [`cli`](packages/cli/README.md), [`lsp`](packages/lsp/README.md),
|
|
301
|
+
[`mta-types`](packages/mta-types/README.md), [`vscode`](packages/vscode/README.md),
|
|
302
|
+
[`template`](packages/template/README.md). Releases are in the
|
|
303
|
+
[changelog](CHANGELOG.md).
|
|
734
304
|
|
|
735
305
|
---
|
|
736
306
|
|