cluaupp 0.1.4 → 0.1.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/CHANGELOG.md +9 -0
- package/README.md +6 -6
- package/docs/README.md +1 -1
- package/docs/architecture.md +28 -78
- package/docs/cli.md +4 -5
- package/docs/comparison.md +3 -3
- package/docs/config.md +6 -6
- package/docs/cpp-organization.md +2 -2
- package/docs/getting-started.md +2 -1
- package/docs/intro.md +1 -1
- 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/package.json +1 -1
- package/src/architecture.js +73 -25
- package/src/cli.js +5 -13
- package/src/compile.js +62 -8
- package/src/emit.js +1 -1
- package/src/headers.js +234 -0
- package/src/libs.js +110 -42
- package/src/preprocess.js +48 -1
- package/src/understand.js +5 -3
- package/templates/game/cluaupp.config.json +2 -2
- package/templates/game/src/client/init.client.cpp +1 -0
- package/templates/game/src/server/leaderstats.server.cpp +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.5
|
|
4
|
+
|
|
5
|
+
- Default emit is one tagged `.cpp` → one `.server.luau` / `.client.luau`. `"architecture": true` keeps the old ForeverHD service folders.
|
|
6
|
+
- `--!strict` is opt-in: `#pragma strict`, `#pragma nstrict`, or `"strict": true` in config (default `false`).
|
|
7
|
+
- `.h` / `.hpp` emit type ModuleScripts (`export type` + typed table). A sibling `.cpp` becomes `*Impl.luau`; the header binds those functions.
|
|
8
|
+
- Shared `#include` modules `require` game-rooted paths (`ReplicatedStorage.Cluaupp...` / `ServerScriptService.Cluaupp...`).
|
|
9
|
+
|
|
3
10
|
## 0.1.4
|
|
4
11
|
|
|
5
12
|
- 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
13
|
- Keep `const` for injected `require` / `GetService` and `const function` for C++ functions (not `local`).
|
|
14
|
+
- `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).
|
|
15
|
+
- 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
16
|
|
|
8
17
|
## 0.1.3
|
|
9
18
|
|
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
|
|
|
@@ -66,12 +66,12 @@ rojo serve
|
|
|
66
66
|
Connect the Rojo plugin in Roblox Studio. Edit `src/**/*.{cpp,h,hpp}`, run `cluaupp watch` to rebuild on save.
|
|
67
67
|
|
|
68
68
|
```
|
|
69
|
-
src/server/*.server.cpp → out/server
|
|
70
|
-
src/client/*.client.cpp → out/client/*.client.luau LocalScript
|
|
71
|
-
src/shared
|
|
69
|
+
src/server/*.server.cpp → out/server/*.server.luau Script
|
|
70
|
+
src/client/*.client.cpp → out/client/*.client.luau LocalScript
|
|
71
|
+
src/shared/*.cpp → out/shared/*.luau ModuleScript
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
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).
|
|
75
75
|
|
|
76
76
|
## Documentation
|
|
77
77
|
|
|
@@ -84,7 +84,7 @@ A tiny `leaderstats.server.cpp` becomes `Main` / `PlayersManager` / `CacheContro
|
|
|
84
84
|
| [Syntax](docs/syntax.md) | C++ subset → Luau (`local`, `const`, types) |
|
|
85
85
|
| [print and cout](docs/print-cout.md) | `cout <<`, `cout::warn`, `endl` |
|
|
86
86
|
| [Roblox API](docs/roblox-api.md) | Vector3, CFrame, UDim2, GetService, Instance.new |
|
|
87
|
-
| [Architecture](docs/architecture.md) |
|
|
87
|
+
| [Architecture](docs/architecture.md) | One file in, one file out; opt-in ForeverHD folders |
|
|
88
88
|
| [OOP structure](docs/oop/index.md) | File tags, services, modules, structs |
|
|
89
89
|
| [Libraries](docs/libraries/index.md) | DataService Init, Janitor, Promise, Net |
|
|
90
90
|
| [Examples](docs/examples/index.md) | Leaderstats, combat validation, shop, HUD, sword |
|
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,52 @@ 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 |
|
|
11
|
-
| --- | --- |
|
|
12
|
-
| `*.server.
|
|
13
|
-
| `*.client.
|
|
14
|
-
| no suffix | ModuleScript |
|
|
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` |
|
|
15
16
|
|
|
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...)`.
|
|
17
18
|
|
|
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).
|
|
19
|
+
`--!strict` is opt-in: put `#pragma strict` in the `.cpp`, or set `"strict": true` in `cluaupp.config.json`.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
The ForeverHD-style folder split (`LeaderStats/Main.luau`, …) is **opt-in**: `"architecture": true`.
|
|
22
22
|
|
|
23
23
|
## File tags
|
|
24
24
|
|
|
25
25
|
| Source | Meaning | Output |
|
|
26
26
|
| --- | --- | --- |
|
|
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` |
|
|
27
|
+
| `combat.server.cpp` | **Script** | `combat.server.luau` |
|
|
28
|
+
| `hud.client.cpp` | **LocalScript** | `hud.client.luau` |
|
|
29
|
+
| `tools.plugin.cpp` | **Script** RunContext Plugin | `tools.luau` (legacy plugin tag) |
|
|
31
30
|
| `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
31
|
| `damage.cpp` (no tag) | **ModuleScript** | `Damage.luau` |
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
## What a tagged file becomes
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
src/server/leaderstats.server.cpp → out/server/leaderstats.server.luau
|
|
37
|
+
src/client/boot/DataBoot.client.cpp → out/client/boot/DataBoot.client.luau
|
|
38
|
+
src/shared/damage.cpp → out/shared/Damage.luau
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
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.
|
|
37
42
|
|
|
38
|
-
##
|
|
43
|
+
## Opt-in: ForeverHD folders (`"architecture": true`)
|
|
44
|
+
|
|
45
|
+
Set `"architecture": true` in `cluaupp.config.json` to restore the old planner: PascalCase service folders, `Main` / Managers / Controllers / Types, and `require(script.Main):Start()`.
|
|
39
46
|
|
|
40
47
|
```
|
|
41
48
|
filename key → server | client | module | legacy
|
|
42
49
|
AST features → GetService, Instance.new, methods, identifiers
|
|
43
50
|
intent scores → combat:2, character:1, …
|
|
44
51
|
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
52
|
```
|
|
55
53
|
|
|
56
54
|
| Evidence in the C++ | Role |
|
|
@@ -64,54 +62,6 @@ Generated files start with that trace:
|
|
|
64
62
|
| Domain shapes / stats | `{Service}Types` (`export type`, `return {}`) |
|
|
65
63
|
| Wiring | `Main.Start` / `Main.Stop` |
|
|
66
64
|
|
|
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).
|
|
65
|
+
Switching back to 1:1 deletes the stale `LeaderStats/` / `DataBoot/` folders on the next `cluaupp build`.
|
|
116
66
|
|
|
117
|
-
How to **write** a
|
|
67
|
+
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
|
@@ -23,13 +23,12 @@ cluaupp init my-game
|
|
|
23
23
|
|
|
24
24
|
## `cluaupp build [folder]`
|
|
25
25
|
|
|
26
|
-
Transpiles `src/**/*.{cpp,h,hpp}` into `out/`.
|
|
26
|
+
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
27
|
|
|
28
|
-
- `--!strict`
|
|
29
|
-
- `#include "file.h"`
|
|
28
|
+
- `--!strict` only with `#pragma strict` or `"strict": true`
|
|
29
|
+
- `#include "file.h"` becomes `require(ReplicatedStorage.Cluaupp...)` / `require(ServerScriptService.Cluaupp...)` for shared/server modules
|
|
30
30
|
- `#include <cluaupp/roblox.hpp>` is ignored
|
|
31
|
-
- `.h` / `.hpp`
|
|
32
|
-
- `new Folder(parent)` in a stats system becomes `CacheController.Ensure`
|
|
31
|
+
- `.h` / `.hpp` emit a type ModuleScript (`export type` + typed table). A sibling `.cpp` becomes `*Impl.luau` (the construction); the header binds those functions.
|
|
33
32
|
- A parse error exits with code 1 and `file:line:column`
|
|
34
33
|
- 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
34
|
- `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.
|
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/getting-started.md
CHANGED
package/docs/intro.md
CHANGED
|
@@ -5,7 +5,7 @@ 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
|
|
package/docs/oop/file-tags.md
CHANGED
|
@@ -16,34 +16,33 @@ The **filename** decides the Roblox instance. This is the same key idea as roblo
|
|
|
16
16
|
| `Boot.legacy.server.cpp` | Script | **Legacy** |
|
|
17
17
|
| `Boot.legacy.client.cpp` | LocalScript | Legacy |
|
|
18
18
|
| `Damage.cpp` (no tag) | **ModuleScript** | — |
|
|
19
|
+
| `LeaderstatsServer.h` | **ModuleScript** (types) | — |
|
|
20
|
+
| `LeaderstatsServer.cpp` (sibling of `.h`) | **ModuleScript** (`*Impl`) | — |
|
|
19
21
|
|
|
20
|
-
##
|
|
22
|
+
## One file in, one file out
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
Rojo infers the instance from the filename key: `*.server.luau` is a Script, `*.client.luau` is a LocalScript, untagged `.luau` is a ModuleScript.
|
|
23
25
|
|
|
24
26
|
```
|
|
25
|
-
out/server/
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
src/server/boot/DataBoot.server.cpp → out/server/boot/DataBoot.server.luau
|
|
28
|
+
src/client/boot/DataBoot.client.cpp → out/client/boot/DataBoot.client.luau
|
|
29
|
+
src/shared/damage.cpp → out/shared/Damage.luau
|
|
30
|
+
src/server/services/leaderstats/LeaderstatsServer.h → LeaderstatsServer.luau (export type)
|
|
31
|
+
src/server/services/leaderstats/LeaderstatsServer.cpp → LeaderstatsServerImpl.luau
|
|
28
32
|
```
|
|
29
33
|
|
|
30
|
-
`.legacy.server.cpp`
|
|
31
|
-
|
|
32
|
-
`.client.cpp` stays `init.client.luau` (LocalScript). Do not add `init.meta.json` on the client boot.
|
|
34
|
+
`.legacy.server.cpp` still emits a Legacy Script (`boot.server.luau`). `.client.cpp` stays a LocalScript. Do not invent `init.meta.json` on the default 1:1 path.
|
|
33
35
|
|
|
34
36
|
## Where files live
|
|
35
37
|
|
|
36
38
|
```
|
|
37
|
-
src/server/.../*.server.cpp → out/server (ServerScriptService)
|
|
38
|
-
src/client/.../*.client.cpp → out/client (StarterPlayerScripts)
|
|
39
|
-
src/shared/.../*.cpp → out/shared (ReplicatedStorage)
|
|
39
|
+
src/server/.../*.server.cpp → out/server (ServerScriptService.Cluaupp)
|
|
40
|
+
src/client/.../*.client.cpp → out/client (StarterPlayerScripts.Cluaupp)
|
|
41
|
+
src/shared/.../*.cpp → out/shared (ReplicatedStorage.Cluaupp)
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
Name the **system**, not `init.server.cpp`. `LeaderstatsServer.server.cpp` and `DataBoot.server.cpp` are two
|
|
43
|
-
|
|
44
|
-
## Skip the planner
|
|
44
|
+
Name the **system**, not `init.server.cpp`. `LeaderstatsServer.server.cpp` and `DataBoot.server.cpp` are two files.
|
|
45
45
|
|
|
46
|
-
-
|
|
47
|
-
- `.legacy.server.cpp` / `.legacy.client.cpp` per file
|
|
46
|
+
## Opt-in planner
|
|
48
47
|
|
|
49
|
-
|
|
48
|
+
`"architecture": true` in `cluaupp.config.json` restores PascalCase service folders (`Main`, Controller, Types). Default is off.
|
package/docs/oop/index.md
CHANGED
|
@@ -11,12 +11,12 @@ The **live site** (not just these markdown files) is GitHub Pages:
|
|
|
11
11
|
- [Guide → OOP](https://kartzrbx.github.io/Cluaupp/guide/oop.html)
|
|
12
12
|
- [Examples](https://kartzrbx.github.io/Cluaupp/guide/examples.html)
|
|
13
13
|
|
|
14
|
-
Cluaupp does **not** compile custom C++ `class` types yet. “OOP” here is how you **lay out systems** so Studio gets
|
|
14
|
+
Cluaupp does **not** compile custom C++ `class` types yet. “OOP” here is how you **lay out systems** so Studio gets Script / LocalScript / ModuleScript from the filename tag — the same idea as roblox-ts. Flamework-style Start/Stop folders are opt-in (`"architecture": true`).
|
|
15
15
|
|
|
16
16
|
| Page | What you learn |
|
|
17
17
|
| --- | --- |
|
|
18
18
|
| [File tags](file-tags.md) | `.server` / `.client` / `.plugin` / `.legacy` / untagged |
|
|
19
|
-
| [Services](services.md) | One `.server.cpp` →
|
|
19
|
+
| [Services](services.md) | One `.server.cpp` → one `.server.luau` |
|
|
20
20
|
| [Modules](modules.md) | Untagged files, structs, named functions as methods |
|
|
21
21
|
|
|
22
22
|
Planner details: [Architecture](../architecture.md). Folder layout: [Organization](../cpp-organization.md). Full services: [Examples](../examples/index.md).
|
package/docs/oop/modules.md
CHANGED
|
@@ -25,7 +25,9 @@ int DoubleCoins(int coins) {
|
|
|
25
25
|
out/shared/util/Coins.luau -- ModuleScript, exported functions
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Quoted `#include "TemplateData.hpp"` is not inlined when the header has a sibling `.cpp` or is a shared module: `cluaupp build` emits `require(ReplicatedStorage.Cluaupp.constants.TemplateData)` / `require(ServerScriptService.Cluaupp.configurations.PlayerDataVersion)` (Rojo roots from `default.project.json`), never `script.Parent.Parent.shared`.
|
|
29
|
+
|
|
30
|
+
`.h` / `.hpp` are **type modules**. A service header becomes `export type Name = { init: (self: Name) -> (), … }` and a typed table. The sibling `.cpp` is the construction (`NameImpl.luau`); the header `require`s that impl and binds the functions. Data-only structs still emit a constructor so `TemplateData()` works. Untagged `.cpp` without a header is a ModuleScript other Luau can `require`. Prefer headers for the public type, tagged `.server.cpp` / `.client.cpp` for scripts, and the sibling `.cpp` for method bodies.
|
|
29
31
|
|
|
30
32
|
## Structs = data, not classes
|
|
31
33
|
|
package/docs/oop/services.md
CHANGED
|
@@ -5,7 +5,7 @@ sidebar_position: 3
|
|
|
5
5
|
|
|
6
6
|
# Services
|
|
7
7
|
|
|
8
|
-
Write **one tagged file per system**. Cluaupp
|
|
8
|
+
Write **one tagged file per system**. Cluaupp emits **one** Luau instance: `LeaderstatsServer.server.luau` from `LeaderstatsServer.server.cpp`. It does not invent Main / Controller / Types unless `"architecture": true`.
|
|
9
9
|
|
|
10
10
|
## Example: leaderstats
|
|
11
11
|
|
|
@@ -44,29 +44,22 @@ void init() {
|
|
|
44
44
|
Typical output:
|
|
45
45
|
|
|
46
46
|
```
|
|
47
|
-
out/server/LeaderstatsServer
|
|
48
|
-
init.luau -- Script, RunContext Server
|
|
49
|
-
init.meta.json
|
|
50
|
-
Main.luau -- Start / Stop
|
|
51
|
-
PlayersManager.luau -- PlayerAdded + Janitor
|
|
52
|
-
DataController.luau -- your WaitFor / GetChangedSignal
|
|
53
|
-
CacheController.luau -- if you create IntValue folders
|
|
54
|
-
LeaderstatsServerTypes.luau
|
|
47
|
+
out/server/services/leaderstats/LeaderstatsServer.server.luau
|
|
55
48
|
```
|
|
56
49
|
|
|
57
|
-
Your functions stay in
|
|
50
|
+
Your functions stay in that file. `init()` runs at the end. There is no fake `Main` that only forwards to a Controller.
|
|
58
51
|
|
|
59
52
|
## Lifecycle
|
|
60
53
|
|
|
61
|
-
|
|
54
|
+
You own `init` and Janitor cleanup in the same file. You do not write `class LeaderstatsServer` — name the **file** `LeaderstatsServer.server.cpp` and keep **functions** as the public API.
|
|
62
55
|
|
|
63
|
-
|
|
56
|
+
`"architecture": true` is the old ForeverHD split (`Main.Start` / `Main.Stop`, Managers, Types). Leave it off unless you want that.
|
|
64
57
|
|
|
65
58
|
## Boot vs gameplay
|
|
66
59
|
|
|
67
60
|
Keep DataService `Init` in `DataBoot.server.cpp` / `DataBoot.client.cpp`. Keep leaderstats / combat in their own `.server.cpp`. Services `WaitFor` after boot has run.
|
|
68
61
|
|
|
69
|
-
##
|
|
62
|
+
## Opt-in roles (`"architecture": true`)
|
|
70
63
|
|
|
71
64
|
| Your C++ | Generated role |
|
|
72
65
|
| --- | --- |
|
|
@@ -78,6 +71,6 @@ Keep DataService `Init` in `DataBoot.server.cpp` / `DataBoot.client.cpp`. Keep l
|
|
|
78
71
|
| `UserInputService` | `InputController` |
|
|
79
72
|
| wiring | `Main.Start` / `Main.Stop` |
|
|
80
73
|
|
|
81
|
-
A tiny `print` in `init.client.cpp` stays a single LocalScript.
|
|
74
|
+
A tiny `print` in `init.client.cpp` stays a single LocalScript.
|
|
82
75
|
|
|
83
76
|
Copy-paste: [Examples](../examples/index.md).
|
package/docs/syntax.md
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Cluaupp is not a full C++ compiler. It is a **subset** aimed at Roblox scripts, in the same spirit as roblox-ts (restricted TypeScript → Luau).
|
|
4
4
|
|
|
5
|
-
Generated Luau follows the current language: [
|
|
5
|
+
Generated Luau follows the current language: [`local`](https://luau.org/getting-started), `const`, and `const function`. Injected `require` / `GetService` lines are `const`. `--!strict` is emitted only when the file has `#pragma strict` (or `"strict": true` in config).
|
|
6
6
|
|
|
7
7
|
## Files
|
|
8
8
|
|
|
9
9
|
- Extensions: `.cpp`, `.h`, `.hpp` (also `.cc`, `.hh`)
|
|
10
|
-
- Quoted `#include "file.h"` is inlined
|
|
10
|
+
- Quoted `#include "file.h"` becomes a Rojo `require` (or is inlined for a header that belongs to the same `.cpp`)
|
|
11
11
|
- `#include <cluaupp/roblox.hpp>` and `<cluaupp/libs/*.hpp>` are IntelliSense only; library headers also inject `require(CluauppLibs.*)`
|
|
12
|
-
-
|
|
13
|
-
-
|
|
12
|
+
- `#pragma once` is ignored
|
|
13
|
+
- `#pragma strict` / `#pragma nstrict` control `--!strict` for that compilation unit
|
|
14
|
+
- Function prototypes in a `.h` / `.hpp` become `export type` fields (`init: (self: Name) -> ()`). Only `.cpp` files emit function bodies.
|
|
14
15
|
|
|
15
16
|
## Functions
|
|
16
17
|
|
|
@@ -199,6 +200,6 @@ Full table and IntelliSense notes: [print and cout](print-cout.md).
|
|
|
199
200
|
|
|
200
201
|
## Not supported yet
|
|
201
202
|
|
|
202
|
-
Custom C++ classes, generic templates besides `GetService<T>`, pointer arithmetic, `std::`, overloading, macros (except
|
|
203
|
+
Custom C++ classes, generic templates besides `GetService<T>`, pointer arithmetic, `std::`, overloading, macros (except `#pragma strict` / `#pragma nstrict` / `#pragma once`).
|
|
203
204
|
|
|
204
205
|
If you need one of those patterns, open an issue with the C++ and the expected Luau.
|
package/package.json
CHANGED