lt-script 1.0.1 → 1.0.5

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 CHANGED
@@ -1,33 +1,566 @@
1
- # LT Language Compiler
1
+ # LT Language
2
2
 
3
- A compiler for the LT language, targeting FiveM Lua.
3
+ <p align="center">
4
+ <img src="https://img.shields.io/npm/v/lt-script?color=blue&label=npm" alt="npm version">
5
+ <img src="https://img.shields.io/github/license/laot7490/lt-script" alt="license">
6
+ <img src="https://img.shields.io/badge/FiveM-Ready-green" alt="FiveM Ready">
7
+ </p>
4
8
 
5
- ## Installation
9
+ **LT** is a modern, statically-typed superset of Lua designed specifically for **FiveM development**. It combines the elegance of TypeScript with the performance of Lua, adding FiveM-specific syntactic sugar to make your scripts robust, readable, and faster to write.
10
+
11
+ > **Goodbye boilerplate, hello productivity.**
12
+ > Write clean, type-safe code that compiles to optimized 100% vanilla Lua.
13
+
14
+ ---
15
+
16
+ ## ✨ Why LT?
17
+
18
+ * **🛡️ Type Safety**: Catch type mismatches and `nil` errors *before* you run the game.
19
+ * **⚡ Modern Syntax**: Use Arrow Functions, Destructuring, Spread syntax, and more.
20
+ * **🎮 FiveM-First**: Built-in keywords like `netevent`, `addcmd`, `thread`, and `wait`.
21
+ * **🔌 Zero Overhead**: Compiles to pure, readable Lua with no runtime dependencies.
22
+
23
+ ---
24
+
25
+ ## 📦 Installation
26
+
27
+ Prerequisites: [Node.js](https://nodejs.org/) (Version 16+)
6
28
 
7
29
  ```bash
30
+ # Global installation (Recommended)
8
31
  npm install -g lt-script
32
+
33
+ # OR run directly via npx
34
+ npx lt-script build .
9
35
  ```
10
36
 
11
- ## Usage
37
+ ---
38
+
39
+ ## 🚀 Quick Start
12
40
 
41
+ Create a `client.lt` file:
42
+
43
+ ```typescript
44
+ // Define a type for player data
45
+ interface PlayerData {
46
+ id: number,
47
+ name: string,
48
+ health: number
49
+ }
50
+
51
+ // Variables with types
52
+ let active: boolean = false
53
+ const MAX_HEALTH = 100
54
+
55
+ // FiveM Command
56
+ addcmd "heal" (source, args)
57
+ let amount = tonumber(args[1]) ?? MAX_HEALTH
58
+ SetEntityHealth(PlayerPedId(), amount)
59
+ print("Healed for ${amount}")
60
+ end
61
+
62
+ // Thread with loop
63
+ thread
64
+ print("System active")
65
+ loop (true)
66
+ wait 1000
67
+ if LocalPlayer.state?.isDead then
68
+ print("Player is dead!")
69
+ end
70
+ end
71
+ end
72
+ ```
73
+
74
+ **Compile it:**
13
75
  ```bash
14
- ltc help
76
+ ltc build .
15
77
  ```
16
78
 
17
- ### Compiler
79
+ ---
18
80
 
19
- ```bash
20
- ltc build <sourceDir> <outDir>
81
+ ## 📘 Language Reference
82
+
83
+ ### 1. Variables & Types
84
+
85
+ LT supports explicit typing with compile-time validation.
86
+
87
+ ```typescript
88
+ // Mutable variables
89
+ let score: number = 0
90
+ var playerName: string = "John" // Type inferred if omitted
91
+
92
+ // Constants (Compiles to Lua 5.4 <const>)
93
+ const MAX_PLAYERS = 32
94
+
95
+ // Available primitive types
96
+ let str: string = "hello"
97
+ let num: number = 42
98
+ let flag: boolean = true
99
+ let data: table = { key: "value" }
100
+ let pos: vector3 = <100.0, 200.0, 30.0>
101
+ let callback: function = () => print("hi")
102
+
103
+ // Arrays
104
+ let inventory: string[] = ["Apple", "Water"]
105
+ let numbers: number[] = [1, 2, 3]
21
106
  ```
22
107
 
23
- ### Watch Mode
108
+ ### 2. Interfaces & Type Aliases
24
109
 
25
- ```bash
26
- ltc watch <sourceDir> <outDir>
110
+ Define complex data structures for compile-time validation.
111
+
112
+ ```typescript
113
+ // Interface - Object shape definition
114
+ interface VehicleConfig {
115
+ model: string,
116
+ price: number,
117
+ color: string
118
+ }
119
+
120
+ // Type Alias - Alternative syntax
121
+ type PlayerPos = { x: number, y: number, z: number }
122
+
123
+ // Usage with validation
124
+ const myCar: VehicleConfig = {
125
+ model: "sultan",
126
+ price: 50000,
127
+ color: "red"
128
+ }
129
+
130
+ // Arrays of interfaces
131
+ interface StoreConfig {
132
+ id: number,
133
+ position: vector3,
134
+ isOpen: boolean
135
+ }
136
+
137
+ const Stores: StoreConfig[] = [
138
+ { id: 1, position: <100.0, 200.0, 30.0>, isOpen: true },
139
+ { id: 2, position: <150.0, 250.0, 35.0>, isOpen: false }
140
+ ]
141
+ ```
142
+
143
+ > **Note:** Type validation ensures field types match. Assigning `number` to a `vector3` field will cause a compile error.
144
+
145
+ ### 3. Functions
146
+
147
+ ```typescript
148
+ // Standard function with typed parameters
149
+ func Add(a: number, b: number)
150
+ return a + b
151
+ end
152
+
153
+ // Default parameters
154
+ func Greet(name: string, prefix = "Hello")
155
+ print("${prefix}, ${name}!")
156
+ end
157
+
158
+ // Local function (Lua local function)
159
+ local function PrivateHelper()
160
+ return "internal"
161
+ end
162
+
163
+ // Arrow functions
164
+ let double = (x: number) => x * 2
165
+ let greet = (name) => print("Hello ${name}")
166
+
167
+ // Multi-line arrow
168
+ let process = (data) => {
169
+ let result = data * 2
170
+ return result
171
+ }
172
+ ```
173
+
174
+ ### 4. Control Flow
175
+
176
+ #### If / Else
177
+ ```typescript
178
+ // Note: 'then' keyword is required after condition
179
+ if health < 20 then
180
+ print("Low health!")
181
+ elseif health < 50 then
182
+ print("Medium health")
183
+ else
184
+ print("Full health")
185
+ end
186
+ ```
187
+
188
+ #### Switch / Case
189
+ ```typescript
190
+ let job = "police"
191
+
192
+ switch job
193
+ case "police", "ambulance"
194
+ print("Government worker")
195
+ case "mechanic"
196
+ print("Service worker")
197
+ default
198
+ print("Civilian")
199
+ end
200
+ ```
201
+
202
+ #### Guard Clauses
203
+ Clean up nested if-statements with early returns.
204
+
205
+ ```typescript
206
+ func RevivePlayer(player)
207
+ // Returns immediately if player is nil
208
+ guard player return
209
+
210
+ // Returns with custom logic if condition fails
211
+ guard player.isDead else
212
+ print("Player is already alive")
213
+ return
214
+ end
215
+
216
+ // Main logic
217
+ player.revive()
218
+ end
219
+
220
+ // Guard with return value
221
+ func GetPlayer(id)
222
+ let player = GetPlayerById(id)
223
+ guard player return nil
224
+ return player
225
+ end
226
+ ```
227
+
228
+ #### For Loops
229
+ ```typescript
230
+ // Numeric for (start, end)
231
+ for i = 1, 10 do
232
+ print(i)
233
+ end
234
+
235
+ // Numeric for with step (start, end, step)
236
+ for i = 0, 100, 5 do
237
+ print(i)
238
+ end
239
+
240
+ // Range for with step
241
+ for i in 1..10 by 2 do
242
+ print(i)
243
+ end
244
+
245
+ // For-in (pairs)
246
+ for key, value in pairs(myTable) do
247
+ print("${key}: ${value}")
248
+ end
249
+
250
+ // For-in (ipairs)
251
+ for index, item in ipairs(myArray) do
252
+ print("${index}: ${item}")
253
+ end
254
+ ```
255
+
256
+ #### While Loop
257
+ ```typescript
258
+ let count = 0
259
+ while count < 10 do
260
+ print(count)
261
+ count += 1
262
+ end
263
+ ```
264
+
265
+ ### 5. Modern Operators
266
+
267
+ #### Compound Assignment
268
+ ```typescript
269
+ let x = 10
270
+ x += 5
271
+ x -= 3
272
+ x *= 2
273
+ x /= 4
274
+ x %= 3
275
+ ```
276
+
277
+ #### Null Coalescing (`??`)
278
+ ```typescript
279
+ let name = playerName ?? "Unknown"
280
+ let health = GetHealth() ?? 100
281
+ ```
282
+
283
+ #### Optional Chaining (`?.`)
284
+ ```typescript
285
+ let state = LocalPlayer.state?.isDead
286
+ let nested = obj?.deep?.value
287
+ let arrItem = arr?[0]
288
+ ```
289
+
290
+ #### Ternary Operator
291
+ ```typescript
292
+ let status = isDead ? "Dead" : "Alive"
293
+ let label = count > 0 ? "${count} items" : "Empty"
294
+ ```
295
+
296
+ ### 6. Destructuring & Spread
297
+
298
+ ```typescript
299
+ // Object Destructuring
300
+ let { x, y, z } = GetEntityCoords(ped)
301
+ let { name, health } = playerData
302
+
303
+ // Array Destructuring
304
+ let [first, second] = GetValues()
305
+
306
+ // Object Spread (tables only)
307
+ let base = { a: 1, b: 2 }
308
+ let extended = { ...base, c: 3 }
27
309
  ```
28
310
 
29
- ## Features
311
+ ### 7. String Interpolation
312
+
313
+ Use `${expression}` inside strings to embed values:
314
+
315
+ ```typescript
316
+ let name = "John"
317
+ let age = 25
318
+
319
+ print("Hello, ${name}!")
320
+ print("You are ${age} years old")
321
+ print("Next year you'll be ${age + 1}")
322
+
323
+ // Complex expressions
324
+ let player = { health: 100 }
325
+ print("Health: ${player.health}")
326
+ ```
327
+
328
+ ### 8. Vector Literals
329
+
330
+ ```typescript
331
+ // Vector3 (FiveM native)
332
+ let pos: vector3 = <100.0, 200.0, 30.0>
333
+
334
+ // Vector2
335
+ let screenPos: vector2 = <0.5, 0.5>
336
+
337
+ // Vector4 (includes heading)
338
+ let spawn: vector4 = <100.0, 200.0, 30.0, 90.0>
339
+ ```
340
+
341
+ ---
342
+
343
+ ## 🎮 FiveM Features
344
+
345
+ ### Thread & Loop
346
+
347
+ ```typescript
348
+ // Create a thread (Citizen.CreateThread)
349
+ thread
350
+ print("Thread started")
351
+
352
+ loop (true)
353
+ wait 0 // Run every frame
354
+
355
+ // Game logic here
356
+ let ped = PlayerPedId()
357
+ let health = GetEntityHealth(ped)
358
+
359
+ if health < 50 then
360
+ print("Low health warning!")
361
+ end
362
+ end
363
+ end
364
+ ```
365
+
366
+ ### Wait
367
+
368
+ ```typescript
369
+ // Wait in milliseconds
370
+ wait 1000 // Wait 1 second
371
+ wait 0 // Yield one frame
372
+ ```
373
+
374
+ ### Network Events
375
+
376
+ ```typescript
377
+ // Register + Handle network event (Client <-> Server)
378
+ netevent "bank:deposit" (amount)
379
+ print("Depositing ${amount}")
380
+ UpdateBankBalance(amount)
381
+ end
382
+
383
+ // Local event handler
384
+ event "onClientResourceStart" (resName)
385
+ guard resName == GetCurrentResourceName() return
386
+ print("Resource started!")
387
+ end
388
+ ```
389
+
390
+ ### Emit Events
391
+
392
+ ```typescript
393
+ // Emit to server
394
+ emit "server:event:name" (arg1, arg2)
395
+
396
+ // Explicit emit variants
397
+ emitServer "myevent" (data)
398
+ emitClient "myevent" (targetPlayer, data)
399
+ ```
400
+
401
+ ### Commands
402
+
403
+ ```typescript
404
+ // Register a command (RegisterCommand wrapper)
405
+ addcmd "teleport" (source, args)
406
+ let x = tonumber(args[1]) ?? 0
407
+ let y = tonumber(args[2]) ?? 0
408
+ let z = tonumber(args[3]) ?? 0
409
+
410
+ SetEntityCoords(PlayerPedId(), x, y, z)
411
+ print("Teleported to ${x}, ${y}, ${z}")
412
+ end
413
+ ```
414
+
415
+ ### Exports
416
+
417
+ ```typescript
418
+ // Export a function
419
+ export "GetPlayerMoney" ()
420
+ return playerMoney
421
+ end
422
+ ```
423
+
424
+ ### Timeout & Interval
425
+
426
+ ```typescript
427
+ // Run once after delay
428
+ timeout 5000
429
+ print("5 seconds passed!")
430
+ end
431
+
432
+ // Run repeatedly
433
+ interval 1000
434
+ print("Every second")
435
+ end
436
+ ```
437
+
438
+ ### Try / Catch
439
+
440
+ ```typescript
441
+ try
442
+ RiskyOperation()
443
+ catch err
444
+ print("Error: ${err}")
445
+ end
446
+ ```
447
+
448
+ ---
449
+
450
+ ## ⚡ Complete Example: Store Robbery System
451
+
452
+ ```typescript
453
+ // 1. Type Definition
454
+ interface StoreConfig {
455
+ id: number,
456
+ position: vector3,
457
+ reward: number,
458
+ isOpen: boolean
459
+ }
460
+
461
+ // 2. Configuration
462
+ const Stores: StoreConfig[] = [
463
+ { id: 1, position: <120.5, -500.2, 30.0>, reward: 5000, isOpen: true },
464
+ { id: 2, position: <250.0, 300.0, 25.0>, reward: 10000, isOpen: true }
465
+ ]
466
+
467
+ let isRobbing = false
468
+
469
+ // 3. Main Game Loop
470
+ thread
471
+ loop (true)
472
+ wait 0
473
+
474
+ if isRobbing then
475
+ break
476
+ end
477
+
478
+ let ped = PlayerPedId()
479
+ let pos = GetEntityCoords(ped)
480
+
481
+ for _, store in ipairs(Stores) do
482
+ if not store.isOpen then
483
+ break
484
+ end
485
+
486
+ let distance = #(pos - store.position)
487
+ if distance < 2.0 then
488
+ ShowHelpText("Press ~INPUT_CONTEXT~ to rob")
489
+
490
+ if IsControlJustPressed(0, 38) then
491
+ StartRobbery(store)
492
+ end
493
+ end
494
+ end
495
+ end
496
+ end
497
+
498
+ // 4. Robbery Function
499
+ func StartRobbery(store: StoreConfig)
500
+ isRobbing = true
501
+
502
+ // Notify server
503
+ emit "robbery:start" (store.id)
504
+
505
+ // Play animation
506
+ TaskPlayAnim(PlayerPedId(), "anim_dict", "anim_name", 8.0, -8.0, -1, 0, 0, false, false, false)
507
+
508
+ wait 5000
509
+
510
+ ClearPedTasks(PlayerPedId())
511
+ isRobbing = false
512
+
513
+ print("Robbery complete! Reward: ${store.reward}")
514
+ end
515
+
516
+ // 5. Server Sync Handler
517
+ netevent "robbery:sync" (storeId, newState)
518
+ let store = Stores.find(s => s.id == storeId)
519
+ guard store return
520
+
521
+ store.isOpen = newState
522
+ let stateStr = newState ? "open" : "closed"
523
+ print("Store ${storeId} is now ${stateStr}")
524
+ end
525
+ ```
526
+
527
+ ---
528
+
529
+ ## 🛠️ CLI Reference
530
+
531
+ | Command | Usage | Description |
532
+ |:--------|:------|:------------|
533
+ | **Build** | `ltc build ./` | Compiles all `.lt` files in the folder to `.lua` |
534
+ | **Watch** | `ltc watch ./` | Watches for file changes and recompiles instantly |
535
+ | **Version** | `ltc -v` | Displays the current compiler version |
536
+
537
+ ### Project Structure
538
+
539
+ LT automatically detects `src/` folders:
540
+
541
+ ```
542
+ my-resource/
543
+ ├── src/
544
+ │ ├── client.lt
545
+ │ └── server.lt
546
+ ├── client.lua ← Generated
547
+ └── server.lua ← Generated
548
+ ```
549
+
550
+ ---
551
+
552
+ ## 🔧 VS Code Extension
553
+
554
+ Get the official **[LT Language Extension](https://marketplace.visualstudio.com/items?itemName=laot.lt-language)** for the best experience.
555
+
556
+ **Features:**
557
+ * 🎨 Full Syntax Highlighting
558
+ * 🔍 Intelligent Autocompletion
559
+ * 📦 **FiveM Native Intellisense**
560
+ * ✨ Real-time Error Checking
561
+
562
+ ---
30
563
 
31
- - Transpiles LT to Lua 5.4 (FiveM compatible)
32
- - Supports static typing syntax (transpiled to comments or checked)
33
- - FiveM native function support
564
+ <p align="center">
565
+ Made with ❤️ for the FiveM Community by <b>LaotScripts</b>
566
+ </p>