Find which script work caused a slow frame
Use profiler record to capture a reproducible action, inspect the resulting timeline, and compare a second capture after a focused change. The command is profiler, not profile. A capture is evidence about the work recorded in that process, not a universal score for the server.
Accessing the Profiler
Choose the context that exhibits the problem. Use F8 for a client capture or the FXServer console for a server capture. A client capture does not measure all server-side work, and a server capture does not explain every GPU or asset-streaming stall on a player’s computer.
On a development environment where the commands are available, enter:
profiler record 500
profiler status500 is the number of frames, not milliseconds or seconds. Start the recording immediately before the slow action. The same frame count can cover different wall-clock durations at different frame rates.
When recording has completed:
profiler view
profiler saveJSON before-menu-open.jsonKeep the relevant process alive when using the viewer. Server-side viewing provides a link to open in a browser; follow the console output for the capture location. Save the JSON before restarting, and retain the conditions under which it was recorded.
If a command is denied or unavailable, inspect the official client developer-mode requirements and confirm that you are using the intended console. Do not change random convars to bypass a restriction on someone else’s server.
Follow one slow action through the timeline
Suppose a menu briefly freezes gameplay. First open it a few times to understand whether only the initial open is slow. Record an initial-load scenario separately from a warmed-up scenario. Mixing the two can make an unchanged implementation look improved.
In the viewer, locate the frame associated with the action. Expand the relevant resource and function stack. Ask whether the cost comes from many repetitions of a small operation, one large operation, or work unexpectedly happening while the feature is idle.
The next change should answer that observation. For example, fetching a stable resource configuration once at startup is different from increasing a loop’s wait interval. A per-frame drawing call may require every frame; an unchanged configuration lookup does not.
Repeat a comparable capture
After one change, repeat the same action under the same conditions:
profiler record 500
profiler statusAfter completion:
profiler saveJSON after-menu-open.json
profiler viewRecord a small comparison note alongside both files:
Scenario: open the same menu after warm-up
Context: client or server
Artifact/client build:
Resource revision before / after:
Approximate player count:
Repeated action count:
Observed slow frame and function:
Change made:
Does the intended gameplay behavior still work?:Repeat the measurement rather than treating a single fast capture as proof. Changes in players, location, warm caches, game build, or unrelated resources can explain differences. There is no universal millisecond budget in this guide because the feature and environment determine what is acceptable.
Common interpretation mistakes
| Mistake | Better interpretation |
|---|---|
Wait(0) appears in a loop | Inspect the loop’s work; frame-dependent rendering may require it |
| Resource monitor looks quiet but the game stutters | Investigate assets, rendering, and other diagnostics as well |
| Before capture includes first-load work; after does not | Repeat both scenarios with equivalent warm-up |
| A function’s name looks suspicious | Inspect when, how often, and for how long it ran |
| A faster timer breaks controls or UI | The optimization is not successful if behavior regresses |
Sources and next steps
The official profiler guide defines the commands and viewer workflow. Use Lua scheduling for choosing events versus loops, resource lifecycle for cleanup, and client diagnostics for issues outside script timing.