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,278 @@
1
+ -- Mouse
2
+ -- Stephen Leitnick
3
+ -- November 07, 2020
4
+
5
+ local Signal = require(script.Parent.Parent.Signal)
6
+ local Trove = require(script.Parent.Parent.Trove)
7
+
8
+ local UserInputService = game:GetService("UserInputService")
9
+
10
+ local RAY_DISTANCE = 1000
11
+
12
+ --[=[
13
+ @class Mouse
14
+ @client
15
+
16
+ The Mouse class is part of the Input package.
17
+
18
+ ```lua
19
+ local Mouse = require(packages.Input).Mouse
20
+ ```
21
+ ]=]
22
+ local Mouse = {}
23
+ Mouse.__index = Mouse
24
+
25
+ --[=[
26
+ @within Mouse
27
+ @prop LeftDown Signal<boolean>
28
+ @tag Event
29
+ ]=]
30
+ --[=[
31
+ @within Mouse
32
+ @prop LeftUp Signal<boolean>
33
+ @tag Event
34
+ ]=]
35
+ --[=[
36
+ @within Mouse
37
+ @prop RightDown Signal<boolean>
38
+ @tag Event
39
+ ]=]
40
+ --[=[
41
+ @within Mouse
42
+ @prop RightUp Signal<boolean>
43
+ @tag Event
44
+ ]=]
45
+ --[=[
46
+ @within Mouse
47
+ @prop MiddleDown Signal<boolean>
48
+ @tag Event
49
+ ]=]
50
+ --[=[
51
+ @within Mouse
52
+ @prop MiddleUp Signal<boolean>
53
+ @tag Event
54
+ ]=]
55
+ --[=[
56
+ @within Mouse
57
+ @prop Moved Signal<Vector2, boolean>
58
+ @tag Event
59
+ ```lua
60
+ mouse.Moved:Connect(function(position, processed) ... end)
61
+ ```
62
+ ]=]
63
+ --[=[
64
+ @within Mouse
65
+ @prop Scrolled Signal<number, boolean>
66
+ @tag Event
67
+ ```lua
68
+ mouse.Scrolled:Connect(function(scrollAmount, processed) ... end)
69
+ ```
70
+ ]=]
71
+
72
+ --[=[
73
+ @return Mouse
74
+
75
+ Constructs a new mouse input capturer.
76
+
77
+ ```lua
78
+ local mouse = Mouse.new()
79
+ ```
80
+ ]=]
81
+ function Mouse.new()
82
+ local self = setmetatable({}, Mouse)
83
+
84
+ self._trove = Trove.new()
85
+
86
+ self.LeftDown = self._trove:Construct(Signal)
87
+ self.LeftUp = self._trove:Construct(Signal)
88
+ self.RightDown = self._trove:Construct(Signal)
89
+ self.RightUp = self._trove:Construct(Signal)
90
+ self.MiddleDown = self._trove:Construct(Signal)
91
+ self.MiddleUp = self._trove:Construct(Signal)
92
+ self.Scrolled = self._trove:Construct(Signal)
93
+ self.Moved = self._trove:Construct(Signal)
94
+
95
+ self._trove:Connect(UserInputService.InputBegan, function(input, processed)
96
+ if input.UserInputType == Enum.UserInputType.MouseButton1 then
97
+ self.LeftDown:Fire(processed)
98
+ elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
99
+ self.RightDown:Fire(processed)
100
+ elseif input.UserInputType == Enum.UserInputType.MouseButton3 then
101
+ self.MiddleDown:Fire(processed)
102
+ end
103
+ end)
104
+
105
+ self._trove:Connect(UserInputService.InputEnded, function(input, processed)
106
+ if input.UserInputType == Enum.UserInputType.MouseButton1 then
107
+ self.LeftUp:Fire(processed)
108
+ elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
109
+ self.RightUp:Fire(processed)
110
+ elseif input.UserInputType == Enum.UserInputType.MouseButton3 then
111
+ self.MiddleUp:Fire(processed)
112
+ end
113
+ end)
114
+
115
+ self._trove:Connect(UserInputService.InputChanged, function(input, processed)
116
+ if input.UserInputType == Enum.UserInputType.MouseMovement then
117
+ local position = input.Position
118
+ self.Moved:Fire(Vector2.new(position.X, position.Y), processed)
119
+ elseif input.UserInputType == Enum.UserInputType.MouseWheel then
120
+ self.Scrolled:Fire(input.Position.Z, processed)
121
+ end
122
+ end)
123
+
124
+ return self
125
+ end
126
+
127
+ --[=[
128
+ Checks if the left mouse button is down.
129
+ ]=]
130
+ function Mouse:IsLeftDown(): boolean
131
+ return UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
132
+ end
133
+
134
+ --[=[
135
+ Checks if the right mouse button is down.
136
+ ]=]
137
+ function Mouse:IsRightDown(): boolean
138
+ return UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2)
139
+ end
140
+
141
+ --[=[
142
+ Checks if the middle mouse button is down.
143
+ ]=]
144
+ function Mouse:IsMiddleDown(): boolean
145
+ return UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton3)
146
+ end
147
+
148
+ --[=[
149
+ Gets the screen position of the mouse.
150
+ ]=]
151
+ function Mouse:GetPosition(): Vector2
152
+ return UserInputService:GetMouseLocation()
153
+ end
154
+
155
+ --[=[
156
+ Gets the delta screen position of the mouse. In other words, the
157
+ distance the mouse has traveled away from its locked position in
158
+ a given frame (see note about mouse locking below).
159
+
160
+ :::info Only When Mouse Locked
161
+ Getting the mouse delta is only intended for when the mouse is locked. If the
162
+ mouse is _not_ locked, this will return a zero Vector2. The mouse can be locked
163
+ using the `mouse:Lock()` and `mouse:LockCenter()` method.
164
+ :::
165
+ ]=]
166
+ function Mouse:GetDelta(): Vector2
167
+ return UserInputService:GetMouseDelta()
168
+ end
169
+
170
+ --[=[
171
+ Returns the viewport point ray for the mouse at the current mouse
172
+ position (or the override position if provided).
173
+ ]=]
174
+ function Mouse:GetRay(overridePos: Vector2?): Ray
175
+ local mousePos = overridePos or UserInputService:GetMouseLocation()
176
+ local viewportMouseRay = workspace.CurrentCamera:ViewportPointToRay(mousePos.X, mousePos.Y)
177
+ return viewportMouseRay
178
+ end
179
+
180
+ --[=[
181
+ Performs a raycast operation out from the mouse position (or the
182
+ `overridePos` if provided) into world space. The ray will go
183
+ `distance` studs forward (or 1000 studs if not provided).
184
+
185
+ Returns the `RaycastResult` if something was hit, else returns `nil`.
186
+
187
+ Use `Raycast` if it is important to capture any objects that could be
188
+ hit along the projected ray. If objects can be ignored and only the
189
+ final position of the ray is needed, use `Project` instead.
190
+
191
+ ```lua
192
+ local params = RaycastParams.new()
193
+ local result = mouse:Raycast(params)
194
+ if result then
195
+ print(result.Instance)
196
+ else
197
+ print("Mouse raycast did not hit anything")
198
+ end
199
+ ```
200
+ ]=]
201
+ function Mouse:Raycast(raycastParams: RaycastParams, distance: number?, overridePos: Vector2?): RaycastResult?
202
+ local viewportMouseRay = self:GetRay(overridePos)
203
+ local result = workspace:Raycast(
204
+ viewportMouseRay.Origin,
205
+ viewportMouseRay.Direction * (distance or RAY_DISTANCE),
206
+ raycastParams
207
+ )
208
+ return result
209
+ end
210
+
211
+ --[=[
212
+ Gets the 3D world position of the mouse when projected forward. This would be the
213
+ end-position of a raycast if nothing was hit. Similar to `Raycast`, optional
214
+ `distance` and `overridePos` arguments are allowed.
215
+
216
+ Use `Project` if you want to get the 3D world position of the mouse at a given
217
+ distance but don't care about any objects that could be in the way. It is much
218
+ faster to project a position into 3D space than to do a full raycast operation.
219
+
220
+ ```lua
221
+ local params = RaycastParams.new()
222
+ local distance = 200
223
+
224
+ local result = mouse:Raycast(params, distance)
225
+ if result then
226
+ -- Do something with result
227
+ else
228
+ -- Raycast failed, but still get the world position of the mouse:
229
+ local worldPosition = mouse:Project(distance)
230
+ end
231
+ ```
232
+ ]=]
233
+ function Mouse:Project(distance: number?, overridePos: Vector2?): Vector3
234
+ local viewportMouseRay = self:GetRay(overridePos)
235
+ return viewportMouseRay.Origin + (viewportMouseRay.Direction.Unit * (distance or RAY_DISTANCE))
236
+ end
237
+
238
+ --[=[
239
+ Locks the mouse in its current position on screen. Call `mouse:Unlock()`
240
+ to unlock the mouse.
241
+
242
+ :::caution Must explicitly unlock
243
+ Be sure to explicitly call `mouse:Unlock()` before cleaning up the mouse.
244
+ The `Destroy` method does _not_ unlock the mouse since there is no way
245
+ to guarantee who "owns" the mouse lock.
246
+ :::
247
+ ]=]
248
+ function Mouse:Lock()
249
+ UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
250
+ end
251
+
252
+ --[=[
253
+ Locks the mouse in the center of the screen. Call `mouse:Unlock()`
254
+ to unlock the mouse.
255
+
256
+ :::caution Must explicitly unlock
257
+ See cautionary in `Lock` method above.
258
+ :::
259
+ ]=]
260
+ function Mouse:LockCenter()
261
+ UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
262
+ end
263
+
264
+ --[=[
265
+ Unlocks the mouse.
266
+ ]=]
267
+ function Mouse:Unlock()
268
+ UserInputService.MouseBehavior = Enum.MouseBehavior.Default
269
+ end
270
+
271
+ --[=[
272
+ Destroys the mouse.
273
+ ]=]
274
+ function Mouse:Destroy()
275
+ self._trove:Destroy()
276
+ end
277
+
278
+ return Mouse
@@ -0,0 +1,91 @@
1
+ --!strict
2
+
3
+ --[=[
4
+ @class PreferredInput
5
+ @client
6
+
7
+ A helper library for observing the preferred user input of the
8
+ player. This is useful for determining what input schemes
9
+ to use during gameplay. A player might switch from using
10
+ a mouse to a gamepad mid-game, and it is important for the
11
+ game to respond to this change.
12
+
13
+ The PreferredInput library is part of the Input package.
14
+
15
+ ```lua
16
+ local PreferredInput = require(packages.Input).PreferredInput
17
+ ```
18
+ ]=]
19
+ --[=[
20
+ @within PreferredInput
21
+ @function observe
22
+ @param handler (preferred: Enum.PreferredInput) -> (() -> ())?
23
+ @return () -> ()
24
+
25
+ Observes the preferred input. In other words, the handler function will
26
+ be fired immediately, as well as any time the preferred input changes.
27
+
28
+ The returned function can be called to disconnect the observer.
29
+
30
+ ```lua
31
+ local disconnect = PreferredInput.observe(function(preferred)
32
+ -- Fires immediately & any time the preferred input changes
33
+ print(preferred)
34
+
35
+ return function()
36
+ -- Preferred input has changed
37
+ end
38
+ end)
39
+
40
+ -- If/when desired, observer can be stopped by calling the returned function:
41
+ disconnect()
42
+ ```
43
+ ]=]
44
+ --[=[
45
+ @within PreferredInput
46
+ @function get
47
+ @return Enum.PreferredInput
48
+
49
+ Gets the preferred input. This is equivalent to
50
+ [`UserInputService.PreferredInput`](https://create.roblox.com/docs/reference/engine/classes/UserInputService#PreferredInput).
51
+ ]=]
52
+
53
+ local UserInputService = game:GetService("UserInputService")
54
+
55
+ local PreferredInput = {}
56
+
57
+ function PreferredInput.observe(callback: (preferred: Enum.PreferredInput) -> (() -> ())?)
58
+ local cleanup: (() -> ())? = nil
59
+ local id = 0
60
+
61
+ local function onPreferredInputChanged()
62
+ id += 1
63
+ local observeId = id
64
+
65
+ local cleanupFn = callback(UserInputService.PreferredInput)
66
+ if typeof(cleanupFn) == "function" then
67
+ if id == observeId then
68
+ cleanup = cleanupFn
69
+ else
70
+ task.spawn(cleanupFn)
71
+ end
72
+ end
73
+ end
74
+
75
+ task.spawn(onPreferredInputChanged)
76
+ local conn = UserInputService:GetPropertyChangedSignal("PreferredInput"):Connect(onPreferredInputChanged)
77
+
78
+ return function()
79
+ conn:Disconnect()
80
+ if typeof(cleanup) == "function" then
81
+ task.spawn(cleanup)
82
+ cleanup = nil
83
+ end
84
+ end
85
+ end
86
+
87
+ function PreferredInput.get()
88
+ return UserInputService.PreferredInput
89
+ end
90
+
91
+ return PreferredInput
@@ -0,0 +1,120 @@
1
+ -- Touch
2
+ -- Stephen Leitnick
3
+ -- March 14, 2021
4
+
5
+ local Trove = require(script.Parent.Parent.Trove)
6
+ local Signal = require(script.Parent.Parent.Signal)
7
+
8
+ local UserInputService = game:GetService("UserInputService")
9
+
10
+ --[=[
11
+ @class Touch
12
+ @client
13
+
14
+ The Touch class is part of the Input package.
15
+
16
+ ```lua
17
+ local Touch = require(packages.Input).Touch
18
+ ```
19
+ ]=]
20
+ local Touch = {}
21
+ Touch.__index = Touch
22
+
23
+ --[=[
24
+ @within Touch
25
+ @prop TouchTap Signal<(touchPositions: {Vector2}, processed: boolean)>
26
+ @tag Event
27
+ Proxy for [UserInputService.TouchTap](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchTap).
28
+ ]=]
29
+ --[=[
30
+ @within Touch
31
+ @prop TouchTapInWorld Signal<(position: Vector2, processed: boolean)>
32
+ @tag Event
33
+ Proxy for [UserInputService.TouchTapInWorld](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchTapInWorld).
34
+ ]=]
35
+ --[=[
36
+ @within Touch
37
+ @prop TouchMoved Signal<(touch: InputObject, processed: boolean)>
38
+ @tag Event
39
+ Proxy for [UserInputService.TouchMoved](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchMoved).
40
+ ]=]
41
+ --[=[
42
+ @within Touch
43
+ @prop TouchLongPress Signal<(touchPositions: {Vector2}, state: Enum.UserInputState, processed: boolean)>
44
+ @tag Event
45
+ Proxy for [UserInputService.TouchLongPress](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchLongPress).
46
+ ]=]
47
+ --[=[
48
+ @within Touch
49
+ @prop TouchPan Signal<(touchPositions: {Vector2}, totalTranslation: Vector2, velocity: Vector2, state: Enum.UserInputState, processed: boolean)>
50
+ @tag Event
51
+ Proxy for [UserInputService.TouchPan](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchPan).
52
+ ]=]
53
+ --[=[
54
+ @within Touch
55
+ @prop TouchPinch Signal<(touchPositions: {Vector2}, scale: number, velocity: Vector2, state: Enum.UserInputState, processed: boolean)>
56
+ @tag Event
57
+ Proxy for [UserInputService.TouchPinch](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchPinch).
58
+ ]=]
59
+ --[=[
60
+ @within Touch
61
+ @prop TouchRotate Signal<(touchPositions: {Vector2}, rotation: number, velocity: number, state: Enum.UserInputState, processed: boolean)>
62
+ @tag Event
63
+ Proxy for [UserInputService.TouchRotate](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchRotate).
64
+ ]=]
65
+ --[=[
66
+ @within Touch
67
+ @prop TouchSwipe Signal<(swipeDirection: Enum.SwipeDirection, numberOfTouches: number, processed: boolean)>
68
+ @tag Event
69
+ Proxy for [UserInputService.TouchSwipe](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchSwipe).
70
+ ]=]
71
+ --[=[
72
+ @within Touch
73
+ @prop TouchStarted Signal<(touch: InputObject, processed: boolean)>
74
+ @tag Event
75
+ Proxy for [UserInputService.TouchStarted](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchStarted).
76
+ ]=]
77
+ --[=[
78
+ @within Touch
79
+ @prop TouchEnded Signal<(touch: InputObject, processed: boolean)>
80
+ @tag Event
81
+ Proxy for [UserInputService.TouchEnded](https://developer.roblox.com/en-us/api-reference/event/UserInputService/TouchEnded).
82
+ ]=]
83
+
84
+ --[=[
85
+ Constructs a new Touch input capturer.
86
+ ]=]
87
+ function Touch.new()
88
+ local self = setmetatable({}, Touch)
89
+
90
+ self._trove = Trove.new()
91
+
92
+ self.TouchTap = self._trove:Construct(Signal.Wrap, UserInputService.TouchTap)
93
+ self.TouchTapInWorld = self._trove:Construct(Signal.Wrap, UserInputService.TouchTapInWorld)
94
+ self.TouchMoved = self._trove:Construct(Signal.Wrap, UserInputService.TouchMoved)
95
+ self.TouchLongPress = self._trove:Construct(Signal.Wrap, UserInputService.TouchLongPress)
96
+ self.TouchPan = self._trove:Construct(Signal.Wrap, UserInputService.TouchPan)
97
+ self.TouchPinch = self._trove:Construct(Signal.Wrap, UserInputService.TouchPinch)
98
+ self.TouchRotate = self._trove:Construct(Signal.Wrap, UserInputService.TouchRotate)
99
+ self.TouchSwipe = self._trove:Construct(Signal.Wrap, UserInputService.TouchSwipe)
100
+ self.TouchStarted = self._trove:Construct(Signal.Wrap, UserInputService.TouchStarted)
101
+ self.TouchEnded = self._trove:Construct(Signal.Wrap, UserInputService.TouchEnded)
102
+
103
+ return self
104
+ end
105
+
106
+ --[=[
107
+ Returns the value of [`UserInputService.TouchEnabled`](https://developer.roblox.com/en-us/api-reference/property/UserInputService/TouchEnabled).
108
+ ]=]
109
+ function Touch:IsTouchEnabled(): boolean
110
+ return UserInputService.TouchEnabled
111
+ end
112
+
113
+ --[=[
114
+ Destroys the Touch input capturer.
115
+ ]=]
116
+ function Touch:Destroy()
117
+ self._trove:Destroy()
118
+ end
119
+
120
+ return Touch
@@ -0,0 +1,33 @@
1
+ -- Input
2
+ -- Stephen Leitnick
3
+ -- October 10, 2021
4
+
5
+ --[=[
6
+ @class Input
7
+
8
+ The Input package provides access to various user input classes.
9
+
10
+ - [PreferredInput](/api/PreferredInput)
11
+ - [Mouse](/api/Mouse)
12
+ - [Keyboard](/api/Keyboard)
13
+ - [Touch](/api/Touch)
14
+ - [Gamepad](/api/Gamepad)
15
+
16
+ Reference the desired input modules via the Input package to get started:
17
+
18
+ ```lua
19
+ local PreferredInput = require(Packages.Input).PreferredInput
20
+ local Mouse = require(Packages.Input).Mouse
21
+ local Keyboard = require(Packages.Input).Keyboard
22
+ local Touch = require(Packages.Input).Touch
23
+ local Gamepad = require(Packages.Input).Gamepad
24
+ ```
25
+ ]=]
26
+
27
+ return {
28
+ PreferredInput = require(script.PreferredInput),
29
+ Mouse = require(script.Mouse),
30
+ Keyboard = require(script.Keyboard),
31
+ Touch = require(script.Touch),
32
+ Gamepad = require(script.Gamepad),
33
+ }
@@ -0,0 +1,12 @@
1
+ [package]
2
+ name = "sleitnick/input"
3
+ description = "Basic input classes"
4
+ version = "3.0.0"
5
+ license = "MIT"
6
+ authors = ["Stephen Leitnick"]
7
+ registry = "https://github.com/UpliftGames/wally-index"
8
+ realm = "shared"
9
+
10
+ [dependencies]
11
+ Signal = "sleitnick/signal@2"
12
+ Trove = "sleitnick/trove@1"
@@ -0,0 +1,15 @@
1
+ type PredicateFn = (module: ModuleScript) => boolean;
2
+ type Modules = { [key: string]: unknown };
3
+
4
+ declare namespace Loader {
5
+ interface Constructor {
6
+ LoadChildren: (parent: Instance, predicate?: PredicateFn) => Modules;
7
+ LoadDescendants: (parent: Instance, predicate?: PredicateFn) => Modules;
8
+ MatchesName: (matchName: string) => (module: ModuleScript) => boolean;
9
+ SpawnAll: (loadedModules: Modules, methodName: string) => void;
10
+ }
11
+ }
12
+
13
+ declare const Loader: Loader.Constructor;
14
+
15
+ export = Loader;
@@ -0,0 +1,137 @@
1
+ --[=[
2
+ @class Loader
3
+
4
+ The Loader module will require all children or descendant ModuleScripts. There are also
5
+ some utility functions included, which assist with loading and starting modules in
6
+ single-script environments.
7
+
8
+ For example, here is a loader that loads all ModuleScripts under a folder that end with
9
+ the name Service, and then calls all of their OnStart methods:
10
+ ```lua
11
+ local MyModules = ReplicatedStorage.MyModules
12
+ Loader.SpawnAll(
13
+ Loader.LoadDescendants(MyModules, Loader.MatchesName("Service$")),
14
+ "OnStart"
15
+ )
16
+ ```
17
+ ]=]
18
+ local Loader = {}
19
+
20
+ --[=[
21
+ @within Loader
22
+ @type PredicateFn (module: ModuleScript) -> boolean
23
+ Predicate function type.
24
+ ]=]
25
+ type PredicateFn = (module: ModuleScript) -> boolean
26
+
27
+ --[=[
28
+ Requires all children ModuleScripts.
29
+
30
+ If a `predicate` function is provided, then the module will only
31
+ be loaded if the predicate returns `true` for the the given
32
+ ModuleScript.
33
+
34
+ ```lua
35
+ -- Load all ModuleScripts directly under MyModules:
36
+ Loader.LoadChildren(ReplicatedStorage.MyModules)
37
+
38
+ -- Load all ModuleScripts directly under MyModules if they have names ending in 'Service':
39
+ Loader.LoadChildren(ReplicatedStorage.MyModules, function(moduleScript)
40
+ return moduleScript.Name:match("Service$") ~= nil
41
+ end)
42
+ ```
43
+ ]=]
44
+ function Loader.LoadChildren(parent: Instance, predicate: PredicateFn?): { [string]: any }
45
+ local modules: { [string]: any } = {}
46
+ for _, child in parent:GetChildren() do
47
+ if child:IsA("ModuleScript") then
48
+ if predicate and not predicate(child) then
49
+ continue
50
+ end
51
+ local m = require(child)
52
+ modules[child.Name] = m
53
+ end
54
+ end
55
+ return modules
56
+ end
57
+
58
+ --[=[
59
+ Requires all descendant ModuleScripts.
60
+
61
+ If a `predicate` function is provided, then the module will only
62
+ be loaded if the predicate returns `true` for the the given
63
+ ModuleScript.
64
+
65
+ ```lua
66
+ -- Load all ModuleScripts under MyModules:
67
+ Loader.LoadDescendants(ReplicatedStorage.MyModules)
68
+
69
+ -- Load all ModuleScripts under MyModules if they have names ending in 'Service':
70
+ Loader.LoadDescendants(ReplicatedStorage.MyModules, function(moduleScript)
71
+ return moduleScript.Name:match("Service$") ~= nil
72
+ end)
73
+ ]=]
74
+ function Loader.LoadDescendants(parent: Instance, predicate: PredicateFn?): { [string]: any }
75
+ local modules: { [string]: any } = {}
76
+ for _, descendant in parent:GetDescendants() do
77
+ if descendant:IsA("ModuleScript") then
78
+ if predicate and not predicate(descendant) then
79
+ continue
80
+ end
81
+ local m = require(descendant)
82
+ modules[descendant.Name] = m
83
+ end
84
+ end
85
+ return modules
86
+ end
87
+
88
+ --[=[
89
+ A commonly-used predicate in the `LoadChildren` and `LoadDescendants`
90
+ functions is one to match names. Therefore, the `MatchesName` utility
91
+ function provides a quick way to create such predicates.
92
+
93
+ ```lua
94
+ Loader.LoadDescendants(ReplicatedStorage.MyModules, Loader.MatchesName("Service$"))
95
+ ```
96
+ ]=]
97
+ function Loader.MatchesName(matchName: string): (module: ModuleScript) -> boolean
98
+ return function(moduleScript: ModuleScript): boolean
99
+ return moduleScript.Name:match(matchName) ~= nil
100
+ end
101
+ end
102
+
103
+ --[=[
104
+ Utility function for spawning a specific method in all given modules.
105
+ If a module does not contain the specified method, it is simply
106
+ skipped. Methods are called with `task.spawn` internally.
107
+
108
+ For example, if the modules are expected to have an `OnStart()` method,
109
+ then `SpawnAll()` could be used to start all of them directly after
110
+ they have been loaded:
111
+
112
+ ```lua
113
+ local MyModules = ReplicatedStorage.MyModules
114
+
115
+ -- Load all modules under MyModules and then call their OnStart methods:
116
+ Loader.SpawnAll(Loader.LoadDescendants(MyModules), "OnStart")
117
+
118
+ -- Same as above, but only loads modules with names that end with Service:
119
+ Loader.SpawnAll(
120
+ Loader.LoadDescendants(MyModules, Loader.MatchesName("Service$")),
121
+ "OnStart"
122
+ )
123
+ ```
124
+ ]=]
125
+ function Loader.SpawnAll(loadedModules: { [string]: any }, methodName: string)
126
+ for name, mod in loadedModules do
127
+ local method = mod[methodName]
128
+ if type(method) == "function" then
129
+ task.spawn(function()
130
+ debug.setmemorycategory(name)
131
+ method(mod)
132
+ end)
133
+ end
134
+ end
135
+ end
136
+
137
+ return Loader
@@ -0,0 +1,8 @@
1
+ [package]
2
+ name = "sleitnick/loader"
3
+ description = "Requires all modules within a given instance"
4
+ version = "2.0.0"
5
+ license = "MIT"
6
+ authors = ["Stephen Leitnick"]
7
+ registry = "https://github.com/UpliftGames/wally-index"
8
+ realm = "shared"