roblox-opencode 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 (248) hide show
  1. package/README.md +122 -0
  2. package/commands/setup-game.md +108 -0
  3. package/commands/sync-check.md +53 -0
  4. package/core/roblox-core.md +93 -0
  5. package/dist/server.js +167 -0
  6. package/package.json +35 -0
  7. package/skills/roblox-analytics/SKILL.md +277 -0
  8. package/skills/roblox-analytics/references/event-batcher.luau +75 -0
  9. package/skills/roblox-animation-vfx/SKILL.md +1325 -0
  10. package/skills/roblox-architecture/SKILL.md +863 -0
  11. package/skills/roblox-architecture/references/combat-systems.md +1381 -0
  12. package/skills/roblox-code-review/SKILL.md +687 -0
  13. package/skills/roblox-data/SKILL.md +889 -0
  14. package/skills/roblox-data/references/inventory-systems.md +1729 -0
  15. package/skills/roblox-debug/SKILL.md +99 -0
  16. package/skills/roblox-gui/SKILL.md +1103 -0
  17. package/skills/roblox-gui-fusion/SKILL.md +150 -0
  18. package/skills/roblox-gui-fusion/references/inventory.luau +427 -0
  19. package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -0
  20. package/skills/roblox-gui-fusion/references/shop.luau +411 -0
  21. package/skills/roblox-luau-mastery/SKILL.md +1519 -0
  22. package/skills/roblox-monetization/SKILL.md +1084 -0
  23. package/skills/roblox-monetization/references/process-receipt.luau +131 -0
  24. package/skills/roblox-networking/SKILL.md +669 -0
  25. package/skills/roblox-networking/references/remote-validator.luau +193 -0
  26. package/skills/roblox-publish-checklist/SKILL.md +128 -0
  27. package/skills/roblox-runtime/SKILL.md +753 -0
  28. package/skills/roblox-sharp-edges/SKILL.md +295 -0
  29. package/skills/roblox-sync/SKILL.md +126 -0
  30. package/skills/roblox-testing/SKILL.md +943 -0
  31. package/skills/roblox-tooling/SKILL.md +150 -0
  32. package/vendor/LICENSES/ProfileStore-LICENSE +201 -0
  33. package/vendor/LICENSES/RbxUtil-LICENSE +7 -0
  34. package/vendor/LICENSES/promise-LICENSE +21 -0
  35. package/vendor/LICENSES/t-LICENSE +21 -0
  36. package/vendor/LICENSES/testez-LICENSE +201 -0
  37. package/vendor/README.md +84 -0
  38. package/vendor/fusion/Animation/ExternalTime.luau +84 -0
  39. package/vendor/fusion/Animation/Spring.luau +322 -0
  40. package/vendor/fusion/Animation/Stopwatch.luau +128 -0
  41. package/vendor/fusion/Animation/Tween.luau +187 -0
  42. package/vendor/fusion/Animation/getTweenDuration.luau +27 -0
  43. package/vendor/fusion/Animation/getTweenRatio.luau +47 -0
  44. package/vendor/fusion/Animation/lerpType.luau +164 -0
  45. package/vendor/fusion/Animation/packType.luau +100 -0
  46. package/vendor/fusion/Animation/springCoefficients.luau +80 -0
  47. package/vendor/fusion/Animation/unpackType.luau +103 -0
  48. package/vendor/fusion/Colour/Oklab.luau +70 -0
  49. package/vendor/fusion/Colour/sRGB.luau +55 -0
  50. package/vendor/fusion/External.luau +168 -0
  51. package/vendor/fusion/ExternalDebug.luau +70 -0
  52. package/vendor/fusion/Graph/Observer.luau +114 -0
  53. package/vendor/fusion/Graph/castToGraph.luau +29 -0
  54. package/vendor/fusion/Graph/change.luau +81 -0
  55. package/vendor/fusion/Graph/depend.luau +33 -0
  56. package/vendor/fusion/Graph/evaluate.luau +56 -0
  57. package/vendor/fusion/Instances/Attribute.luau +58 -0
  58. package/vendor/fusion/Instances/AttributeChange.luau +47 -0
  59. package/vendor/fusion/Instances/AttributeOut.luau +63 -0
  60. package/vendor/fusion/Instances/Child.luau +21 -0
  61. package/vendor/fusion/Instances/Children.luau +148 -0
  62. package/vendor/fusion/Instances/Hydrate.luau +33 -0
  63. package/vendor/fusion/Instances/New.luau +53 -0
  64. package/vendor/fusion/Instances/OnChange.luau +50 -0
  65. package/vendor/fusion/Instances/OnEvent.luau +54 -0
  66. package/vendor/fusion/Instances/Out.luau +69 -0
  67. package/vendor/fusion/Instances/applyInstanceProps.luau +149 -0
  68. package/vendor/fusion/Instances/defaultProps.luau +194 -0
  69. package/vendor/fusion/LICENSE +21 -0
  70. package/vendor/fusion/Logging/formatError.luau +49 -0
  71. package/vendor/fusion/Logging/messages.luau +52 -0
  72. package/vendor/fusion/Logging/parseError.luau +25 -0
  73. package/vendor/fusion/Memory/checkLifetime.luau +134 -0
  74. package/vendor/fusion/Memory/deriveScope.luau +24 -0
  75. package/vendor/fusion/Memory/deriveScopeImpl.luau +45 -0
  76. package/vendor/fusion/Memory/doCleanup.luau +79 -0
  77. package/vendor/fusion/Memory/innerScope.luau +34 -0
  78. package/vendor/fusion/Memory/legacyCleanup.luau +18 -0
  79. package/vendor/fusion/Memory/needsDestruction.luau +17 -0
  80. package/vendor/fusion/Memory/poisonScope.luau +34 -0
  81. package/vendor/fusion/Memory/scopePool.luau +55 -0
  82. package/vendor/fusion/Memory/scoped.luau +27 -0
  83. package/vendor/fusion/Memory/whichLivesLonger.luau +75 -0
  84. package/vendor/fusion/RobloxExternal.luau +98 -0
  85. package/vendor/fusion/State/Computed.luau +139 -0
  86. package/vendor/fusion/State/For/Disassembly.luau +211 -0
  87. package/vendor/fusion/State/For/ForTypes.luau +30 -0
  88. package/vendor/fusion/State/For/init.luau +110 -0
  89. package/vendor/fusion/State/ForKeys.luau +94 -0
  90. package/vendor/fusion/State/ForPairs.luau +97 -0
  91. package/vendor/fusion/State/ForValues.luau +94 -0
  92. package/vendor/fusion/State/Value.luau +88 -0
  93. package/vendor/fusion/State/castToState.luau +26 -0
  94. package/vendor/fusion/State/peek.luau +31 -0
  95. package/vendor/fusion/State/updateAll.luau +1 -0
  96. package/vendor/fusion/Types.luau +314 -0
  97. package/vendor/fusion/Utility/Contextual.luau +91 -0
  98. package/vendor/fusion/Utility/Safe.luau +23 -0
  99. package/vendor/fusion/Utility/isSimilar.luau +29 -0
  100. package/vendor/fusion/Utility/merge.luau +35 -0
  101. package/vendor/fusion/Utility/nameOf.luau +35 -0
  102. package/vendor/fusion/Utility/never.luau +14 -0
  103. package/vendor/fusion/Utility/nicknames.luau +11 -0
  104. package/vendor/fusion/Utility/xtypeof.luau +27 -0
  105. package/vendor/fusion/init.luau +82 -0
  106. package/vendor/profilestore/init.luau +2243 -0
  107. package/vendor/promise/init.luau +1982 -0
  108. package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -0
  109. package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -0
  110. package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -0
  111. package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -0
  112. package/vendor/rbxutil/buffer-util/Types.luau +60 -0
  113. package/vendor/rbxutil/buffer-util/index.d.ts +153 -0
  114. package/vendor/rbxutil/buffer-util/init.luau +41 -0
  115. package/vendor/rbxutil/buffer-util/package.json +16 -0
  116. package/vendor/rbxutil/buffer-util/wally.toml +9 -0
  117. package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -0
  118. package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -0
  119. package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -0
  120. package/vendor/rbxutil/comm/Client/init.luau +135 -0
  121. package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -0
  122. package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -0
  123. package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -0
  124. package/vendor/rbxutil/comm/Server/init.luau +140 -0
  125. package/vendor/rbxutil/comm/Types.luau +18 -0
  126. package/vendor/rbxutil/comm/Util.luau +27 -0
  127. package/vendor/rbxutil/comm/init.luau +35 -0
  128. package/vendor/rbxutil/comm/wally.toml +13 -0
  129. package/vendor/rbxutil/component/init.luau +759 -0
  130. package/vendor/rbxutil/component/init.test.luau +311 -0
  131. package/vendor/rbxutil/component/wally.toml +14 -0
  132. package/vendor/rbxutil/concur/init.luau +542 -0
  133. package/vendor/rbxutil/concur/init.test.luau +364 -0
  134. package/vendor/rbxutil/concur/wally.toml +8 -0
  135. package/vendor/rbxutil/enum-list/init.luau +101 -0
  136. package/vendor/rbxutil/enum-list/init.test.luau +91 -0
  137. package/vendor/rbxutil/enum-list/wally.toml +8 -0
  138. package/vendor/rbxutil/find/index.d.ts +20 -0
  139. package/vendor/rbxutil/find/init.luau +44 -0
  140. package/vendor/rbxutil/find/package.json +17 -0
  141. package/vendor/rbxutil/find/wally.toml +8 -0
  142. package/vendor/rbxutil/input/Gamepad.luau +559 -0
  143. package/vendor/rbxutil/input/Keyboard.luau +124 -0
  144. package/vendor/rbxutil/input/Mouse.luau +278 -0
  145. package/vendor/rbxutil/input/PreferredInput.luau +91 -0
  146. package/vendor/rbxutil/input/Touch.luau +120 -0
  147. package/vendor/rbxutil/input/init.luau +33 -0
  148. package/vendor/rbxutil/input/wally.toml +12 -0
  149. package/vendor/rbxutil/loader/index.d.ts +15 -0
  150. package/vendor/rbxutil/loader/init.luau +137 -0
  151. package/vendor/rbxutil/loader/wally.toml +8 -0
  152. package/vendor/rbxutil/log/index.d.ts +38 -0
  153. package/vendor/rbxutil/log/init.luau +746 -0
  154. package/vendor/rbxutil/log/wally.toml +8 -0
  155. package/vendor/rbxutil/net/init.luau +190 -0
  156. package/vendor/rbxutil/net/wally.toml +8 -0
  157. package/vendor/rbxutil/option/index.d.ts +44 -0
  158. package/vendor/rbxutil/option/init.luau +489 -0
  159. package/vendor/rbxutil/option/init.test.luau +342 -0
  160. package/vendor/rbxutil/option/wally.toml +8 -0
  161. package/vendor/rbxutil/pid/index.d.ts +53 -0
  162. package/vendor/rbxutil/pid/init.luau +195 -0
  163. package/vendor/rbxutil/pid/package.json +16 -0
  164. package/vendor/rbxutil/pid/wally.toml +9 -0
  165. package/vendor/rbxutil/quaternion/index.d.ts +117 -0
  166. package/vendor/rbxutil/quaternion/init.luau +570 -0
  167. package/vendor/rbxutil/quaternion/package.json +16 -0
  168. package/vendor/rbxutil/quaternion/wally.toml +9 -0
  169. package/vendor/rbxutil/query/index.d.ts +43 -0
  170. package/vendor/rbxutil/query/init.luau +117 -0
  171. package/vendor/rbxutil/query/package.json +18 -0
  172. package/vendor/rbxutil/query/wally.toml +9 -0
  173. package/vendor/rbxutil/sequent/index.d.ts +28 -0
  174. package/vendor/rbxutil/sequent/init.luau +340 -0
  175. package/vendor/rbxutil/sequent/package.json +16 -0
  176. package/vendor/rbxutil/sequent/wally.toml +9 -0
  177. package/vendor/rbxutil/ser/init.luau +175 -0
  178. package/vendor/rbxutil/ser/init.test.luau +50 -0
  179. package/vendor/rbxutil/ser/wally.toml +11 -0
  180. package/vendor/rbxutil/shake/index.d.ts +36 -0
  181. package/vendor/rbxutil/shake/init.luau +532 -0
  182. package/vendor/rbxutil/shake/init.test.luau +267 -0
  183. package/vendor/rbxutil/shake/package.json +16 -0
  184. package/vendor/rbxutil/shake/wally.toml +9 -0
  185. package/vendor/rbxutil/signal/index.d.ts +100 -0
  186. package/vendor/rbxutil/signal/init.luau +432 -0
  187. package/vendor/rbxutil/signal/init.test.luau +190 -0
  188. package/vendor/rbxutil/signal/package.json +17 -0
  189. package/vendor/rbxutil/signal/wally.toml +9 -0
  190. package/vendor/rbxutil/silo/TableWatcher.luau +65 -0
  191. package/vendor/rbxutil/silo/Util.luau +55 -0
  192. package/vendor/rbxutil/silo/init.luau +338 -0
  193. package/vendor/rbxutil/silo/init.test.luau +215 -0
  194. package/vendor/rbxutil/silo/wally.toml +8 -0
  195. package/vendor/rbxutil/spring/index.d.ts +40 -0
  196. package/vendor/rbxutil/spring/init.luau +97 -0
  197. package/vendor/rbxutil/spring/package.json +17 -0
  198. package/vendor/rbxutil/spring/wally.toml +8 -0
  199. package/vendor/rbxutil/stream/index.d.ts +88 -0
  200. package/vendor/rbxutil/stream/init.luau +597 -0
  201. package/vendor/rbxutil/stream/package.json +18 -0
  202. package/vendor/rbxutil/stream/wally.toml +9 -0
  203. package/vendor/rbxutil/streamable/Streamable.luau +202 -0
  204. package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -0
  205. package/vendor/rbxutil/streamable/init.luau +8 -0
  206. package/vendor/rbxutil/streamable/wally.toml +12 -0
  207. package/vendor/rbxutil/symbol/init.luau +56 -0
  208. package/vendor/rbxutil/symbol/init.test.luau +37 -0
  209. package/vendor/rbxutil/symbol/wally.toml +8 -0
  210. package/vendor/rbxutil/table-util/init.luau +938 -0
  211. package/vendor/rbxutil/table-util/init.test.luau +439 -0
  212. package/vendor/rbxutil/table-util/wally.toml +8 -0
  213. package/vendor/rbxutil/task-queue/index.d.ts +27 -0
  214. package/vendor/rbxutil/task-queue/init.luau +97 -0
  215. package/vendor/rbxutil/task-queue/wally.toml +8 -0
  216. package/vendor/rbxutil/timer/index.d.ts +81 -0
  217. package/vendor/rbxutil/timer/init.luau +249 -0
  218. package/vendor/rbxutil/timer/init.test.luau +73 -0
  219. package/vendor/rbxutil/timer/wally.toml +11 -0
  220. package/vendor/rbxutil/tree/index.d.ts +15 -0
  221. package/vendor/rbxutil/tree/init.luau +137 -0
  222. package/vendor/rbxutil/tree/wally.toml +8 -0
  223. package/vendor/rbxutil/trove/index.d.ts +46 -0
  224. package/vendor/rbxutil/trove/init.luau +787 -0
  225. package/vendor/rbxutil/trove/init.test.luau +203 -0
  226. package/vendor/rbxutil/trove/wally.toml +8 -0
  227. package/vendor/rbxutil/typed-remote/init.luau +196 -0
  228. package/vendor/rbxutil/typed-remote/wally.toml +8 -0
  229. package/vendor/rbxutil/wait-for/index.d.ts +17 -0
  230. package/vendor/rbxutil/wait-for/init.luau +257 -0
  231. package/vendor/rbxutil/wait-for/init.test.luau +182 -0
  232. package/vendor/rbxutil/wait-for/wally.toml +11 -0
  233. package/vendor/t/t.lua +1350 -0
  234. package/vendor/testez/Context.lua +26 -0
  235. package/vendor/testez/Expectation.lua +311 -0
  236. package/vendor/testez/ExpectationContext.lua +38 -0
  237. package/vendor/testez/LifecycleHooks.lua +89 -0
  238. package/vendor/testez/Reporters/TeamCityReporter.lua +102 -0
  239. package/vendor/testez/Reporters/TextReporter.lua +106 -0
  240. package/vendor/testez/Reporters/TextReporterQuiet.lua +97 -0
  241. package/vendor/testez/TestBootstrap.lua +147 -0
  242. package/vendor/testez/TestEnum.lua +28 -0
  243. package/vendor/testez/TestPlan.lua +304 -0
  244. package/vendor/testez/TestPlanner.lua +40 -0
  245. package/vendor/testez/TestResults.lua +112 -0
  246. package/vendor/testez/TestRunner.lua +188 -0
  247. package/vendor/testez/TestSession.lua +243 -0
  248. package/vendor/testez/init.lua +40 -0
@@ -0,0 +1,687 @@
1
+ ---
2
+ name: roblox-code-review
3
+ description: "Code review with security, performance, and monetization lenses for Roblox projects"
4
+ tags: [roblox, code-review, security, performance, monetization, networking, data-persistence]
5
+ ---
6
+
7
+ # /code-review - Code Quality Review
8
+
9
+ You are performing a code quality review on a Roblox project. Follow these 8 steps. Apply the relevant lens based on what changed. Don't apply all lenses every time.
10
+
11
+ ---
12
+
13
+ ## Quick Reference
14
+
15
+ **Load lenses below only when code matching that domain changed. Don't apply all lenses every time.**
16
+
17
+ Key rules:
18
+ - **Remote types:** RemoteEvent (fire-and-forget), UnreliableRemoteEvent (loss-tolerant VFX/position), RemoteFunction (request-response, use sparingly), BindableEvent/BindableFunction (intra-client/server internal, never cross-boundary).
19
+ - **Data persistence:** ALWAYS ProfileStore for player state. Never raw DataStore. Schema template with defaults, DataVersion, migration functions, session locking, BindToClose.
20
+ - **Security:** Validate every remote parameter server-side. Rate-limit all remotes per-player.
21
+ - **Performance:** Consolidate Heartbeat loops. Cache services. Disconnect unused events.
22
+
23
+ ---
24
+
25
+ ## Step 1: Project Scan
26
+
27
+ Read the project directory structure. Survey script count, naming patterns, and organization.
28
+
29
+ Record:
30
+ - Total script count
31
+ - Folder organization
32
+ - Module naming patterns
33
+ - Whether the project uses Rojo/Wally or in-Studio editing
34
+
35
+ ---
36
+
37
+ ## Step 2: Organization Review
38
+
39
+ Check:
40
+ - Scripts in correct locations (ServerScriptService, StarterPlayerScripts, etc.)
41
+ - Proper use of services vs standalone scripts
42
+ - Clean folder structure (no orphaned scripts, no nesting > 3 levels deep)
43
+ - Module naming conventions consistent (PascalCase for ModuleScripts, camelCase for functions)
44
+ - No scripts with duplicate or overlapping responsibilities
45
+
46
+ ---
47
+
48
+ ## Step 3: Code Quality Scan
49
+
50
+ Search for anti-patterns:
51
+
52
+ ```
53
+ Deprecated APIs:
54
+ - wait( → replace with task.wait()
55
+ - spawn( → replace with task.spawn()
56
+ - delay( → replace with task.delay()
57
+
58
+ Code smells:
59
+ - Global variables (should be module-scoped)
60
+ - Missing type annotations on public functions
61
+ - Instance.new() in client scripts (should be server-created)
62
+ - while true without task.wait() (unbounded loops)
63
+ ```
64
+
65
+ Check for:
66
+ - Deprecated APIs (`wait()`, `spawn()`, `delay()`)
67
+ - Global variable usage (should be module-scoped)
68
+ - Missing type annotations on public functions
69
+ - Inconsistent naming conventions
70
+ - Dead code / unreachable code
71
+ - Duplicate code across scripts
72
+ - Overly long functions (>100 lines, should be refactored)
73
+
74
+ ---
75
+
76
+ ## Step 4: Architecture Review
77
+
78
+ Check:
79
+ - Module boundaries - Does each module have a single responsibility?
80
+ - Dependency direction - Do modules depend on abstractions, not concrete implementations?
81
+ - Circular requires - Any modules that depend on each other?
82
+ - Separation of concerns - Server vs Client logic properly separated
83
+ - Framework usage - If using a framework, is it used consistently?
84
+ - Configuration - Hardcoded values should be in config modules
85
+
86
+ ---
87
+
88
+ ## Step 5: Security Quick-Check
89
+
90
+ Quick scan for:
91
+ - Unvalidated RemoteEvent handlers (server-side)
92
+ - Client-trusted logic (currency, inventory, damage, position)
93
+ - Sensitive data in ReplicatedStorage or StarterPlayer
94
+ - Missing rate limiting on remotes
95
+ - ProcessReceipt implementation correctness
96
+
97
+ > **For a deep security review, run the Security Lens below.**
98
+
99
+ ---
100
+
101
+ ## Step 6: Performance Quick-Check
102
+
103
+ Quick scan for:
104
+ - `wait()` or `spawn()` in tight loops
105
+ - Multiple `RunService.Heartbeat:Connect()` in same script
106
+ - Large tables without cleanup
107
+ - Undisconnected events (memory leaks)
108
+ - Unanchored parts without collision groups
109
+ - Excessive RemoteEvent usage
110
+
111
+ > **For a deep performance review, run the Performance Lens below.**
112
+
113
+ ---
114
+
115
+ ## Step 7: Quality Report
116
+
117
+ Rate overall quality:
118
+
119
+ - **A** - Production-ready. Clean, organized, secure, performant
120
+ - **B** - Solid with minor issues. Safe to ship with minor cleanup
121
+ - **C** - Functional but needs work. Ship with caveats
122
+ - **D** - Significant issues. Needs refactoring before ship
123
+ - **F** - Critical problems. Do not ship in current state
124
+
125
+ List findings by severity:
126
+ - **Critical** - Security vulnerabilities, data loss risk, crashes
127
+ - **High** - Memory leaks, performance bottlenecks, broken features
128
+ - **Medium** - Code smells, deprecated APIs, poor organization
129
+ - **Low** - Style inconsistencies, missing documentation
130
+
131
+ For each finding, provide:
132
+ 1. File and line (or function name)
133
+ 2. What's wrong
134
+ 3. The specific fix (code)
135
+
136
+ ---
137
+
138
+ ## Step 8: Refactoring Suggestions
139
+
140
+ If significant issues found, suggest refactoring priorities:
141
+
142
+ 1. **Immediate** - Must fix before next publish
143
+ 2. **Short-term** - Fix in the next development cycle
144
+ 3. **Long-term** - Plan for when the project grows
145
+
146
+ For each suggestion:
147
+ - What to change
148
+ - Why it matters
149
+ - Estimated effort (small/medium/large)
150
+
151
+ ---
152
+
153
+ # Security Lens
154
+
155
+ *Apply this lens when security-relevant code changed: remotes, data persistence, monetization, player input handling, or server authority.*
156
+
157
+ ---
158
+
159
+ ## Security Step 1: Remote Surface Scan
160
+
161
+ Search for all `RemoteEvent` and `RemoteFunction` instances. Search for `:FireServer`, `:FireClient`, `:InvokeServer`, `:InvokeClient` to map the full remote surface.
162
+
163
+ Record every remote found with:
164
+ - Name
165
+ - Location (ReplicatedStorage path)
166
+ - Direction (Client→Server, Server→Client, Client↔Server)
167
+ - What it appears to do
168
+
169
+ ---
170
+
171
+ ## Security Step 2: Validation Check
172
+
173
+ For each remote, verify:
174
+ - **Argument type checking** - Server validates `typeof(arg)` for every parameter
175
+ - **Range validation** - Numeric inputs checked against min/max bounds
176
+ - **Cooldown enforcement** - Rate limiting prevents spam/exploitation
177
+ - **Authorization check** - Server verifies the requesting player owns the action
178
+ - **Sanitization** - String inputs cleaned, no injection vectors
179
+
180
+ Flag any remote that accepts input without full server-side validation.
181
+
182
+ ---
183
+
184
+ ## Security Step 3: Client Trust Audit
185
+
186
+ Search for client-side logic that should be server-side:
187
+ - Currency operations (giving/removing coins, cash, gems)
188
+ - Inventory changes (adding/removing items)
189
+ - Damage calculation (should be server-authoritative)
190
+ - Position setting (teleporting, movement authority)
191
+ - Leaderboard/stat modification
192
+ - Game state changes (win/lose conditions)
193
+
194
+ **Rule:** If it affects game state or other players, it must be server-validated.
195
+
196
+ ---
197
+
198
+ ## Security Step 4: Data Exposure Check
199
+
200
+ Verify:
201
+ - No sensitive data in `ReplicatedStorage` (secrets, configs with admin keys)
202
+ - No server-only logic in `StarterPlayerScripts` (game state, anti-cheat)
203
+ - No player data exposed to other players via remotes (unless intentional)
204
+ - RemoteEvent payloads don't include excess data (send only what's needed)
205
+ - No `require()` paths to server-only modules from client scripts
206
+
207
+ ---
208
+
209
+ ## Security Step 5: Rate Limiting Check
210
+
211
+ Verify all remotes have per-player rate limiting:
212
+ - Track last-fire timestamps server-side
213
+ - Reject requests faster than expected human input
214
+ - Different limits for different actions (chat: 1/sec, purchase: 1/5sec, movement: 30/sec)
215
+ - Log rate limit violations for monitoring
216
+
217
+ ---
218
+
219
+ ## Security Step 6: Vulnerability Report
220
+
221
+ Categorize findings:
222
+
223
+ - **Critical** - Exploitable for direct advantage (free currency, item duplication, account takeover)
224
+ - **High** - Data exposure or corruption possible
225
+ - **Medium** - Potential for abuse with moderate effort
226
+ - **Low** - Best practice violation, hard to exploit
227
+
228
+ For each vulnerability:
229
+ 1. Remote/method affected
230
+ 2. Exploit scenario (how an attacker would abuse it)
231
+ 3. Impact (what they gain)
232
+ 4. Fix (specific hardened code)
233
+
234
+ ---
235
+
236
+ ## Security Step 7: Hardening
237
+
238
+ Apply hardened code for each vulnerable remote. Include before/after for clarity.
239
+
240
+ Hardening patterns to apply:
241
+ - Server-side validation wrapper for each remote
242
+ - Rate limiting middleware
243
+ - Data sanitization functions
244
+ - Ownership verification for state changes
245
+
246
+ ---
247
+
248
+ ## Security Step 8: Re-verify
249
+
250
+ Confirm all vulnerabilities addressed:
251
+ - Each Critical/High finding has a corresponding fix applied
252
+ - Legitimate functionality still works after hardening
253
+ - No new issues introduced by the fixes
254
+ - Output a before/after comparison of the security posture
255
+
256
+ ---
257
+
258
+ # Performance Lens
259
+
260
+ *Apply this lens when performance-sensitive code changed: large loops, data structures, rendering, network-heavy features, or when the user reports lag.*
261
+
262
+ ---
263
+
264
+ ## Performance Step 1: Project Scan
265
+
266
+ Search for known anti-patterns:
267
+ - `wait()` and `spawn()` (yield-based, blocks thread)
268
+ - `RunService` loops (Heartbeat, Stepped, RenderStepped frequency)
269
+ - `GetDescendants()` and `GetChildren()` in loops (expensive at scale)
270
+
271
+ ---
272
+
273
+ ## Performance Step 2: Part Audit
274
+
275
+ Check for:
276
+ - Total part count (target: <50,000 for mobile, <200,000 for PC)
277
+ - Unanchored parts without assembly (physics chaos)
278
+ - Parts without collision groups (unnecessary collision detection)
279
+ - MeshParts vs Unions vs parts (MeshParts are most efficient)
280
+ - Transparent/reflective parts (rendering cost)
281
+
282
+ ---
283
+
284
+ ## Performance Step 3: Script Audit
285
+
286
+ Check for:
287
+ - Multiple `Heartbeat:Connect()` in the same script (consolidate into one)
288
+ - Excessive RemoteEvent usage (batch updates, reduce frequency)
289
+ - Tight loops without `task.wait()` (thread starvation)
290
+ - Unindexed table operations (linear search vs hash lookup)
291
+ - String concatenation in loops (use table.concat instead)
292
+ - `Instance.new()` in hot paths (cache and reuse)
293
+ - Deep `WaitForChild()` chains (cache references)
294
+
295
+ ---
296
+
297
+ ## Performance Step 4: Memory Audit
298
+
299
+ Check for:
300
+ - Undisconnected events (every `:Connect()` must have a matching `:Disconnect()`)
301
+ - Unreferenced instances (created but never parented or referenced)
302
+ - Large data tables held in memory (use lazy loading)
303
+ - String/internment issues (unnecessary duplicate strings)
304
+ - Module-level state that grows without cleanup
305
+
306
+ ---
307
+
308
+ ## Performance Step 5: Network Audit
309
+
310
+ Check:
311
+ - RemoteEvent frequency - Are updates sent every frame when 1/sec would suffice?
312
+ - Data size per event - Are payloads unnecessarily large?
313
+ - Unnecessary replication - Is data sent to all players when only some need it?
314
+ - `FireAllClients` vs `FireClient` - Target specific players when possible
315
+ - Debouncing - Are rapid-fire remotes properly debounced server-side?
316
+
317
+ ---
318
+
319
+ ## Performance Step 6: Priority Report
320
+
321
+ Generate prioritized list:
322
+
323
+ - **Critical** - Causes crashes or completely unplayable experience
324
+ - **High** - Noticeable lag, frame drops, or rubber-banding
325
+ - **Medium** - Suboptimal but functional, wasted resources
326
+ - **Low** - Minor optimization opportunity
327
+
328
+ For each item:
329
+ 1. What's slow
330
+ 2. Why it's slow (technical explanation)
331
+ 3. The fix (specific code change)
332
+ 4. Expected improvement
333
+
334
+ ---
335
+
336
+ ## Performance Step 7: Apply Fixes
337
+
338
+ Provide optimized code for each finding. Include before/after with expected impact.
339
+
340
+ Common fixes:
341
+ - Replace `wait()` with `task.wait()`
342
+ - Consolidate Heartbeat connections
343
+ - Add `task.wait()` to prevent thread starvation
344
+ - Cache `GetService()` calls
345
+ - Use spatial indexing for distance checks
346
+ - Batch RemoteEvent updates
347
+
348
+ ---
349
+
350
+ ## Performance Step 8: Before/After
351
+
352
+ Document improvements:
353
+ 1. **Metric** - What was measured (frame time, memory, network traffic)
354
+ 2. **Before** - Original value
355
+ 3. **After** - Improved value
356
+ 4. **Change** - Percentage improvement
357
+ 5. **Remaining** - What's left to optimize
358
+
359
+ ---
360
+
361
+ # Monetization Lens
362
+
363
+ *Apply this lens when monetization code changed: GamePasses, DevProducts, Premium integration, shop UI, or when reviewing revenue strategy.*
364
+
365
+ ---
366
+
367
+ ## Monetization Step 1: Current State
368
+
369
+ Search for `MarketplaceService` usage. Find all GamePass and DevProduct references. List all existing monetization.
370
+
371
+ Record:
372
+ - All GamePasses (ID, name, price, what it grants)
373
+ - All DevProducts (ID, name, price, what it consumes)
374
+ - Premium benefits (if any)
375
+ - Where monetization is presented in-game
376
+
377
+ ---
378
+
379
+ ## Monetization Step 2: GamePass Review
380
+
381
+ Evaluate each GamePass:
382
+ - Is the value clear to the player?
383
+ - Is the price appropriate for what it grants?
384
+ - Is it discoverable in-game (shown at relevant moments)?
385
+ - Does it persist correctly (works after rejoin)?
386
+ - Is it idempotent (purchasing twice doesn't break anything)?
387
+ - Does it provide lasting value vs one-time use?
388
+
389
+ ---
390
+
391
+ ## Monetization Step 3: DevProduct Review
392
+
393
+ Evaluate each consumable:
394
+ - Is it compelling enough for repeat purchase?
395
+ - Is it priced for impulse buy (<100 Robux) or considered purchase?
396
+ - Does ProcessReceipt handle correctly (grant then confirm)?
397
+ - Are there diminishing returns or purchase limits?
398
+ - Is the value clear before purchasing?
399
+ - Does it complement (not replace) gameplay?
400
+
401
+ ---
402
+
403
+ ## Monetization Step 4: Missing Opportunities
404
+
405
+ Based on genre best practices, suggest monetization the game is missing.
406
+
407
+ **Simulator:** VIP GamePass (2x currency, exclusive pets), Auto-farm DevProduct, Lucky egg/spin DevProducts, Season pass.
408
+
409
+ **Tycoon:** VIP GamePass (faster income, exclusive materials), Extra plot slots, Cosmetic upgrades.
410
+
411
+ **RPG:** Inventory expansion, Experience boosts, Cosmetic gear, Character slots.
412
+
413
+ **Horror:** Skip/co-op passes, Cosmetic items (flashlight skins, outfits), Hint system DevProduct.
414
+
415
+ **Battle Royale:** Battle pass (seasonal), Cosmetic-only items, Victory animations.
416
+
417
+ ---
418
+
419
+ ## Monetization Step 5: Pricing Analysis
420
+
421
+ Compare prices against Roblox norms:
422
+ - **Entry point** - 25-49 Robux for impulse buys
423
+ - **Mid-tier** - 99-199 Robux for meaningful upgrades
424
+ - **Premium** - 499-999 Robux for VIP/lifetime benefits
425
+ - **Consumables** - 10-50 Robux for repeat purchases
426
+
427
+ Evaluate Robux-to-value ratio, price anchoring, and bundle discounts.
428
+
429
+ ---
430
+
431
+ ## Monetization Step 6: Premium Integration
432
+
433
+ Check:
434
+ - Premium payouts configured and optimized
435
+ - Premium-exclusive benefits (10-15% bonus, exclusive items, priority queue)
436
+ - Premium benefits clearly communicated to non-Premium players
437
+ - Premium doesn't create unfair advantages in competitive games
438
+
439
+ ---
440
+
441
+ ## Monetization Step 7: Ad Integration
442
+
443
+ Evaluate if Rewarded Video Ads would fit:
444
+ - Natural placement points (extra life, bonus currency, skip wait timer)
445
+ - Player opt-in only (never forced)
446
+ - Doesn't interrupt core gameplay loop
447
+ - Frequency capped (1 ad per X minutes)
448
+ - Value exchange is fair (ad view = meaningful reward)
449
+
450
+ ---
451
+
452
+ ## Monetization Step 8: Ethical Review
453
+
454
+ Flag potentially predatory patterns:
455
+ - Loot boxes / gambling mechanics - Are odds disclosed?
456
+ - FOMO pressure - Limited-time offers that pressure quick decisions?
457
+ - Pay-to-win - Can paying players dominate free players unfairly?
458
+ - Dark patterns - Confusing UI that leads to accidental purchases?
459
+
460
+ ---
461
+
462
+ ## Monetization Step 9: Recommendations Report
463
+
464
+ Prioritized list of monetization improvements:
465
+
466
+ - **Must-have** - Items that directly increase revenue
467
+ - **Should-have** - Items that improve conversion or retention
468
+ - **Nice-to-have** - Items that optimize existing revenue
469
+
470
+ For each recommendation:
471
+ 1. What to implement
472
+ 2. Why it will increase revenue
473
+ 3. Implementation effort (small/medium/large)
474
+ 4. Where in the game to present it
475
+ 5. Pricing suggestion
476
+
477
+ ---
478
+
479
+ # Networking / Remote Architecture Lens
480
+
481
+ *Apply this lens when networking code changed: new remotes, Bindable refactoring, effect syncing, or when auditing remote surface for scaling.*
482
+
483
+ ---
484
+
485
+ ## Networking Step 1: Remote Surface Map
486
+
487
+ Search for all `RemoteEvent`, `RemoteFunction`, and `UnreliableRemoteEvent` instances. Search for `:FireServer`, `:FireClient`, `:FireAllClients`, `:InvokeServer`, `:InvokeClient`, and `:Invoke` to map the full remote surface.
488
+
489
+ Record every remote found with:
490
+ - Name
491
+ - Location (ReplicatedStorage path)
492
+ - Type (RemoteEvent, RemoteFunction, UnreliableRemoteEvent)
493
+ - Direction (Client→Server, Server→Client, Client↔Server)
494
+ - What it does and whether it carries critical or cosmetic data
495
+
496
+ ---
497
+
498
+ ## Networking Step 2: Type Selection Audit
499
+
500
+ Verify each remote uses the correct type:
501
+
502
+ | Type | Best For | Notes |
503
+ |------|----------|-------|
504
+ | `RemoteEvent` | Fire-and-forget messages | Most common. No return value. |
505
+ | `RemoteFunction` | Request-response patterns | Blocking. Avoid in hot paths. Prefer RemoteEvent + callback pattern. |
506
+ | `UnreliableRemoteEvent` | Loss-tolerant data (effects, cosmetics, position updates) | Can drop packets under load. NEVER for currency, inventory, damage, game state. |
507
+ | `BindableEvent` | Intra-client or intra-server pub/sub | LocalScript→LocalScript or Script→Script only. Never cross Server↔Client boundary. |
508
+ | `BindableFunction` | Intra-client or intra-server request-response | Same boundary rule as BindableEvent. |
509
+
510
+ Flag any remote using the wrong type:
511
+ - `RemoteFunction` where `RemoteEvent` + response pattern would suffice
512
+ - `RemoteEvent` used as BindableEvent (firing a remote only to reach other scripts on the same client)
513
+ - `RemoteEvent` carrying critical data that should use reliable delivery
514
+ - `UnreliableRemoteEvent` carrying game-critical state
515
+
516
+ ---
517
+
518
+ ## Networking Step 3: RemoteFunction Check
519
+
520
+ `RemoteFunction` is a blocking pattern - the caller yields until the receiver returns. This can cause lag if overused.
521
+
522
+ Verify:
523
+ - `:InvokeServer` is used sparingly (not per-frame or in tight loops)
524
+ - `:InvokeClient` is only used when the server genuinely needs an answer from a specific client (rare)
525
+ - Consider replacing with `RemoteEvent` + response event pattern for non-critical request-response flows
526
+ - `:InvokeClient` has a timeout safeguard (client may not respond)
527
+
528
+ ---
529
+
530
+ ## Networking Step 4: Bindable Audit
531
+
532
+ `BindableEvent` and `BindableFunction` are strictly intra-boundary (Server→Server or Client→Client).
533
+
534
+ Check:
535
+ - No `BindableEvent` / `BindableFunction` in ReplicatedStorage that is fired by server and listened to by client (use `RemoteEvent` instead - Bindables don't replicate)
536
+ - Client-side `BindableEvent`s are used for decoupling LocalScripts (cleaner than direct module references)
537
+ - Server-side `BindableEvent`s are used for service-to-service pub/sub within the same script context
538
+ - No orphaned or unused Bindable instances left in the hierarchy
539
+
540
+ ---
541
+
542
+ ## Networking Step 5: UnreliableRemoteEvent Audit
543
+
544
+ `UnreliableRemoteEvent` trades reliability for speed. Data may arrive out of order, arrive duplicates, or not arrive at all.
545
+
546
+ Verify:
547
+ - Used only for loss-tolerant data: cosmetic effects, non-critical position interpolation, particle triggers, sound events
548
+ - Never used for: currency transactions, inventory changes, damage application, game state transitions, unlock/upgrade actions
549
+ - Client-side has fallback logic (if a cosmetic event is dropped, the game still functions)
550
+ - Server-side does not rely on unreliable delivery for authoritative state
551
+
552
+ Recommended pattern - separate critical and cosmetic remotes:
553
+ ```luau
554
+ -- Critical: reliable RemoteEvent
555
+ local PurchaseRequest = ReplicatedStorage.Remotes.PurchaseRequest -- RemoteEvent
556
+ -- Cosmetic: unreliable
557
+ local HitEffectSync = ReplicatedStorage.Remotes.HitEffectSync -- UnreliableRemoteEvent
558
+ ```
559
+
560
+ ---
561
+
562
+ ## Networking Step 6: Organization & Naming
563
+
564
+ Check:
565
+ - All remotes organized under a consistent folder structure (e.g., `ReplicatedStorage > Remotes > {Category}`)
566
+ - Naming convention is consistent: `PascalCase` for remote names, `VerbNoun` pattern (`PlayerRequestPurchase`, `ServerSyncInventory`)
567
+ - No unused / orphaned remotes in ReplicatedStorage
568
+ - RemoteFunction and its response type are clearly paired by naming
569
+ - UnreliableRemoteEvents are clearly distinguishable by name or naming suffix (e.g., `Sync_` prefix)
570
+
571
+ ---
572
+
573
+ ## Networking Step 7: Anti-Patterns
574
+
575
+ Flag these common networking mistakes:
576
+
577
+ - **Using RemoteFunction in a hot path** - blocks the caller. Prefer RemoteEvent.
578
+ - **Using RemoteEvent when BindableEvent would suffice** - a remote that only reaches scripts on the same player should be a BindableEvent, avoiding network overhead.
579
+ - **Using RemoteEvent when UnreliableRemoteEvent would be better** - for high-frequency cosmetic updates (position, VFX), unreliable saves bandwidth and CPU.
580
+ - **Using UnreliableRemoteEvent for critical state** - dropped packets will corrupt game state.
581
+ - **No remote surface map** - undocumented remotes make auditing and debugging harder.
582
+ - **Inconsistent naming** - `fireRemote`, `HandleRequest`, `r1` mixed in the same project.
583
+ - **Remotes scattered across ReplicatedStorage** - all remotes should live under a single `Remotes` folder.
584
+ - **BindableEvent in ReplicatedStorage used cross-boundary** - Bindables don't replicate; this will silently fail on the client.
585
+
586
+ ---
587
+
588
+ # Data Persistence Lens
589
+
590
+ *Apply this lens when data persistence code changed: player data loading/saving, ProfileStore setup, data migration, or when auditing data integrity for production readiness.*
591
+
592
+ ---
593
+
594
+ ## Data Step 1: Data Library Detection
595
+
596
+ Search for how player data is stored:
597
+
598
+ - **ProfileStore found (recommended):** Continue to Step 2.
599
+ - **Raw DataStoreService** used directly: Flag as **High** priority. ProfileStore handles session locking, auto-save, BindToClose, retry logic, and schema reconciliation automatically. Recommend migration. Cross-reference: `roblox-data` §4.
600
+ - **No data persistence found:** Flag if the game needs it.
601
+
602
+ Verify ProfileStore installation:
603
+ - Wally dependency: `ProfileStore = "madstudioroblox/profileservice@1.4.0"`
604
+ - Or manual ModuleScript in ServerScriptService / ReplicatedStorage
605
+ - ProfileStore is required from the correct path
606
+
607
+ ---
608
+
609
+ ## Data Step 2: Profile Structure Review
610
+
611
+ Verify the `PROFILE_TEMPLATE` (or equivalent schema):
612
+
613
+ - Exists and is a table
614
+ - Contains a `DataVersion` field (number, incremented on schema changes)
615
+ - Uses nested structure for non-trivial games (separate `Currency`, `Progression`, `Inventory`, `Settings` sections)
616
+ - Every field has a sensible default value (ProfileStore's `:Reconcile()` fills missing fields from the template)
617
+ - No Instance references in the template (only JSON-compatible types: number, string, boolean, table)
618
+ - Cross-reference: `roblox-data` §6
619
+
620
+ ---
621
+
622
+ ## Data Step 3: Session Locking
623
+
624
+ Confirm session locking is properly configured:
625
+
626
+ - `profile:AddUserId(player.UserId)` is called after loading (GDPR compliance)
627
+ - `profile:ListenToRelease()` is connected, kicks the player if lock is stolen
628
+ - `"ForceLoad"` strategy is used (waits for lock, does not fail silently)
629
+ - `profile:Reconcile()` is called after loading to fill missing fields from template
630
+ - Cross-reference: `roblox-data` §5
631
+
632
+ ---
633
+
634
+ ## Data Step 4: Lifecycle Review
635
+
636
+ Verify the full player data lifecycle:
637
+
638
+ | Event | Must Do | Cross-Ref |
639
+ |-------|---------|-----------|
640
+ | `PlayerAdded` | Load profile via `LoadProfileAsync`, reconcile, store in cache | `roblox-data` §4 |
641
+ | Mid-game | Mutate `profile.Data.*` directly, leaderstats sync back | `roblox-data` §4 |
642
+ | `PlayerRemoving` | Sync leaderstats to profile, call `profile:Release()` | `roblox-data` §4 |
643
+ | `BindToClose` | If using raw DataStore: parallel saves with 30s timeout | `roblox-data` §10.3 |
644
+ | Auto-save | ProfileStore handles internally. If raw: 5-min interval, exponential retry | `roblox-data` §10.1 |
645
+
646
+ Flag missing lifecycle handlers, especially `PlayerRemoving` release and `BindToClose`.
647
+
648
+ ---
649
+
650
+ ## Data Step 5: Data Access Patterns
651
+
652
+ Check how data is read and written:
653
+
654
+ - Data is mutated via `profile.Data.fieldName`, not by calling DataStore methods directly
655
+ - Leaderstats `IntValue`/`StringValue` are synced back to `profile.Data` before `:Release()`
656
+ - Other scripts access player data via a getter module (`getProfile(player)`), not by directly importing ProfileStore
657
+ - Data writes happen immediately in memory; saves are handled by ProfileStore's auto-save interval
658
+ - Cross-reference: `roblox-data` §4
659
+
660
+ ---
661
+
662
+ ## Data Step 6: Migration Strategy
663
+
664
+ If the game has evolved its data schema:
665
+
666
+ - `DataVersion` field exists in the template
667
+ - Migration functions exist for each version bump (v1→v2, v2→v3, etc.)
668
+ - `DataMigrations.migrate(data)` is called after `LoadProfileAsync` and before `:Reconcile()`
669
+ - Migrations are sequential, pure functions (no yields, no side effects)
670
+ - Migration for old data that lacks `DataVersion` defaults to version 1
671
+ - Cross-reference: `roblox-data` §7
672
+
673
+ ---
674
+
675
+ ## Data Step 7: Anti-Patterns
676
+
677
+ Flag these common data persistence mistakes:
678
+
679
+ - **Raw DataStore for player state** instead of ProfileStore - missing session locking, auto-save, retry, BindToClose. Cross-ref: `roblox-data` §4.
680
+ - **Saving too frequently** - every coin pickup triggers a DataStore write. Rate limits will be hit. Cross-ref: `roblox-data` §11.
681
+ - **No `pcall` around DataStore calls** - unhandled errors crash the script. Cross-ref: `roblox-data` §11.
682
+ - **Storing Instance references in DataStore** - Instances are not serializable. Store IDs instead. Cross-ref: `roblox-data` §11.
683
+ - **No data validation before save** - NaN values or corrupt data can silently break the save. Cross-ref: `roblox-data` §10.5.
684
+ - **Missing `DataVersion`** - no way to detect or migrate old schema formats. Cross-ref: `roblox-data` §6.
685
+ - **Session locking bypassed** - using raw DataStore without manual lock implementation risks data loss. Cross-ref: `roblox-data` §5.
686
+ - **No `BindToClose` handler** - server shutdown loses unsaved player data. Cross-ref: `roblox-data` §10.3.
687
+ - **Sequential saves in `BindToClose`** - with many players, 30s timeout may be exceeded. Must use `task.spawn` for parallel saves. Cross-ref: `roblox-data` §12.