---
title: Signals
nav_order: 5
---

# Signals

All signals are plain tables (not Roblox userdata):

```lua
local c = signal:Connect(fn)   -- RBXScriptConnection
signal:Once(fn)
local ... = signal:Wait()      -- yields; resumes with fire args
signal:Fire(...)               -- local VM only
c:Disconnect()
```

Each new script execute **clears** previous `Connect` / `Once` / `Wait` hooks (no stacking across runs).

## Sources

| Signal | Args | How it fires |
|--------|------|----------------|
| `RunService.Heartbeat` / `RenderStepped` / `Stepped` | `dt` | tick (all three share one kind) |
| `Players.PlayerAdded` / `PlayerRemoving` | `player` | polled |
| `Player.CharacterAdded` | `character` | polled |
| `UserInputService.InputBegan` / `InputEnded` | `input`, `gameProcessed` | polled keys |
| `Instance.ChildAdded` / `ChildRemoved` | `child` | polled |
| `Instance.DescendantAdded` | `descendant` | polled, throttled |
| `GetPropertyChangedSignal(prop)` | *(none)* | polled subset of props |
| `BindableEvent.Event` | fire args | `:Fire` / `Event:Fire` |
| `RemoteEvent.OnClientEvent` | args | local `:Fire` **or** test Bus `OE` |
| `ProximityPrompt.Triggered` | player name (string) | local `:Fire` **or** test Bus `PX` |

## Fire (local VM)

Works **everywhere** — only wakes Connects inside the cheat VM (not real Roblox scripts).

```lua
-- BindableEvent
be.Event:Connect(function(...) end)
be:Fire(1, "hi")
be.Event:Fire(1, "hi")

-- ProximityPrompt
prompt.Triggered:Connect(function(playerName) end)
prompt:Fire()              -- arg = LocalPlayer.Name
prompt:Fire("Someone")
prompt.Triggered:Fire("Someone")

-- RemoteEvent (client-side test)
remote.OnClientEvent:Connect(function(...) end)
remote.OnClientEvent:Fire("local", 123)

-- remote:FireServer / InvokeServer — not wired
```

`instance:Fire(...)` is only valid on `BindableEvent` and `ProximityPrompt`.

## Listening to real game remotes / prompts (test stand)

External VM cannot attach to native Roblox signals. For the **SpitariTest** place, a LocalScript writes a small Bus; the cheat polls it.

```
ReplicatedStorage.SpitariTest.Bus
  Seq (IntValue)
  Payload (StringValue)
```

Protocol (tab-separated), then `Seq = Seq + 1`:

| Kind | Payload example | Cheat signal |
|------|-----------------|--------------|
| `OE` | `OE	Ping	server_tick	12.3` | `Ping.OnClientEvent` |
| `PX` | `PX	JP_Prompt	Player1` | `JP_Prompt.Triggered` |

Bridge script (Studio only, not for cheat executor):

`scripts/spitari_bridge_localscript.lua`

Smoke:

`scripts/remote_listen_test.lua`

## Input object shape

```lua
input.KeyCode.Name          -- "Space", "A", …
input.KeyCode.Value         -- VK
input.UserInputType.Name    -- "Keyboard", "MouseButton1", …
```

`gameProcessed` is always `false` for now.

## Polling notes

- Hierarchy / players / props / input are **polled**, not native Roblox events
- `DescendantAdded` is throttled — avoid hanging it on huge `workspace` trees
- `GetPropertyChangedSignal` polls: `Name`, `ClassName`, `Parent`, ValueBases, Humanoid health/speed, …

## Example

```lua
local rs = game:GetService("RunService")

local c = rs.Heartbeat:Connect(function(dt)
    -- every frame
end)

task.spawn(function()
    local dt = rs.Heartbeat:Wait()
    print("got", dt)
end)

rs.RenderStepped:Once(function()
    print("once")
end)
```
