cluaupp 0.2.2 → 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 (129) hide show
  1. package/CHANGELOG.md +14 -75
  2. package/README.md +42 -88
  3. package/docs/README.md +25 -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/cpp-advanced.md +6 -3
  9. package/docs/cpp-types.md +2 -0
  10. package/docs/examples/combat.md +19 -227
  11. package/docs/examples/hud.md +13 -81
  12. package/docs/examples/index.md +9 -16
  13. package/docs/examples/leaderstats.md +44 -115
  14. package/docs/getting-started.md +20 -135
  15. package/docs/intellisense.md +5 -42
  16. package/docs/intro.md +16 -15
  17. package/docs/libraries/dataservice.md +4 -1
  18. package/docs/libraries/index.md +2 -1
  19. package/docs/libraries/more.md +3 -1
  20. package/docs/libraries/ui.md +76 -0
  21. package/docs/migration.md +38 -0
  22. package/docs/oop/file-tags.md +12 -36
  23. package/docs/oop/index.md +18 -11
  24. package/docs/roblox-api.md +4 -56
  25. package/docs/syntax.md +54 -179
  26. package/editors/vscode/extension.js +1 -1
  27. package/editors/vscode/package.json +4 -4
  28. package/examples/README.md +5 -7
  29. package/examples/game/.vscode/extensions.json +2 -2
  30. package/examples/game/.vscode/settings.json +6 -23
  31. package/examples/game/src/client/hud.client.clpp +54 -0
  32. package/examples/game/src/client/init.client.clpp +6 -0
  33. package/examples/game/src/server/combat.server.clpp +85 -0
  34. package/examples/game/src/server/leaderstats.server.clpp +28 -0
  35. package/examples/game/src/shared/PlayerData.clh +20 -0
  36. package/examples/game/src/shared/config.clp +6 -0
  37. package/examples/game/src/shared/features.clp +88 -0
  38. package/generated/api.js +15 -1
  39. package/generated/cli.js +40 -24
  40. package/generated/clpp/contract.js +5 -0
  41. package/generated/clpp/index.js +27 -0
  42. package/generated/clpp/paths.js +121 -0
  43. package/generated/clpp/postprocess.js +78 -0
  44. package/generated/clpp/runner.js +102 -0
  45. package/generated/compile.js +26 -138
  46. package/generated/emit.js +79 -3
  47. package/generated/intellisense.js +83 -207
  48. package/generated/lex.js +3 -0
  49. package/generated/libs.js +1 -1
  50. package/generated/lsp.js +1 -8
  51. package/generated/parse.js +119 -24
  52. package/generated/preprocess.js +8 -179
  53. package/generated/system-understander.js +1 -1
  54. package/generated/transpile.js +3 -50
  55. package/generated/utils/project.js +13 -28
  56. package/include/{cluaupp/datatypes.hpp → clpp/datatypes.clh} +5 -1
  57. package/include/{cluaupp/generated/instances.hpp → clpp/generated/instances.clh} +1 -1
  58. package/include/{cluaupp/libs/chrono.hpp → clpp/libs/chrono.clh} +9 -9
  59. package/include/{cluaupp/libs/cmdr.hpp → clpp/libs/cmdr.clh} +4 -4
  60. package/include/{cluaupp/libs/dataservice.hpp → clpp/libs/dataservice.clh} +8 -15
  61. package/include/{cluaupp/libs/display.hpp → clpp/libs/display.clh} +1 -2
  62. package/include/{cluaupp/libs/ezvisual.hpp → clpp/libs/ezvisual.clh} +1 -3
  63. package/include/{cluaupp/libs/formatnumber.hpp → clpp/libs/formatnumber.clh} +2 -3
  64. package/include/{cluaupp/libs/fusion.hpp → clpp/libs/fusion.clh} +5 -5
  65. package/include/{cluaupp/libs/iris.hpp → clpp/libs/iris.clh} +2 -2
  66. package/include/{cluaupp/libs/janitor.hpp → clpp/libs/janitor.clh} +1 -2
  67. package/include/{cluaupp/libs/module3d.hpp → clpp/libs/module3d.clh} +2 -4
  68. package/include/{cluaupp/libs/net.hpp → clpp/libs/net.clh} +2 -4
  69. package/include/{cluaupp/libs/promise.hpp → clpp/libs/promise.clh} +1 -4
  70. package/include/{cluaupp/libs/spring.hpp → clpp/libs/spring.clh} +1 -2
  71. package/include/{cluaupp/libs/statemachine.hpp → clpp/libs/statemachine.clh} +2 -3
  72. package/include/{cluaupp/libs/stickybillboard.hpp → clpp/libs/stickybillboard.clh} +1 -2
  73. package/include/{cluaupp/libs/topbarplus.hpp → clpp/libs/topbarplus.clh} +3 -4
  74. package/include/clpp/libs.clh +24 -0
  75. package/include/clpp/roblox.clh +31 -0
  76. package/package.json +20 -16
  77. package/src/api.ts +15 -1
  78. package/src/cli.ts +39 -25
  79. package/src/clpp/contract.ts +39 -0
  80. package/src/clpp/index.ts +18 -0
  81. package/src/clpp/paths.ts +117 -0
  82. package/src/clpp/postprocess.ts +93 -0
  83. package/src/clpp/runner.ts +102 -0
  84. package/src/compile.ts +26 -149
  85. package/src/intellisense.ts +82 -211
  86. package/src/libs.ts +1 -1
  87. package/src/lsp.ts +1 -5
  88. package/src/preprocess.ts +8 -180
  89. package/src/system-understander.ts +1 -1
  90. package/src/transpile.ts +9 -52
  91. package/src/utils/project.ts +12 -28
  92. package/templates/game/.vscode/extensions.json +2 -2
  93. package/templates/game/.vscode/settings.json +6 -23
  94. package/templates/game/src/client/init.client.clpp +6 -0
  95. package/templates/game/src/server/leaderstats.server.clpp +29 -0
  96. package/templates/game/src/shared/config.clp +6 -0
  97. package/examples/game/.clangd +0 -25
  98. package/examples/game/.vscode/c_cpp_properties.json +0 -27
  99. package/examples/game/compile_flags.txt +0 -6
  100. package/examples/game/src/client/hud.client.cpp +0 -12
  101. package/examples/game/src/client/init.client.cpp +0 -6
  102. package/examples/game/src/server/combat.server.cpp +0 -23
  103. package/examples/game/src/server/leaderstats.server.cpp +0 -29
  104. package/examples/game/src/shared/config.cpp +0 -5
  105. package/examples/game/src/shared/config.h +0 -5
  106. package/include/cluaupp/libs.hpp +0 -25
  107. package/include/cluaupp/roblox.hpp +0 -47
  108. package/src/architecture.ts +0 -500
  109. package/src/ast.ts +0 -37
  110. package/src/emit.ts +0 -531
  111. package/src/emitter/luau-codegen.ts +0 -187
  112. package/src/emitter/translators.ts +0 -168
  113. package/src/headers.ts +0 -233
  114. package/src/layout.ts +0 -114
  115. package/src/lex.ts +0 -155
  116. package/src/parse.ts +0 -630
  117. package/src/parser/collector.ts +0 -148
  118. package/src/parser/index.ts +0 -27
  119. package/src/tree-sitter-cpp.d.ts +0 -4
  120. package/src/understand.ts +0 -322
  121. package/templates/game/.vscode/c_cpp_properties.json +0 -27
  122. package/templates/game/src/client/init.client.cpp +0 -6
  123. package/templates/game/src/server/leaderstats.server.cpp +0 -29
  124. package/templates/game/src/shared/config.cpp +0 -5
  125. package/templates/game/src/shared/config.h +0 -5
  126. /package/include/{cluaupp/generated/enums.hpp → clpp/generated/enums.clh} +0 -0
  127. /package/include/{cluaupp/libs/math.hpp → clpp/libs/math.clh} +0 -0
  128. /package/include/{cluaupp/libs/twinkle.hpp → clpp/libs/twinkle.clh} +0 -0
  129. /package/include/{cluaupp/libs/vfx.hpp → clpp/libs/vfx.clh} +0 -0
package/docs/syntax.md CHANGED
@@ -1,205 +1,80 @@
1
- # C++ → Luau syntax
1
+ # CL++ syntax (Cluaupp)
2
2
 
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
-
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).
3
+ Cluaupp does **not** define the language. Write CL++ (`.clpp` / `.clp` / `.clh`); `clpp` emits Luau. Full course and reference: **[kartzrbx.github.io/CLPP](https://kartzrbx.github.io/CLPP/)**.
6
4
 
7
5
  ## Files
8
6
 
9
- - Extensions: `.cpp`, `.h`, `.hpp` (also `.cc`, `.hh`)
10
- - Quoted `#include "file.h"` becomes a Rojo `require` (or is inlined for a header that belongs to the same `.cpp`)
11
- - `#include <cluaupp/roblox.hpp>` and `<cluaupp/libs/*.hpp>` are IntelliSense only; library headers also inject `require(CluauppLibs.*)`
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.
15
-
16
- ## Functions
17
-
18
- ```cpp
19
- void CreateLeaderstats(Player* player) {
20
- return;
21
- }
22
-
23
- int doubleCoins(int coins) {
24
- return coins;
25
- }
26
- ```
27
-
28
- ```luau
29
- const function CreateLeaderstats(player: Player)
30
- return
31
- end
32
-
33
- const function doubleCoins(coins: number): number
34
- return coins
35
- end
36
- ```
7
+ | Source | Rojo |
8
+ | --- | --- |
9
+ | `*.server.clpp` | Script |
10
+ | `*.client.clpp` | LocalScript |
11
+ | `*.plugin.clpp` | Plugin Script |
12
+ | `*.clp` / untagged `.clpp` | ModuleScript |
13
+ | `*.clh` | ModuleScript (types / structs) |
37
14
 
38
- `void` omits a return annotation. `int` / `float` / `double` → `number`. `bool` → `boolean`. Roblox types (`Player`, `Folder`) keep their name.
15
+ `void init()` is the script entry. There is no `int main()`.
39
16
 
40
- If `void init()` exists, emit appends `init()` at the end of the file.
17
+ ## Accessors
41
18
 
42
- ## Locals and const
19
+ CL++ does **not** use `->`.
43
20
 
44
- Luau uses `local` for variables and `const` for constants. `const int` in C++ becomes `const` in Luau.
21
+ | Write | Meaning | Luau |
22
+ | --- | --- | --- |
23
+ | `player.Name` | property | `.` |
24
+ | `player::FindFirstChild("x")` | method | `:` |
25
+ | `DataService:Server` | table key | `.` |
26
+ | `"hi " .: name` | concat | `..` |
27
+ | `signal~>Connect(fn)` | janitor Connect | `janitor:Add(..., "Disconnect")` |
28
+ | `signal~>Once(fn)` | one-shot | `Once` + janitor |
45
29
 
46
- ```cpp
47
- int coins = 10;
48
- const int STARTING_COINS = 0;
49
- auto* folder = new Folder(player);
50
- ```
51
-
52
- ```luau
53
- local coins: number = 10
54
- const STARTING_COINS: number = 0
55
- local folder: Folder = Instance.new("Folder")
56
- folder.Parent = player
57
- ```
30
+ `post` / `warn` / `report` → `print` / `warn` / `error`. `null` is `nil`.
58
31
 
59
- `auto` infers the type when the value is `new Class(...)` or `GetService<Service>()`.
32
+ ## Exclusive CL++ (compiled by `clpp`)
60
33
 
61
- ## Control flow
62
-
63
- ```cpp
64
- if (player->FindFirstChild("leaderstats") != nullptr) {
34
+ ```clpp
35
+ guard (player != null) else {
36
+ warn("Invalid player");
65
37
  return;
66
- } else {
67
- print("ok");
68
- }
69
-
70
- while (true) {
71
- print("tick");
72
- }
73
-
74
- for (auto* player : players->GetPlayers()) {
75
- CreateLeaderstats(player);
76
- }
77
-
78
- switch (action) {
79
- case "buy":
80
- case "purchase":
81
- Grant(player);
82
- break;
83
- case "sell":
84
- if (amount <= 0) {
85
- break;
86
- }
87
- Take(player);
88
- break;
89
- default:
90
- warn("unknown");
91
- break;
92
38
  }
93
- ```
94
-
95
- ```luau
96
- if player:FindFirstChild("leaderstats") ~= nil then
97
- return
98
- else
99
- print("ok")
100
- end
101
-
102
- while true do
103
- print("tick")
104
- end
105
-
106
- for _, player in players:GetPlayers() do
107
- CreateLeaderstats(player)
108
- end
109
-
110
- repeat
111
- if action == "buy" or action == "purchase" then
112
- Grant(player)
113
- elseif action == "sell" then
114
- if amount <= 0 then
115
- break
116
- end
117
- Take(player)
118
- else
119
- warn("unknown")
120
- end
121
- until true
122
- ```
123
-
124
- `switch` evaluates the discriminant **once**, then becomes `if` / `elseif` / `else` inside `repeat … until true` so `break` still exits the switch (even from inside an `if`). Stacked `case` labels share a body (`case "buy": case "purchase":`). There is no C-style fall-through into the next case’s statements. C-style `for (int i = 0; i < n; i++)` is not supported yet.
125
39
 
126
- ## Expressions
40
+ match (child) {
41
+ BasePart* p => BindPart(p),
42
+ Model* m => post("model spawned " .: m.Name),
43
+ _ => warn("ignored instance")
44
+ };
127
45
 
128
- | C++ | Luau |
129
- | --- | --- |
130
- | `nullptr` | `nil` |
131
- | `true` / `false` | `true` / `false` |
132
- | `!=` | `~=` |
133
- | `&&` | `and` |
134
- | `\|\|` | `or` |
135
- | `==` `+` `-` `*` `/` `<` `>` `<=` `>=` | same |
136
- | `"text"` | `"text"` |
137
- | `obj->Prop` | `obj.Prop` |
138
- | `obj->Method(a)` | `obj:Method(a)` if the method is a Roblox API |
139
- | `fn(a)` | `fn(a)` |
140
- | `signal.Connect(fn)` | `signal:Connect(fn)` |
141
- | `Type { .Field = value }` | `{ Field = value }` |
142
-
143
- Designated initializers become Luau tables. Nested braces work the same way:
144
-
145
- ```cpp
146
- DataService::Server.Init(DataServiceOptions {
147
- .Template = playerData,
148
- .StoreName = "PlayerData",
149
- .UseMock = true,
46
+ observable int wallet = 100;
47
+ wallet.OnChange(func [](int newValue) {
48
+ post("Coins changed to: " .: newValue);
150
49
  });
151
- ```
152
50
 
153
- ```luau
154
- DataService.Server:Init({
155
- Template = playerData,
156
- StoreName = "PlayerData",
157
- UseMock = true,
158
- })
159
- ```
160
-
161
- ## `new` and services
162
-
163
- ```cpp
164
- auto* coins = new IntValue(leaderstats);
165
- auto* players = GetService<Players>();
166
- ```
167
-
168
- ```luau
169
- local coins: IntValue = Instance.new("IntValue")
170
- coins.Parent = leaderstats
171
- local players: Players = game:GetService("Players")
172
- ```
51
+ signal<Player*, int> OnHit;
52
+ OnHit~>Connect(func [](Player* player, int amount) {
53
+ post(player.Name .: " dmg " .: amount);
54
+ });
55
+ OnHit::Fire(player, 10);
173
56
 
174
- The first argument of `new Class(parent)` becomes `.Parent`. With no argument: `Instance.new("Class")` only.
57
+ array<string> names = {"Kartz", "Player1"};
58
+ dictionary<string, int> stats = { {"Coins", 100}, {"Gems", 50} };
175
59
 
176
- ## print / cout
60
+ spawn { task::wait(1); post("ready"); };
61
+ parallel { post("desync"); };
177
62
 
178
- `print`, `warn`, and `error` work as in Luau. `cout << … << endl` is the C++ spelling — each `<<` is another argument, `endl` ends the line. `cout::warn` / `cout::error` / `cout::ping` pick the Roblox function.
63
+ async Data* FetchData(Player* player) {
64
+ return await DataService:Server::WaitFor(player);
65
+ }
179
66
 
180
- ```cpp
181
- cout << "EnsureStat: " << name << " not found" << endl;
182
- cout::print << "EnsureStat: " << name << " not found" << endl;
183
- cerr << "failed";
184
- cout::print("ok");
185
- cout::warn("careful");
186
- cout::error("fail");
187
- cout::ping("here");
188
- ```
67
+ [[server]]
68
+ void SaveData(Player* player) { post(player.Name); }
189
69
 
190
- ```luau
191
- print("EnsureStat: ", name, " not found")
192
- warn("failed")
193
- print("ok")
194
- warn("careful")
195
- error("fail")
196
- print("here")
70
+ [[client]]
71
+ void UpdateUI() { post("ui"); }
197
72
  ```
198
73
 
199
- Full table and IntelliSense notes: [print and cout](print-cout.md).
200
-
201
- ## Not supported yet
74
+ Fusion HUD uses `Fusion:scoped`, `Fusion:Value`, `Fusion:Computed`, `Fusion:New`. See [`examples/game`](../examples/game) (`combat.server.clpp`, `hud.client.clpp`, `features.clp`, `PlayerData.clh`).
202
75
 
203
- Custom C++ classes, generic templates besides `GetService<T>`, pointer arithmetic, `std::`, overloading, macros (except `#pragma strict` / `#pragma nstrict` / `#pragma once`).
76
+ ## What Cluaupp adds after `clpp`
204
77
 
205
- If you need one of those patterns, open an issue with the C++ and the expected Luau.
78
+ - `require(ClppLibs.X)` → `require(ReplicatedStorage.CluauppLibs.X)`
79
+ - `--!strict` from `cluaupp.config.json` / `#pragma strict`
80
+ - `out/` layout for Rojo (`init`, `build`, `watch`)
@@ -55,7 +55,7 @@ function activate(context) {
55
55
  });
56
56
 
57
57
  const refreshDiagnostics = (document) => {
58
- if (!document || document.languageId !== "cpp") {
58
+ if (!document || (document.languageId !== "clpp" && document.languageId !== "cpp")) {
59
59
  return;
60
60
  }
61
61
  if (typeof loaded.engine.diagnosticsFor !== "function") {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "cluaupp-diagnostics",
3
3
  "displayName": "Cluaupp",
4
- "description": "Cluaupp subset parse errors. C++ completion, hover, and go-to-definition come from clangd + include/cluaupp/roblox.hpp.",
5
- "version": "0.2.2",
4
+ "description": "Cluaupp project diagnostics. Language highlighting and IntelliSense come from clpp install (CL++).",
5
+ "version": "1.0.0",
6
6
  "publisher": "kartzdev",
7
7
  "engines": {
8
8
  "vscode": "^1.74.0"
@@ -11,14 +11,14 @@
11
11
  "Linters"
12
12
  ],
13
13
  "activationEvents": [
14
- "onLanguage:cpp"
14
+ "onLanguage:clpp"
15
15
  ],
16
16
  "main": "./extension.js",
17
17
  "contributes": {
18
18
  "commands": [
19
19
  {
20
20
  "command": "cluaupp.restartIntelliSense",
21
- "title": "Cluaupp: Reload subset diagnostics"
21
+ "title": "Cluaupp: Reload CL++ diagnostics"
22
22
  }
23
23
  ]
24
24
  }
@@ -1,18 +1,16 @@
1
1
  # Sample game
2
2
 
3
- This is the C++ a Cluaupp game looks like — **not** the compiler.
3
+ CL++ sources for a Cluaupp project — **not** the compiler. Language samples: [CL++ examples](https://github.com/KartzRbx/CLPP/tree/main/examples).
4
4
 
5
5
  | Folder | Rojo | Tag |
6
6
  | --- | --- | --- |
7
- | `src/server/*.server.cpp` | Script | server |
8
- | `src/client/*.client.cpp` | LocalScript | client |
9
- | `src/shared/*` | ModuleScript | none |
10
-
11
- `src/` of **this repo** is the TypeScript CLI ([roblox-ts](https://github.com/roblox-ts/roblox-ts) does the same). The sample scripts live here so they never mix with `understand.ts`.
7
+ | `src/server/*.server.clpp` | Script | server |
8
+ | `src/client/*.client.clpp` | LocalScript | client |
9
+ | `src/shared/*.clp` / `*.clh` | ModuleScript | none |
12
10
 
13
11
  ```bash
14
12
  cd examples/game
15
13
  npx cluaupp build .
16
14
  ```
17
15
 
18
- `cluaupp init` copies `templates/game` (the slim scaffold). This folder adds combat / HUD so `SystemUnderstander` has real tokens to score.
16
+ `cluaupp init` copies `templates/game`. This folder adds combat (`guard` / `match` / `signal` / `observable` / `spawn`), a Fusion HUD, `features.clp`, and `PlayerData.clh`.
@@ -1,5 +1,5 @@
1
1
  {
2
- "recommendations": [
3
- "llvm-vs-code-extensions.vscode-clangd"
2
+ "unwantedRecommendations": [
3
+ "ms-vscode.cpptools"
4
4
  ]
5
5
  }
@@ -1,27 +1,10 @@
1
1
  {
2
- "C_Cpp.intelliSenseEngine": "Disabled",
3
- "C_Cpp.default.cppStandard": "c++20",
4
- "C_Cpp.default.cStandard": "c17",
5
- "C_Cpp.default.compilerPath": "clang++",
6
- "C_Cpp.default.intelliSenseMode": "windows-clang-x64",
7
- "C_Cpp.default.includePath": [
8
- "${workspaceFolder}/include",
9
- "${workspaceFolder}/src"
10
- ],
11
- "clangd.enable": true,
12
- "clangd.arguments": [
13
- "--compile-commands-dir=${workspaceFolder}",
14
- "--header-insertion=never",
15
- "--query-driver=**/clang++*,**/clang++.exe,**/g++*,**/g++.exe"
16
- ],
17
2
  "files.associations": {
18
- "*.hpp": "cpp",
19
- "*.h": "cpp",
20
- "*.server.cpp": "cpp",
21
- "*.client.cpp": "cpp",
22
- "*.plugin.cpp": "cpp",
23
- "*.legacy.cpp": "cpp",
24
- "*.legacy.server.cpp": "cpp",
25
- "*.legacy.client.cpp": "cpp"
3
+ "*.clpp": "clpp",
4
+ "*.clp": "clpp",
5
+ "*.clh": "clpp",
6
+ "*.server.clpp": "clpp",
7
+ "*.client.clpp": "clpp",
8
+ "*.plugin.clpp": "clpp"
26
9
  }
27
10
  }
@@ -0,0 +1,54 @@
1
+ #pragma strict
2
+ #include <clpp/roblox.clh>
3
+ #include <clpp/libs/fusion.clh>
4
+
5
+ [[client]]
6
+ void init() {
7
+ Players* players = GetService<Players>();
8
+ Player* localPlayer = players.LocalPlayer;
9
+ guard (localPlayer != null) else {
10
+ report("LocalPlayer missing");
11
+ return;
12
+ }
13
+
14
+ Instance* playerGui = localPlayer::WaitForChild("PlayerGui");
15
+ auto scope = Fusion:scoped();
16
+ auto Children = Fusion:Children;
17
+
18
+ auto coins = Fusion:Value(scope, 0);
19
+ auto title = Fusion:Computed(scope, func []() {
20
+ return "Coins: " .: coins();
21
+ });
22
+
23
+ auto newScreenGui = Fusion:New(scope, "ScreenGui");
24
+ auto newFrame = Fusion:New(scope, "Frame");
25
+ auto newLabel = Fusion:New(scope, "TextLabel");
26
+
27
+ auto label = newLabel({
28
+ {"Name", "Amount"},
29
+ {"BackgroundTransparency", 1},
30
+ {"Size", UDim2.fromScale(1, 1)},
31
+ {"Text", title},
32
+ {"TextColor3", Color3.fromRGB(255, 255, 255)},
33
+ {"TextScaled", true}
34
+ });
35
+
36
+ auto frame = newFrame({
37
+ {"Name", "Hud"},
38
+ {"AnchorPoint", Vector2(0, 1)},
39
+ {"Position", UDim2.fromScale(0, 1)},
40
+ {"Size", UDim2.fromOffset(220, 64)},
41
+ {"BackgroundColor3", Color3.fromRGB(28, 18, 48)},
42
+ {Children, label}
43
+ });
44
+
45
+ newScreenGui({
46
+ {"Name", "CoinsHud"},
47
+ {"ResetOnSpawn", false},
48
+ {"Parent", playerGui},
49
+ {Children, frame}
50
+ });
51
+
52
+ coins(100);
53
+ post("hud ready");
54
+ }
@@ -0,0 +1,6 @@
1
+ #pragma strict
2
+ #include <clpp/roblox.clh>
3
+
4
+ void init() {
5
+ post("Cluaupp client ok");
6
+ }
@@ -0,0 +1,85 @@
1
+ #pragma strict
2
+ #include <clpp/roblox.clh>
3
+ #include <clpp/libs/janitor.clh>
4
+
5
+ struct CombatServer {
6
+ Janitor* janitor;
7
+ signal<Player*, int> OnHit;
8
+ void PlayerEntered(Player* player);
9
+ void BindPart(BasePart* part);
10
+ void WatchWorkspace();
11
+ };
12
+
13
+ void CombatServer::BindPart(BasePart* part) {
14
+ guard (part != null) else {
15
+ return;
16
+ }
17
+
18
+ part.Touched~>Once(func [](BasePart* other) {
19
+ Instance* character = other.Parent;
20
+ guard (character != null) else {
21
+ return;
22
+ }
23
+
24
+ match (character::FindFirstChild("Humanoid")) {
25
+ Humanoid* humanoid => {
26
+ guard (humanoid.Health > 0) else {
27
+ return;
28
+ }
29
+ Players* players = GetService<Players>();
30
+ Player* player = players::GetPlayerFromCharacter(character);
31
+ guard (player != null) else {
32
+ return;
33
+ }
34
+ OnHit::Fire(player, 10);
35
+ part::Destroy();
36
+ },
37
+ _ => warn("touch without humanoid")
38
+ };
39
+ });
40
+ }
41
+
42
+ void CombatServer::PlayerEntered(Player* player) {
43
+ guard (player != null) else {
44
+ return;
45
+ }
46
+
47
+ observable int combo = 0;
48
+ OnHit~>Connect(func [](Player* victim, int amount) {
49
+ guard (victim == player) else {
50
+ return;
51
+ }
52
+ combo = combo + 1;
53
+ post(player.Name .: " combo " .: combo .: " dmg " .: amount);
54
+ });
55
+ }
56
+
57
+ [[server]]
58
+ void CombatServer::WatchWorkspace() {
59
+ workspace.ChildAdded~>Connect(func [](Instance* child) {
60
+ match (child) {
61
+ BasePart* p => BindPart(p),
62
+ Model* m => post("model spawned " .: m.Name),
63
+ _ => warn("ignored instance")
64
+ };
65
+ });
66
+ }
67
+
68
+ void init() {
69
+ CombatServer combat;
70
+ combat.janitor = new Janitor();
71
+
72
+ spawn {
73
+ task::wait(1);
74
+ post("combat ready");
75
+ };
76
+
77
+ Players* players = GetService<Players>();
78
+ for (Player* player : players::GetPlayers()) {
79
+ combat::PlayerEntered(player);
80
+ }
81
+ players::PlayerAdded~>Connect(func [](Player* p) {
82
+ combat::PlayerEntered(p);
83
+ });
84
+ combat::WatchWorkspace();
85
+ }
@@ -0,0 +1,28 @@
1
+ #pragma strict
2
+ #include <clpp/roblox.clh>
3
+
4
+ void CreateLeaderstats(Player* player) {
5
+ if (player::FindFirstChild("leaderstats") != null) {
6
+ return;
7
+ }
8
+
9
+ Folder* leaderstats = new Folder(player);
10
+ leaderstats.Name = "leaderstats";
11
+
12
+ IntValue* coins = new IntValue(leaderstats);
13
+ coins.Name = "Coins";
14
+ coins.Value = 0;
15
+
16
+ IntValue* level = new IntValue(leaderstats);
17
+ level.Name = "Level";
18
+ level.Value = 0;
19
+ }
20
+
21
+ void init() {
22
+ Players* players = GetService<Players>();
23
+ for (Player* player : players::GetPlayers()) {
24
+ CreateLeaderstats(player);
25
+ }
26
+
27
+ players::PlayerAdded::Connect(CreateLeaderstats);
28
+ }
@@ -0,0 +1,20 @@
1
+ #pragma once
2
+
3
+ #include <clpp/datatypes.clh>
4
+
5
+ struct PlayerDataCurrencies {
6
+ int Coins = 0;
7
+ int Rebirths = 0;
8
+ };
9
+
10
+ struct PlayerDataInventory {
11
+ array<int> HotBar;
12
+ array<int> Storage;
13
+
14
+ int MaxStorage = 90;
15
+ };
16
+
17
+ struct PlayerData {
18
+ PlayerDataCurrencies Currencies;
19
+ PlayerDataInventory Inventory;
20
+ };
@@ -0,0 +1,6 @@
1
+ #pragma once
2
+ #include <clpp/roblox.clh>
3
+
4
+ const int STARTING_COINS = 0;
5
+ const string REMOTE_COINS = "Coins";
6
+ const string LEADERSTATS_FOLDER = "leaderstats";
@@ -0,0 +1,88 @@
1
+ #pragma once
2
+ #include <clpp/roblox.clh>
3
+
4
+ void ShowcaseFeatures(int coins, Player* playerRef) {
5
+ int n = 100;
6
+ float speed = 16.5;
7
+ string name = "Kartz";
8
+ bool isActive = true;
9
+ func callback = []() {};
10
+ (void)speed;
11
+ (void)isActive;
12
+ (void)callback;
13
+
14
+ array<string> names = {"Kartz", "Player1"};
15
+ dictionary<string, int> stats = {
16
+ {"Coins", 100},
17
+ {"Gems", 50}
18
+ };
19
+ (void)names;
20
+ (void)stats;
21
+
22
+ if (coins > 50) {
23
+ post("Enough balance!");
24
+ } else if (coins == 0) {
25
+ warn("No coins!");
26
+ } else {
27
+ report("Balance sync error.");
28
+ }
29
+
30
+ for (int i = 0; i < 10; i++) {
31
+ post("Count: " .: i);
32
+ }
33
+
34
+ n += 1;
35
+
36
+ observable int wallet = 100;
37
+ wallet.OnChange(func [](int newValue) {
38
+ post("Coins changed to: " .: newValue);
39
+ });
40
+
41
+ signal<Player*, int> OnCoinsUpdated;
42
+ OnCoinsUpdated~>Connect(func [](Player* player, int newAmount) {
43
+ post("New coins for " .: player.Name .: ": " .: newAmount);
44
+ });
45
+ OnCoinsUpdated~>Once(func [](Player* player, int newAmount) {
46
+ (void)newAmount;
47
+ post("First coins for " .: player.Name);
48
+ });
49
+ OnCoinsUpdated::Fire(playerRef, wallet);
50
+
51
+ guard (playerRef != null) else {
52
+ warn("Invalid player");
53
+ return;
54
+ }
55
+
56
+ playerRef::GetPropertyChangedSignal("Name")~>Connect(func []() {
57
+ post("Name changed");
58
+ });
59
+
60
+ auto [success, result] = pcall(func []() {
61
+ return 1;
62
+ });
63
+ (void)result;
64
+
65
+ const int moeda = 4;
66
+ match (moeda) {
67
+ int a => post(a),
68
+ _ => post("Not found")
69
+ };
70
+
71
+ if (success) {
72
+ post("Data loaded successfully!");
73
+ }
74
+
75
+ spawn {
76
+ task::wait(2);
77
+ post("Delay finished!");
78
+ };
79
+
80
+ parallel {
81
+ post("desync");
82
+ };
83
+
84
+ match (name) {
85
+ string s => post(s),
86
+ _ => warn("Instance not supported")
87
+ };
88
+ }