cluaupp 1.5.0 → 1.5.1

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 (323) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +10 -5
  3. package/api/CHANGELOG.md +3 -0
  4. package/api/chat.js +74 -0
  5. package/api/fixtures/roblox/README.md +6 -0
  6. package/api/fixtures/roblox/aux/sample.d.luau +6 -0
  7. package/api/fixtures/roblox/mini/Mini-API-Dump.json +72 -0
  8. package/api/generated/bench-latest.json +39 -0
  9. package/api/generated/capability-profile.json +76 -0
  10. package/api/generated/lsp-index.json +1 -0
  11. package/api/generated/luau/classes.d.luau +11221 -0
  12. package/api/generated/luau/datatypes.d.luau +327 -0
  13. package/api/generated/luau/enums.d.luau +4918 -0
  14. package/api/generated/luau/globals.d.luau +12 -0
  15. package/api/manifests/roblox-target.manifest.json +22 -0
  16. package/api/normalized/roblox-target.profile.json +237461 -0
  17. package/api/overrides/classes.json +8 -0
  18. package/api/overrides/compatibility.json +9 -0
  19. package/api/overrides/datatypes.json +1579 -0
  20. package/api/overrides/enums.json +8 -0
  21. package/api/overrides/globals.json +8 -0
  22. package/api/overrides/type-mappings.json +9 -0
  23. package/api/roblox-api.lock.json +9 -0
  24. package/data/Mini-API-Dump.json +1 -0
  25. package/editors/vscode/README.md +12 -10
  26. package/editors/vscode/extension.js +82 -0
  27. package/editors/vscode/icons/axiom.svg +4 -0
  28. package/editors/vscode/icons/bloom.svg +5 -0
  29. package/editors/vscode/icons/helm.svg +4 -0
  30. package/editors/vscode/icons/hive.svg +5 -0
  31. package/editors/vscode/icons/mint.svg +4 -0
  32. package/editors/vscode/icons/shift.svg +6 -0
  33. package/editors/vscode/language-configuration-schema.json +24 -0
  34. package/editors/vscode/package.json +172 -12
  35. package/editors/vscode/snippets/axiom.json +12 -0
  36. package/editors/vscode/snippets/bloom.json +12 -0
  37. package/editors/vscode/snippets/helm.json +12 -0
  38. package/editors/vscode/snippets/hive.json +12 -0
  39. package/editors/vscode/snippets/mint.json +12 -0
  40. package/editors/vscode/snippets/shift.json +17 -0
  41. package/editors/vscode/syntaxes/axiom.tmLanguage.json +5 -0
  42. package/editors/vscode/syntaxes/bloom.tmLanguage.json +5 -0
  43. package/editors/vscode/syntaxes/helm.tmLanguage.json +5 -0
  44. package/editors/vscode/syntaxes/hive.tmLanguage.json +5 -0
  45. package/editors/vscode/syntaxes/mint.tmLanguage.json +5 -0
  46. package/editors/vscode/syntaxes/schema.tmLanguage.json +89 -0
  47. package/editors/vscode/syntaxes/shift.tmLanguage.json +5 -0
  48. package/examples/game/.cluaupp/compile-cache/ReplicatedStorage__Shared__Constants__Datas__TemplateData.clh.json +1 -0
  49. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Boot__DataBoot.server.clpp.json +1 -0
  50. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Configuration__ServerConfig.clp.json +1 -0
  51. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Handlers__Guard.server.clpp.json +1 -0
  52. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Handlers__PlayerHandler.server.clpp.json +1 -0
  53. package/examples/game/.cluaupp/compile-cache/StarterPlayer__StarterCharacterScripts__Character__CharacterReady.client.clpp.json +1 -0
  54. package/examples/game/.cluaupp/compile-cache/StarterPlayer__StarterPlayerScripts__Controllers__DataController.client.clpp.json +1 -0
  55. package/examples/game/.cluaupp/compile-cache/index.json +12 -0
  56. package/examples/game/.cluaupp/datamodel-profile.json +94 -0
  57. package/examples/game/.vscode/settings.json +12 -1
  58. package/examples/game/include/clpp/datatypes.clh +337 -373
  59. package/examples/game/include/clpp/generated/datamodel.clh +25 -0
  60. package/examples/game/include/clpp/generated/enums.clh +1 -1
  61. package/examples/game/include/clpp/generated/instances.clh +41135 -41064
  62. package/examples/game/include/clpp/libs/axiom.clh +1 -1
  63. package/examples/game/include/clpp/libs/math.clh +14 -0
  64. package/examples/game/include/clpp/libs/spring.clh +17 -0
  65. package/examples/game/include/clpp/libs/ward.clh +1 -0
  66. package/examples/game/include/clpp/roblox.clh +3 -4
  67. package/examples/game/libs/ArrayIndexer/init.luau +209 -0
  68. package/examples/game/libs/Axiom/init.luau +608 -0
  69. package/examples/game/libs/Bloom/init.luau +433 -0
  70. package/examples/game/libs/Coil/init.luau +215 -0
  71. package/examples/game/libs/Crest/init.luau +426 -0
  72. package/examples/game/libs/Echo/init.luau +417 -0
  73. package/examples/game/libs/Ember/init.luau +365 -0
  74. package/examples/game/libs/Flare/init.luau +717 -0
  75. package/examples/game/libs/Gleam/init.luau +729 -0
  76. package/examples/game/libs/Guide/init.luau +215 -0
  77. package/examples/game/libs/Helm/init.luau +377 -0
  78. package/examples/game/libs/Hive/init.luau +241 -0
  79. package/examples/game/libs/Keep/Client.luau +114 -0
  80. package/examples/game/libs/Keep/Data.luau +883 -0
  81. package/examples/game/libs/Keep/Engine.luau +211 -0
  82. package/examples/game/libs/Keep/Enum.luau +6 -0
  83. package/examples/game/libs/Keep/Enums.luau +10 -0
  84. package/examples/game/libs/Keep/Path.luau +236 -0
  85. package/examples/game/libs/Keep/Replicator.luau +298 -0
  86. package/examples/game/libs/Keep/Server.luau +251 -0
  87. package/examples/game/libs/Keep/Store.luau +652 -0
  88. package/examples/game/libs/Keep/Trade.luau +455 -0
  89. package/examples/game/libs/Keep/init.luau +205 -0
  90. package/examples/game/libs/Lens/init.luau +609 -0
  91. package/examples/game/libs/Mint/init.luau +279 -0
  92. package/examples/game/libs/Net/init.luau +156 -0
  93. package/examples/game/libs/Net/src/codec.luau +224 -0
  94. package/examples/game/libs/Occlude/init.luau +117 -0
  95. package/examples/game/libs/Pin/init.luau +309 -0
  96. package/examples/game/libs/Promise/LICENSE +21 -0
  97. package/examples/game/libs/Promise/_impl/LICENSE +21 -0
  98. package/examples/game/libs/Promise/_impl/init.lua +1991 -0
  99. package/examples/game/libs/Promise/init.lua +1990 -0
  100. package/examples/game/libs/Promise/init.luau +13 -0
  101. package/examples/game/libs/Promise/types.luau +46 -0
  102. package/examples/game/libs/Roster/init.luau +686 -0
  103. package/examples/game/libs/SOURCES.md +31 -0
  104. package/examples/game/libs/Shift/init.luau +238 -0
  105. package/examples/game/libs/Spark/init.luau +487 -0
  106. package/examples/game/libs/Stage/init.luau +178 -0
  107. package/examples/game/libs/Sweep/init.luau +259 -0
  108. package/examples/game/libs/Trace/init.luau +213 -0
  109. package/examples/game/libs/Ward/init.luau +211 -0
  110. package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau +29 -0
  111. package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau.map.json +13 -0
  112. package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau +83 -0
  113. package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau.map.json +13 -0
  114. package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau +18 -0
  115. package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau.map.json +13 -0
  116. package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau +14 -0
  117. package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau.map.json +13 -0
  118. package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau +15 -0
  119. package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau.map.json +13 -0
  120. package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau +50 -0
  121. package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau.map.json +13 -0
  122. package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau +12 -0
  123. package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau.map.json +13 -0
  124. package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau +16 -0
  125. package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau.map.json +13 -0
  126. package/examples/game/src/ReplicatedStorage/Shared/Net/Net.clh +26 -0
  127. package/examples/game/src/ServerScriptService/Boot/DataBoot.server.clpp +1 -1
  128. package/examples/game/src/ServerScriptService/Handlers/PlayerHandler.server.clpp +1 -1
  129. package/examples/game/stylua.toml +9 -0
  130. package/generated/api/build-profile.js +115 -0
  131. package/generated/api/cache.js +44 -0
  132. package/generated/api/coverage.js +32 -0
  133. package/generated/api/diff.js +125 -0
  134. package/generated/api/generators/clpp-headers.js +353 -0
  135. package/generated/api/generators/docs-reference.js +7 -0
  136. package/generated/api/generators/lsp-index.js +81 -0
  137. package/generated/api/generators/luau-defs.js +94 -0
  138. package/generated/api/ide.js +76 -0
  139. package/generated/api/identifier.js +47 -0
  140. package/generated/api/index.js +324 -0
  141. package/generated/api/loader.js +57 -0
  142. package/generated/api/merge.js +88 -0
  143. package/generated/api/model.js +5 -0
  144. package/generated/api/normalize.js +231 -0
  145. package/generated/api/overrides-validate.js +58 -0
  146. package/generated/api/perf.js +12 -0
  147. package/generated/api/registry.js +136 -0
  148. package/generated/api/release.js +44 -0
  149. package/generated/api/resolver.js +250 -0
  150. package/generated/api/sources/aux-types-diff.js +75 -0
  151. package/generated/api/sources/client-tracker.js +11 -0
  152. package/generated/api/sources/creator-docs.js +42 -0
  153. package/generated/api/sources/luau-types.js +34 -0
  154. package/generated/api/sources/mini-dump.js +17 -0
  155. package/generated/api/sources/studio-api.js +8 -0
  156. package/generated/api/sources/studio-apiv2.js +11 -0
  157. package/generated/api/sources/studio-full-api.js +8 -0
  158. package/generated/api/studio-smoke.js +80 -0
  159. package/generated/api/type-parse.js +49 -0
  160. package/generated/api/understander.js +51 -0
  161. package/generated/api/validate.js +135 -0
  162. package/generated/api-cli.js +421 -0
  163. package/generated/cli.js +16 -5
  164. package/generated/clpp/contract.js +3 -3
  165. package/generated/clpp/format-luau.js +236 -0
  166. package/generated/clpp/index.js +13 -1
  167. package/generated/clpp/modules.js +227 -0
  168. package/generated/clpp/postprocess.js +86 -5
  169. package/generated/clpp/rewrite-janitor.js +145 -0
  170. package/generated/clpp/runner.js +14 -2
  171. package/generated/compile.js +82 -0
  172. package/generated/flare/parse.js +12 -1
  173. package/generated/intellisense.js +57 -1
  174. package/generated/native/index.js +217 -16
  175. package/generated/target/authority-check.js +136 -0
  176. package/generated/target/authority-graph.js +74 -0
  177. package/generated/target/build-cache.js +112 -0
  178. package/generated/target/capabilities.js +89 -0
  179. package/generated/target/capability-profile.js +30 -0
  180. package/generated/target/component-contracts.js +60 -0
  181. package/generated/target/context-check.js +160 -0
  182. package/generated/target/datamodel-check.js +170 -0
  183. package/generated/target/datamodel-generate.js +74 -0
  184. package/generated/target/datamodel.js +233 -0
  185. package/generated/target/diagnostics.js +63 -0
  186. package/generated/target/doctor.js +152 -0
  187. package/generated/target/flare-version.js +58 -0
  188. package/generated/target/get-service.js +69 -0
  189. package/generated/target/lifetime-check.js +47 -0
  190. package/generated/target/luau-stamp.js +39 -0
  191. package/generated/target/optimizer-advise.js +88 -0
  192. package/generated/target/optimizer-apply.js +44 -0
  193. package/generated/target/optimizer-soa.js +254 -0
  194. package/generated/target/parallel-check.js +136 -0
  195. package/generated/target/pgo.js +148 -0
  196. package/generated/target/project-docs.js +69 -0
  197. package/generated/target/project-graph.js +71 -0
  198. package/generated/target/roblox.js +63 -0
  199. package/generated/target/security-check.js +41 -0
  200. package/generated/target/source-map.js +25 -0
  201. package/generated/target/studio-bridge.js +112 -0
  202. package/generated/utils/project.js +178 -8
  203. package/generated/utils/rojo-mapper.js +11 -3
  204. package/include/clpp/datatypes.clh +337 -373
  205. package/include/clpp/generated/enums.clh +1 -1
  206. package/include/clpp/generated/instances.clh +41135 -41064
  207. package/include/clpp/libs/axiom.clh +1 -1
  208. package/include/clpp/libs/hive.clh +1 -0
  209. package/include/clpp/libs/keep.clh +2 -0
  210. package/include/clpp/libs/math.clh +14 -0
  211. package/include/clpp/libs/spring.clh +17 -0
  212. package/include/clpp/libs/ward.clh +1 -0
  213. package/include/clpp/roblox.clh +3 -4
  214. package/package.json +10 -3
  215. package/plugins/CluauppNav/Plugin.luau +207 -0
  216. package/plugins/CluauppNav/ProfileLogger.luau +27 -0
  217. package/plugins/CluauppNav/README.md +24 -0
  218. package/runtime/Axiom/init.luau +10 -7
  219. package/runtime/Coil/init.luau +8 -2
  220. package/runtime/Crest/init.luau +1 -0
  221. package/runtime/Flare/init.luau +2 -1
  222. package/runtime/Gleam/init.luau +15 -4
  223. package/runtime/Hive/init.luau +36 -14
  224. package/runtime/Pin/init.luau +5 -2
  225. package/runtime/Roster/init.luau +2 -0
  226. package/runtime/Spark/init.luau +3 -0
  227. package/runtime/Sweep/init.luau +2 -0
  228. package/runtime/Trace/init.luau +3 -0
  229. package/runtime/Ward/init.luau +38 -5
  230. package/scripts/postinstall-editor.js +17 -0
  231. package/skills/README.md +13 -0
  232. package/skills/clpp-hive-flare/SKILL.md +79 -0
  233. package/skills/clpp-language/SKILL.md +123 -0
  234. package/skills/clpp-language/compiler.md +89 -0
  235. package/skills/clpp-style/SKILL.md +95 -0
  236. package/src/api/build-profile.ts +138 -0
  237. package/src/api/cache.ts +45 -0
  238. package/src/api/coverage.ts +46 -0
  239. package/src/api/diff.ts +143 -0
  240. package/src/api/generators/clpp-headers.ts +377 -0
  241. package/src/api/generators/docs-reference.ts +11 -0
  242. package/src/api/generators/lsp-index.ts +106 -0
  243. package/src/api/generators/luau-defs.ts +98 -0
  244. package/src/api/ide.ts +87 -0
  245. package/src/api/identifier.ts +47 -0
  246. package/src/api/index.ts +269 -0
  247. package/src/api/loader.ts +60 -0
  248. package/src/api/merge.ts +126 -0
  249. package/src/api/model.ts +283 -0
  250. package/src/api/normalize.ts +257 -0
  251. package/src/api/overrides-validate.ts +58 -0
  252. package/src/api/perf.ts +15 -0
  253. package/src/api/registry.ts +162 -0
  254. package/src/api/release.ts +47 -0
  255. package/src/api/resolver.ts +255 -0
  256. package/src/api/sources/aux-types-diff.ts +81 -0
  257. package/src/api/sources/client-tracker.ts +10 -0
  258. package/src/api/sources/creator-docs.ts +37 -0
  259. package/src/api/sources/luau-types.ts +30 -0
  260. package/src/api/sources/mini-dump.ts +50 -0
  261. package/src/api/sources/studio-api.ts +7 -0
  262. package/src/api/sources/studio-apiv2.ts +10 -0
  263. package/src/api/sources/studio-full-api.ts +7 -0
  264. package/src/api/studio-smoke.ts +82 -0
  265. package/src/api/type-parse.ts +48 -0
  266. package/src/api/understander.ts +72 -0
  267. package/src/api/validate.ts +160 -0
  268. package/src/api-cli.ts +493 -0
  269. package/src/api.generated.js +37 -22
  270. package/src/cli.ts +21 -6
  271. package/src/clpp/contract.ts +34 -3
  272. package/src/clpp/format-luau.ts +262 -0
  273. package/src/clpp/index.ts +13 -2
  274. package/src/clpp/modules.ts +252 -0
  275. package/src/clpp/postprocess.ts +100 -5
  276. package/src/clpp/rewrite-janitor.ts +156 -0
  277. package/src/clpp/runner.ts +14 -2
  278. package/src/compile.ts +87 -0
  279. package/src/flare/parse.ts +14 -1
  280. package/src/flare/types.ts +2 -0
  281. package/src/intellisense.ts +58 -1
  282. package/src/native/index.ts +225 -16
  283. package/src/target/authority-check.ts +162 -0
  284. package/src/target/authority-graph.ts +80 -0
  285. package/src/target/build-cache.ts +129 -0
  286. package/src/target/capabilities.ts +115 -0
  287. package/src/target/capability-profile.ts +25 -0
  288. package/src/target/component-contracts.ts +64 -0
  289. package/src/target/context-check.ts +177 -0
  290. package/src/target/datamodel-check.ts +188 -0
  291. package/src/target/datamodel-generate.ts +78 -0
  292. package/src/target/datamodel.ts +261 -0
  293. package/src/target/diagnostics.ts +67 -0
  294. package/src/target/doctor.ts +171 -0
  295. package/src/target/flare-version.ts +61 -0
  296. package/src/target/get-service.ts +85 -0
  297. package/src/target/lifetime-check.ts +45 -0
  298. package/src/target/luau-stamp.ts +33 -0
  299. package/src/target/optimizer-advise.ts +93 -0
  300. package/src/target/optimizer-apply.ts +63 -0
  301. package/src/target/optimizer-soa.ts +270 -0
  302. package/src/target/parallel-check.ts +135 -0
  303. package/src/target/pgo.ts +157 -0
  304. package/src/target/project-docs.ts +68 -0
  305. package/src/target/project-graph.ts +75 -0
  306. package/src/target/roblox.ts +78 -0
  307. package/src/target/security-check.ts +40 -0
  308. package/src/target/source-map.ts +36 -0
  309. package/src/target/studio-bridge.ts +140 -0
  310. package/src/types.ts +14 -0
  311. package/src/utils/project.ts +183 -9
  312. package/src/utils/rojo-mapper.ts +12 -3
  313. package/stylua.toml +9 -0
  314. package/templates/game/.vscode/settings.json +7 -1
  315. package/templates/game/include/clpp/datatypes.clh +337 -373
  316. package/templates/game/include/clpp/generated/enums.clh +1 -1
  317. package/templates/game/include/clpp/generated/instances.clh +41135 -41064
  318. package/templates/game/include/clpp/libs/axiom.clh +1 -1
  319. package/templates/game/include/clpp/libs/ward.clh +1 -0
  320. package/templates/game/include/clpp/roblox.clh +3 -4
  321. package/templates/game/src/ServerScriptService/Boot/DataBoot.server.clpp +1 -1
  322. package/templates/game/src/ServerScriptService/Handlers/PlayerHandler.server.clpp +1 -1
  323. package/templates/game/stylua.toml +9 -0
@@ -0,0 +1,178 @@
1
+ --!native
2
+ --!optimize 2
3
+ --!strict
4
+ -- Stage — ViewportFrame 3D (Module3D successor).
5
+
6
+ local Sweep = require(script.Parent.Sweep)
7
+
8
+ local Stage = {}
9
+ Stage.__index = Stage
10
+
11
+ export type Stage = typeof(setmetatable(
12
+ {} :: {
13
+ Object3D: Model,
14
+ AdornFrame: GuiObject,
15
+ Camera: Camera,
16
+ Visible: boolean,
17
+ Viewport: ViewportFrame,
18
+ World: WorldModel,
19
+ },
20
+ Stage
21
+ ))
22
+
23
+ local function wrapModel(source: Instance): Model
24
+ local clone = source:Clone()
25
+ if clone:IsA("Model") then
26
+ if clone.PrimaryPart == nil then
27
+ clone.PrimaryPart = clone:FindFirstChildWhichIsA("BasePart", true)
28
+ end
29
+ return clone
30
+ end
31
+ local wrap = Instance.new("Model")
32
+ wrap.Name = clone.Name
33
+ clone.Parent = wrap
34
+ if clone:IsA("BasePart") then
35
+ wrap.PrimaryPart = clone
36
+ else
37
+ wrap.PrimaryPart = wrap:FindFirstChildWhichIsA("BasePart", true)
38
+ end
39
+ return wrap
40
+ end
41
+
42
+ local function fit(model: Model): (Vector3, number)
43
+ local cf, size = model:GetBoundingBox()
44
+ local extent = math.max(size.X, size.Y, size.Z)
45
+ return cf.Position, math.max(extent, 1)
46
+ end
47
+
48
+ local function distance(extent: number, camera: Camera, depth: number): number
49
+ local fov = math.rad(camera.FieldOfView)
50
+ local half = math.tan(fov * 0.5)
51
+ if half <= 1e-4 then
52
+ half = 1e-4
53
+ end
54
+ return ((extent * 0.5) / half) * 1.25 * math.max(depth, 0.05)
55
+ end
56
+
57
+ local function look(self: any)
58
+ local model = self.Object3D
59
+ if not model or not model.Parent then
60
+ return
61
+ end
62
+ local center, extent = fit(model)
63
+ self._center = center
64
+ local dist = distance(extent, self.Camera, self._depth or 1)
65
+ local relative: CFrame = self._relative or CFrame.identity
66
+ local offset = relative:VectorToWorldSpace(Vector3.new(0, extent * 0.12, dist))
67
+ self.Camera.CFrame = CFrame.lookAt(center + offset, center)
68
+ end
69
+
70
+ function Stage.Attach(frame: GuiObject, model: Instance): Stage
71
+ local viewport = Instance.new("ViewportFrame")
72
+ viewport.Name = "Stage"
73
+ viewport.Size = UDim2.fromScale(1, 1)
74
+ viewport.BackgroundTransparency = 1
75
+ viewport.Ambient = Color3.fromRGB(186, 186, 186)
76
+ viewport.LightColor = Color3.fromRGB(255, 255, 255)
77
+ viewport.LightDirection = Vector3.new(-1, -1, -1)
78
+ viewport.Parent = frame
79
+
80
+ local camera = Instance.new("Camera")
81
+ camera.FieldOfView = 70
82
+ camera.Parent = viewport
83
+ viewport.CurrentCamera = camera
84
+
85
+ local world = Instance.new("WorldModel")
86
+ world.Name = "StageWorld"
87
+ world.Parent = viewport
88
+
89
+ local clone = wrapModel(model)
90
+ clone.Parent = world
91
+
92
+ local sweep = Sweep.new()
93
+ sweep:Add(viewport)
94
+ sweep:LinkToInstance(frame)
95
+
96
+ local self = setmetatable({
97
+ Object3D = clone,
98
+ AdornFrame = frame,
99
+ Camera = camera,
100
+ Visible = true,
101
+ Viewport = viewport,
102
+ World = world,
103
+ _depth = 1,
104
+ _relative = CFrame.identity,
105
+ _orbit = 0,
106
+ _center = Vector3.zero,
107
+ _sweep = sweep,
108
+ }, Stage)
109
+ look(self)
110
+ return self
111
+ end
112
+
113
+ Stage.new = function(model: Instance): Stage
114
+ local holder = Instance.new("Frame")
115
+ holder.Name = "Stage"
116
+ holder.Size = UDim2.fromScale(1, 1)
117
+ holder.BackgroundTransparency = 1
118
+ return Stage.Attach(holder, model)
119
+ end
120
+
121
+ function Stage:SetCFrame(newCF: CFrame)
122
+ self._relative = newCF
123
+ self._orbit = 0
124
+ if self.Visible then
125
+ look(self)
126
+ end
127
+ end
128
+
129
+ function Stage:GetCFrame(): CFrame
130
+ return self._relative or CFrame.identity
131
+ end
132
+
133
+ function Stage:SetDepthMultiplier(multiplier: number)
134
+ self._depth = multiplier
135
+ if self.Visible then
136
+ look(self)
137
+ end
138
+ end
139
+
140
+ function Stage:GetDepthMultiplier(): number
141
+ return self._depth or 1
142
+ end
143
+
144
+ function Stage:SetActive(active: boolean)
145
+ self.Viewport.Visible = active
146
+ self.Visible = active
147
+ end
148
+
149
+ function Stage:GetActive(): boolean
150
+ return self.Visible
151
+ end
152
+
153
+ function Stage:Update(dt: number?)
154
+ if not self.Visible then
155
+ return
156
+ end
157
+ if typeof(dt) == "number" then
158
+ self._orbit += dt
159
+ self._relative = CFrame.Angles(0, self._orbit, 0)
160
+ end
161
+ look(self)
162
+ end
163
+
164
+ function Stage:Destroy()
165
+ local sweep = self._sweep
166
+ if sweep then
167
+ sweep:Destroy()
168
+ self._sweep = nil
169
+ elseif self.Viewport then
170
+ self.Viewport:Destroy()
171
+ end
172
+ self.Visible = false
173
+ end
174
+
175
+ Stage.End = Stage.Destroy
176
+ Stage.Attach3D = Stage.Attach
177
+
178
+ return Stage
@@ -0,0 +1,259 @@
1
+ --!native
2
+ --!optimize 2
3
+ --!strict
4
+ -- Sweep — Cluaupp zelador. Flare sends; Sweep clears.
5
+ -- Auto-detects Disconnect / Destroy / task.cancel / call / Promise cancel.
6
+ -- Indexed Add replaces and cleans the previous task.
7
+
8
+ local Sweep = {}
9
+ Sweep.__index = Sweep
10
+
11
+ export type Sweep = typeof(setmetatable(
12
+ {} :: {
13
+ CurrentlyCleaning: boolean,
14
+ _frozen: boolean,
15
+ _tasks: { any },
16
+ _methods: { any },
17
+ _indices: { [any]: number },
18
+ _links: { RBXScriptConnection },
19
+ },
20
+ Sweep
21
+ ))
22
+
23
+ local function typeofOk(value: any): string
24
+ return typeof(value)
25
+ end
26
+
27
+ local function cleanupOne(object: any, method: any)
28
+ if object == nil then
29
+ return
30
+ end
31
+ local kind = typeofOk(object)
32
+ if method == true or typeofOk(method) == "function" then
33
+ local fn = if typeofOk(method) == "function" then method else object
34
+ if typeofOk(fn) == "function" then
35
+ fn()
36
+ end
37
+ return
38
+ end
39
+ if typeofOk(method) == "string" then
40
+ local fn = object[method]
41
+ if typeofOk(fn) == "function" then
42
+ if method == "Destroy" and kind == "Instance" then
43
+ pcall(fn, object)
44
+ else
45
+ fn(object)
46
+ end
47
+ end
48
+ return
49
+ end
50
+ if kind == "RBXScriptConnection" then
51
+ if object.Connected then
52
+ object:Disconnect()
53
+ end
54
+ return
55
+ end
56
+ if kind == "Instance" then
57
+ pcall(function()
58
+ (object :: Instance):Destroy()
59
+ end)
60
+ return
61
+ end
62
+ if kind == "thread" then
63
+ pcall(task.cancel, object)
64
+ return
65
+ end
66
+ if kind == "function" then
67
+ object()
68
+ return
69
+ end
70
+ if kind == "table" then
71
+ if typeofOk(object.Cancel) == "function" and object.getStatus then
72
+ pcall(object.Cancel, object)
73
+ return
74
+ end
75
+ if typeofOk(object.Destroy) == "function" then
76
+ object:Destroy()
77
+ return
78
+ end
79
+ if typeofOk(object.Disconnect) == "function" then
80
+ object:Disconnect()
81
+ return
82
+ end
83
+ if typeofOk(object.DisconnectAll) == "function" then
84
+ object:DisconnectAll()
85
+ end
86
+ end
87
+ end
88
+
89
+ local function detect(object: any): any
90
+ local kind = typeofOk(object)
91
+ if kind == "RBXScriptConnection" then
92
+ return "Disconnect"
93
+ end
94
+ if kind == "Instance" then
95
+ return "Destroy"
96
+ end
97
+ if kind == "thread" then
98
+ return true
99
+ end
100
+ if kind == "function" then
101
+ return true
102
+ end
103
+ if kind == "table" then
104
+ if typeofOk(object.Cancel) == "function" and object.getStatus then
105
+ return "Cancel"
106
+ end
107
+ if typeofOk(object.Destroy) == "function" then
108
+ return "Destroy"
109
+ end
110
+ if typeofOk(object.Disconnect) == "function" then
111
+ return "Disconnect"
112
+ end
113
+ if typeofOk(object.DisconnectAll) == "function" then
114
+ return "DisconnectAll"
115
+ end
116
+ end
117
+ return "Destroy"
118
+ end
119
+
120
+ function Sweep.new(): Sweep
121
+ return setmetatable({
122
+ CurrentlyCleaning = false,
123
+ _frozen = false,
124
+ _tasks = {},
125
+ _methods = {},
126
+ _indices = {},
127
+ _links = {},
128
+ }, Sweep)
129
+ end
130
+
131
+ function Sweep:Add<T>(object: T, methodName: (boolean | string)?, index: any?): T
132
+ if self._frozen or self.CurrentlyCleaning then
133
+ return object
134
+ end
135
+ local method: any = methodName
136
+ if method == nil then
137
+ method = detect(object)
138
+ end
139
+ if index ~= nil then
140
+ local previous = self._indices[index]
141
+ if previous then
142
+ local oldObject = self._tasks[previous]
143
+ local oldMethod = self._methods[previous]
144
+ self._tasks[previous] = nil
145
+ self._methods[previous] = nil
146
+ self._indices[index] = nil
147
+ cleanupOne(oldObject, oldMethod)
148
+ end
149
+ table.insert(self._tasks, object)
150
+ table.insert(self._methods, method)
151
+ self._indices[index] = #self._tasks
152
+ return object
153
+ end
154
+ table.insert(self._tasks, object)
155
+ table.insert(self._methods, method)
156
+ return object
157
+ end
158
+
159
+ function Sweep:Remove(index: any): Sweep
160
+ local slot = self._indices[index]
161
+ if not slot then
162
+ return self
163
+ end
164
+ local object = self._tasks[slot]
165
+ local method = self._methods[slot]
166
+ self._tasks[slot] = nil
167
+ self._methods[slot] = nil
168
+ self._indices[index] = nil
169
+ cleanupOne(object, method)
170
+ return self
171
+ end
172
+
173
+ function Sweep:RemoveNoClean(index: any): Sweep
174
+ local slot = self._indices[index]
175
+ if not slot then
176
+ return self
177
+ end
178
+ self._tasks[slot] = nil
179
+ self._methods[slot] = nil
180
+ self._indices[index] = nil
181
+ return self
182
+ end
183
+
184
+ function Sweep:Get(index: any): any
185
+ local slot = self._indices[index]
186
+ if not slot then
187
+ return nil
188
+ end
189
+ return self._tasks[slot]
190
+ end
191
+
192
+ function Sweep:Cleanup()
193
+ if self.CurrentlyCleaning then
194
+ return
195
+ end
196
+ self.CurrentlyCleaning = true
197
+ for i = #self._tasks, 1, -1 do
198
+ local object = self._tasks[i]
199
+ local method = self._methods[i]
200
+ self._tasks[i] = nil
201
+ self._methods[i] = nil
202
+ cleanupOne(object, method)
203
+ end
204
+ table.clear(self._indices)
205
+ self.CurrentlyCleaning = false
206
+ end
207
+
208
+ function Sweep:Destroy()
209
+ self:Cleanup()
210
+ self._frozen = true
211
+ for _, link in self._links do
212
+ if link.Connected then
213
+ link:Disconnect()
214
+ end
215
+ end
216
+ table.clear(self._links)
217
+ end
218
+
219
+ function Sweep:LinkToInstance(object: Instance, allowMultiple: boolean?): RBXScriptConnection
220
+ if self._frozen then
221
+ return (nil :: any)
222
+ end
223
+ if not allowMultiple then
224
+ self:Remove("LinkToInstance")
225
+ end
226
+ local function onGone()
227
+ self:Destroy()
228
+ end
229
+ local destroying = object.Destroying:Connect(onGone)
230
+ local ancestry = object.AncestryChanged:Connect(function(_, parent)
231
+ if parent == nil then
232
+ onGone()
233
+ end
234
+ end)
235
+ table.insert(self._links, destroying)
236
+ table.insert(self._links, ancestry)
237
+ if not allowMultiple then
238
+ self._indices["LinkToInstance"] = #self._links
239
+ end
240
+ return destroying
241
+ end
242
+
243
+ function Sweep.Is(value: any): boolean
244
+ return typeof(value) == "table" and getmetatable(value) == Sweep
245
+ end
246
+
247
+ Sweep.AddPromise = function(self: Sweep, promise: any, index: any?): any
248
+ return self:Add(promise, "Cancel", index)
249
+ end
250
+
251
+ Sweep.New = Sweep.new
252
+
253
+ setmetatable(Sweep, {
254
+ __call = function()
255
+ return Sweep.new()
256
+ end,
257
+ })
258
+
259
+ return Sweep
@@ -0,0 +1,213 @@
1
+ --!optimize 2
2
+ --!strict
3
+ -- Trace — pretty-print values.
4
+
5
+ local Trace = {}
6
+
7
+ local DEFAULT_DEPTH = 4
8
+ local DEFAULT_INDENT = " "
9
+
10
+ local function formatNumber(value: number): string
11
+ if value ~= value then
12
+ return "nan"
13
+ end
14
+ if value == math.huge then
15
+ return "inf"
16
+ end
17
+ if value == -math.huge then
18
+ return "-inf"
19
+ end
20
+ return tostring(value)
21
+ end
22
+
23
+ local function formatVector(prefix: string, ...: number): string
24
+ local parts = { prefix, "(" }
25
+ local count = select("#", ...)
26
+ for i = 1, count do
27
+ if i > 1 then
28
+ table.insert(parts, ", ")
29
+ end
30
+ table.insert(parts, formatNumber(select(i, ...)))
31
+ end
32
+ table.insert(parts, ")")
33
+ return table.concat(parts)
34
+ end
35
+
36
+ local function isArray(value: { [any]: any }): boolean
37
+ local count = 0
38
+ for key in value do
39
+ if typeof(key) ~= "number" or key ~= math.floor(key) or key < 1 then
40
+ return false
41
+ end
42
+ count += 1
43
+ end
44
+ return count == #value
45
+ end
46
+
47
+ local function formatValue(value: any, depth: number, maxDepth: number, indentWith: string, seen: { [any]: boolean }): string
48
+ local kind = typeof(value)
49
+ if kind == "string" then
50
+ return string.format("%q", value)
51
+ end
52
+ if kind == "number" then
53
+ return formatNumber(value)
54
+ end
55
+ if kind == "boolean" or kind == "nil" then
56
+ return tostring(value)
57
+ end
58
+ if kind == "Instance" then
59
+ local ok, fullName = pcall(function()
60
+ return value:GetFullName()
61
+ end)
62
+ if ok then
63
+ return `{value.ClassName}({fullName})`
64
+ end
65
+ return `{value.ClassName}({value.Name})`
66
+ end
67
+ if kind == "Vector3" then
68
+ return formatVector("Vector3", value.X, value.Y, value.Z)
69
+ end
70
+ if kind == "Vector2" then
71
+ return formatVector("Vector2", value.X, value.Y)
72
+ end
73
+ if kind == "Vector3int16" then
74
+ return formatVector("Vector3int16", value.X, value.Y, value.Z)
75
+ end
76
+ if kind == "Vector2int16" then
77
+ return formatVector("Vector2int16", value.X, value.Y)
78
+ end
79
+ if kind == "CFrame" then
80
+ local x, y, z, r00, r01, r02, r10, r11, r12, r20, r21, r22 = value:GetComponents()
81
+ return formatVector("CFrame", x, y, z, r00, r01, r02, r10, r11, r12, r20, r21, r22)
82
+ end
83
+ if kind == "Color3" then
84
+ return formatVector("Color3", value.R, value.G, value.B)
85
+ end
86
+ if kind == "UDim" then
87
+ return formatVector("UDim", value.Scale, value.Offset)
88
+ end
89
+ if kind == "UDim2" then
90
+ return formatVector("UDim2", value.X.Scale, value.X.Offset, value.Y.Scale, value.Y.Offset)
91
+ end
92
+ if kind == "Rect" then
93
+ return formatVector("Rect", value.Min.X, value.Min.Y, value.Max.X, value.Max.Y)
94
+ end
95
+ if kind == "NumberRange" then
96
+ return formatVector("NumberRange", value.Min, value.Max)
97
+ end
98
+ if kind == "BrickColor" then
99
+ return `BrickColor({string.format("%q", value.Name)})`
100
+ end
101
+ if kind == "EnumItem" then
102
+ return tostring(value)
103
+ end
104
+ if kind == "buffer" then
105
+ return `buffer({buffer.len(value)})`
106
+ end
107
+ if kind == "table" then
108
+ if seen[value] then
109
+ return "<circular>"
110
+ end
111
+ if depth >= maxDepth then
112
+ return "{...}"
113
+ end
114
+ seen[value] = true
115
+ local pad = string.rep(indentWith, depth)
116
+ local inner = string.rep(indentWith, depth + 1)
117
+ local parts = { "{" }
118
+ if isArray(value) then
119
+ if #value == 0 then
120
+ seen[value] = nil
121
+ return "{}"
122
+ end
123
+ for index, child in ipairs(value) do
124
+ table.insert(parts, `\n{inner}[{index}] = {formatValue(child, depth + 1, maxDepth, indentWith, seen)},`)
125
+ end
126
+ else
127
+ local keys = {}
128
+ for key in value do
129
+ table.insert(keys, key)
130
+ end
131
+ table.sort(keys, function(a, b)
132
+ if typeof(a) == "number" and typeof(b) == "number" then
133
+ return a < b
134
+ end
135
+ if typeof(a) == "string" and typeof(b) == "string" then
136
+ return a < b
137
+ end
138
+ return tostring(a) < tostring(b)
139
+ end)
140
+ if #keys == 0 then
141
+ seen[value] = nil
142
+ return "{}"
143
+ end
144
+ for _, key in keys do
145
+ table.insert(
146
+ parts,
147
+ `\n{inner}[{formatValue(key, depth + 1, maxDepth, indentWith, seen)}] = {formatValue(value[key], depth + 1, maxDepth, indentWith, seen)},`
148
+ )
149
+ end
150
+ end
151
+ table.insert(parts, `\n{pad}}`)
152
+ seen[value] = nil
153
+ return table.concat(parts)
154
+ end
155
+ return `{kind}({tostring(value)})`
156
+ end
157
+
158
+ local function stringify(value: any, level: number?, maxDepth: number?, indentWith: string?): string
159
+ return formatValue(value, level or 0, maxDepth or DEFAULT_DEPTH, indentWith or DEFAULT_INDENT, {})
160
+ end
161
+
162
+ function Trace.display(value: any, level: number?): string
163
+ return stringify(value, level, DEFAULT_DEPTH, DEFAULT_INDENT)
164
+ end
165
+
166
+ function Trace.Display(value: any, level: number?): string
167
+ return stringify(value, level, DEFAULT_DEPTH, DEFAULT_INDENT)
168
+ end
169
+
170
+ function Trace.Print(value: any)
171
+ print(Trace.Display(value))
172
+ end
173
+
174
+ Trace.Dump = Trace.Print
175
+
176
+ function Trace.builder()
177
+ local maxDepth = DEFAULT_DEPTH
178
+ local indentWith = DEFAULT_INDENT
179
+ local builder = {}
180
+
181
+ function builder:MaxDepth(depth: number)
182
+ if typeof(depth) ~= "number" then
183
+ return self
184
+ end
185
+ maxDepth = math.max(0, depth)
186
+ return self
187
+ end
188
+
189
+ function builder:Indent(indent: string)
190
+ indentWith = indent
191
+ return self
192
+ end
193
+
194
+ function builder:Display(value: any, level: number?): string
195
+ return stringify(value, level, maxDepth, indentWith)
196
+ end
197
+
198
+ function builder:display(value: any, level: number?): string
199
+ return stringify(value, level, maxDepth, indentWith)
200
+ end
201
+
202
+ function builder:Print(value: any)
203
+ print(self:Display(value))
204
+ end
205
+
206
+ function builder:build()
207
+ return self
208
+ end
209
+
210
+ return builder
211
+ end
212
+
213
+ return Trace