Watch any Luau expression over time (live value monitor)
watch-valueSample any Luau expression over a bounded window, logging every value and exact change times to verify, time, or debug in-game state.
Instructions
Sample ANY Luau expression repeatedly over a bounded window and report every value it took plus exactly when it changed — a live memory/state monitor for reverse-engineering and debugging. Give an expression that returns a value (no return keyword needed) and the tool compiles it once with loadstring, then polls it on a fixed interval until the duration elapses, recording the first sample and every subsequent change. Use it to confirm a value actually mutates when you trigger an action (watch leaderstats coins tick up, a Humanoid's Health drop, an anti-cheat flag flip, a getgenv() speed multiplier, a remote-cooldown timer, or a metatable hook's hit counter), to time how fast something updates, or to prove a suspected variable is the one that drives a behavior. EXAMPLES: 'game.Players.LocalPlayer.leaderstats.Coins.Value', 'getgenv().speed', 'workspace.CurrentCamera.CFrame.Position', '#getconnections(game.Workspace.Part.Touched)', 'tostring(getgenv().__mcp_remotespy and #getgenv().__mcp_remotespy.logs)'. The expression is evaluated as return <expression>, so it can be any value-producing Luau (indexing, function calls, arithmetic, concatenation). Each sample is stringified for transport (Instances become GetFullName()). Change detection compares the live value with the previous one via ~=, so it catches identity changes for tables/Instances and equality changes for scalars. IMPORTANT: this call BLOCKS in-client for roughly durationMs while it samples (it is inherently synchronous), so keep durations short and perform the triggering action shortly before or during the watch. Everything is fully pcall-guarded: a compile error returns { error } immediately, and a per-tick evaluation error is recorded as a sample value rather than aborting the loop. Returns { expression, intervalMs, durationMs, sampleCount, changeCount, truncated, samples = [{ t, value, changed, ok }] }. Signature: { expression: string, intervalMs: any?, durationMs: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-event-snapshot. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| durationMs | No | Total time to watch in milliseconds (default: 5000, clamped 50..30000). The call blocks in-client for about this long; the network timeout is set to durationMs + 10000 so the loop finishes before the round-trip times out. | |
| expression | Yes | Any Luau expression that returns a value (do NOT prefix with `return` — the tool adds it). Examples: 'game.Players.LocalPlayer.leaderstats.Coins.Value', 'getgenv().speed', 'workspace.CurrentCamera.FieldOfView', '#getconnections(game.Workspace.Part.Touched)'. | |
| intervalMs | No | Polling interval in milliseconds between samples (default: 200, clamped 20..5000). Smaller catches fast transitions but produces more samples and more in-client overhead. | |
| threadContext | No | Optional Roblox thread identity for this call; omit it to use the server default. |