pulse-rb 1.2.24

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 (54) hide show
  1. package/README.md +225 -0
  2. package/adapters/linoria.lua +233 -0
  3. package/adapters/windui.llms.txt +366 -0
  4. package/adapters/windui.lua +505 -0
  5. package/bin/rb.js +2 -0
  6. package/dist/index.js +3285 -0
  7. package/package.json +59 -0
  8. package/pulse/dev/debuggui.lua +1206 -0
  9. package/pulse/dev/devconfig.lua +81 -0
  10. package/pulse/dev/ui/9_DevPanel.lua +384 -0
  11. package/pulse/helpers/aim.lua +193 -0
  12. package/pulse/helpers/cache.lua +68 -0
  13. package/pulse/helpers/cleaner.lua +110 -0
  14. package/pulse/helpers/conn.lua +33 -0
  15. package/pulse/helpers/cooldown.lua +47 -0
  16. package/pulse/helpers/draw.lua +122 -0
  17. package/pulse/helpers/hitbox.lua +63 -0
  18. package/pulse/helpers/input.lua +24 -0
  19. package/pulse/helpers/log.lua +228 -0
  20. package/pulse/helpers/loop.lua +58 -0
  21. package/pulse/helpers/memory.lua +48 -0
  22. package/pulse/helpers/narrate.lua +160 -0
  23. package/pulse/helpers/notify.lua +51 -0
  24. package/pulse/helpers/perf.lua +48 -0
  25. package/pulse/helpers/remote.lua +128 -0
  26. package/pulse/helpers/restore.lua +59 -0
  27. package/pulse/helpers/store.lua +39 -0
  28. package/pulse/helpers/team.lua +83 -0
  29. package/pulse/helpers/testmode.lua +80 -0
  30. package/pulse/helpers/trace.lua +111 -0
  31. package/pulse/helpers/track.lua +85 -0
  32. package/pulse/helpers/vec.lua +52 -0
  33. package/pulse/helpers/world.lua +51 -0
  34. package/pulse/runtime.lua +343 -0
  35. package/pulse/ui/linoria_settings.lua +55 -0
  36. package/pulse/ui/windui_settings.lua +87 -0
  37. package/templates/AGENTS.md +177 -0
  38. package/templates/CLAUDE.md +424 -0
  39. package/templates/deploy_config.example +17 -0
  40. package/templates/example_esp.rblua +69 -0
  41. package/templates/example_fov.rblua +20 -0
  42. package/templates/example_speed.rblua +25 -0
  43. package/templates/gitignore +4 -0
  44. package/templates/globals.lua +66 -0
  45. package/templates/layout.rblua +28 -0
  46. package/templates/module.lua +7 -0
  47. package/templates/module.rblua +32 -0
  48. package/templates/page_home.rblua +9 -0
  49. package/templates/remote.lua +6 -0
  50. package/templates/remotes.lua +14 -0
  51. package/vscode/language-configuration.json +35 -0
  52. package/vscode/package.json +35 -0
  53. package/vscode/src/extension.js +397 -0
  54. package/vscode/syntaxes/rblua.tmLanguage.json +126 -0
@@ -0,0 +1,177 @@
1
+ # AGENTS.md — {NAME}
2
+
3
+ Roblox script project built with the **rb / Pulse** framework.
4
+ Run `rb docs` (or read `PULSE_DOCS.md` if it exists) for the complete framework reference.
5
+
6
+ ---
7
+
8
+ ## Build
9
+
10
+ ```
11
+ rb build # compile + obfuscate → build/script.lua
12
+ rb build --no-obfuscate # compile only
13
+ rb copy # compile + copy to clipboard
14
+ rb lint # static analysis: dead signals, ghost refs, orphan funcs
15
+ rb check # syntax-check compiled output
16
+ rb docs # generate PULSE_DOCS.md full reference
17
+ ```
18
+
19
+ ---
20
+
21
+ ## Architecture rules
22
+
23
+ - Each `.rblua` file = one **component**. Filename = component name.
24
+ - All files in `src/` concatenate into **one flat Lua chunk** — no `require()`, no module system.
25
+ - `local` variables from files compiled earlier are visible in files compiled later.
26
+ - Load order: `globals.lua` → `remotes.lua` → feature modules (alphabetical) → UI files → defaults runner.
27
+
28
+ ---
29
+
30
+ ## Component rules
31
+
32
+ ```rblua
33
+ component {
34
+ signal enabled = false -- reactive state
35
+ shared { Key = "value" } -- Pulse.Store cross-component entry
36
+ remote Foo = "Remotes/Foo" -- FireServer wrapper
37
+ invoke Bar = "Remotes/Bar" -- InvokeServer wrapper
38
+
39
+ ui {
40
+ toggle "Enable" -> enabled default=true tip="..."
41
+ slider "Radius" -> radius [50, 800]
42
+ dropdown "Mode" -> mode ["A","B"] default="B"
43
+ button "Reset" -> Reset()
44
+ }
45
+
46
+ init {
47
+ local _loop = Pulse.Loop.new(1.0, fn)
48
+ local function privateHelper() ... end -- PRIVATE
49
+ }
50
+
51
+ on enabled { ... } -- signal change (v = new value)
52
+ on Heartbeat when enabled { } -- service event with guard
53
+ on CharacterAdded { } -- fires on spawn/respawn
54
+ on InputBegan(input, gpe) { } -- user input
55
+
56
+ func Toggle() { enabled(not enabled()) } -- PUBLIC method
57
+ }
58
+ ```
59
+
60
+ **Private vs public:**
61
+ - `local function` in `init {}` = private (component-scoped)
62
+ - `func Name() {}` DSL = public (`Component:Name()` callable externally)
63
+ - `func.X = function()` inside `init {}` = **BANNED** (global pollution)
64
+
65
+ ---
66
+
67
+ ## Signal access
68
+
69
+ | Context | Read | Write |
70
+ |---|---|---|
71
+ | `on X {}` handlers | bare name `radius` (auto-mirrored) | `radius(newValue)` |
72
+ | `func {}` / `init {}` | `ComponentName.radius()` | `ComponentName.radius(newValue)` |
73
+ | Other component | `Aimbot.radius()` | `Aimbot.radius(true)` |
74
+
75
+ ---
76
+
77
+ ## Key globals
78
+
79
+ ```lua
80
+ _LocalPlayer -- game.Players.LocalPlayer
81
+ _PulseRS -- RunService
82
+ _PulseUIS -- UserInputService
83
+ _PulseGetChar() -- Character (nil-safe)
84
+ _PulseGetHRP() -- HumanoidRootPart (nil-safe)
85
+ func.GetCachedPlayers() -- cached player list (1.5 s TTL)
86
+ Pulse.Notify("msg", secs) -- in-game toast (preferred over _Library direct call)
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Key Pulse helpers
92
+
93
+ ```lua
94
+ -- Tasks / timing
95
+ Pulse.Loop.new(interval, fn) -- managed repeating task
96
+ Pulse.Cooldown.new(dur) -- shared cooldown
97
+ Pulse.Cooldown.perEntity(dur) -- per-entity cooldown with .purge(isDeadFn)
98
+
99
+ -- Connections / store
100
+ Pulse.Conn.bind("name", conn) -- named connection manager
101
+ Pulse.Conn.disconnect("name")
102
+ Pulse.Store.define/get/set/watch("key") -- cross-component reactive KV
103
+
104
+ -- Combat / targeting
105
+ Pulse.Aim.findNearest(list, opts) -- nearest entity search
106
+ Pulse.Aim.inFOV(pos, radius) -- FOV circle check
107
+ Pulse.Hitbox.new("tag") -- BasePart size-expansion manager
108
+ local r = Pulse.Team.resolver(opts) -- enemy/ally classifier (.isEnemy/.filter/.partition)
109
+
110
+ -- Drawing / ESP
111
+ Pulse.Draw.highlight(inst, "tag", opts)
112
+ Pulse.Draw.removeHighlight(inst, "tag")
113
+
114
+ -- Data / caching
115
+ Pulse.Restore.new() -- save/restore instance properties
116
+ Pulse.Cache.wrap(ttl, fn) -- timed caching of any function
117
+ Pulse.Track.new() -- entity lifecycle tracking
118
+
119
+ -- Notifications (always available)
120
+ Pulse.Notify("msg") -- instant toast
121
+ Pulse.Notify.onToggle(signal, "Name") -- auto on/off toast on signal change
122
+
123
+ -- Executor capability
124
+ Pulse.Memory.supports("writefile") -- bool: UNC fn exists
125
+ Pulse.Memory.requireFrom("Mod", "Child") -- safe Character child require
126
+
127
+ -- Input simulation
128
+ Pulse.Input.simulateKey(Enum.KeyCode.T)
129
+
130
+ -- Live debug monitor (always available)
131
+ Pulse.Monitor.set("key", value) -- track a named value in the debug GUI
132
+ Pulse.Monitor.tick("key") -- increment counter (stops = loop died)
133
+
134
+ -- Logging (dev-only; no-ops in prod)
135
+ Pulse.Log.info/warn/error("Tag", "msg")
136
+ Pulse.Log.throttle("Tag", 5, "debug", "msg") -- at most once per 5 s
137
+ Pulse.Log.watchSignal(signal, "Tag", "name") -- log every signal change
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Game-load guard
143
+
144
+ Wrap features that use Roblox services in `task.spawn` + load check when injecting before the game finishes loading:
145
+
146
+ ```lua
147
+ task.spawn(function()
148
+ if not game:IsLoaded() then game.Loaded:Wait() end
149
+ RS:BindToRenderStep("__Key__", Enum.RenderPriority.Last.Value, fn)
150
+ end)
151
+ -- cleanup bind outside spawn so it always fires
152
+ MyComponent:bind("_rs", { Disconnect = function() RS:UnbindFromRenderStep("__Key__") end })
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Obfuscator (Prometheus)
158
+
159
+ `rb/prometheus_config.lua` overrides the default preset when present. Exclude these steps — they break Roblox runtime:
160
+
161
+ | Step | Reason |
162
+ |---|---|
163
+ | `Vmify` | Breaks member-access patterns |
164
+ | `AntiTamper` | Requires `debug` library — unavailable in exploits |
165
+ | `EncryptStrings` | Corrupts strings used as service/member names |
166
+
167
+ Safe: `ConstantArray` (StringsOnly) + `NumbersToExpressions` + `WrapInFunction`.
168
+
169
+ ---
170
+
171
+ ## What NOT to do
172
+
173
+ - No `require()` — flat compilation
174
+ - No `func.X = function()` inside component `init {}` — use `local function`
175
+ - No `GetChildren()` in tight loops — use `func.GetCachedPlayers()` / cached helpers
176
+ - No game-specific code in `rb/pulse/helpers/` — framework is game-agnostic
177
+ - No `wait()` / `spawn()` — use `task.wait()` / `task.spawn()` / `task.delay()`
@@ -0,0 +1,424 @@
1
+ # CLAUDE.md — Pulse Framework Reference
2
+
3
+ > **Project:** `{NAME}` — Roblox script built with the **rb / Pulse** framework.
4
+ > **Architecture:** flat-compiled reactive DSL. All `.rblua` and `.lua` files in `src/` are concatenated into one Lua chunk at build time.
5
+ > Run `rb docs` to generate `PULSE_DOCS.md` in this directory for the full framework reference.
6
+
7
+ ---
8
+
9
+ ## Build commands
10
+
11
+ | Command | Description |
12
+ |---|---|
13
+ | `rb build` | Compile + obfuscate → `build/script.lua` |
14
+ | `rb build --no-obfuscate` | Compile only, no obfuscation |
15
+ | `rb copy` | Compile and copy to clipboard |
16
+ | `rb watch` | Auto-rebuild on file save |
17
+ | `rb lint` | Dead signals, ghost refs, orphan funcs |
18
+ | `rb docs` | Generate `PULSE_DOCS.md` full reference |
19
+ | `rb check` | Syntax-check compiled output |
20
+
21
+ ---
22
+
23
+ ## Project layout
24
+
25
+ ```
26
+ src/
27
+ misc/helpers/globals.lua ← compiled first — defines local func = {}
28
+ misc/remotes.lua ← func.Remote_X fire-server wrappers
29
+ <category>/<Name>.rblua ← components (one per feature)
30
+ ui/layout.rblua ← window title / size / toggle key
31
+ ui/pages/*.rblua ← tab layout (mount components)
32
+ build/
33
+ script.lua ← compiled output (never edit directly)
34
+ ```
35
+
36
+ ---
37
+
38
+ ## Component structure
39
+
40
+ ```rblua
41
+ component {
42
+ -- reactive state
43
+ signal enabled = false
44
+ signal radius = 400
45
+ signal mode = "Normal"
46
+
47
+ -- cross-component reactive store entry
48
+ shared {
49
+ GlobalKey = "defaultValue"
50
+ }
51
+
52
+ -- fire-server remote wrapper
53
+ remote Attack = "Remotes/Combat/Attack"
54
+
55
+ -- invoke-server remote wrapper (returns a value)
56
+ invoke GetStats = "Remotes/Combat/GetStats"
57
+
58
+ -- UI widgets (auto-wired to signals, compiled into Linoria)
59
+ ui {
60
+ toggle "Enable" -> enabled default=true tip="Tooltip text"
61
+ slider "Radius" -> radius [50, 800]
62
+ dropdown "Mode" -> mode ["Normal", "Big"] default="Big"
63
+ button "Reset" -> Reset()
64
+ separator
65
+ label "Section heading"
66
+ keybind "Toggle" key="F" -> Toggle()
67
+ }
68
+
69
+ -- constructor: private locals and helper functions
70
+ init {
71
+ local lockedTarget = nil
72
+
73
+ local function findTarget()
74
+ -- private: NOT accessible outside this component
75
+ end
76
+ }
77
+
78
+ -- signal change handler (v = new value)
79
+ on enabled {
80
+ if v then ... else ... end
81
+ }
82
+
83
+ -- service event handlers
84
+ on Heartbeat when enabled {
85
+ guard h = humanoid
86
+ guard r = hrp
87
+ }
88
+
89
+ on Heartbeat when enabled every 0.5 {
90
+ -- throttled to at most once per 0.5 s
91
+ }
92
+
93
+ on Heartbeat when enabled every interval {
94
+ -- throttle uses the 'interval' signal value dynamically
95
+ }
96
+
97
+ on CharacterAdded {
98
+ lockedTarget = nil
99
+ }
100
+
101
+ on CharacterRemoving {
102
+ -- cleanup before character is removed
103
+ }
104
+
105
+ on InputBegan(input, gpe) when enabled debounce 0.2 {
106
+ if gpe then return end
107
+ }
108
+
109
+ -- public method (callable as Component:Name() from anywhere)
110
+ func Toggle() {
111
+ enabled(not enabled())
112
+ }
113
+
114
+ func GetTarget() {
115
+ return lockedTarget
116
+ }
117
+ }
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Private vs public — the golden rule
123
+
124
+ | Pattern | Visibility | Use for |
125
+ |---|---|---|
126
+ | `local function name()` in `init {}` | Component-private | Internal helpers |
127
+ | `func Name() {}` DSL block | Public (Component:Name()) | API for other components |
128
+ | `func.X = function()` in `init {}` | **BANNED** — global pollution | Never |
129
+
130
+ The `func` table is a shared global used for cross-file helpers defined in `.lua` files.
131
+ Assigning `func.X` from inside a component's `init {}` pollutes that global. Always use `local function` instead.
132
+
133
+ ---
134
+
135
+ ## Signals — reading and writing
136
+
137
+ ```lua
138
+ -- Inside handlers (on X {}) — read as bare name (transpiler mirrors it)
139
+ on Heartbeat when enabled {
140
+ if radius > 500 then ... end -- bare read
141
+ radius(200) -- write (call as function)
142
+ }
143
+
144
+ -- Inside func {} blocks or init {} — call as function to read
145
+ func PrintState() {
146
+ print(enabled(), radius())
147
+ }
148
+
149
+ -- From another component
150
+ Aimbot.enabled(true) -- write
151
+ local r = Aimbot.radius() -- read
152
+ Aimbot:Toggle() -- call public method
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Events reference
158
+
159
+ | Name | Fires |
160
+ |---|---|
161
+ | `Heartbeat` | Every frame (~60 fps) |
162
+ | `RenderStepped` | Before camera renders |
163
+ | `Stepped` | Physics step |
164
+ | `InputBegan` | Key or mouse button pressed |
165
+ | `InputEnded` | Key or mouse button released |
166
+ | `CharacterAdded` | Player spawned or respawned |
167
+ | `CharacterRemoving` | Character about to be removed |
168
+ | `Respawn` | Legacy alias for CharacterAdded |
169
+ | `signalName` | When that signal changes (v = new value) |
170
+
171
+ **Modifiers:**
172
+
173
+ ```rblua
174
+ on Heartbeat when enabled { } -- skip if enabled is false
175
+ on Heartbeat every 0.5 { } -- throttle: at most once per 0.5 s
176
+ on Heartbeat every interval { } -- throttle using signal value
177
+ on Heartbeat when enabled debounce 0.3 { } -- cooldown after firing
178
+ on InputBegan(input, gpe) when enabled { } -- pass event params
179
+ after 2.5 { } -- delayed task (runs once on load)
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Guard — nil-safe early return
185
+
186
+ ```rblua
187
+ guard h = humanoid -- local h = humanoid; if not h then return end
188
+ guard r = hrp -- same for HumanoidRootPart
189
+ guard character -- return if falsy, no capture
190
+ ```
191
+
192
+ **Character refs** (auto-resolved anywhere in handlers):
193
+
194
+ | Name | Value |
195
+ |---|---|
196
+ | `humanoid` | `Character.Humanoid` |
197
+ | `hrp` | `Character.HumanoidRootPart` |
198
+ | `character` | `LocalPlayer.Character` |
199
+ | `alive` | `true` if Humanoid.Health > 0 |
200
+
201
+ ---
202
+
203
+ ## Pulse helpers
204
+
205
+ ```lua
206
+ -- Managed task loop
207
+ local _loop = Pulse.Loop.new(interval, fn)
208
+ _loop:start() _loop:stop() _loop:running() _loop:setInterval(n)
209
+ -- fn already wrapped in pcall; return false from fn to self-stop
210
+
211
+ -- Cooldowns
212
+ local cd = Pulse.Cooldown.new(1.0) -- single shared cooldown
213
+ cd:ready() cd:use() cd:reset() cd:set(dur)
214
+
215
+ local pcd = Pulse.Cooldown.perEntity(0.5) -- one timer per entity key
216
+ pcd:ready(key) pcd:use(key) pcd:reset(key) pcd:set(dur)
217
+ pcd:purge(isDeadFn) -- drop entries where fn(key) is true
218
+
219
+ -- Named connection manager
220
+ Pulse.Conn.bind("Name", connection) -- registers + auto-disconnects old
221
+ Pulse.Conn.disconnect("Name")
222
+ Pulse.Conn.disconnectAll()
223
+
224
+ -- Cross-component reactive KV store
225
+ Pulse.Store.define("Key", defaultValue)
226
+ Pulse.Store.get("Key")
227
+ Pulse.Store.set("Key", value)
228
+ Pulse.Store.watch("Key", fn)
229
+ Pulse.Store.signal("Key") -- returns the raw Signal
230
+
231
+ -- Targeting / aiming
232
+ Pulse.Aim.inFOV(worldPos, pixelRadius) -- bool: is position inside FOV circle?
233
+ Pulse.Aim.lookAt(worldPos) -- snap camera to world position
234
+ Pulse.Aim.findNearest(list, {
235
+ maxDist = 500,
236
+ fovRadius = radius(),
237
+ filter = function(e) return not func.IsDead(e) end,
238
+ getRoot = function(e) return e:FindFirstChild("HumanoidRootPart") end,
239
+ origin = someVector3, -- defaults to local player HRP
240
+ })
241
+
242
+ -- Drawing / ESP
243
+ Pulse.Draw.highlight(instance, "Tag", {
244
+ fill = Color3.fromRGB(255,255,0), outline = Color3.fromRGB(255,0,0),
245
+ fillAlpha = 0.5, alwaysOnTop = true,
246
+ })
247
+ Pulse.Draw.removeHighlight(instance, "Tag")
248
+ local circle = Pulse.Draw.circle({ radius=300, color=Color3.new(1,1,1), thickness=2, alpha=0.8 })
249
+ circle.Position = Vector2.new(cx, cy)
250
+ Pulse.Draw.remove(circle)
251
+
252
+ -- Timed cache
253
+ local getTitans = Pulse.Cache.wrap(1.5, function()
254
+ return workspace.Titans.Alive:GetChildren()
255
+ end)
256
+
257
+ -- Save / restore instance properties
258
+ local r = Pulse.Restore.new()
259
+ r:save(part, "Size") -- store current value
260
+ r:one(part, "Size") -- restore one property
261
+ r:all() -- restore everything
262
+ r:has(part, "Size") -- bool
263
+
264
+ -- Entity lifecycle tracking
265
+ local tracker = Pulse.Track.new()
266
+ tracker:apply(entity, cleanupFn) -- track + register cleanup
267
+ tracker:remove(entity) -- remove + run cleanup
268
+ tracker:cleanup(isDeadFn) -- remove all where predicate is true
269
+ tracker:clear() -- remove everything
270
+ tracker:has(entity) -- bool
271
+ tracker:count()
272
+ tracker:each(fn)
273
+
274
+ -- Logging (dev-only — no-ops in prod; levels: trace < debug < info < warn < error)
275
+ Pulse.Log.trace("Tag", "msg") Pulse.Log.debug("Tag", "msg")
276
+ Pulse.Log.info("Tag", "msg") Pulse.Log.warn("Tag", "msg") Pulse.Log.error("Tag", "msg")
277
+ Pulse.Log.assert(cond, "Tag", "msg") -- logs ERROR if cond is false
278
+ Pulse.Log.throttle("Tag", 5, "debug", "msg") -- at most once per 5 s; safe in loops
279
+ Pulse.Log.watchSignal(signal, "Tag", "name") -- log every signal change
280
+ Pulse.Log.snapshot("Tag", "label", tbl) -- dump table as debug entry
281
+ Pulse.Log.configure({ level="debug", file="dev.log", tags={"Aimbot"} })
282
+ Pulse.Log.save("pulse_log.txt") -- write buffer to file
283
+ Pulse.Log.dump() -- return buffer as string
284
+ Pulse.Log.clear()
285
+
286
+ -- Live debug monitor (always available — use in Heartbeat loops to prove execution)
287
+ Pulse.Monitor.set("key", value) -- set a named live value
288
+ Pulse.Monitor.tick("key") -- increment counter (stops incrementing = loop died)
289
+ Pulse.Monitor.get("key") -- read one value
290
+ Pulse.Monitor.getAll() -- { key=value, ... }
291
+
292
+ -- Notifications (always available)
293
+ Pulse.Notify("Message") -- instant toast (3 s)
294
+ Pulse.Notify("Message", 5) -- custom duration
295
+ Pulse.Notify.onToggle(signal, "FeatureName") -- auto "on"/"off" toast on toggle
296
+ Pulse.Notify.onToggle(signal, "AutoFarm", {
297
+ on="AutoFarm started", off="AutoFarm stopped", duration=5,
298
+ }) -- returns unsubscribe fn
299
+
300
+ -- Hitbox expansion (game-agnostic BasePart size manager)
301
+ local hm = Pulse.Hitbox.new("tag")
302
+ hm:apply(part, 30) -- expand to 30×30×30, saves original on first call
303
+ hm:restore(part) -- restore to saved size
304
+ hm:restoreAll() -- restore all managed parts
305
+ hm:isExpanded(part) -- bool
306
+
307
+ -- Key simulation
308
+ Pulse.Input.simulateKey(Enum.KeyCode.T)
309
+
310
+ -- Executor capability checks
311
+ Pulse.Memory.supports("writefile") -- bool: UNC function exists
312
+ Pulse.Memory.testWritable(tbl, key) -- bool: field is actually writable
313
+ Pulse.Memory.requireFrom("ODMG", "Client", "Memory") -- safe Character child require
314
+
315
+ -- Enemy/ally resolver factory
316
+ local r = Pulse.Team.resolver({
317
+ isSelf = function(e) return e == _LocalPlayer end,
318
+ isValid = function(e) return e.Character ~= nil end,
319
+ isHostile = function(e) return func.IsEnemy(e) end,
320
+ exclude = { func.IsFriendly },
321
+ })
322
+ r:isEnemy(player) -- bool
323
+ r:isAlly(player) -- bool
324
+ r:filter(playerList) -- enemies only
325
+ r:partition(playerList) -- allies, enemies
326
+
327
+ -- Frame-time sampler (call Pulse.Perf.tick() in a Heartbeat to track perf)
328
+ Pulse.Perf.tick() -- sample current frame time
329
+ Pulse.Perf.avg() -- average frame time in seconds
330
+ Pulse.Perf.fps() -- estimated FPS
331
+ Pulse.Perf.setThreshold(50) -- warn when avg > 50 ms
332
+
333
+ -- Workspace navigation
334
+ Pulse.World.find("Folder", "SubFolder") -- nil if missing
335
+ Pulse.World.children("Folder", "SubFolder") -- {} on failure
336
+ Pulse.World.await(parent, "ChildName", timeout)
337
+
338
+ -- Vec helpers
339
+ Pulse.Vec.flatDir(from, to, fallback) -- XZ-plane normalized direction
340
+ ```
341
+
342
+ ---
343
+
344
+ ## Globals available everywhere
345
+
346
+ ```lua
347
+ _LocalPlayer -- game.Players.LocalPlayer
348
+ _PulseRS -- game:GetService("RunService")
349
+ _PulseUIS -- game:GetService("UserInputService")
350
+ _PulseGetChar() -- LocalPlayer.Character (nil-safe)
351
+ _PulseGetHRP() -- Character.HumanoidRootPart (nil-safe)
352
+ _PulseGetHumanoid() -- Character.Humanoid (nil-safe)
353
+ _PulseGetAlive() -- bool: health > 0
354
+
355
+ func.GetCachedPlayers() -- cached player list (1.5 s TTL)
356
+ func.GetCachedTitans() -- cached titan list (game-specific, if defined)
357
+
358
+ _Library -- WindUI library instance (ui_library = "windui" default)
359
+
360
+ Components.Name -- access any component by name
361
+ ```
362
+
363
+ ---
364
+
365
+ ## Flat compilation order
366
+
367
+ 1. `rb/pulse/runtime.lua` + `rb/pulse/helpers/*.lua` — framework (auto-injected)
368
+ 2. `rb/adapters/windui.lua` — UI adapter (auto-injected; controlled by `ui_library` in layout.rblua, defaults to `"windui"`)
369
+ 3. `src/misc/helpers/globals.lua` — your bootstrap (`local func = {}` etc.)
370
+ 4. `src/misc/remotes.lua` — remote wrappers
371
+ 5. All other `src/**/*.rblua|.lua` — alphabetical by path
372
+ 6. `src/ui/layout.rblua` then `src/ui/pages/*.rblua` — UI wiring
373
+ 7. Generated `_DEFAULTS_RUNNER` — applies all `default=` values after 0.5 s
374
+
375
+ **Key consequence:** `local` variables from earlier files **are** visible in later files as Lua upvalues. This is intentional — `func.GetCachedPlayers` defined in `globals.lua` is accessible everywhere.
376
+
377
+ ---
378
+
379
+ ## Game-load guard
380
+
381
+ For features that activate Roblox services that may not be ready when the script is injected early, defer activation with:
382
+
383
+ ```lua
384
+ init {
385
+ task.spawn(function()
386
+ if not game:IsLoaded() then game.Loaded:Wait() end
387
+ -- safe to use RunService, workspace services, etc. here
388
+ RS:BindToRenderStep("__Key__", Enum.RenderPriority.Last.Value, function()
389
+ -- ...
390
+ end)
391
+ end)
392
+
393
+ -- cleanup bind OUTSIDE spawn so it always fires even if load hasn't completed
394
+ MyComponent:bind("_rs", { Disconnect = function()
395
+ RS:UnbindFromRenderStep("__Key__")
396
+ end })
397
+ }
398
+ ```
399
+
400
+ ---
401
+
402
+ ## Obfuscator config (Prometheus)
403
+
404
+ If `rb/prometheus_config.lua` exists it overrides the default `--preset`. Exclude steps that break the runtime:
405
+
406
+ | Step | Why to exclude |
407
+ |---|---|
408
+ | `Vmify` | Breaks Roblox member-access patterns at runtime |
409
+ | `AntiTamper` | Uses `debug` library — unavailable in exploit environments |
410
+ | `EncryptStrings` | Strings used as service/member names are corrupted → `X is not a valid member` errors |
411
+
412
+ Minimal safe set: `ConstantArray` (StringsOnly), `NumbersToExpressions`, `WrapInFunction`.
413
+
414
+ ---
415
+
416
+ ## What NOT to do
417
+
418
+ - **Do not** use `require()` anywhere — flat compilation, no module system
419
+ - **Do not** assign `func.X = function()` inside a component's `init {}` — use `local function`
420
+ - **Do not** call `GetChildren()` in tight loops — use `func.GetCachedPlayers()` / `func.GetCachedTitans()`
421
+ - **Do not** put game-specific code in `rb/pulse/helpers/` — it is a game-agnostic framework library
422
+ - **Do not** use `Components.SomeComponent.x()` to reference your **own** component's signals — use `ComponentName.x()` directly
423
+ - **Do not** use `wait()` or `spawn()` — always use `task.wait()` / `task.spawn()` / `task.delay()`
424
+ - **Do not** nest `WaitForChild` chains inside loops or callbacks — cache at the top of `init {}`
@@ -0,0 +1,17 @@
1
+ # .rb-deploy — GitHub deployment config for rb deploy
2
+ # Copy this file to .rb-deploy and fill in your details.
3
+ # .rb-deploy is gitignored — never commit it (it contains your token).
4
+
5
+ # GitHub Personal Access Token — needs 'repo' and 'contents' scope
6
+ # Create one at: https://github.com/settings/tokens
7
+ GITHUB_TOKEN=ghp_your_token_here
8
+
9
+ # The GitHub repo to push the obfuscated script to
10
+ # Create a separate empty public repo for this (e.g. "yourname/my-script-release")
11
+ GITHUB_REPO=yourname/my-script-release
12
+
13
+ # Filename in the repo (default is fine)
14
+ GITHUB_FILE=script.obf.lua
15
+
16
+ # Branch to push to
17
+ GITHUB_BRANCH=main
@@ -0,0 +1,69 @@
1
+ -- PlayerESP — example component. Customize or delete this file.
2
+ component {
3
+ signal enabled = false
4
+
5
+ init {
6
+ Pulse.Notify.onToggle(PlayerESP.enabled, "Player ESP")
7
+
8
+ local _CoreGui = game:GetService("CoreGui")
9
+ local _Players = game:GetService("Players")
10
+ local _highlights = {}
11
+
12
+ local function _addHighlight(player)
13
+ if not player.Character then return end
14
+ if _highlights[player] then return end
15
+ local hl = Instance.new("Highlight")
16
+ hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
17
+ hl.FillColor = Color3.fromRGB(255, 60, 60)
18
+ hl.FillTransparency = 0.4
19
+ hl.OutlineColor = Color3.fromRGB(255, 60, 60)
20
+ hl.Adornee = player.Character
21
+ hl.Parent = _CoreGui
22
+ _highlights[player] = hl
23
+ Pulse.Log.trace("PlayerESP", "highlighted", { name = player.Name })
24
+ end
25
+
26
+ local function _removeHighlight(player)
27
+ if _highlights[player] then
28
+ _highlights[player]:Destroy()
29
+ _highlights[player] = nil
30
+ end
31
+ end
32
+
33
+ local function _clearAll()
34
+ for _, hl in pairs(_highlights) do hl:Destroy() end
35
+ _highlights = {}
36
+ end
37
+
38
+ local _loop = Pulse.Loop.new(1.0, function()
39
+ for _, player in ipairs(func.GetCachedPlayers()) do
40
+ if player ~= _Players.LocalPlayer then
41
+ _addHighlight(player)
42
+ end
43
+ end
44
+ end)
45
+
46
+ local function espLoop(value)
47
+ if value then
48
+ _loop:start()
49
+ Pulse.Log.info("PlayerESP", "started")
50
+ else
51
+ _loop:stop()
52
+ _clearAll()
53
+ Pulse.Log.info("PlayerESP", "stopped")
54
+ end
55
+ end
56
+ }
57
+
58
+ on enabled { espLoop(v) }
59
+
60
+ on CharacterAdded {
61
+ if not enabled then return end
62
+ _clearAll()
63
+ _loop:start()
64
+ }
65
+
66
+ ui {
67
+ toggle "Player ESP" -> enabled tip="Highlight all players through walls"
68
+ }
69
+ }