cluaupp 0.1.2 → 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 +29 -1
- package/README.md +10 -13
- package/docs/README.md +13 -10
- package/docs/architecture.md +30 -73
- package/docs/cli.md +5 -6
- package/docs/comparison.md +3 -3
- package/docs/config.md +6 -6
- package/docs/cpp-advanced.md +10 -6
- package/docs/cpp-organization.md +4 -2
- package/docs/cpp-safety.md +11 -7
- package/docs/cpp-types.md +1 -1
- package/docs/examples/_category_.json +5 -0
- package/docs/examples/combat.md +239 -0
- package/docs/examples/data-boot.md +98 -0
- package/docs/examples/hud.md +96 -0
- package/docs/examples/index.md +43 -0
- package/docs/examples/leaderstats.md +140 -0
- package/docs/examples/shop.md +122 -0
- package/docs/examples/sword.md +108 -0
- package/docs/getting-started.md +14 -7
- package/docs/intellisense.md +31 -0
- package/docs/intro.md +3 -3
- package/docs/libraries/_category_.json +5 -0
- package/docs/libraries/dataservice.md +104 -0
- package/docs/libraries/index.md +22 -0
- package/docs/libraries/janitor.md +65 -0
- package/docs/libraries/more.md +79 -0
- package/docs/libraries/net.md +35 -0
- package/docs/libraries/promise.md +27 -0
- package/docs/oop/_category_.json +5 -0
- package/docs/oop/file-tags.md +48 -0
- package/docs/oop/index.md +22 -0
- package/docs/oop/modules.md +88 -0
- package/docs/oop/services.md +76 -0
- package/docs/print-cout.md +91 -0
- package/docs/syntax.md +63 -8
- package/editors/vscode/extension.js +146 -0
- package/editors/vscode/package.json +25 -0
- package/include/cluaupp/libs/janitor.hpp +7 -3
- package/include/cluaupp/roblox.hpp +19 -0
- package/package.json +66 -65
- package/runtime/Janitor/init.luau +4 -34
- package/src/architecture.js +174 -66
- package/src/cli.js +88 -21
- package/src/client/init.client.cpp +5 -0
- package/src/compile.js +77 -7
- package/src/editor-install.js +218 -0
- package/src/emit.js +321 -9
- package/src/headers.js +234 -0
- package/src/intellisense.js +1368 -0
- package/src/layout.js +129 -0
- package/src/lex.js +17 -9
- package/src/libs.js +165 -18
- package/src/lsp.js +227 -0
- package/src/parse.js +187 -6
- package/src/preprocess.js +118 -3
- package/src/server/leaderstats.server.cpp +28 -0
- package/src/shared/config.cpp +5 -0
- package/src/shared/config.h +3 -0
- package/src/understand.js +66 -6
- package/templates/game/.clangd +11 -0
- package/templates/game/.vscode/c_cpp_properties.json +6 -2
- package/templates/game/.vscode/extensions.json +6 -0
- package/templates/game/.vscode/settings.json +16 -2
- package/templates/game/cluaupp.config.json +2 -2
- package/templates/game/compile_flags.txt +2 -0
- package/templates/game/src/client/init.client.cpp +1 -0
- package/templates/game/src/server/leaderstats.server.cpp +1 -0
- package/docs/libraries.md +0 -80
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,38 @@
|
|
|
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
|
+
|
|
10
|
+
## 0.1.4
|
|
11
|
+
|
|
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()`).
|
|
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.
|
|
16
|
+
|
|
17
|
+
## 0.1.3
|
|
18
|
+
|
|
19
|
+
- Architecture: generated services keep a fixed declaration order (requires, types, constants, variables, functions, cleanup, return) without section banners. Domain `Stop` runs `janitor:Cleanup()`.
|
|
20
|
+
- IntelliSense: `cluaupp init` / `cluaupp intellisense` install Microsoft `ms-vscode.cpptools` (VSIX on Cursor, where the marketplace omits it), write `.vscode/c_cpp_properties.json` (LLVM clang++, C++20, `include/` + `src/`, `compile_commands.json`), and disable clangd so the two engines do not fight. `build`/`watch` only refresh `compile_commands.json`.
|
|
21
|
+
- `Class::method` on game types becomes `Class:method()` (`self`). Datatype/library statics stay dotted (`CFrame.lookAt`, `Color3.fromRGB`, `FormatNumber.Abbreviate`).
|
|
22
|
+
- `switch` / `case` / `default` / `break` compile to a one-shot `repeat` with `if` / `elseif` / `else`. The discriminant is evaluated once; stacked `case` labels share a body; `break` leaves the switch even from inside an `if`.
|
|
23
|
+
- Janitor typed border re-exports `_impl` (`export type Janitor = Impl.Janitor; return Impl`). It no longer invents `Has` or requires Promise for a parallel type that did not match howmanysmall.
|
|
24
|
+
- Emit: injected `require` / `GetService` are `const`. C++ functions emit as `const function` instead of `local function`.
|
|
25
|
+
- `.server.cpp` emits `init.luau` + `init.meta.json` with `RunContext.Server`. `init.server.luau` is Legacy and is pruned.
|
|
26
|
+
- `cout << ... << endl` emits `print(...)`. `cerr <<` emits `warn`. `cout::print` / `cout::warn` / `cout::error` / `cout::ping` map to the Roblox globals.
|
|
27
|
+
- Docs: [print and cout](docs/print-cout.md); [Libraries](docs/libraries/index.md) how-tos (DataService Init, Janitor, Promise, Net); [OOP structure](docs/oop/index.md) (file tags, services, modules); [Examples](docs/examples/index.md) (leaderstats, combat validation, shop, HUD, sword). GitHub Pages Learn tabs: OOP, Libraries, print/cout, Examples — generated into `site/` (`guide/oop.html`, `guide/examples.html`).
|
|
28
|
+
|
|
3
29
|
## 0.1.2
|
|
4
30
|
|
|
5
31
|
- Watch does not write `out/` while any file fails to compile (Studio keeps the last good scripts).
|
|
6
32
|
- Watch/build skip rewriting Luau whose contents did not change (a space in C++ no longer floods Rojo).
|
|
7
|
-
- `libs/`
|
|
33
|
+
- Watch never copies `libs/` or headers. Changing a constant no longer makes Rojo 7 crash on `libs/ArrayIndexer`.
|
|
34
|
+
- `libs/` on `cluaupp build` is fill-only: missing files are restored, existing files are never overwritten or deleted.
|
|
35
|
+
- Filename tags: `.server.cpp` → Script (`init.server.luau`), `.client.cpp` → LocalScript (`init.client.luau`), `.plugin.cpp` → Plugin, `.legacy` / `.legacy.client` / `.legacy.server` → Legacy. Bare `init.luau` is not used for `.server` (Rojo would make a ModuleScript).
|
|
8
36
|
- Dropped `$optional` from `default.project.json` (Rojo 7.7 failed to deserialize it).
|
|
9
37
|
|
|
10
38
|
## 0.1.1
|
package/README.md
CHANGED
|
@@ -8,18 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
[Docs](https://kartzrbx.github.io/Cluaupp/) · [Learn](https://kartzrbx.github.io/Cluaupp/learn/) · [API](https://kartzrbx.github.io/Cluaupp/api/classes/)
|
|
10
10
|
|
|
11
|
-
The cinematic docs site deploys to [Vercel](https://vercel.com) from `site/` (`vercel.json`). Code blocks use **Dark Modern**, **Tokyo Night**, and **Dracula**. Ask Cluaupp (AI Gateway) is the floating chat on the Vercel deploy.
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
cp .env.example .env.local # set AI_GATEWAY_API_KEY
|
|
15
|
-
npx vercel
|
|
16
|
-
```
|
|
17
|
-
|
|
18
11
|
[](https://www.npmjs.com/package/cluaupp)
|
|
19
12
|
[](https://nodejs.org)
|
|
20
13
|
[](LICENSE)
|
|
21
14
|
|
|
22
|
-
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.
|
|
23
16
|
|
|
24
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()`.
|
|
25
18
|
|
|
@@ -73,12 +66,12 @@ rojo serve
|
|
|
73
66
|
Connect the Rojo plugin in Roblox Studio. Edit `src/**/*.{cpp,h,hpp}`, run `cluaupp watch` to rebuild on save.
|
|
74
67
|
|
|
75
68
|
```
|
|
76
|
-
src/server/*.server.cpp → out/server
|
|
77
|
-
src/client/*.client.cpp → out/client/*.client.luau LocalScript
|
|
78
|
-
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
|
|
79
72
|
```
|
|
80
73
|
|
|
81
|
-
|
|
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).
|
|
82
75
|
|
|
83
76
|
## Documentation
|
|
84
77
|
|
|
@@ -89,8 +82,12 @@ A tiny `leaderstats.server.cpp` becomes `Main` / `PlayersManager` / `CacheContro
|
|
|
89
82
|
| [Learn](https://kartzrbx.github.io/Cluaupp/learn/) | C++ subset, Luau output, safety, architecture |
|
|
90
83
|
| [CLI](docs/cli.md) | `init`, `build`, `watch`, flags |
|
|
91
84
|
| [Syntax](docs/syntax.md) | C++ subset → Luau (`local`, `const`, types) |
|
|
85
|
+
| [print and cout](docs/print-cout.md) | `cout <<`, `cout::warn`, `endl` |
|
|
92
86
|
| [Roblox API](docs/roblox-api.md) | Vector3, CFrame, UDim2, GetService, Instance.new |
|
|
93
|
-
| [Architecture](docs/architecture.md) |
|
|
87
|
+
| [Architecture](docs/architecture.md) | One file in, one file out; opt-in ForeverHD folders |
|
|
88
|
+
| [OOP structure](docs/oop/index.md) | File tags, services, modules, structs |
|
|
89
|
+
| [Libraries](docs/libraries/index.md) | DataService Init, Janitor, Promise, Net |
|
|
90
|
+
| [Examples](docs/examples/index.md) | Leaderstats, combat validation, shop, HUD, sword |
|
|
94
91
|
| [C++ types](docs/cpp-types.md) | Typing, `const`, safety, organization |
|
|
95
92
|
| [Comparison](docs/comparison.md) | vs roblox-ts and WASM toolchains |
|
|
96
93
|
| [Contributing](CONTRIBUTING.md) | Tests, layout, how to ship |
|
package/docs/README.md
CHANGED
|
@@ -4,16 +4,19 @@
|
|
|
4
4
|
2. [Getting started](getting-started.md) — npm, Rojo, Wally
|
|
5
5
|
3. [CLI](cli.md) — `init`, `build`, `watch`
|
|
6
6
|
4. [Syntax](syntax.md) — C++ subset, `local`, `const`
|
|
7
|
-
5. [
|
|
8
|
-
6. [
|
|
9
|
-
7. [
|
|
10
|
-
8. [
|
|
11
|
-
9. [
|
|
12
|
-
10. [
|
|
13
|
-
11. [
|
|
14
|
-
12. [
|
|
15
|
-
13. [
|
|
16
|
-
14. [
|
|
7
|
+
5. [print and cout](print-cout.md) — `cout <<`, `cout::warn`, `endl`
|
|
8
|
+
6. [C++ types](cpp-types.md) — primitives, Instances, `nullptr`
|
|
9
|
+
7. [const](cpp-const.md) — immutability
|
|
10
|
+
8. [Safety](cpp-safety.md) — client trust, Janitor, Net, DataService
|
|
11
|
+
9. [Organization](cpp-organization.md) — server / client / shared
|
|
12
|
+
10. [Advanced](cpp-advanced.md) — `::` vs `:`, Wally, performance
|
|
13
|
+
11. [Architecture](architecture.md) — one file in, one file out; opt-in ForeverHD folders
|
|
14
|
+
12. [OOP structure](oop/index.md) — file tags, services, modules, structs
|
|
15
|
+
13. [Libraries](libraries/index.md) — DataService Init, Janitor, Promise, Net, more
|
|
16
|
+
14. [Examples](examples/index.md) — leaderstats, combat validation, shop, HUD, sword
|
|
17
|
+
15. [Roblox API](roblox-api.md) — Vector3, CFrame, UDim2, classes
|
|
18
|
+
16. [Config](config.md) — `cluaupp.config.json`
|
|
19
|
+
17. [Comparison](comparison.md) — roblox-ts and WASM
|
|
17
20
|
|
|
18
21
|
Moonwave site (local): `npx moonwave dev`
|
|
19
22
|
|
package/docs/architecture.md
CHANGED
|
@@ -3,51 +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` |
|
|
28
|
-
| `hud.client.cpp` |
|
|
29
|
-
| `
|
|
30
|
-
| `boot.legacy.
|
|
31
|
-
| `damage.cpp` (no tag) | **
|
|
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) |
|
|
30
|
+
| `boot.legacy.server.cpp` | Legacy Script | `boot.server.luau` |
|
|
31
|
+
| `damage.cpp` (no tag) | **ModuleScript** | `Damage.luau` |
|
|
32
|
+
|
|
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
|
+
```
|
|
32
40
|
|
|
33
|
-
|
|
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.
|
|
34
42
|
|
|
35
|
-
##
|
|
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()`.
|
|
36
46
|
|
|
37
47
|
```
|
|
38
48
|
filename key → server | client | module | legacy
|
|
39
49
|
AST features → GetService, Instance.new, methods, identifiers
|
|
40
50
|
intent scores → combat:2, character:1, …
|
|
41
51
|
roles → Main + Managers + Controllers + Types
|
|
42
|
-
user functions→ kept in the matching Controller (not discarded)
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Generated files start with that trace:
|
|
46
|
-
|
|
47
|
-
```luau
|
|
48
|
-
-- tag server → Script (service)
|
|
49
|
-
-- intents combat:2, character:1
|
|
50
|
-
-- roles Main, CombatController, CombatTypes
|
|
51
52
|
```
|
|
52
53
|
|
|
53
54
|
| Evidence in the C++ | Role |
|
|
@@ -61,50 +62,6 @@ Generated files start with that trace:
|
|
|
61
62
|
| Domain shapes / stats | `{Service}Types` (`export type`, `return {}`) |
|
|
62
63
|
| Wiring | `Main.Start` / `Main.Stop` |
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
## What leaderstats becomes
|
|
67
|
-
|
|
68
|
-
```
|
|
69
|
-
src/server/leaderstats.server.cpp
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
out/server/LeaderStats/
|
|
74
|
-
init.server.luau
|
|
75
|
-
Main.luau
|
|
76
|
-
PlayersManager.luau
|
|
77
|
-
CacheController.luau
|
|
78
|
-
LeaderStatsTypes.luau
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## What combat becomes
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
src/server/combat.server.cpp -- TakeDamage, Humanoid
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
out/server/Combat/
|
|
89
|
-
init.server.luau
|
|
90
|
-
Main.luau
|
|
91
|
-
CombatController.luau -- your ApplyDamage / OnHit
|
|
92
|
-
CombatTypes.luau
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
No PlayersManager unless you actually listen to players. No CacheController unless you actually create value Instances.
|
|
96
|
-
|
|
97
|
-
## ForeverHD-style rules
|
|
98
|
-
|
|
99
|
-
- PascalCase folders and modules; camelCase locals
|
|
100
|
-
- `--!strict` everywhere
|
|
101
|
-
- Public API `Start` / `Stop`
|
|
102
|
-
- Janitor owns connections in the Manager
|
|
103
|
-
- Types modules `return {}`
|
|
104
|
-
- Transparent `require(script.Parent.X)`
|
|
105
|
-
|
|
106
|
-
## Config
|
|
107
|
-
|
|
108
|
-
`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`.
|
|
109
66
|
|
|
110
|
-
|
|
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.
|
|
@@ -41,7 +40,7 @@ cluaupp build ./my-game
|
|
|
41
40
|
|
|
42
41
|
## `cluaupp watch [folder]`
|
|
43
42
|
|
|
44
|
-
Runs a `
|
|
43
|
+
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
44
|
|
|
46
45
|
## `cluaupp --version` / `cluaupp -v`
|
|
47
46
|
|
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.
|
|
31
|
+
`*.server.cpp` becomes `*.server.luau` (Script). `*.client.cpp` becomes `*.client.luau` (LocalScript). Untagged files become ModuleScripts.
|
package/docs/cpp-advanced.md
CHANGED
|
@@ -9,7 +9,7 @@ The subset is intentional. What exists is enough for game scripts; what is missi
|
|
|
9
9
|
|
|
10
10
|
## Supported
|
|
11
11
|
|
|
12
|
-
- Functions, prototypes (headers only), `if` / `else` / `while` / range-`for`
|
|
12
|
+
- Functions, prototypes (headers only), `if` / `else` / `while` / range-`for` / `switch` (`case`, `default`, `break`)
|
|
13
13
|
- `new Class(parent)`, `GetService<T>()`, `::` statics (`CFrame::lookAt`, `Enum::Material::Plastic`)
|
|
14
14
|
- `->` methods and properties, `.` members, `Connect`
|
|
15
15
|
- `const`, `auto`, `nullptr`, arithmetic, `&&` `||` `!=`
|
|
@@ -18,7 +18,7 @@ The subset is intentional. What exists is enough for game scripts; what is missi
|
|
|
18
18
|
|
|
19
19
|
## Not supported (yet)
|
|
20
20
|
|
|
21
|
-
Full C++: templates besides `GetService<T>`, `class` bodies as emitted types, `std::`, overloading as two runtimes,
|
|
21
|
+
Full C++: templates besides `GetService<T>`, `class` bodies as emitted types, `std::`, overloading as two runtimes, C-style `for`, macros, pointer arithmetic.
|
|
22
22
|
|
|
23
23
|
If you need a custom type, it is usually a **ModuleScript in shared** (a `.cpp` of functions) or a Wally package, not a C++ class the compiler would lower to a metatable.
|
|
24
24
|
|
|
@@ -45,12 +45,16 @@ CluauppLibs already contains the full Janitor, Fusion, Cmdr, DataServiceV2, …
|
|
|
45
45
|
#include <cluaupp/libs/dataservice.hpp>
|
|
46
46
|
|
|
47
47
|
void Grant(Player* player, int amount) {
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
Data* data = DataService::Server.WaitFor(player);
|
|
49
|
+
if (data == nullptr) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
int coins = data->Get(DataService::Server.Paths.Currencies.Money);
|
|
53
|
+
data->Set(DataService::Server.Paths.Currencies.Money, coins + amount);
|
|
50
54
|
}
|
|
51
55
|
```
|
|
52
56
|
|
|
53
|
-
|
|
57
|
+
`Paths.Currencies.Money` exists because **your** Template passed to `Init` had that field. Full copies: [Examples](examples/index.md).
|
|
54
58
|
|
|
55
59
|
## Performance notes
|
|
56
60
|
|
|
@@ -68,4 +72,4 @@ Keep path strings in `config.h`. Match the tokens your DataServiceV2 template al
|
|
|
68
72
|
5. **Headers declare, scripts define.** Prototypes in `.h`, bodies in `.cpp`.
|
|
69
73
|
6. **Do not share mutable statics across server and client** — use Net or DataService.
|
|
70
74
|
|
|
71
|
-
See also: [syntax](syntax.md), [libraries](libraries.md), [comparison](comparison.md).
|
|
75
|
+
See also: [syntax](syntax.md), [print and cout](print-cout.md), [libraries](libraries/index.md), [OOP](oop/index.md), [examples](examples/index.md), [comparison](comparison.md).
|
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
|
|
|
@@ -58,4 +58,6 @@ const string REMOTE_COINS = "Coins";
|
|
|
58
58
|
|
|
59
59
|
Do not install a second Janitor from Wally unless you have a reason — CluauppLibs already has howmanysmall/Janitor. DataServiceV2 still bundles its own janitor/quicknet/signal inside the DataService folder.
|
|
60
60
|
|
|
61
|
+
How-tos: [Libraries](libraries/index.md). Service layout: [OOP](oop/index.md). Copy-paste: [Examples](examples/index.md).
|
|
62
|
+
|
|
61
63
|
Next: [advanced Cluaupp](cpp-advanced.md).
|
package/docs/cpp-safety.md
CHANGED
|
@@ -9,7 +9,7 @@ Safety in Cluaupp is not a sandbox flag. It is a set of habits the compiler and
|
|
|
9
9
|
|
|
10
10
|
## 1. Never trust the client
|
|
11
11
|
|
|
12
|
-
[Net](libraries.md) lets a client `FireServer`. The server must validate:
|
|
12
|
+
[Net](libraries/net.md) lets a client `FireServer`. The server must validate:
|
|
13
13
|
|
|
14
14
|
```cpp
|
|
15
15
|
void OnBuy(Player* player, int productId) {
|
|
@@ -17,19 +17,23 @@ void OnBuy(Player* player, int productId) {
|
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
int price = PriceOf(productId);
|
|
20
|
-
|
|
20
|
+
Data* data = DataService::Server.WaitFor(player);
|
|
21
|
+
if (data == nullptr) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
int coins = data->Get(DataService::Server.Paths.Currencies.Money);
|
|
21
25
|
if (coins < price) {
|
|
22
26
|
return;
|
|
23
27
|
}
|
|
24
|
-
DataService::
|
|
28
|
+
data->Set(DataService::Server.Paths.Currencies.Money, coins - price);
|
|
25
29
|
}
|
|
26
30
|
```
|
|
27
31
|
|
|
28
|
-
Do not store coins only on the client. Do not let the client pass the new coin total — pass the *intent* (`productId`).
|
|
32
|
+
Do not store coins only on the client. Do not let the client pass the new coin total — pass the *intent* (`productId`). Full systems: [Shop](examples/shop.md), [Combat](examples/combat.md).
|
|
29
33
|
|
|
30
34
|
## 2. Clean up with Janitor
|
|
31
35
|
|
|
32
|
-
Every `Connect` that outlives a player, a GUI, or a tool needs a Janitor. Leaving a step, destroying a character, or closing a menu should `Cleanup()` or `LinkToInstance`.
|
|
36
|
+
Every `Connect` that outlives a player, a GUI, or a tool needs a [Janitor](libraries/janitor.md). Leaving a step, destroying a character, or closing a menu should `Cleanup()` or `LinkToInstance`.
|
|
33
37
|
|
|
34
38
|
```cpp
|
|
35
39
|
auto* janitor = new Janitor();
|
|
@@ -45,7 +49,7 @@ Leaked connections duplicate effects: double coins, stacked cameras, lingering h
|
|
|
45
49
|
|
|
46
50
|
## 4. One writer for persisted data
|
|
47
51
|
|
|
48
|
-
[
|
|
52
|
+
[DataService](libraries/dataservice.md) distinguishes `Get()` (merged, includes transient admin overlays) from `GetPersisted()` (what ProfileStore will save). Use `SetTransient` for test panels so you never persist cheat values. Only the server writes persisted paths. The save **shape** is your Template — the library does not ship `Currencies`.
|
|
49
53
|
|
|
50
54
|
## 5. Buffers, not ad-hoc strings
|
|
51
55
|
|
|
@@ -55,4 +59,4 @@ Leaked connections duplicate effects: double coins, stacked cameras, lingering h
|
|
|
55
59
|
|
|
56
60
|
Remote names (`Net::Event("Coins")`) are public protocol. Keep them `const`, short, and unique. Changing a name without a migration breaks old clients.
|
|
57
61
|
|
|
58
|
-
Next: [organization](cpp-organization.md).
|
|
62
|
+
Next: [organization](cpp-organization.md), [OOP](oop/index.md), [Examples](examples/index.md).
|
package/docs/cpp-types.md
CHANGED
|
@@ -46,7 +46,7 @@ player.Name = "Kartz"
|
|
|
46
46
|
player:FindFirstChild("leaderstats")
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
There is no pointer arithmetic, no `delete`, no `std::unique_ptr`. Lifetime is Roblox’s: parented Instances live until `Destroy` or until a [Janitor](libraries.md) cleans them.
|
|
49
|
+
There is no pointer arithmetic, no `delete`, no `std::unique_ptr`. Lifetime is Roblox’s: parented Instances live until `Destroy` or until a [Janitor](libraries/janitor.md) cleans them.
|
|
50
50
|
|
|
51
51
|
## `nullptr`
|
|
52
52
|
|