cluaupp 0.1.4 → 0.2.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/CHANGELOG.md +21 -0
- package/README.md +12 -7
- package/bin/cluau.js +1 -1
- package/bin/cluaupp.js +1 -1
- package/docs/README.md +1 -1
- package/docs/architecture.md +52 -77
- package/docs/cli.md +29 -9
- package/docs/comparison.md +3 -3
- package/docs/config.md +6 -6
- package/docs/cpp-organization.md +2 -2
- package/docs/examples/index.md +2 -0
- package/docs/getting-started.md +7 -5
- package/docs/intellisense.md +49 -31
- package/docs/intro.md +2 -2
- package/docs/oop/file-tags.md +16 -17
- package/docs/oop/index.md +2 -2
- package/docs/oop/modules.md +3 -1
- package/docs/oop/services.md +7 -14
- package/docs/syntax.md +6 -5
- package/editors/vscode/extension.js +97 -146
- package/editors/vscode/package.json +6 -6
- package/examples/README.md +18 -0
- package/examples/game/.clangd +25 -0
- package/examples/game/.vscode/c_cpp_properties.json +27 -0
- package/examples/game/.vscode/extensions.json +5 -0
- package/examples/game/.vscode/settings.json +27 -0
- package/examples/game/Packages/.gitkeep +0 -0
- package/examples/game/cluaupp.config.json +6 -0
- package/examples/game/compile_flags.txt +6 -0
- package/examples/game/default.project.json +39 -0
- package/examples/game/package.json +9 -0
- package/examples/game/rokit.toml +5 -0
- package/examples/game/src/client/hud.client.cpp +12 -0
- package/{src → examples/game/src}/client/init.client.cpp +1 -0
- package/examples/game/src/server/combat.server.cpp +23 -0
- package/{src → examples/game/src}/server/leaderstats.server.cpp +1 -0
- package/examples/game/wally.toml +11 -0
- package/generated/api.js +51 -0
- package/generated/architecture.js +473 -0
- package/generated/ast.js +2 -0
- package/generated/cli.js +191 -0
- package/generated/compile.js +115 -0
- package/generated/editor-install.js +170 -0
- package/generated/emit.js +503 -0
- package/generated/emitter/luau-codegen.js +167 -0
- package/generated/emitter/translators.js +164 -0
- package/generated/headers.js +220 -0
- package/generated/index.html +49 -0
- package/generated/intellisense.js +277 -0
- package/generated/layout.js +112 -0
- package/generated/lex.js +146 -0
- package/generated/libs.js +484 -0
- package/generated/lsp.js +55 -0
- package/generated/package-info.js +11 -0
- package/generated/parse.js +607 -0
- package/generated/parser/collector.js +100 -0
- package/generated/parser/index.js +30 -0
- package/generated/preprocess.js +181 -0
- package/generated/system-understander.js +443 -0
- package/generated/transpile.js +66 -0
- package/generated/types.js +2 -0
- package/generated/understand.js +298 -0
- package/generated/utils/process-orchestrator.js +63 -0
- package/generated/utils/project.js +491 -0
- package/generated/utils/rojo-mapper.js +181 -0
- package/generated/utils/safe-paths.js +104 -0
- package/package.json +25 -8
- package/src/api.ts +53 -0
- package/src/{architecture.js → architecture.ts} +80 -33
- package/src/ast.ts +37 -0
- package/src/cli.ts +214 -0
- package/src/compile.ts +118 -0
- package/src/editor-install.ts +182 -0
- package/src/{emit.js → emit.ts} +5 -6
- package/src/emitter/luau-codegen.ts +187 -0
- package/src/emitter/translators.ts +168 -0
- package/src/headers.ts +233 -0
- package/src/intellisense.ts +286 -0
- package/src/{layout.js → layout.ts} +114 -129
- package/src/{lex.js → lex.ts} +4 -6
- package/src/{libs.js → libs.ts} +119 -46
- package/src/lsp.ts +60 -0
- package/src/package-info.ts +7 -0
- package/src/{parse.js → parse.ts} +3 -4
- package/src/parser/collector.ts +115 -0
- package/src/parser/index.ts +27 -0
- package/src/{preprocess.js → preprocess.ts} +64 -32
- package/src/system-understander.ts +501 -0
- package/src/transpile.ts +64 -0
- package/src/tree-sitter-cpp.d.ts +4 -0
- package/src/types.ts +81 -0
- package/src/{understand.js → understand.ts} +24 -213
- package/src/utils/process-orchestrator.ts +72 -0
- package/src/utils/project.ts +506 -0
- package/src/utils/rojo-mapper.ts +190 -0
- package/src/utils/safe-paths.ts +98 -0
- package/templates/game/.clangd +9 -0
- package/templates/game/.vscode/c_cpp_properties.json +1 -1
- package/templates/game/.vscode/extensions.json +5 -6
- package/templates/game/.vscode/settings.json +7 -6
- package/templates/game/cluaupp.config.json +2 -2
- package/templates/game/compile_flags.txt +1 -0
- package/templates/game/rokit.toml +5 -0
- package/templates/game/src/client/init.client.cpp +1 -0
- package/templates/game/src/server/leaderstats.server.cpp +1 -0
- package/src/api.js +0 -57
- package/src/cli.js +0 -481
- package/src/compile.js +0 -56
- package/src/editor-install.js +0 -218
- package/src/intellisense.js +0 -1368
- package/src/lsp.js +0 -227
- /package/{src → examples/game/src}/shared/config.cpp +0 -0
- /package/{src → examples/game/src}/shared/config.h +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.2.0
|
|
6
|
+
|
|
7
|
+
- CLI rewritten as a TypeScript collector-emitter pipeline: Tree-sitter collection, Rojo-mapped `require`s, ordered Luau blocks (Services → Requires → Types → Constants → Code), then optional StyLua / `luau-analyze`. Commands `init`, `build`, `watch`, `lsp`, and `intellisense` stay. `cluaupp build -i file.cpp -o out.luau --rojo default.project.json` is the single-file path.
|
|
8
|
+
- C++ IntelliSense is **clangd** only. The old tokenizer/`completeAt` engine is gone. Tree-sitter is the compiler frontend. `cluaupp lsp` publishes subset parse errors only.
|
|
9
|
+
- `SystemUnderstander` scans identifiers, scores Roblox intents, and stamps Controller / Manager / utility plus `GetService` injections. Filename tags still decide Script vs LocalScript vs ModuleScript.
|
|
10
|
+
- Sample game C++ lives in `examples/game/` (`src/server`, `src/client`, `src/shared`). Compiler `src/` is TypeScript only.
|
|
11
|
+
- CLI security: StyLua / luau-analyze via `spawn` without a shell; emitted paths cannot leave the project; `.env*` stays out of git and the npm pack.
|
|
12
|
+
- Docs / GitHub Pages: clangd, SystemUnderstander, one-file-out emit, `examples/game`. Rojo **7.7.0**.
|
|
13
|
+
- Tests cover `out/` tree, types, modules, path safety, and understander roles.
|
|
14
|
+
|
|
15
|
+
## 0.1.5
|
|
16
|
+
|
|
17
|
+
- Default emit is one tagged `.cpp` → one `.server.luau` / `.client.luau`. `"architecture": true` keeps the old ForeverHD service folders.
|
|
18
|
+
- `--!strict` is opt-in: `#pragma strict`, `#pragma nstrict`, or `"strict": true` in config (default `false`).
|
|
19
|
+
- `.h` / `.hpp` emit type ModuleScripts (`export type` + typed table). A sibling `.cpp` becomes `*Impl.luau`; the header binds those functions.
|
|
20
|
+
- Shared `#include` modules `require` game-rooted paths (`ReplicatedStorage.Cluaupp...` / `ServerScriptService.Cluaupp...`).
|
|
21
|
+
|
|
3
22
|
## 0.1.4
|
|
4
23
|
|
|
5
24
|
- Quoted `#include "Header.h"` of project files becomes `const Header = require(...)`. Header-only structs emit a constructor (`TemplateData()`); const headers bind `PLAYER_DATA_VERSION` from the module. Boot scripts require services (`LeaderstatsServer:init()`).
|
|
6
25
|
- Keep `const` for injected `require` / `GetService` and `const function` for C++ functions (not `local`).
|
|
26
|
+
- `init.meta.json` stays pure JSON. Library `require` injection no longer prepends Luau onto Rojo meta files (which made `rojo serve` fail with a JSONC parse error).
|
|
27
|
+
- Server services emit `init.server.luau` + `init.meta.json` with **only** `RunContext.Server`. Rojo forbids `className` when an `init.*` script exists (the folder is already a Script, not a Folder). `init.luau` is pruned so the instance is not a ModuleScript.
|
|
7
28
|
|
|
8
29
|
## 0.1.3
|
|
9
30
|
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
[](https://nodejs.org)
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
|
|
15
|
-
Source-to-source transpiler: you write a C++ subset, Cluaupp emits modern [Luau](https://luau.org/getting-started) (
|
|
15
|
+
Source-to-source transpiler: you write a C++ subset, Cluaupp emits modern [Luau](https://luau.org/getting-started) (`local`, `const`, optional `--!strict`). C++ structure, Luau quality, one language.
|
|
16
16
|
|
|
17
17
|
No WASM. No Emscripten. No `lua_call`. Roblox APIs come out as they do in Studio: `game:GetService("Players")`, `player:FindFirstChild("leaderstats")`, `players:GetPlayers()`.
|
|
18
18
|
|
|
@@ -42,7 +42,7 @@ players.PlayerAdded:Connect(CreateLeaderstats)
|
|
|
42
42
|
|
|
43
43
|
## Install
|
|
44
44
|
|
|
45
|
-
Node.js 18+ and [Rojo](https://rojo.space/) for Studio sync.
|
|
45
|
+
Node.js 18+ and [Rojo](https://rojo.space/) **7.7.0** for Studio sync (`rokit.toml` in the game template).
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
48
|
npm install -g cluaupp
|
|
@@ -59,19 +59,24 @@ npx cluaupp init my-game
|
|
|
59
59
|
```bash
|
|
60
60
|
cluaupp init my-game
|
|
61
61
|
cd my-game
|
|
62
|
+
rokit install
|
|
62
63
|
cluaupp build
|
|
63
64
|
rojo serve
|
|
64
65
|
```
|
|
65
66
|
|
|
66
67
|
Connect the Rojo plugin in Roblox Studio. Edit `src/**/*.{cpp,h,hpp}`, run `cluaupp watch` to rebuild on save.
|
|
67
68
|
|
|
69
|
+
C++ autocomplete is **clangd**, not a Cluaupp tokenizer and not Microsoft cpptools. Put `#include <cluaupp/roblox.hpp>` at the top of each script; `cluaupp init` writes `.clangd` / `compile_flags.txt` / `compile_commands.json` with `-Iinclude` so clangd finds that header. Tree-sitter is only used to compile. See [IntelliSense](docs/intellisense.md).
|
|
70
|
+
|
|
68
71
|
```
|
|
69
|
-
src/server/*.server.cpp → out/server
|
|
70
|
-
src/client/*.client.cpp → out/client/*.client.luau LocalScript
|
|
71
|
-
src/shared
|
|
72
|
+
src/server/*.server.cpp → out/server/*.server.luau Script
|
|
73
|
+
src/client/*.client.cpp → out/client/*.client.luau LocalScript
|
|
74
|
+
src/shared/*.cpp → out/shared/*.luau ModuleScript
|
|
72
75
|
```
|
|
73
76
|
|
|
74
|
-
|
|
77
|
+
Filename tags: `.server.cpp`, `.client.cpp`, `.legacy.server.cpp`, `.legacy.client.cpp`, or no tag (ModuleScript). One source file becomes one instance. Set `"architecture": true` only for the old PascalCase folder split. See [Architecture](docs/architecture.md) and [OOP structure](docs/oop/index.md).
|
|
78
|
+
|
|
79
|
+
Compiler TypeScript lives in `src/`. Sample game C++ is [`examples/game`](examples/game) (`src/server`, `src/client`, `src/shared`). `cluaupp init` still copies [`templates/game`](templates/game).
|
|
75
80
|
|
|
76
81
|
## Documentation
|
|
77
82
|
|
|
@@ -84,7 +89,7 @@ A tiny `leaderstats.server.cpp` becomes `Main` / `PlayersManager` / `CacheContro
|
|
|
84
89
|
| [Syntax](docs/syntax.md) | C++ subset → Luau (`local`, `const`, types) |
|
|
85
90
|
| [print and cout](docs/print-cout.md) | `cout <<`, `cout::warn`, `endl` |
|
|
86
91
|
| [Roblox API](docs/roblox-api.md) | Vector3, CFrame, UDim2, GetService, Instance.new |
|
|
87
|
-
| [Architecture](docs/architecture.md) |
|
|
92
|
+
| [Architecture](docs/architecture.md) | One file in, one file out; opt-in ForeverHD folders |
|
|
88
93
|
| [OOP structure](docs/oop/index.md) | File tags, services, modules, structs |
|
|
89
94
|
| [Libraries](docs/libraries/index.md) | DataService Init, Janitor, Promise, Net |
|
|
90
95
|
| [Examples](docs/examples/index.md) | Leaderstats, combat validation, shop, HUD, sword |
|
package/bin/cluau.js
CHANGED
package/bin/cluaupp.js
CHANGED
package/docs/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
8. [Safety](cpp-safety.md) — client trust, Janitor, Net, DataService
|
|
11
11
|
9. [Organization](cpp-organization.md) — server / client / shared
|
|
12
12
|
10. [Advanced](cpp-advanced.md) — `::` vs `:`, Wally, performance
|
|
13
|
-
11. [Architecture](architecture.md) —
|
|
13
|
+
11. [Architecture](architecture.md) — one file in, one file out; opt-in ForeverHD folders
|
|
14
14
|
12. [OOP structure](oop/index.md) — file tags, services, modules, structs
|
|
15
15
|
13. [Libraries](libraries/index.md) — DataService Init, Janitor, Promise, Net, more
|
|
16
16
|
14. [Examples](examples/index.md) — leaderstats, combat validation, shop, HUD, sword
|
package/docs/architecture.md
CHANGED
|
@@ -3,54 +3,77 @@ title: Architecture
|
|
|
3
3
|
sidebar_position: 15
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# One file in, one file out
|
|
7
7
|
|
|
8
|
-
roblox-ts decides **what instance you get** from a filename **key** (the same idea as Rojo)
|
|
8
|
+
roblox-ts decides **what instance you get** from a filename **key** (the same idea as Rojo). Cluaupp does the same — and **stops there** by default. It does not invent Main / Controller / Types folders.
|
|
9
9
|
|
|
10
|
-
| Key | Rojo instance |
|
|
10
|
+
| Key | Rojo instance | Default output |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| `*.server.cpp` | Script | `*.server.luau` |
|
|
13
|
+
| `*.client.cpp` | LocalScript | `*.client.luau` |
|
|
14
|
+
| no suffix | ModuleScript | `Name.luau` |
|
|
15
|
+
| `*.legacy.server.cpp` | Legacy Script | `*.server.luau` |
|
|
16
|
+
|
|
17
|
+
`DataBoot.client.cpp` becomes `out/client/boot/DataBoot.client.luau` with your `init()` at the end. Shared `#include` modules use `require(ReplicatedStorage.Cluaupp...)`.
|
|
18
|
+
|
|
19
|
+
`--!strict` is opt-in: put `#pragma strict` in the `.cpp`, or set `"strict": true` in `cluaupp.config.json`.
|
|
20
|
+
|
|
21
|
+
The ForeverHD-style folder split (`LeaderStats/Main.luau`, …) is **opt-in**: `"architecture": true`.
|
|
22
|
+
|
|
23
|
+
## SystemUnderstander
|
|
24
|
+
|
|
25
|
+
Like [roblox-ts](https://github.com/roblox-ts/roblox-ts) (filename **key** first) and [roblox-cs](https://github.com/roblox-csharp/roblox-cs) (scan the AST, then decide), Cluaupp does **not** call a generative model. `src/system-understander.ts` walks the Tree-sitter tree, scores token density against Roblox engine services, and returns a report the emitter may stamp as comments / extra `GetService` lines.
|
|
26
|
+
|
|
27
|
+
| Step | What happens |
|
|
11
28
|
| --- | --- |
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
29
|
+
| `parseFileTag` | `.server.cpp` → Script / Server, `.client.cpp` → LocalScript / Client, no tag → ModuleScript |
|
|
30
|
+
| `namesIn` | identifiers, `GetService<T>`, `new Class`, string literals |
|
|
31
|
+
| `scoreIntents` | evidence count × side weight (server tokens count more on `.server.cpp`) |
|
|
32
|
+
| `determineArchitecture` | score < 2 → utility Module; otherwise Knit-style Controller / Manager / Service. `players` / `cache` stay supporting if combat, UI, or net already has ≥ 2 tokens |
|
|
33
|
+
|
|
34
|
+
The **Rojo class never changes** because of a role. A HUD LocalScript can be classified as `ViewController` and still emit `hud.client.luau`. Sample sources: [examples/game](../examples/game).
|
|
15
35
|
|
|
16
|
-
|
|
36
|
+
## Compiler pipeline
|
|
17
37
|
|
|
18
|
-
|
|
19
|
-
2. **Intent** (AST) — what the code *is for*: players, cache, combat, input, UI, net, data, … scored from APIs and identifiers, the same idea as intent classification in program analysis (features from the tree, not a 200-line dump).
|
|
38
|
+
Cluaupp does not rewrite C++ as text. The CLI parses a Tree-sitter CST, collects symbols (`GetService<T>()`, `#include`, types, constants), then emits Luau in a fixed order:
|
|
20
39
|
|
|
21
|
-
|
|
40
|
+
1. `game:GetService(...)`
|
|
41
|
+
2. `require(...)` (Rojo `default.project.json` when present)
|
|
42
|
+
3. types
|
|
43
|
+
4. constants
|
|
44
|
+
5. functions / script body
|
|
45
|
+
|
|
46
|
+
Formatting is delegated to StyLua; type sanity to `luau-analyze`. See [CLI](cli.md).
|
|
22
47
|
|
|
23
48
|
## File tags
|
|
24
49
|
|
|
25
50
|
| Source | Meaning | Output |
|
|
26
51
|
| --- | --- | --- |
|
|
27
|
-
| `combat.server.cpp` | **Script**
|
|
28
|
-
| `hud.client.cpp` | **LocalScript** | `
|
|
29
|
-
| `tools.plugin.cpp` | **Script** RunContext Plugin | `
|
|
30
|
-
| `boot.legacy.cpp` | Legacy Script | `boot.server.luau` |
|
|
52
|
+
| `combat.server.cpp` | **Script** | `combat.server.luau` |
|
|
53
|
+
| `hud.client.cpp` | **LocalScript** | `hud.client.luau` |
|
|
54
|
+
| `tools.plugin.cpp` | **Script** RunContext Plugin | `tools.luau` (legacy plugin tag) |
|
|
31
55
|
| `boot.legacy.server.cpp` | Legacy Script | `boot.server.luau` |
|
|
32
|
-
| `boot.legacy.client.cpp` | Legacy LocalScript | `boot.client.luau` |
|
|
33
|
-
| `boot.legacy.plugin.cpp` | Plugin | `boot.luau` + Plugin meta |
|
|
34
56
|
| `damage.cpp` (no tag) | **ModuleScript** | `Damage.luau` |
|
|
35
57
|
|
|
36
|
-
|
|
58
|
+
## What a tagged file becomes
|
|
37
59
|
|
|
38
|
-
|
|
60
|
+
```
|
|
61
|
+
src/server/leaderstats.server.cpp → out/server/leaderstats.server.luau
|
|
62
|
+
src/client/boot/DataBoot.client.cpp → out/client/boot/DataBoot.client.luau
|
|
63
|
+
src/shared/damage.cpp → out/shared/Damage.luau
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Scripts and LocalScripts keep your functions and call `init()` at the end. ModuleScripts return a table. There is no invented Main, Controller, or Types file.
|
|
67
|
+
|
|
68
|
+
## Opt-in: ForeverHD folders (`"architecture": true`)
|
|
69
|
+
|
|
70
|
+
Set `"architecture": true` in `cluaupp.config.json` to restore the old planner: PascalCase service folders, `Main` / Managers / Controllers / Types, and `require(script.Main):Start()`. Server folders emit `init.server.luau` plus a **pure JSON** `init.meta.json` with only `RunContext.Server` — never `className`, and never library `require` lines (Rojo 7.7 rejects both).
|
|
39
71
|
|
|
40
72
|
```
|
|
41
73
|
filename key → server | client | module | legacy
|
|
42
74
|
AST features → GetService, Instance.new, methods, identifiers
|
|
43
75
|
intent scores → combat:2, character:1, …
|
|
44
76
|
roles → Main + Managers + Controllers + Types
|
|
45
|
-
user functions→ kept in the matching Controller (not discarded)
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Generated files start with that trace:
|
|
49
|
-
|
|
50
|
-
```luau
|
|
51
|
-
-- tag server → Script (service)
|
|
52
|
-
-- intents combat:2, character:1
|
|
53
|
-
-- roles Main, CombatController, CombatTypes
|
|
54
77
|
```
|
|
55
78
|
|
|
56
79
|
| Evidence in the C++ | Role |
|
|
@@ -64,54 +87,6 @@ Generated files start with that trace:
|
|
|
64
87
|
| Domain shapes / stats | `{Service}Types` (`export type`, `return {}`) |
|
|
65
88
|
| Wiring | `Main.Start` / `Main.Stop` |
|
|
66
89
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
The domain controller keeps **every** user function. CacheController is generated beside it; it must not delete `SetupPlayerManager` while `init` still calls that name. `GetChangedSignal(Paths.Currencies)` stays in `DataController`.
|
|
70
|
-
|
|
71
|
-
## What leaderstats becomes
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
src/server/leaderstats.server.cpp
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
out/server/LeaderStats/
|
|
79
|
-
init.luau
|
|
80
|
-
init.meta.json
|
|
81
|
-
Main.luau
|
|
82
|
-
PlayersManager.luau
|
|
83
|
-
CacheController.luau
|
|
84
|
-
LeaderStatsTypes.luau
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## What combat becomes
|
|
88
|
-
|
|
89
|
-
```
|
|
90
|
-
src/server/combat.server.cpp -- TakeDamage, Humanoid
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
```
|
|
94
|
-
out/server/Combat/
|
|
95
|
-
init.luau
|
|
96
|
-
init.meta.json
|
|
97
|
-
Main.luau
|
|
98
|
-
CombatController.luau -- your ApplyDamage / OnHit
|
|
99
|
-
CombatTypes.luau
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
No PlayersManager unless you actually listen to players. No CacheController unless you actually create value Instances.
|
|
103
|
-
|
|
104
|
-
## ForeverHD-style rules
|
|
105
|
-
|
|
106
|
-
- PascalCase folders and modules; camelCase locals
|
|
107
|
-
- `--!strict` everywhere
|
|
108
|
-
- Public API `Start` / `Stop`. `Start` is idempotent (`Stop` first). Domain `Stop` is `janitor:Cleanup()` (unbind, janitor stays reusable). `OnClose` / `Destroy` stay for `BindToClose`. `PlayersManager.Stop` disconnects and runs `onLeave`. `CacheController.ClearAll` drops the cache.
|
|
109
|
-
- Janitor owns connections in the Manager
|
|
110
|
-
- Module layout in generated Luau (no section banners): requires, types, constants, variables, functions, cleanup, return.
|
|
111
|
-
- Transparent `require(script.Parent.X)`
|
|
112
|
-
|
|
113
|
-
## Config
|
|
114
|
-
|
|
115
|
-
`cluaupp.config.json`: `"architecture": true` (default). `"architecture": false` forces 1:1 dumps (or use `.legacy.server.cpp` / `.legacy.client.cpp` per file).
|
|
90
|
+
Switching back to 1:1 deletes the stale `LeaderStats/` / `DataBoot/` folders on the next `cluaupp build`.
|
|
116
91
|
|
|
117
|
-
How to **write** a
|
|
92
|
+
How to **write** a system, tags, and module-style OOP: [OOP structure](oop/index.md). Copy-paste systems: [Examples](examples/index.md). Also [organization](cpp-organization.md) and [comparison](comparison.md).
|
package/docs/cli.md
CHANGED
|
@@ -6,6 +6,8 @@ cluaupp <command> [folder]
|
|
|
6
6
|
|
|
7
7
|
If `[folder]` is omitted, the current directory is used.
|
|
8
8
|
|
|
9
|
+
The compiler is a **collector-emitter** pipeline: Tree-sitter walks the C++ CST, Rojo maps `#include` to `require`, Luau is emitted in a fixed block order (Services → Requires → Types → Constants → Code), then StyLua / `luau-analyze` can run as post-process.
|
|
10
|
+
|
|
9
11
|
## `cluaupp init [folder]`
|
|
10
12
|
|
|
11
13
|
Creates a game from the template:
|
|
@@ -13,8 +15,9 @@ Creates a game from the template:
|
|
|
13
15
|
- `src/server`, `src/client`, `src/shared`
|
|
14
16
|
- `cluaupp.config.json`
|
|
15
17
|
- `default.project.json` (Rojo)
|
|
18
|
+
- `rokit.toml` (Rojo 7.7.0)
|
|
16
19
|
- `include/cluaupp/roblox.hpp` (IntelliSense)
|
|
17
|
-
- `.vscode
|
|
20
|
+
- `.vscode/` (clangd)
|
|
18
21
|
|
|
19
22
|
```bash
|
|
20
23
|
cluaupp init .
|
|
@@ -23,13 +26,12 @@ cluaupp init my-game
|
|
|
23
26
|
|
|
24
27
|
## `cluaupp build [folder]`
|
|
25
28
|
|
|
26
|
-
Transpiles `src/**/*.{cpp,h,hpp}` into `out/`.
|
|
29
|
+
Transpiles `src/**/*.{cpp,h,hpp}` into `out/`. One tagged `.cpp` becomes one Luau instance (`leaderstats.server.luau`, `hud.client.luau`). Shared untagged files become ModuleScripts. Set `"architecture": true` for the old PascalCase service folders.
|
|
27
30
|
|
|
28
|
-
- `--!strict` on
|
|
29
|
-
- `#include "file.h"`
|
|
31
|
+
- `--!strict` only with `#pragma strict`, `"strict": true`, or `--strict` on the single-file path
|
|
32
|
+
- `#include "file.h"` becomes `require(...)` resolved from `default.project.json` when present
|
|
30
33
|
- `#include <cluaupp/roblox.hpp>` is ignored
|
|
31
|
-
- `.h` / `.hpp`
|
|
32
|
-
- `new Folder(parent)` in a stats system becomes `CacheController.Ensure`
|
|
34
|
+
- `.h` / `.hpp` emit a type ModuleScript (`export type` + typed table). A sibling `.cpp` becomes `*Impl.luau` (the construction); the header binds those functions.
|
|
33
35
|
- A parse error exits with code 1 and `file:line:column`
|
|
34
36
|
- After emit, **orphans in `out/` are removed** (source deleted → matching Luau deleted). `out/` itself is never wiped, so a running Rojo serve keeps the live tree.
|
|
35
37
|
- `libs/` and `include/cluaupp` are synced by writing missing/changed files only. They are **never** deleted as a folder — Rojo 7 unwrap-crashes if `libs/ArrayIndexer` vanishes while serving.
|
|
@@ -37,12 +39,29 @@ Transpiles `src/**/*.{cpp,h,hpp}` into `out/`. Script files become PascalCase **
|
|
|
37
39
|
```bash
|
|
38
40
|
cluaupp build
|
|
39
41
|
cluaupp build ./my-game
|
|
42
|
+
cluaupp build --format --analyze
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Single file
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cluaupp build --input ./src/server/boot.server.cpp --output ./out/boot.server.luau --rojo ./default.project.json
|
|
40
49
|
```
|
|
41
50
|
|
|
51
|
+
`--format` runs StyLua; `--analyze` runs `luau-analyze`. On the single-file path both run by default (warnings if the binaries are missing). On a project build they are opt-in.
|
|
52
|
+
|
|
42
53
|
## `cluaupp watch [folder]`
|
|
43
54
|
|
|
44
55
|
Runs a compile (without copying `libs/`) and rebuilds when anything under `src/` changes, including deletes. Parse errors are printed; the watcher stays alive and **does not write `out/`** until the project compiles cleanly (Studio keeps the last good scripts). A second watcher in the same game exits. Deleted `.cpp` files prune their `out/` artifacts on the next successful compile.
|
|
45
56
|
|
|
57
|
+
## `cluaupp lsp [folder]`
|
|
58
|
+
|
|
59
|
+
Stdio JSON-RPC for **Cluaupp subset diagnostics** only. Completion, hover, and definitions are clangd.
|
|
60
|
+
|
|
61
|
+
## `cluaupp intellisense [folder]`
|
|
62
|
+
|
|
63
|
+
Writes `compile_commands.json`, `.clangd`, and `.vscode` for clangd, and installs LLVM clangd when needed.
|
|
64
|
+
|
|
46
65
|
## `cluaupp --version` / `cluaupp -v`
|
|
47
66
|
|
|
48
67
|
Prints the npm package version.
|
|
@@ -65,7 +84,8 @@ Shows usage.
|
|
|
65
84
|
In the Cluaupp development repo:
|
|
66
85
|
|
|
67
86
|
```bash
|
|
68
|
-
npm run build
|
|
69
|
-
npm
|
|
70
|
-
npm run
|
|
87
|
+
npm run build:cli # compile the TypeScript CLI
|
|
88
|
+
npm test
|
|
89
|
+
npm run dev # local gitignored playground in game/ + Rojo
|
|
90
|
+
npm run stop # stop Rojo
|
|
71
91
|
```
|
package/docs/comparison.md
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
Both are source-to-source. Neither goes through WASM. Generated Luau calls the Roblox API directly.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
By default Cluaupp matches that filename key: `*.server.cpp` → one Script, `*.client.cpp` → one LocalScript, untagged → ModuleScript. The ForeverHD folder split is opt-in (`"architecture": true`). See [Architecture](architecture.md).
|
|
10
10
|
|
|
11
|
-
Current Luau has [`local`, `const`, and `--!strict`](https://luau.org/getting-started). Cluaupp emits
|
|
11
|
+
Current Luau has [`local`, `const`, and `--!strict`](https://luau.org/getting-started). Cluaupp emits `const` from C++ `const`. `--!strict` is opt-in (`#pragma strict` or `"strict": true`).
|
|
12
12
|
|
|
13
13
|
## vs C++ → WASM → Luau (RBX-CPP / Emscripten)
|
|
14
14
|
|
|
@@ -33,5 +33,5 @@ is exactly what Studio expects, not a parallel runtime.
|
|
|
33
33
|
| Goal | Tool |
|
|
34
34
|
| --- | --- |
|
|
35
35
|
| Game in TypeScript | roblox-ts |
|
|
36
|
-
| Game in C++, clear Roblox API
|
|
36
|
+
| Game in C++, clear Roblox API | **Cluaupp** |
|
|
37
37
|
| Full native C++ (templates, STL, engines) | not Cluaupp today |
|
package/docs/config.md
CHANGED
|
@@ -6,17 +6,17 @@ File: `cluaupp.config.json` at the game root (next to `src/`).
|
|
|
6
6
|
{
|
|
7
7
|
"rootDir": "src",
|
|
8
8
|
"outDir": "out",
|
|
9
|
-
"strict":
|
|
10
|
-
"architecture":
|
|
9
|
+
"strict": false,
|
|
10
|
+
"architecture": false
|
|
11
11
|
}
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
| Field | Default | Effect |
|
|
15
15
|
| --- | --- | --- |
|
|
16
16
|
| `rootDir` | `"src"` | Where the `.cpp` / `.h` / `.hpp` files live |
|
|
17
|
-
| `outDir` | `"out"` | Where
|
|
18
|
-
| `strict` | `
|
|
19
|
-
| `architecture` | `
|
|
17
|
+
| `outDir` | `"out"` | Where Luau is written |
|
|
18
|
+
| `strict` | `false` | Prefix `--!strict` on generated files (overridden by `#pragma strict` / `#pragma nstrict`) |
|
|
19
|
+
| `architecture` | `false` | If `true`, emit PascalCase service folders (`LeaderStats/Main.luau`, …) instead of one Luau per `.cpp` |
|
|
20
20
|
|
|
21
21
|
If the file is missing, those defaults apply.
|
|
22
22
|
|
|
@@ -28,4 +28,4 @@ The template ships `default.project.json` mapping:
|
|
|
28
28
|
- `out/client` → `StarterPlayer.StarterPlayerScripts.Cluaupp`
|
|
29
29
|
- `out/shared` → `ReplicatedStorage.Cluaupp`
|
|
30
30
|
|
|
31
|
-
`*.server.cpp` becomes
|
|
31
|
+
`*.server.cpp` becomes `*.server.luau` (Script). `*.client.cpp` becomes `*.client.luau` (LocalScript). Untagged files become ModuleScripts.
|
package/docs/cpp-organization.md
CHANGED
|
@@ -5,7 +5,7 @@ sidebar_position: 13
|
|
|
5
5
|
|
|
6
6
|
# Organization
|
|
7
7
|
|
|
8
|
-
A Cluaupp game is laid out like a roblox-ts project on disk.
|
|
8
|
+
A Cluaupp game is laid out like a roblox-ts project on disk. One tagged `.cpp` becomes one Luau instance (`leaderstats.server.luau`, `hud.client.luau`). See [Architecture](architecture.md).
|
|
9
9
|
|
|
10
10
|
```
|
|
11
11
|
src/
|
|
@@ -47,7 +47,7 @@ const string REMOTE_COINS = "Coins";
|
|
|
47
47
|
|
|
48
48
|
`leaderstats.server.cpp` creates leaderstats. It does not also open the shop UI. Name files after the system: `inventory.server.cpp`, `shop.client.cpp`.
|
|
49
49
|
|
|
50
|
-
`*.server.cpp` / `*.client.cpp` are **tags** (the same keys roblox-ts uses). Untagged `.cpp` is a ModuleScript.
|
|
50
|
+
`*.server.cpp` / `*.client.cpp` are **tags** (the same keys roblox-ts uses). Untagged `.cpp` is a ModuleScript. Set `"architecture": true` only if you want the old PascalCase folder split. See [Architecture](architecture.md) and [OOP structure](oop/index.md).
|
|
51
51
|
|
|
52
52
|
## CluauppLibs vs extra Wally
|
|
53
53
|
|
package/docs/examples/index.md
CHANGED
|
@@ -7,6 +7,8 @@ sidebar_position: 1
|
|
|
7
7
|
|
|
8
8
|
High-quality Cluaupp systems you can copy. Each page is a full service: C++ that the subset actually compiles, server authority, Janitor cleanup, and the file names Studio expects.
|
|
9
9
|
|
|
10
|
+
In this repo the live sample is [`examples/game`](../../examples/game) (`src/server`, `src/client`, `src/shared`). Compiler TypeScript is never mixed with game C++. `cluaupp init` still copies [`templates/game`](../../templates/game).
|
|
11
|
+
|
|
10
12
|
These are **not** dumps of `int main()`. Entry is `void init()`. There are no lambdas and no custom C++ classes — named functions + structs.
|
|
11
13
|
|
|
12
14
|
## Suggested layout
|
package/docs/getting-started.md
CHANGED
|
@@ -5,8 +5,8 @@ Cluaupp installs from **npm**, the same channel as roblox-ts and most Roblox too
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
7
|
- [Node.js](https://nodejs.org/) 18 or newer
|
|
8
|
-
- [Rojo](https://rojo.space/) to sync `out/` into Studio
|
|
9
|
-
-
|
|
8
|
+
- [Rojo](https://rojo.space/) **7.7.0** to sync `out/` into Studio (`cluaupp init` writes `rokit.toml`; run `rokit install`)
|
|
9
|
+
- LLVM clangd for C++ IntelliSense (Cursor / VS Code — installed by `cluaupp init`)
|
|
10
10
|
|
|
11
11
|
## Install the compiler
|
|
12
12
|
|
|
@@ -43,6 +43,7 @@ npm install --save-dev cluaupp
|
|
|
43
43
|
```bash
|
|
44
44
|
cluaupp init my-game
|
|
45
45
|
cd my-game
|
|
46
|
+
rokit install
|
|
46
47
|
cluaupp build
|
|
47
48
|
rojo serve
|
|
48
49
|
```
|
|
@@ -66,7 +67,8 @@ my-game/
|
|
|
66
67
|
shared/config.h
|
|
67
68
|
shared/config.cpp
|
|
68
69
|
out/ ← generated Luau (do not edit)
|
|
69
|
-
server/
|
|
70
|
+
server/leaderstats.server.luau
|
|
71
|
+
client/init.client.luau
|
|
70
72
|
shared/Config.luau
|
|
71
73
|
```
|
|
72
74
|
|
|
@@ -122,13 +124,13 @@ If a file defines `void init()`, Cluaupp calls `init()` at the end of the `.luau
|
|
|
122
124
|
|
|
123
125
|
## IntelliSense
|
|
124
126
|
|
|
125
|
-
`cluaupp init` writes
|
|
127
|
+
`cluaupp init` writes clangd config and installs LLVM `clang++` plus the clangd editor extension when missing. Then reload the window. Completion is clangd; Cluaupp does not index C++ itself.
|
|
126
128
|
|
|
127
129
|
```bash
|
|
128
130
|
cluaupp intellisense
|
|
129
131
|
```
|
|
130
132
|
|
|
131
|
-
`#include <cluaupp/roblox.hpp>` at the top of each source file. The header is **not** compiled to Luau.
|
|
133
|
+
`#include <cluaupp/roblox.hpp>` at the top of each source file. The header is **not** compiled to Luau. clangd learns that path from `-Iinclude` in `.clangd`, `compile_flags.txt`, and `compile_commands.json` — it does not read `c_cpp_properties.json`.
|
|
132
134
|
|
|
133
135
|
See [IntelliSense](intellisense.md).
|
|
134
136
|
|
package/docs/intellisense.md
CHANGED
|
@@ -1,31 +1,49 @@
|
|
|
1
|
-
# IntelliSense
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
1
|
+
# IntelliSense
|
|
2
|
+
|
|
3
|
+
C++ completion, hover, and go-to-definition are **clangd**. Cluaupp does not ship a second completion engine.
|
|
4
|
+
|
|
5
|
+
`cluaupp init` / `cluaupp intellisense` install:
|
|
6
|
+
|
|
7
|
+
1. [clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd) (`llvm-vs-code-extensions.vscode-clangd`)
|
|
8
|
+
2. LLVM `clang++` when missing (Windows: `winget install --id LLVM.LLVM -e`)
|
|
9
|
+
3. `.clangd`, `compile_flags.txt`, and `compile_commands.json` so clangd finds `include/` (clangd does **not** read `.vscode/c_cpp_properties.json`)
|
|
10
|
+
4. Forced include of `include/cluaupp/roblox.hpp` so `GetService`, `Player`, `Janitor` complete from the real C++ stubs
|
|
11
|
+
|
|
12
|
+
Tree-sitter is the **compiler** frontend (collect → emit Luau). It is not an editor language server. A homemade tokenizer in the CLI would fight clangd — that path is gone.
|
|
13
|
+
|
|
14
|
+
Microsoft `ms-vscode.cpptools` is **not** used. Two C++ engines in the same window fight; Cluaupp disables the Microsoft engine (`C_Cpp.intelliSenseEngine: Disabled`).
|
|
15
|
+
|
|
16
|
+
`cluaupp lsp` only publishes **subset parse errors** (code that clangd may accept as C++ but Cluaupp will not transpile).
|
|
17
|
+
|
|
18
|
+
## Headers clangd must see
|
|
19
|
+
|
|
20
|
+
`#include <cluaupp/roblox.hpp>` resolves only if `-Iinclude` is on the clangd compile flags. That maps to `include/cluaupp/roblox.hpp`. Angle-bracket includes are ignored by the transpiler.
|
|
21
|
+
|
|
22
|
+
`cluaupp init` / `build` / `watch` / `intellisense` rewrite:
|
|
23
|
+
|
|
24
|
+
- `-Iinclude` and `-Isrc`
|
|
25
|
+
- `-include include/cluaupp/roblox.hpp`
|
|
26
|
+
- one `compile_commands.json` entry per file under `src/`
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cluaupp intellisense
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Reload: Command Palette → **Developer: Reload Window**. clangd should attach to `.cpp` files.
|
|
35
|
+
|
|
36
|
+
`cluaupp build` / `watch` only refresh `compile_commands.json` (no download). They never keep deleted files in the compilation database.
|
|
37
|
+
|
|
38
|
+
## Config that ships
|
|
39
|
+
|
|
40
|
+
| File | Role |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `.vscode/c_cpp_properties.json` | compiler path (unused by clangd; kept if someone re-enables cpptools) |
|
|
43
|
+
| `.vscode/settings.json` | `C_Cpp.intelliSenseEngine: Disabled`, `clangd.enable: true`, `--compile-commands-dir` |
|
|
44
|
+
| `.vscode/extensions.json` | recommends `llvm-vs-code-extensions.vscode-clangd` |
|
|
45
|
+
| `.clangd` | C++20, `-Iinclude`, skip `out/` and `libs/` |
|
|
46
|
+
| `compile_flags.txt` | fallback flags if a file is not yet in `compile_commands.json` |
|
|
47
|
+
| `compile_commands.json` | one entry per `src/` file |
|
|
48
|
+
|
|
49
|
+
`#include <cluaupp/roblox.hpp>` at the top of each source file. The header is not compiled to Luau.
|
package/docs/intro.md
CHANGED
|
@@ -5,14 +5,14 @@ sidebar_position: 1
|
|
|
5
5
|
|
|
6
6
|
# Cluaupp
|
|
7
7
|
|
|
8
|
-
**The definitive merge of C++ and modern Luau.** You write a C++ subset. Cluaupp emits [Luau](https://luau.org/getting-started) with
|
|
8
|
+
**The definitive merge of C++ and modern Luau.** You write a C++ subset. Cluaupp emits [Luau](https://luau.org/getting-started) with `local` and `const` (and `--!strict` when you opt in), and calls the Roblox API the way Studio does.
|
|
9
9
|
|
|
10
10
|
This site is built with [Moonwave](https://eryn.io/moonwave/) for local markdown (`npm run docs`). The **public** site is generated into `site/` and deployed to [GitHub Pages](https://kartzrbx.github.io/Cluaupp/) (Learn tabs, OOP, Examples, API). The language is in the same spirit as [roblox-ts](https://roblox-ts.com): a familiar syntax, a restricted subset, readable output.
|
|
11
11
|
|
|
12
12
|
## What you get
|
|
13
13
|
|
|
14
14
|
1. A compiler (`cluaupp init` / `build` / `watch`)
|
|
15
|
-
2. Headers for
|
|
15
|
+
2. Headers for **clangd** (`#include <cluaupp/roblox.hpp>`)
|
|
16
16
|
3. First-party libraries in `ReplicatedStorage.CluauppLibs`
|
|
17
17
|
4. Wally wrappers for DataServiceV2, Fusion, Cmdr, EzVisualz, TopbarPlus, and the rest of your stack
|
|
18
18
|
|