cluaupp 0.2.3 → 1.0.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.
Files changed (114) hide show
  1. package/CHANGELOG.md +10 -79
  2. package/README.md +42 -88
  3. package/docs/README.md +13 -21
  4. package/docs/architecture.md +13 -76
  5. package/docs/cli.md +12 -64
  6. package/docs/comparison.md +6 -24
  7. package/docs/config.md +6 -7
  8. package/docs/examples/combat.md +19 -227
  9. package/docs/examples/hud.md +13 -81
  10. package/docs/examples/index.md +9 -16
  11. package/docs/getting-started.md +20 -137
  12. package/docs/intellisense.md +5 -41
  13. package/docs/intro.md +16 -15
  14. package/docs/migration.md +38 -0
  15. package/docs/oop/file-tags.md +12 -36
  16. package/docs/oop/index.md +8 -14
  17. package/docs/syntax.md +54 -236
  18. package/editors/vscode/extension.js +1 -1
  19. package/editors/vscode/package.json +4 -4
  20. package/examples/README.md +5 -7
  21. package/examples/game/.vscode/extensions.json +0 -3
  22. package/examples/game/.vscode/settings.json +6 -14
  23. package/examples/game/src/client/hud.client.clpp +54 -0
  24. package/examples/game/src/client/init.client.clpp +6 -0
  25. package/examples/game/src/server/combat.server.clpp +85 -0
  26. package/examples/game/src/server/leaderstats.server.clpp +28 -0
  27. package/examples/game/src/shared/PlayerData.clh +20 -0
  28. package/examples/game/src/shared/config.clp +6 -0
  29. package/examples/game/src/shared/features.clp +88 -0
  30. package/generated/cli.js +40 -24
  31. package/generated/clpp/contract.js +5 -0
  32. package/generated/clpp/index.js +27 -0
  33. package/generated/clpp/paths.js +121 -0
  34. package/generated/clpp/postprocess.js +78 -0
  35. package/generated/clpp/runner.js +102 -0
  36. package/generated/compile.js +26 -138
  37. package/generated/intellisense.js +38 -157
  38. package/generated/libs.js +1 -1
  39. package/generated/lsp.js +1 -8
  40. package/generated/preprocess.js +8 -179
  41. package/generated/system-understander.js +1 -1
  42. package/generated/transpile.js +3 -50
  43. package/generated/utils/project.js +13 -28
  44. package/include/{cluaupp/datatypes.hpp → clpp/datatypes.clh} +1 -1
  45. package/include/{cluaupp/generated/instances.hpp → clpp/generated/instances.clh} +1 -1
  46. package/include/{cluaupp/libs/chrono.hpp → clpp/libs/chrono.clh} +9 -9
  47. package/include/{cluaupp/libs/cmdr.hpp → clpp/libs/cmdr.clh} +4 -4
  48. package/include/{cluaupp/libs/dataservice.hpp → clpp/libs/dataservice.clh} +8 -15
  49. package/include/{cluaupp/libs/display.hpp → clpp/libs/display.clh} +1 -2
  50. package/include/{cluaupp/libs/ezvisual.hpp → clpp/libs/ezvisual.clh} +1 -3
  51. package/include/{cluaupp/libs/formatnumber.hpp → clpp/libs/formatnumber.clh} +2 -3
  52. package/include/{cluaupp/libs/fusion.hpp → clpp/libs/fusion.clh} +5 -5
  53. package/include/{cluaupp/libs/iris.hpp → clpp/libs/iris.clh} +2 -2
  54. package/include/{cluaupp/libs/janitor.hpp → clpp/libs/janitor.clh} +1 -2
  55. package/include/{cluaupp/libs/module3d.hpp → clpp/libs/module3d.clh} +2 -4
  56. package/include/{cluaupp/libs/net.hpp → clpp/libs/net.clh} +2 -4
  57. package/include/{cluaupp/libs/promise.hpp → clpp/libs/promise.clh} +1 -4
  58. package/include/{cluaupp/libs/spring.hpp → clpp/libs/spring.clh} +1 -2
  59. package/include/{cluaupp/libs/statemachine.hpp → clpp/libs/statemachine.clh} +2 -3
  60. package/include/{cluaupp/libs/stickybillboard.hpp → clpp/libs/stickybillboard.clh} +1 -2
  61. package/include/{cluaupp/libs/topbarplus.hpp → clpp/libs/topbarplus.clh} +3 -4
  62. package/include/clpp/libs.clh +24 -0
  63. package/include/clpp/roblox.clh +31 -0
  64. package/package.json +7 -14
  65. package/src/cli.ts +39 -25
  66. package/src/clpp/contract.ts +39 -0
  67. package/src/clpp/index.ts +18 -0
  68. package/src/clpp/paths.ts +117 -0
  69. package/src/clpp/postprocess.ts +93 -0
  70. package/src/clpp/runner.ts +102 -0
  71. package/src/compile.ts +26 -149
  72. package/src/intellisense.ts +36 -165
  73. package/src/libs.ts +1 -1
  74. package/src/lsp.ts +1 -5
  75. package/src/preprocess.ts +8 -180
  76. package/src/system-understander.ts +1 -1
  77. package/src/transpile.ts +9 -52
  78. package/src/utils/project.ts +12 -28
  79. package/templates/game/.vscode/extensions.json +0 -3
  80. package/templates/game/.vscode/settings.json +6 -14
  81. package/templates/game/src/client/init.client.clpp +6 -0
  82. package/templates/game/src/server/leaderstats.server.clpp +29 -0
  83. package/templates/game/src/shared/config.clp +6 -0
  84. package/examples/game/.clangd +0 -25
  85. package/examples/game/compile_flags.txt +0 -6
  86. package/examples/game/src/client/hud.client.cpp +0 -12
  87. package/examples/game/src/client/init.client.cpp +0 -6
  88. package/examples/game/src/server/combat.server.cpp +0 -23
  89. package/examples/game/src/server/leaderstats.server.cpp +0 -29
  90. package/examples/game/src/shared/config.cpp +0 -5
  91. package/examples/game/src/shared/config.h +0 -5
  92. package/include/cluaupp/libs.hpp +0 -25
  93. package/include/cluaupp/roblox.hpp +0 -47
  94. package/src/architecture.ts +0 -500
  95. package/src/ast.ts +0 -37
  96. package/src/emit.ts +0 -609
  97. package/src/emitter/luau-codegen.ts +0 -187
  98. package/src/emitter/translators.ts +0 -168
  99. package/src/headers.ts +0 -233
  100. package/src/layout.ts +0 -114
  101. package/src/lex.ts +0 -158
  102. package/src/parse.ts +0 -729
  103. package/src/parser/collector.ts +0 -148
  104. package/src/parser/index.ts +0 -27
  105. package/src/tree-sitter-cpp.d.ts +0 -4
  106. package/src/understand.ts +0 -322
  107. package/templates/game/src/client/init.client.cpp +0 -6
  108. package/templates/game/src/server/leaderstats.server.cpp +0 -29
  109. package/templates/game/src/shared/config.cpp +0 -5
  110. package/templates/game/src/shared/config.h +0 -5
  111. /package/include/{cluaupp/generated/enums.hpp → clpp/generated/enums.clh} +0 -0
  112. /package/include/{cluaupp/libs/math.hpp → clpp/libs/math.clh} +0 -0
  113. /package/include/{cluaupp/libs/twinkle.hpp → clpp/libs/twinkle.clh} +0 -0
  114. /package/include/{cluaupp/libs/vfx.hpp → clpp/libs/vfx.clh} +0 -0
@@ -3,237 +3,29 @@ title: Combat (server validation)
3
3
  sidebar_position: 4
4
4
  ---
5
5
 
6
- # Combat (server validation)
6
+ # Combat
7
7
 
8
- The client never sends **damage**. It sends **who I want to hit**. The server decides range, cooldown, alive state, and the damage constant.
8
+ Live source: [`examples/game/src/server/combat.server.clpp`](../../examples/game/src/server/combat.server.clpp). Language: [CL++](https://kartzrbx.github.io/CLPP/).
9
9
 
10
- Pair with [Data boot](data-boot.md) if a kill should grant Money.
10
+ This sample uses exclusive CL++:
11
11
 
12
- ## Shared config
12
+ - `guard` / `match` instead of nested null checks
13
+ - `signal<Player*, int> OnHit` and `OnHit~>Connect` / `OnHit::Fire`
14
+ - `observable int combo`
15
+ - `[[server]]` on `WatchWorkspace`
16
+ - `spawn { task::wait(1); … }`
13
17
 
14
- `src/shared/constants/CombatConfig.hpp`
18
+ The client never decides damage. Touched parts fire `OnHit`; the server prints combo and destroys the part.
15
19
 
16
- ```cpp
17
- #pragma once
20
+ ```clpp
21
+ #include <clpp/roblox.clh>
22
+ #include <clpp/libs/janitor.clh>
18
23
 
19
- const double ATTACK_RANGE = 12;
20
- const double ATTACK_COOLDOWN = 0.4;
21
- const int ATTACK_DAMAGE = 12;
22
- const int KILL_REWARD = 5;
24
+ struct CombatServer {
25
+ Janitor* janitor;
26
+ signal<Player*, int> OnHit;
27
+ void PlayerEntered(Player* player);
28
+ void BindPart(BasePart* part);
29
+ void WatchWorkspace();
30
+ };
23
31
  ```
24
-
25
- Keep numbers in a header. Both server and client can include range for FX; **only the server** applies `TakeDamage`.
26
-
27
- ## Server — `CombatServer.server.cpp`
28
-
29
- ```cpp
30
- #include <cluaupp/roblox.hpp>
31
- #include <cluaupp/libs/janitor.hpp>
32
- #include <cluaupp/libs/net.hpp>
33
- #include <cluaupp/libs/dataservice.hpp>
34
- #include "../../../shared/constants/CombatConfig.hpp"
35
-
36
- Players* Players = GetService<Players>();
37
- Janitor* janitor = new Janitor();
38
- NetEvent* Attack = Net::Event("Attack");
39
-
40
- BasePart* RootPart(Model* character) {
41
- if (character == nullptr) {
42
- return nullptr;
43
- }
44
- return character->FindFirstChild("HumanoidRootPart");
45
- }
46
-
47
- Humanoid* HumanoidOf(Model* character) {
48
- if (character == nullptr) {
49
- return nullptr;
50
- }
51
- return character->FindFirstChildOfClass("Humanoid");
52
- }
53
-
54
- bool InRange(Model* a, Model* b, double maxRange) {
55
- BasePart* rootA = RootPart(a);
56
- BasePart* rootB = RootPart(b);
57
- if (rootA == nullptr) {
58
- return false;
59
- }
60
- if (rootB == nullptr) {
61
- return false;
62
- }
63
- Vector3 delta = rootA->Position - rootB->Position;
64
- if (delta.Magnitude > maxRange) {
65
- return false;
66
- }
67
- return true;
68
- }
69
-
70
- bool OnCooldown(Player* attacker) {
71
- NumberValue* last = attacker->FindFirstChild("LastAttackAt");
72
- if (last == nullptr) {
73
- return false;
74
- }
75
- if (tick() - last->Value < ATTACK_COOLDOWN) {
76
- return true;
77
- }
78
- return false;
79
- }
80
-
81
- void MarkAttack(Player* attacker) {
82
- NumberValue* last = attacker->FindFirstChild("LastAttackAt");
83
- if (last == nullptr) {
84
- last = new NumberValue(attacker);
85
- last->Name = "LastAttackAt";
86
- }
87
- last->Value = tick();
88
- }
89
-
90
- void RewardKill(Player* attacker) {
91
- Data* data = DataService::Server.Get(attacker);
92
- if (data == nullptr) {
93
- return;
94
- }
95
- int money = data->Get(DataService::Server.Paths.Currencies.Money);
96
- data->Set(DataService::Server.Paths.Currencies.Money, money + KILL_REWARD);
97
- }
98
-
99
- void OnAttack(Player* attacker, int targetUserId) {
100
- if (attacker == nullptr) {
101
- return;
102
- }
103
- if (targetUserId < 1) {
104
- return;
105
- }
106
- if (OnCooldown(attacker)) {
107
- return;
108
- }
109
-
110
- Player* target = Players->GetPlayerByUserId(targetUserId);
111
- if (target == nullptr) {
112
- return;
113
- }
114
- if (target == attacker) {
115
- return;
116
- }
117
-
118
- Model* attackerChar = attacker->Character;
119
- Model* targetChar = target->Character;
120
- Humanoid* attackerHum = HumanoidOf(attackerChar);
121
- Humanoid* targetHum = HumanoidOf(targetChar);
122
- if (attackerHum == nullptr) {
123
- return;
124
- }
125
- if (targetHum == nullptr) {
126
- return;
127
- }
128
- if (attackerHum->Health <= 0) {
129
- return;
130
- }
131
- if (targetHum->Health <= 0) {
132
- return;
133
- }
134
- if (InRange(attackerChar, targetChar, ATTACK_RANGE) == false) {
135
- cout::ping << attacker->Name << " out of range" << endl;
136
- return;
137
- }
138
-
139
- MarkAttack(attacker);
140
- double healthBefore = targetHum->Health;
141
- targetHum->TakeDamage(ATTACK_DAMAGE);
142
- if (healthBefore > 0) {
143
- if (targetHum->Health <= 0) {
144
- RewardKill(attacker);
145
- }
146
- }
147
- }
148
-
149
- void init() {
150
- Attack->On(OnAttack);
151
- janitor->Add(Attack);
152
- }
153
- ```
154
-
155
- ## Client — `CombatClient.client.cpp`
156
-
157
- The LocalScript only picks a target and fires. It does **not** pass `ATTACK_DAMAGE`.
158
-
159
- ```cpp
160
- #include <cluaupp/roblox.hpp>
161
- #include <cluaupp/libs/janitor.hpp>
162
- #include <cluaupp/libs/net.hpp>
163
-
164
- Players* Players = GetService<Players>();
165
- UserInputService* UserInput = GetService<UserInputService>();
166
- Janitor* janitor = new Janitor();
167
- NetEvent* Attack = Net::Event("Attack");
168
-
169
- Player* PlayerFromPart(Instance* part) {
170
- if (part == nullptr) {
171
- return nullptr;
172
- }
173
- Instance* model = part->FindFirstAncestorOfClass("Model");
174
- if (model == nullptr) {
175
- return nullptr;
176
- }
177
- Player* fromModel = Players->GetPlayerFromCharacter(model);
178
- if (fromModel != nullptr) {
179
- return fromModel;
180
- }
181
- Instance* outer = model->FindFirstAncestorOfClass("Model");
182
- if (outer == nullptr) {
183
- return nullptr;
184
- }
185
- return Players->GetPlayerFromCharacter(outer);
186
- }
187
-
188
- void OnInputBegan(InputObject* input, bool gameProcessed) {
189
- if (gameProcessed) {
190
- return;
191
- }
192
- if (input->UserInputType != Enum::UserInputType::MouseButton1) {
193
- return;
194
- }
195
- Player* localPlayer = Players->LocalPlayer;
196
- if (localPlayer == nullptr) {
197
- return;
198
- }
199
- Mouse* mouse = localPlayer->GetMouse();
200
- if (mouse == nullptr) {
201
- return;
202
- }
203
- Player* target = PlayerFromPart(mouse->Target);
204
- if (target == nullptr) {
205
- return;
206
- }
207
- if (target == localPlayer) {
208
- return;
209
- }
210
- Attack->FireServer(target->UserId);
211
- }
212
-
213
- void init() {
214
- janitor->Add(UserInput->InputBegan.Connect(OnInputBegan));
215
- }
216
- ```
217
-
218
- ## What the server rejects
219
-
220
- | Client cheat | Server check |
221
- | --- | --- |
222
- | `FireServer(99999)` damage | Damage is `ATTACK_DAMAGE` in the header — not an argument |
223
- | Hit a player across the map | `delta.Magnitude > ATTACK_RANGE` |
224
- | Spam click | `LastAttackAt` + `ATTACK_COOLDOWN` |
225
- | Target userId `0` / self | `targetUserId < 1`, `target == attacker` |
226
- | Hit a dead / missing character | Humanoid nil or `Health <= 0` |
227
- | Fire before spawn | `Character` / `HumanoidRootPart` missing |
228
-
229
- `Net::Event("Attack")` must be the **same string** on both sides. Treat that name as public protocol.
230
-
231
- ## Cooldown storage
232
-
233
- `LastAttackAt` is a `NumberValue` on the Player: session-only, no DataStore. Do not persist combat cadence. For anti-exploit that must survive respawn, use DataService `SetTransient` on a path **you** added to the Template — still not a library field.
234
-
235
- ## No lambdas
236
-
237
- `Attack->On(OnAttack)` needs a named function. The first argument of a server `On` is the `Player` who fired.
238
-
239
- See [Net](../libraries/net.md) and [Safety](../cpp-safety.md).
@@ -5,92 +5,24 @@ sidebar_position: 6
5
5
 
6
6
  # HUD
7
7
 
8
- Client-only: wait for the replicated profile, write labels, listen for currency changes. No `Set` on persisted paths from the client.
8
+ Live source: [`examples/game/src/client/hud.client.clpp`](../../examples/game/src/client/hud.client.clpp). Fusion API: [CL++](https://kartzrbx.github.io/CLPP/).
9
9
 
10
- Put a ScreenGui named `Hud` in StarterGui with `MoneyLabel` and `LevelLabel` (`TextLabel`).
10
+ Client-only (`[[client]]`). `Fusion:scoped` / `Fusion:Value` / `Fusion:Computed` / `Fusion:New` build a coins label. `guard` fails if `LocalPlayer` is missing.
11
11
 
12
- Define callbacks **above** `init()` or use lambdas in `Connect`.
13
-
14
- ## `HudClient.client.cpp`
15
-
16
- ```cpp
17
- #include <cluaupp/roblox.hpp>
18
- #include <cluaupp/libs/janitor.hpp>
19
- #include <cluaupp/libs/dataservice.hpp>
20
- #include <cluaupp/libs/formatnumber.hpp>
21
- #include <cluaupp/libs/twinkle.hpp>
22
-
23
- Players* Players = GetService<Players>();
24
- Janitor* janitor = new Janitor();
25
-
26
- TextLabel* FindLabel(PlayerGui* playerGui, string name) {
27
- if (playerGui == nullptr) {
28
- return nullptr;
29
- }
30
- Instance* gui = playerGui->FindFirstChild("Hud");
31
- if (gui == nullptr) {
32
- return nullptr;
33
- }
34
- return gui->FindFirstChild(name);
35
- }
36
-
37
- void Render(Data* data, TextLabel* moneyLabel, TextLabel* levelLabel) {
38
- if (data == nullptr) {
39
- return;
40
- }
41
- int money = data->Get(DataService::Client.Paths.Currencies.Money);
42
- int level = data->Get(DataService::Client.Paths.Currencies.Level);
43
- if (moneyLabel != nullptr) {
44
- moneyLabel->Text = FormatNumber::Abbreviate(money);
45
- }
46
- if (levelLabel != nullptr) {
47
- levelLabel->Text = FormatNumber::Comma(level);
48
- }
49
- }
50
-
51
- void OnCurrenciesChanged() {
52
- Player* player = Players->LocalPlayer;
53
- if (player == nullptr) {
54
- return;
55
- }
56
- PlayerGui* playerGui = player->FindFirstChildOfClass("PlayerGui");
57
- TextLabel* moneyLabel = FindLabel(playerGui, "MoneyLabel");
58
- TextLabel* levelLabel = FindLabel(playerGui, "LevelLabel");
59
- Render(DataService::Client.Get(), moneyLabel, levelLabel);
60
- }
12
+ ```clpp
13
+ #include <clpp/roblox.clh>
14
+ #include <clpp/libs/fusion.clh>
61
15
 
16
+ [[client]]
62
17
  void init() {
63
- Player* player = Players->LocalPlayer;
64
- if (player == nullptr) {
65
- return;
66
- }
67
- PlayerGui* playerGui = player->FindFirstChildOfClass("PlayerGui");
68
- if (playerGui == nullptr) {
69
- return;
70
- }
71
-
72
- Data* data = DataService::Client.WaitForData();
73
- if (data == nullptr) {
74
- cout::warn << "HUD: profile missing" << endl;
18
+ Players* players = GetService<Players>();
19
+ Player* localPlayer = players.LocalPlayer;
20
+ guard (localPlayer != null) else {
21
+ report("LocalPlayer missing");
75
22
  return;
76
23
  }
77
-
78
- TextLabel* moneyLabel = FindLabel(playerGui, "MoneyLabel");
79
- TextLabel* levelLabel = FindLabel(playerGui, "LevelLabel");
80
- Render(data, moneyLabel, levelLabel);
81
-
82
- if (moneyLabel != nullptr) {
83
- Twinkle::Fade(moneyLabel, true);
84
- }
85
-
86
- janitor->Add(data->GetChangedSignal(DataService::Client.Paths.Currencies).Connect(OnCurrenciesChanged));
24
+ auto scope = Fusion:scoped();
25
+ auto coins = Fusion:Value(scope, 0);
26
+ coins(100);
87
27
  }
88
28
  ```
89
-
90
- ## Rules
91
-
92
- - Call `DataService::Client.Init()` in [Data boot](data-boot.md) first. Script order in StarterPlayerScripts is not a contract — `WaitForData` yields until the profile exists.
93
- - Do not `data->Set` Money from the HUD. Display only.
94
- - `Twinkle::Fade` is optional. See [more libraries](../libraries/more.md).
95
-
96
- `HudClient.client.cpp` is a LocalScript (`init.client.luau`).
@@ -5,28 +5,21 @@ sidebar_position: 1
5
5
 
6
6
  # Examples
7
7
 
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.
8
+ High-quality Cluaupp systems you can copy. Each page is a full service in **CL++**. Live sample: [`examples/game`](../../examples/game). Language reference: [kartzrbx.github.io/CLPP](https://kartzrbx.github.io/CLPP/).
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
-
12
- These are **not** dumps of `int main()`. Entry is `void init()`. Types are `struct` + `Class::` methods. Callbacks may be named functions or lambdas. Canonical Leaderstats: [handbook](https://kartzrbx.github.io/Cluaupp/docs/leaderstats.html).
10
+ These are **not** dumps of `int main()`. Entry is `void init()`. Types are `struct` + `Class::` methods. Canonical Leaderstats: [handbook](https://kartzrbx.github.io/Cluaupp/docs/leaderstats.html).
13
11
 
14
12
  ## Suggested layout
15
13
 
16
14
  ```
17
15
  src/
18
- shared/constants/TemplateData.hpp
19
- shared/constants/CombatConfig.hpp
20
- shared/constants/ShopCatalog.hpp
21
- server/boot/DataBoot.server.cpp
22
- client/boot/DataBoot.client.cpp
23
- server/services/leaderstats/LeaderstatsServer.server.cpp
24
- server/services/combat/CombatServer.server.cpp
25
- client/controllers/combat/CombatClient.client.cpp
26
- server/services/shop/ShopServer.server.cpp
27
- client/controllers/shop/ShopClient.client.cpp
28
- client/controllers/hud/HudClient.client.cpp
29
- server/services/weapons/SwordServer.server.cpp
16
+ shared/PlayerData.clh
17
+ shared/config.clp
18
+ shared/features.clp
19
+ server/leaderstats.server.clpp
20
+ server/combat.server.clpp
21
+ client/init.client.clpp
22
+ client/hud.client.clpp
30
23
  ```
31
24
 
32
25
  Boot DataService **once**. Other services `WaitFor` after that.
@@ -1,43 +1,31 @@
1
1
  # Getting started
2
2
 
3
- Cluaupp installs from **npm**, the same channel as roblox-ts and most Roblox tooling outside Studio.
3
+ Cluaupp is the **game toolchain**. [CL++](https://kartzrbx.github.io/CLPP/) is the **language**.
4
4
 
5
5
  ## Requirements
6
6
 
7
7
  - [Node.js](https://nodejs.org/) 18 or newer
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`)
8
+ - [Rojo](https://rojo.space/) **7.7.0** (`cluaupp init` writes `rokit.toml`)
9
+ - **`clpp` on PATH** from [KartzRbx/CLPP](https://github.com/KartzRbx/CLPP)
10
10
 
11
- ## Install the compiler
11
+ ```bash
12
+ cargo install --path . # inside a CL++ checkout
13
+ clpp install # VS Code / Cursor language pack
14
+ ```
12
15
 
13
- Global (`cluaupp` on your PATH):
16
+ ## Install Cluaupp
14
17
 
15
18
  ```bash
16
19
  npm install -g cluaupp
17
20
  cluaupp --version
18
21
  ```
19
22
 
20
- Without a global install, via `npx`:
23
+ Or:
21
24
 
22
25
  ```bash
23
26
  npx cluaupp init my-game
24
27
  ```
25
28
 
26
- As a game dependency:
27
-
28
- ```bash
29
- npm install --save-dev cluaupp
30
- ```
31
-
32
- ```json
33
- {
34
- "scripts": {
35
- "build": "cluaupp build",
36
- "watch": "cluaupp watch"
37
- }
38
- }
39
- ```
40
-
41
29
  ## First game
42
30
 
43
31
  ```bash
@@ -48,132 +36,27 @@ cluaupp build
48
36
  rojo serve
49
37
  ```
50
38
 
51
- In Roblox Studio: install the Rojo plugin and connect to `localhost:34872` (default port).
52
-
53
- Generated layout:
54
-
55
39
  ```
56
40
  my-game/
57
41
  cluaupp.config.json
58
- default.project.json ← Rojo
59
- include/cluaupp/roblox.hpp
60
- include/cluaupp/libs/
61
- libs/ ← CluauppLibs (Janitor, Fusion, Cmdr, DataService, …)
62
- Packages/ ← optional extra Wally
63
- wally.toml
42
+ default.project.json
64
43
  src/
65
- server/leaderstats.server.cpp
66
- client/init.client.cpp
67
- shared/config.h
68
- shared/config.cpp
44
+ server/leaderstats.server.clpp
45
+ client/init.client.clpp
46
+ shared/config.clp
69
47
  out/ ← generated Luau (do not edit)
70
- server/leaderstats.server.luau
71
- client/init.client.luau
72
- shared/Config.luau
73
- ```
74
-
75
- ## Datatypes (Vector3, CFrame, UDim2)
76
-
77
- ```cpp
78
- #include <cluaupp/roblox.hpp>
79
-
80
- void init() {
81
- auto* part = new Part(workspace);
82
- part->Size = Vector3(8, 1, 8);
83
- part->Position = Vector3(0, 10, 0);
84
- part->CFrame = CFrame::lookAt(Vector3(0, 10, 0), Vector3(0, 10, -10));
85
- part->Color = Color3::fromRGB(255, 0, 0);
86
- part->Material = Enum::Material::Plastic;
87
-
88
- auto* frame = new Frame();
89
- frame->Size = UDim2::fromScale(1, 1);
90
- frame->Position = UDim2(0, 0, 0.5, 0);
91
- }
92
- ```
93
-
94
- This becomes `Vector3.new`, `CFrame.lookAt`, `Color3.fromRGB`, `UDim2.fromScale`, `Enum.Material.Plastic`.
95
-
96
- How to spell engine calls: [Roblox in Cluaupp](https://kartzrbx.github.io/Cluaupp/docs/engine.html). Official members: [create.roblox.com](https://create.roblox.com/docs/reference/engine). The complete subset: [Language reference](https://kartzrbx.github.io/Cluaupp/docs/reference.html).
97
-
98
- ## How to write
99
-
100
- Every `.cpp` / `.h` / `.hpp` file can start with the IntelliSense header. Angle-bracket includes are ignored. Quoted `#include "config.h"` is inlined into the file.
101
-
102
- ```cpp
103
- #include <cluaupp/roblox.hpp>
104
-
105
- void CreateLeaderstats(Player* player) {
106
- if (player->FindFirstChild("leaderstats") != nullptr) {
107
- return;
108
- }
109
-
110
- auto* leaderstats = new Folder(player);
111
- leaderstats->Name = "leaderstats";
112
- }
113
-
114
- void init() {
115
- auto* players = GetService<Players>();
116
- for (auto* player : players->GetPlayers()) {
117
- CreateLeaderstats(player);
118
- }
119
- players->PlayerAdded.Connect(CreateLeaderstats);
120
- }
121
- ```
122
-
123
- If a file defines `void init()`, Cluaupp calls `init()` at the end of the `.luau`. Use that in Scripts and LocalScripts.
124
-
125
- ## IntelliSense
126
-
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.
128
-
129
- ```bash
130
- cluaupp intellisense
48
+ libs/ ← CluauppLibs
131
49
  ```
132
50
 
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`.
51
+ ## Tiny program
134
52
 
135
- See [IntelliSense](intellisense.md).
136
-
137
- ## Watch
138
-
139
- ```bash
140
- cluaupp watch
141
- ```
142
-
143
- Saving a `.cpp`, `.h`, or `.hpp` under `src/` rebuilds the project. Keep Rojo running at the same time.
144
-
145
- ## Libraries
146
-
147
- `cluaupp build` copies runtime modules to `libs/` (Rojo: `ReplicatedStorage.CluauppLibs`). Include a header and the compiler injects `require`.
148
-
149
- ```cpp
150
- #include <cluaupp/libs/janitor.hpp>
151
- #include <cluaupp/libs/net.hpp>
53
+ ```clpp
54
+ #include <clpp/roblox.clh>
152
55
 
153
56
  void init() {
154
- auto* janitor = new Janitor();
155
- auto* coins = Net::Event("Coins");
156
- janitor->Add(coins);
57
+ Players* players = GetService<Players>();
58
+ post("online: " .: players::GetPlayers());
157
59
  }
158
60
  ```
159
61
 
160
- Wally is optional. Fusion, Cmdr, DataServiceV2, and the rest ship **inside** `libs/` (full GitHub source). See [Libraries](libraries/index.md) — start with [DataService Init](libraries/dataservice.md) and [Janitor](libraries/janitor.md).
161
-
162
- See [Libraries](libraries/index.md), [OOP](oop/index.md), [types](cpp-types.md), [safety](cpp-safety.md).
163
-
164
- ## Next
165
-
166
- Language handbook (GitHub Pages): **[Docs](https://kartzrbx.github.io/Cluaupp/docs/)** — [every construct](https://kartzrbx.github.io/Cluaupp/docs/reference.html).
167
-
168
- - [C++ → Luau syntax](syntax.md)
169
- - [print and cout](print-cout.md)
170
- - [C++ types](cpp-types.md)
171
- - [const](cpp-const.md)
172
- - [Safety](cpp-safety.md)
173
- - [Organization](cpp-organization.md)
174
- - [Architecture](architecture.md)
175
- - [OOP structure](oop/index.md)
176
- - [Libraries](libraries/index.md)
177
- - [Examples](examples/index.md)
178
- - [Roblox API](roblox-api.md)
179
- - [CLI](cli.md)
62
+ Language course and reference: [kartzrbx.github.io/CLPP](https://kartzrbx.github.io/CLPP/). Migrating `.cpp`: [migration](migration.md).
@@ -1,48 +1,12 @@
1
1
  # IntelliSense
2
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/`
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 and is **not licensed for Cursor**. Two C++ engines in the same window fight; Cluaupp recommends only clangd and marks cpptools as unwanted.
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
3
+ CL++ highlighting, completion, and diagnostics come from **`clpp install`** ([KartzRbx/CLPP](https://github.com/KartzRbx/CLPP) language pack). Cluaupp does not ship clangd or a C++ engine.
29
4
 
30
5
  ```bash
31
- cluaupp intellisense
6
+ clpp install
7
+ cluaupp intellisense # writes files.associations for .clpp / .clp / .clh
32
8
  ```
33
9
 
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/settings.json` | `clangd.enable: true`, `--compile-commands-dir` |
43
- | `.vscode/extensions.json` | recommends `llvm-vs-code-extensions.vscode-clangd`; marks `ms-vscode.cpptools` unwanted |
44
- | `.clangd` | C++20, `-Iinclude`, skip `out/` and `libs/` |
45
- | `compile_flags.txt` | fallback flags if a file is not yet in `compile_commands.json` |
46
- | `compile_commands.json` | one entry per `src/` file |
10
+ Reload the editor. Language id is **`clpp`**, not `cpp`.
47
11
 
48
- `#include <cluaupp/roblox.hpp>` at the top of each source file. The header is not compiled to Luau.
12
+ `cluaupp lsp` can surface `clpp` compile errors over stdio; prefer the official CL++ extension for day-to-day editing.