---
title: Instance
nav_order: 4
---

# Instance

All Instances are userdata with methods below. `game` / `workspace` refresh each execute.

## Methods

```lua
instance:GetChildren(): { Instance }
instance:GetDescendants(): { Instance }          -- capped
instance:FindFirstChild(name: string): Instance?
instance:FindFirstChildOfClass(className: string): Instance?
instance:FindFirstChildWhichIsA(className: string): Instance?
instance:IsA(className: string): boolean
instance:IsDescendantOf(ancestor: Instance): boolean
instance:WaitForChild(name: string, timeout: number?): Instance?
instance:GetFullName(): string
instance:GetService(name: string): Instance | table | nil
instance:GetPlayers(): { Instance }              -- useful on Players
instance:GetAttribute(name: string): any
instance:SetAttribute(name: string, value: any)
instance:GetAttributes(): { [string]: any }
instance:GetPropertyChangedSignal(prop: string): RBXScriptSignal
instance:Fire(...): void   -- BindableEvent / ProximityPrompt only (local VM)
```

### Fire

```lua
bindable:Fire(...)           -- fires bindable.Event
prompt:Fire()                -- fires prompt.Triggered (LocalPlayer.Name)
prompt:Fire("Name")
```

Does **not** run real Roblox listeners. See [Signals](signals.md) for Bus listen on the test place.

### FindFirstChild / WaitForChild

Match **Name or ClassName** (helps when Name read is weird for services like Workspace).

### IsA

Exact class, plus limited inheritance:

- `Instance` — always
- `BasePart` / `PVInstance` — Part, MeshPart, Seat, …
- `GuiObject` / `GuiBase*` — Frame, TextLabel, …
- `ValueBase` — *Value classes
- `Model`, `LuaSourceContainer`, `Accoutrement`, `Tool`, `LayerCollector`

### Attributes

- Read: real attribute map + fake overlay
- `SetAttribute` for **new** keys → fake only (does not allocate Roblox map)
- Existing real keys: bool/number can be written through

## Properties (common)

| Prop | Notes |
|------|--------|
| `Name` | string |
| `ClassName` | string |
| `Address` | number (debug) |
| `Parent` | Instance? — writable; `nil` unparents |
| child name | `inst.ChildName` via `__index` |

### Signals on Instance

| Class | Signal / API |
|-------|----------------|
| any | `ChildAdded`, `ChildRemoved`, `DescendantAdded` |
| `BindableEvent` | `.Event`, `:Fire(...)` |
| `RemoteEvent` / `UnreliableRemoteEvent` | `.OnClientEvent` (no `FireServer` yet) |
| `ProximityPrompt` | `.Triggered`, `:Fire(...)` |

Details: [Signals](signals.md).

## By class

**DataModel:** `PlaceId`, `GameId`, `JobId`, `Workspace`  
**Players:** `LocalPlayer`, `PlayerAdded`, `PlayerRemoving`  
**Player:** `Character`, `CharacterAdded`, `DisplayName`, `UserId`, `Team`  
**Workspace:** `CurrentCamera`  
**Camera:** `FieldOfView` (r/w)  
**Lighting:** Brightness, ClockTime, Fog*, Ambient*, GlobalShadows (r/w)  
**BasePart:** Position, Size, CFrame, Transparency, Anchored, Velocity / Assembly*Velocity; write Position/Size/Transparency/Anchored/Velocity/CanCollide/Color  
**Humanoid:** Health, MaxHealth, WalkSpeed, DisplayName, RootPart; write Health/MaxHealth/WalkSpeed/JumpPower/JumpHeight  
**ValueBases:** `.Value` (StringValue write only short SSO &lt; 16)  
**BindableEvent / ProximityPrompt / RemoteEvent:** see table above

## Instance.new

```lua
Instance.new(className: string, parent: Instance?): Instance?
```

Works. Goes through **CallGate** — the bridge hijacks the implementation pointer of one currently-hot `BoundFuncDesc` slot (tries `IsA`, `FindFirstChild`, `GetChildren`, `WaitForChild`, `FindFirstChildOfClass`, `GetDescendants`, `GetAttribute`, `Clone`, in that order) so the class constructor actually runs **on the real game thread**, not from outside. Re-running the cheat without restarting Roblox is safe: it recognizes and unwraps its own leftover hook from a previous run, and if the candidate slot turns out cold (nothing calls it) it silently moves on to the next candidate.

Verified against 56 Roblox classes (`scripts/instance_new_test.lua`): 54–56 / 56 create successfully depending on run.

**⚠️ Known limitation — no rendering.** Objects created via `Instance.new` genuinely exist in the game's memory: they are correctly parented, `Anchored` / `Position` / `Size` / other properties read back correctly, `GetChildren` on the real parent finds them. But the geometry is **not picked up by the render pipeline** — created parts/meshes/effects stay invisible in the 3D viewport. This is an open problem, not a stub; do not rely on visually seeing objects created this way.

Two classes fail with `"unknown class"` (not found by name in the reflection table) and cannot be created:

- `ColorCorrectionEffect`
- `DepthOfFieldEffect`

On failure `Instance.new` returns `nil` and prints a reason:

| Reason | Meaning |
|--------|---------|
| `unknown class` | class name not in the reflection table (e.g. the two above) |
| `not creatable` | class exists but is abstract/service, engine refuses to construct it |
| `no call gate` / `gate timeout` | CallGate not installed / engine never hit the hijacked slot in time |
| `create timeout` / `create returned junk` | constructor call went through CallGate but didn't return a usable instance |
| `parent failed` | object was created but parenting via CallGate failed |

```lua
local part = Instance.new("Part", workspace)
part.Anchored = true
part.Position = Vector3.new(0, 50, 0)
-- part exists, is parented, has correct properties — but won't be visible
```

### Setting Parent

```lua
inst.Parent = otherInstance   -- reparent, also goes through CallGate
inst.Parent = nil             -- unparent
```

Reparenting an instance created by hand or fetched from the tree uses the same CallGate mechanism as `Instance.new`'s own parenting step, so it has the same reliability characteristics (falls back to a direct write if the gate call fails).

### Writing strings / Content fields

There is no per-property `SetContent`/`SetString` method on the Instance userdata. Instead, raw string and `Content` fields (e.g. a `Sky` face texture, `Decal.Texture`) are written directly by address with the low-level [`mem`](memory.md) primitives:

```lua
local at = addrof(sky)
wrcontent(at + 0xf8, "rbxassetid://15536110634")  -- Sky.SkyboxBk, for example
```

See [Memory](memory.md) for `wrstr` / `wrcontent` and the rest of the raw memory API, and `scripts/custom_skybox.lua` / `scripts/weather.lua` for worked examples (including the explicit cache-invalidation Content writes need).
