Skip to content

The profiler

The profiler records what every frame did: the scopes each thread ran, the passes the GPU ran, and the device’s counters (draws, render passes, binds, GPU memory). You read it in three places: the editor’s Profiler page, an overlay in a running game, and capture files you can open later in the editor or in Perfetto.

The profiler is in every build except Shipping. In a Shipping build none of this shows and nothing is recorded.

View > Profiler opens the Profiler as a page, a tab beside the pages you have open. Like any page, it can be docked elsewhere or floated in its own window.

The Profiler page after a recording: the toolbar, the frame strip with its counter plots, the timeline of the chosen frame, and the scope table.

It records the editor process as a whole: every open page, every viewport preview and every Play-in-editor game share one frame. Its numbers are the editor’s, not one game’s. To measure a game on its own, profile its player (see Capture files).

  • Record starts recording, and pressing it again stops. View > Profiler Record does the same. The recording keeps the last 3,600 frames, about a minute at 60 frames a second.
  • Live shows the editor’s own recording and follows its newest frame. Choosing a frame on the strip stops following; Live starts it again.
  • Open shows a capture from the profiles folder, such as one copied from another machine. Opening a capture stops a recording.
  • Clear drops the recorded frames. A recording goes on from the next frame.
  • Save writes the recording as a capture to the profiles folder (see Capture files).
  • Budget (30, 60 or 120 frames a second, or None; 60 by default) is the frame time the strip measures each frame against.
  • Stop on spike stops recording at the first frame that takes longer than the time beside it (25, 33, 50 or 100 ms; 50 by default), and chooses that frame.

Under the toolbar, the frame strip shows each frame’s CPU time as a bar, coloured by whether the frame is within the budget, over it, or over twice it. Under the strip, a plot per counter shows its value in the same frames.

  • Click a frame to choose it, or drag across the strip to choose a range.
  • Longest and Median choose the longest frame and the frame of the median time.
  • Scroll the wheel to zoom about the pointer, and drag with the middle button to pan. Double-click to show every frame again.

The rest of the page shows the chosen frames.

The timeline shows the chosen frames on one time axis. Each thread has a lane, its scopes stacked by how deeply they nest, and the GPU has a lane for its passes.

  • Scroll the wheel to zoom about the pointer, and drag to pan. Hold Shift and scroll to move through the lanes.
  • Double-click a scope to zoom to it, a lane’s name to zoom to the lane, or empty space to show the frames again.
  • Hover a scope to see its name and how long it took. Click it to choose its name: every run of it lights up, and the table and the detail show it.
  • Drag along the ruler at the top to mark a span and read its length; the table then covers only that span. Click the ruler to clear it.
  • Click the arrow beside a lane’s name to fold the lane.

Under the timeline, the table lists the scopes and GPU passes in the chosen frames. By default it is a call tree: each thread and the GPU is a group, and each scope sits under the scope it ran in. Its columns are the calls, the total time, the self time (the total without the scopes inside it), the mean and longest call, and the share of the frames’ time. Click a heading to sort by it as a flat list, and click it again to reverse the order. The filter box keeps the names that contain its text. Click a row to choose that name.

Beside the table, the detail shows the chosen name on its own: its calls, total, mean and longest time, the lanes it ran in, what called it, its children with their share of its time, and a histogram of how long its calls took. Zoom to longest shows its longest call on the timeline.

A running game can show the profiler over itself: the frame times as a graph, the frame statistics, the scopes and GPU passes that took longest, and the counters. It sits in the top right corner and never takes the mouse from the game.

  • Press F3 to show or hide it.
  • Start a player with --profile-overlay to show it from the start.
  • In a browser, add ?profile-overlay to the page’s address.

Play in editor runs the game inside the editor, so F3 works there too, but the overlay then shows the whole editor, like the Profiler page.

A game can show the overlay from a script, from its own debug menu for example. run.profilerAvailable() is false in Shipping builds, so use it to hide the menu entry there. Both calls are safe in every build; in Shipping, run.setProfilerOverlay does nothing.

if run.profilerAvailable() then
run.setProfilerOverlay(true)
end

A capture is a few seconds of frames saved to a file, so a game can be profiled where it runs and read somewhere else.

  • In a running game, press F9 to capture the next five seconds.
  • Start a player with --profile-capture <seconds> to capture from the start.
  • In the editor, Save on the Profiler page writes the recording.

Each capture is two files in the profiles folder of the user data folder (~/.local/share/assiduousengine/profiles on Linux, %LOCALAPPDATA%\assiduousengine\profiles on Windows and ~/Library/Application Support/assiduousengine/profiles on macOS), named after the game (or Editor) and the time it was taken:

  • The .aeprofile file opens in the editor’s Profiler page with Open. To read a capture from another machine, copy it into that folder.
  • The .json file beside it holds the same frames as a Chrome trace. Open it in Perfetto or chrome://tracing.

A game running in a browser writes its captures to the page’s own storage, so you cannot open them from the editor.

An agent connected to the editor can take a capture with the profiler_capture tool, which answers with the frame times and the scopes and passes that took longest. See What agents can do.