rbxts-transform-boost 1.0.0 → 1.1.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.
- package/README.md +22 -84
- package/dist/index.js +0 -2
- package/dist/passes/annotate.js +2 -6
- package/package.json +11 -5
- package/.github/workflows/publish.yml +0 -26
- package/bench/default.project.json +0 -20
- package/bench/out/include/Promise.lua +0 -2068
- package/bench/out/include/RuntimeLib.lua +0 -260
- package/bench/out/src/server/benchmark.server.luau +0 -122
- package/bench/out/src/shared/fns-bare.luau +0 -258
- package/bench/out/src/shared/fns.luau +0 -259
- package/bench/package-lock.json +0 -59
- package/bench/src/server/benchmark.server.ts +0 -57
- package/bench/src/shared/fns-bare.ts +0 -127
- package/bench/src/shared/fns.ts +0 -129
- package/bench/tsconfig.json +0 -32
- package/bench/tsconfig.notransform.json +0 -24
- package/rokit.toml +0 -3
- package/src/config.ts +0 -14
- package/src/index.ts +0 -25
- package/src/passes/annotate.ts +0 -400
- package/src/passes/cache.ts +0 -163
- package/src/passes/loops.ts +0 -80
- package/src/passes/native.ts +0 -34
- package/src/util.ts +0 -37
- package/tsconfig.json +0 -16
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
local Promise = require(script.Parent.Promise)
|
|
2
|
-
|
|
3
|
-
local RunService = game:GetService("RunService")
|
|
4
|
-
|
|
5
|
-
local OUTPUT_PREFIX = "roblox-ts: "
|
|
6
|
-
local NODE_MODULES = "node_modules"
|
|
7
|
-
local DEFAULT_SCOPE = "@rbxts"
|
|
8
|
-
|
|
9
|
-
local TS = {}
|
|
10
|
-
|
|
11
|
-
TS.Promise = Promise
|
|
12
|
-
|
|
13
|
-
local function isPlugin(context)
|
|
14
|
-
return RunService:IsStudio() and context:FindFirstAncestorWhichIsA("Plugin") ~= nil
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
function TS.getModule(context, scope, moduleName)
|
|
18
|
-
-- legacy call signature
|
|
19
|
-
if moduleName == nil then
|
|
20
|
-
moduleName = scope
|
|
21
|
-
scope = DEFAULT_SCOPE
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
-- ensure modules have fully replicated
|
|
25
|
-
if RunService:IsRunning() and RunService:IsClient() and not isPlugin(context) and not game:IsLoaded() then
|
|
26
|
-
game.Loaded:Wait()
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
local object = context
|
|
30
|
-
repeat
|
|
31
|
-
local nodeModulesFolder = object:FindFirstChild(NODE_MODULES)
|
|
32
|
-
if nodeModulesFolder then
|
|
33
|
-
local scopeFolder = nodeModulesFolder:FindFirstChild(scope)
|
|
34
|
-
if scopeFolder then
|
|
35
|
-
local module = scopeFolder:FindFirstChild(moduleName)
|
|
36
|
-
if module then
|
|
37
|
-
return module
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
object = object.Parent
|
|
42
|
-
until object == nil
|
|
43
|
-
|
|
44
|
-
error(OUTPUT_PREFIX .. "Could not find module: " .. moduleName, 2)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
-- This is a hash which TS.import uses as a kind of linked-list-like history of [Script who Loaded] -> Library
|
|
48
|
-
local currentlyLoading = {}
|
|
49
|
-
local registeredLibraries = {}
|
|
50
|
-
|
|
51
|
-
function TS.import(context, module, ...)
|
|
52
|
-
for i = 1, select("#", ...) do
|
|
53
|
-
module = module:WaitForChild((select(i, ...)))
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
if module.ClassName ~= "ModuleScript" then
|
|
57
|
-
error(OUTPUT_PREFIX .. "Failed to import! Expected ModuleScript, got " .. module.ClassName, 2)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
currentlyLoading[context] = module
|
|
61
|
-
|
|
62
|
-
-- Check to see if a case like this occurs:
|
|
63
|
-
-- module -> Module1 -> Module2 -> module
|
|
64
|
-
|
|
65
|
-
-- WHERE currentlyLoading[module] is Module1
|
|
66
|
-
-- and currentlyLoading[Module1] is Module2
|
|
67
|
-
-- and currentlyLoading[Module2] is module
|
|
68
|
-
|
|
69
|
-
local currentModule = module
|
|
70
|
-
local depth = 0
|
|
71
|
-
|
|
72
|
-
while currentModule do
|
|
73
|
-
depth = depth + 1
|
|
74
|
-
currentModule = currentlyLoading[currentModule]
|
|
75
|
-
|
|
76
|
-
if currentModule == module then
|
|
77
|
-
local str = currentModule.Name -- Get the string traceback
|
|
78
|
-
|
|
79
|
-
for _ = 1, depth do
|
|
80
|
-
currentModule = currentlyLoading[currentModule]
|
|
81
|
-
str = str .. " ⇒ " .. currentModule.Name
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
error(OUTPUT_PREFIX .. "Failed to import! Detected a circular dependency chain: " .. str, 2)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
if not registeredLibraries[module] then
|
|
89
|
-
if _G[module] then
|
|
90
|
-
error(
|
|
91
|
-
OUTPUT_PREFIX
|
|
92
|
-
.. "Invalid module access! Do you have multiple TS runtimes trying to import this? "
|
|
93
|
-
.. module:GetFullName(),
|
|
94
|
-
2
|
|
95
|
-
)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
_G[module] = TS
|
|
99
|
-
registeredLibraries[module] = true -- register as already loaded for subsequent calls
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
local data = require(module)
|
|
103
|
-
|
|
104
|
-
if currentlyLoading[context] == module then -- Thread-safe cleanup!
|
|
105
|
-
currentlyLoading[context] = nil
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
return data
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
function TS.instanceof(obj, class)
|
|
112
|
-
-- custom Class.instanceof() check
|
|
113
|
-
if type(class) == "table" and type(class.instanceof) == "function" then
|
|
114
|
-
return class.instanceof(obj)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
-- metatable check
|
|
118
|
-
if type(obj) == "table" then
|
|
119
|
-
obj = getmetatable(obj)
|
|
120
|
-
while obj ~= nil do
|
|
121
|
-
if obj == class then
|
|
122
|
-
return true
|
|
123
|
-
end
|
|
124
|
-
local mt = getmetatable(obj)
|
|
125
|
-
if mt then
|
|
126
|
-
obj = mt.__index
|
|
127
|
-
else
|
|
128
|
-
obj = nil
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
return false
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
function TS.async(callback)
|
|
137
|
-
return function(...)
|
|
138
|
-
local n = select("#", ...)
|
|
139
|
-
local args = { ... }
|
|
140
|
-
return Promise.new(function(resolve, reject)
|
|
141
|
-
coroutine.wrap(function()
|
|
142
|
-
local ok, result = pcall(callback, unpack(args, 1, n))
|
|
143
|
-
if ok then
|
|
144
|
-
resolve(result)
|
|
145
|
-
else
|
|
146
|
-
reject(result)
|
|
147
|
-
end
|
|
148
|
-
end)()
|
|
149
|
-
end)
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
function TS.await(promise)
|
|
154
|
-
if not Promise.is(promise) then
|
|
155
|
-
return promise
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
local status, value = promise:awaitStatus()
|
|
159
|
-
if status == Promise.Status.Resolved then
|
|
160
|
-
return value
|
|
161
|
-
elseif status == Promise.Status.Rejected then
|
|
162
|
-
error(value, 2)
|
|
163
|
-
else
|
|
164
|
-
error("The awaited Promise was cancelled", 2)
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
local SIGN = 2 ^ 31
|
|
169
|
-
local COMPLEMENT = 2 ^ 32
|
|
170
|
-
local function bit_sign(num)
|
|
171
|
-
-- Restores the sign after an unsigned conversion according to 2s complement.
|
|
172
|
-
if bit32.btest(num, SIGN) then
|
|
173
|
-
return num - COMPLEMENT
|
|
174
|
-
else
|
|
175
|
-
return num
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
function TS.bit_lrsh(a, b)
|
|
180
|
-
return bit_sign(bit32.arshift(a, b))
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
TS.TRY_RETURN = 1
|
|
184
|
-
TS.TRY_BREAK = 2
|
|
185
|
-
TS.TRY_CONTINUE = 3
|
|
186
|
-
|
|
187
|
-
function TS.try(try, catch, finally)
|
|
188
|
-
-- execute try
|
|
189
|
-
local trySuccess, exitTypeOrTryError, returns = pcall(try)
|
|
190
|
-
local exitType, tryError
|
|
191
|
-
if trySuccess then
|
|
192
|
-
exitType = exitTypeOrTryError
|
|
193
|
-
else
|
|
194
|
-
tryError = exitTypeOrTryError
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
local catchSuccess = true
|
|
198
|
-
local catchError
|
|
199
|
-
|
|
200
|
-
-- if try block failed, and catch block exists, execute catch
|
|
201
|
-
if not trySuccess and catch then
|
|
202
|
-
local newExitTypeOrCatchError, newReturns
|
|
203
|
-
catchSuccess, newExitTypeOrCatchError, newReturns = pcall(catch, tryError)
|
|
204
|
-
local newExitType
|
|
205
|
-
if catchSuccess then
|
|
206
|
-
newExitType = newExitTypeOrCatchError
|
|
207
|
-
else
|
|
208
|
-
catchError = newExitTypeOrCatchError
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
if newExitType then
|
|
212
|
-
exitType, returns = newExitType, newReturns
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
-- execute finally
|
|
217
|
-
if finally then
|
|
218
|
-
local newExitType, newReturns = finally()
|
|
219
|
-
if newExitType then
|
|
220
|
-
exitType, returns = newExitType, newReturns
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
-- if exit type is a control flow, do not rethrow errors
|
|
225
|
-
if exitType ~= TS.TRY_RETURN and exitType ~= TS.TRY_BREAK and exitType ~= TS.TRY_CONTINUE then
|
|
226
|
-
-- if catch block threw an error, rethrow it
|
|
227
|
-
if not catchSuccess then
|
|
228
|
-
error(catchError, 2)
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
-- if try block threw an error and there was no catch block, rethrow it
|
|
232
|
-
if not trySuccess and not catch then
|
|
233
|
-
error(tryError, 2)
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
return exitType, returns
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
function TS.generator(callback)
|
|
241
|
-
local co = coroutine.create(callback)
|
|
242
|
-
return {
|
|
243
|
-
next = function(...)
|
|
244
|
-
if coroutine.status(co) == "dead" then
|
|
245
|
-
return { done = true }
|
|
246
|
-
else
|
|
247
|
-
local success, value = coroutine.resume(co, ...)
|
|
248
|
-
if success == false then
|
|
249
|
-
error(value, 2)
|
|
250
|
-
end
|
|
251
|
-
return {
|
|
252
|
-
value = value,
|
|
253
|
-
done = coroutine.status(co) == "dead",
|
|
254
|
-
}
|
|
255
|
-
end
|
|
256
|
-
end,
|
|
257
|
-
}
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
return TS
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
--!optimize 2
|
|
2
|
-
|
|
3
|
-
-- Compiled with rotor v2.2.0
|
|
4
|
-
|
|
5
|
-
-- Runtime
|
|
6
|
-
local TS = require(_ReplicatedStorage:WaitForChild("include"):WaitForChild("RuntimeLib"))
|
|
7
|
-
|
|
8
|
-
-- Services
|
|
9
|
-
local _ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
10
|
-
local _Workspace = game:GetService("Workspace")
|
|
11
|
-
|
|
12
|
-
-- Imports
|
|
13
|
-
local base = TS.import(script, _ReplicatedStorage, "shared", "fns-bare")
|
|
14
|
-
local opt = TS.import(script, _ReplicatedStorage, "shared", "fns")
|
|
15
|
-
|
|
16
|
-
local function bench(label: string, n: number, fn)
|
|
17
|
-
local _cache0 = os.clock
|
|
18
|
-
task.wait(0.05)
|
|
19
|
-
const t0 = _cache0()
|
|
20
|
-
|
|
21
|
-
do
|
|
22
|
-
local i = 0
|
|
23
|
-
local _shouldIncrement = false
|
|
24
|
-
|
|
25
|
-
while true do
|
|
26
|
-
if _shouldIncrement then
|
|
27
|
-
i += 1
|
|
28
|
-
else
|
|
29
|
-
_shouldIncrement = true
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
if not (i < n) then
|
|
33
|
-
break
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
fn()
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
const elapsed = _cache0() - t0
|
|
41
|
-
print(` {label}: {string.format("%.3f", (elapsed / n) * 1e6)} us/iter`)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
const N = 100000
|
|
45
|
-
const NS = 10000
|
|
46
|
-
const pos = Vector3.new(1, 2, 3)
|
|
47
|
-
const vel = Vector3.new(0, 1, 0)
|
|
48
|
-
const acc = Vector3.new(0, -9.8, 0)
|
|
49
|
-
const vecA = Vector3.new(1, 0, 0)
|
|
50
|
-
const vecB = Vector3.new(0, 1, 0)
|
|
51
|
-
const eye = Vector3.new(0, 5, 10)
|
|
52
|
-
const tgt = Vector3.new(0, 0, 0)
|
|
53
|
-
const cf = CFrame.lookAt(eye, tgt)
|
|
54
|
-
const buf = buffer.create(256)
|
|
55
|
-
const vals = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
|
|
56
|
-
const wts = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
|
|
57
|
-
const cam = _Workspace.CurrentCamera
|
|
58
|
-
|
|
59
|
-
local function runSuite(fns)
|
|
60
|
-
bench("integrate (verlet)", N, function()
|
|
61
|
-
return fns.integrate(pos, vel, acc, 1 / 60)
|
|
62
|
-
end)
|
|
63
|
-
bench("dot (V3 manual)", N, function()
|
|
64
|
-
return fns.dot(vecA, vecB)
|
|
65
|
-
end)
|
|
66
|
-
bench("cross (V3 manual)", N, function()
|
|
67
|
-
return fns.cross(vecA, vecB)
|
|
68
|
-
end)
|
|
69
|
-
bench("lerpVec3 (V3 manual)", N, function()
|
|
70
|
-
return fns.lerpVec3(pos, eye, 0.5)
|
|
71
|
-
end)
|
|
72
|
-
bench("encodeFixed (buf+math)", N, function()
|
|
73
|
-
return fns.encodeFixed(buf, 0, 3.14, 100)
|
|
74
|
-
end)
|
|
75
|
-
bench("encodePacket(3x fixed)", N, function()
|
|
76
|
-
return fns.encodePacket(buf, 1.1, 2.2, 3.3, 100)
|
|
77
|
-
end)
|
|
78
|
-
bench("sumWeighted (loop)", N, function()
|
|
79
|
-
return fns.sumWeighted(vals, wts)
|
|
80
|
-
end)
|
|
81
|
-
bench("dotProduct (loop)", N, function()
|
|
82
|
-
return fns.dotProduct(vals, vals)
|
|
83
|
-
end)
|
|
84
|
-
bench("norm (loop+sqrt)", N, function()
|
|
85
|
-
return fns.norm(vals)
|
|
86
|
-
end)
|
|
87
|
-
bench("mathHeavy (trig+sqrt)", N, function()
|
|
88
|
-
return fns.mathHeavy(1.23, 4.56)
|
|
89
|
-
end)
|
|
90
|
-
bench("fib(20) (iter)", N, function()
|
|
91
|
-
return fns.fib(20)
|
|
92
|
-
end)
|
|
93
|
-
bench("cfLookAt (ctor)", NS, function()
|
|
94
|
-
return fns.cfLookAt(eye, tgt)
|
|
95
|
-
end)
|
|
96
|
-
bench("cfChain (mul+angles)", N, function()
|
|
97
|
-
return fns.cfChain(cf, 0.016)
|
|
98
|
-
end)
|
|
99
|
-
bench("serviceWork (GetService x2)", N, function()
|
|
100
|
-
return fns.serviceWork()
|
|
101
|
-
end)
|
|
102
|
-
bench("multiSvc (GetService x3)", N, function()
|
|
103
|
-
return fns.multiService()
|
|
104
|
-
end)
|
|
105
|
-
bench("cameraWork (prop chain)", N, function()
|
|
106
|
-
return fns.cameraWork(cam)
|
|
107
|
-
end)
|
|
108
|
-
bench("formatStats (template)", N, function()
|
|
109
|
-
return fns.formatStats("speed", 9.81, "m/s")
|
|
110
|
-
end)
|
|
111
|
-
bench("buildKey (template)", N, function()
|
|
112
|
-
return fns.buildKey("player", 42, "data")
|
|
113
|
-
end)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
print("\n=== optimized (--!native + transformer) ===")
|
|
117
|
-
runSuite(opt)
|
|
118
|
-
print("===========================================\n")
|
|
119
|
-
task.wait(1)
|
|
120
|
-
print("\n=== baseline (plain rotor, no transformer) ===")
|
|
121
|
-
runSuite(base)
|
|
122
|
-
print("==============================================\n")
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
--!optimize 2
|
|
2
|
-
|
|
3
|
-
-- Compiled with rotor v2.2.0
|
|
4
|
-
|
|
5
|
-
-- Services
|
|
6
|
-
local _RunService = game:GetService("RunService")
|
|
7
|
-
local _Workspace = game:GetService("Workspace")
|
|
8
|
-
local _Players = game:GetService("Players")
|
|
9
|
-
|
|
10
|
-
local function integrate(pos: Vector3, vel: Vector3, acc: Vector3, dt: number)
|
|
11
|
-
local _vel = vel
|
|
12
|
-
local _acc = acc
|
|
13
|
-
local _dt = dt
|
|
14
|
-
const newVel = _vel + (_acc * _dt)
|
|
15
|
-
|
|
16
|
-
local _pos = pos
|
|
17
|
-
local _dt_1 = dt
|
|
18
|
-
local _arg0 = newVel * _dt_1
|
|
19
|
-
const newPos = _pos + _arg0
|
|
20
|
-
|
|
21
|
-
return { newPos, newVel }
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
local function dot(a: Vector3, b: Vector3): number
|
|
25
|
-
return a.X * b.X + a.Y * b.Y + a.Z * b.Z
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
local function cross(a: Vector3, b: Vector3): Vector3
|
|
29
|
-
local _cache0 = a.Y
|
|
30
|
-
local _cache1 = b.Z
|
|
31
|
-
local _cache2 = a.Z
|
|
32
|
-
local _cache3 = b.Y
|
|
33
|
-
local _cache4 = b.X
|
|
34
|
-
local _cache5 = a.X
|
|
35
|
-
|
|
36
|
-
return Vector3.new(_cache0 * _cache1 - _cache2 * _cache3, _cache2 * _cache4 - _cache5 * _cache1, _cache5 * _cache3 - _cache0 * _cache4)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
local function lerpVec3(a: Vector3, b: Vector3, t: number): Vector3
|
|
40
|
-
local _cache0 = a.X
|
|
41
|
-
local _cache1 = a.Y
|
|
42
|
-
local _cache2 = a.Z
|
|
43
|
-
|
|
44
|
-
return Vector3.new(_cache0 + (b.X - _cache0) * t, _cache1 + (b.Y - _cache1) * t, _cache2 + (b.Z - _cache2) * t)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
-- ── Buffer / encoding ────────────────────────────────────────────────────────
|
|
48
|
-
|
|
49
|
-
local function encodeFixed(buf: buffer, offset: number, value: number, scale: number): number
|
|
50
|
-
const fixed = math.floor(value * scale)
|
|
51
|
-
const clamped = math.clamp(fixed, -32768, 32767)
|
|
52
|
-
buffer.writei16(buf, offset, clamped)
|
|
53
|
-
|
|
54
|
-
return offset + 2
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
local function encodePacket(buf: buffer, x: number, y: number, z: number, scale: number)
|
|
58
|
-
local off = 0
|
|
59
|
-
off = encodeFixed(buf, off, x, scale)
|
|
60
|
-
off = encodeFixed(buf, off, y, scale)
|
|
61
|
-
encodeFixed(buf, off, z, scale)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
-- ── Math / arithmetic ────────────────────────────────────────────────────────
|
|
65
|
-
|
|
66
|
-
local function sumWeighted(values: {number}, weights: {number}): number
|
|
67
|
-
local total = 0
|
|
68
|
-
|
|
69
|
-
do
|
|
70
|
-
local _len_values = #values
|
|
71
|
-
|
|
72
|
-
do
|
|
73
|
-
local i = 0
|
|
74
|
-
local _shouldIncrement = false
|
|
75
|
-
|
|
76
|
-
while true do
|
|
77
|
-
if _shouldIncrement then
|
|
78
|
-
i += 1
|
|
79
|
-
else
|
|
80
|
-
_shouldIncrement = true
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
if not (i < _len_values) then
|
|
84
|
-
break
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
total += values[i + 1] * weights[i + 1]
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
return total
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
local function dotProduct(a: {number}, b: {number}): number
|
|
96
|
-
local sum = 0
|
|
97
|
-
|
|
98
|
-
do
|
|
99
|
-
local _len_a = #a
|
|
100
|
-
|
|
101
|
-
do
|
|
102
|
-
local i = 0
|
|
103
|
-
local _shouldIncrement = false
|
|
104
|
-
|
|
105
|
-
while true do
|
|
106
|
-
if _shouldIncrement then
|
|
107
|
-
i += 1
|
|
108
|
-
else
|
|
109
|
-
_shouldIncrement = true
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
if not (i < _len_a) then
|
|
113
|
-
break
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
sum += a[i + 1] * b[i + 1]
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
return sum
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
local function norm(values: {number}): number
|
|
125
|
-
local sq = 0
|
|
126
|
-
|
|
127
|
-
do
|
|
128
|
-
local _len_values = #values
|
|
129
|
-
|
|
130
|
-
do
|
|
131
|
-
local i = 0
|
|
132
|
-
local _shouldIncrement = false
|
|
133
|
-
|
|
134
|
-
while true do
|
|
135
|
-
if _shouldIncrement then
|
|
136
|
-
i += 1
|
|
137
|
-
else
|
|
138
|
-
_shouldIncrement = true
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
if not (i < _len_values) then
|
|
142
|
-
break
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
sq += values[i + 1] * values[i + 1]
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
return math.sqrt(sq)
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
local function mathHeavy(x: number, y: number): number
|
|
154
|
-
return math.sin(x) * math.cos(y) + math.sqrt(x * x + y * y) + math.atan2(y, x)
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
local function fib(n: number): number
|
|
158
|
-
|
|
159
|
-
if n <= 1 then
|
|
160
|
-
return n
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
local a = 0
|
|
164
|
-
local b = 1
|
|
165
|
-
|
|
166
|
-
do
|
|
167
|
-
local i = 2
|
|
168
|
-
local _shouldIncrement = false
|
|
169
|
-
|
|
170
|
-
while true do
|
|
171
|
-
if _shouldIncrement then
|
|
172
|
-
i += 1
|
|
173
|
-
else
|
|
174
|
-
_shouldIncrement = true
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
if not (i <= n) then
|
|
178
|
-
break
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
const tmp = a + b
|
|
182
|
-
a = b
|
|
183
|
-
b = tmp
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
return b
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
-- ── CFrame ───────────────────────────────────────────────────────────────────
|
|
191
|
-
|
|
192
|
-
local function cfLookAt(eye: Vector3, target: Vector3): CFrame
|
|
193
|
-
return CFrame.lookAt(eye, target)
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
local function cfChain(cf: CFrame, dt: number): CFrame
|
|
197
|
-
local _cf = cf
|
|
198
|
-
local _arg0 = CFrame.Angles(0, dt, 0)
|
|
199
|
-
|
|
200
|
-
return _cf * _arg0
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
-- ── Services / instance ──────────────────────────────────────────────────────
|
|
204
|
-
|
|
205
|
-
local function serviceWork(): string
|
|
206
|
-
const count = #_Players:GetPlayers()
|
|
207
|
-
const running = _RunService:IsRunning()
|
|
208
|
-
|
|
209
|
-
return `{count}-{running}`
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
local function multiService(): boolean
|
|
213
|
-
const players = _Players
|
|
214
|
-
const rs = _RunService
|
|
215
|
-
const ws = _Workspace
|
|
216
|
-
|
|
217
|
-
return rs:IsRunning() and players.MaxPlayers > 0 and ws.Gravity > 0
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
local function cameraWork(camera: Camera): number
|
|
221
|
-
local _cache0 = camera.CFrame
|
|
222
|
-
const pos = _cache0.Position
|
|
223
|
-
const look = _cache0.LookVector
|
|
224
|
-
const fov = camera.FieldOfView
|
|
225
|
-
|
|
226
|
-
return pos.Magnitude + look.X + fov
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
-- ── String ───────────────────────────────────────────────────────────────────
|
|
230
|
-
|
|
231
|
-
local function formatStats(label: string, value: number, unit: string): string
|
|
232
|
-
return `{label}: {string.format("%.4f", value)} {unit}`
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
local function buildKey(prefix: string, id: number, suffix: string): string
|
|
236
|
-
return `{prefix}_{id}_{suffix}`
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
return {
|
|
240
|
-
integrate = integrate,
|
|
241
|
-
dot = dot,
|
|
242
|
-
cross = cross,
|
|
243
|
-
lerpVec3 = lerpVec3,
|
|
244
|
-
encodeFixed = encodeFixed,
|
|
245
|
-
encodePacket = encodePacket,
|
|
246
|
-
sumWeighted = sumWeighted,
|
|
247
|
-
dotProduct = dotProduct,
|
|
248
|
-
norm = norm,
|
|
249
|
-
mathHeavy = mathHeavy,
|
|
250
|
-
fib = fib,
|
|
251
|
-
cfLookAt = cfLookAt,
|
|
252
|
-
cfChain = cfChain,
|
|
253
|
-
serviceWork = serviceWork,
|
|
254
|
-
multiService = multiService,
|
|
255
|
-
cameraWork = cameraWork,
|
|
256
|
-
formatStats = formatStats,
|
|
257
|
-
buildKey = buildKey,
|
|
258
|
-
}
|