---
title: "The debug overlay"
url: https://recursiveai.org/onegame/cookbook/debug-overlay/
description: "Show frame time, tick, entity count, network and audio figures over a running C# game with onegame’s debug overlay, toggle it with F3 or a gamepad chord…"
version: "1.5.1"
---

# The debug overlay

Show frame time, tick, entity count, network and audio figures over a running C# game with onegame’s debug overlay, toggle it with F3 or a gamepad chord, capture it in a screenshot test, and keep it out of release builds.

New in 1.5.0. A development build of a game has an on-screen panel in the top-right corner. Press F3, or hold Back and Start on a gamepad, to show or hide it. It reads only what live control already reports: the frame time (current, min, average and max over the last 60 frames, with a small chart), the tick and entity count, the round trip, bytes per second and drift when the game is connected to a server, and the audio device’s backend, underruns, peak and frames written and played. Exports and Release builds don’t contain it.

## Show it

Nothing to add to the game. Start any Debug build in a window, here the scaffold from `onegame new beacon`, and press F3:

```shell
onegame run
```

Three environment variables change how it starts:

```shell
ONEGAME_OVERLAY=on onegame run                                    # shown from the first frame
ONEGAME_OVERLAY_KEY=Backquote onegame run                         # another key; "none" turns the key off
ONEGAME_OVERLAY_CHORD=LeftShoulder+RightShoulder onegame run      # another pad chord; "none" turns it off
```

The toggle key is swallowed, so the game never sees F3. The window and the keys weren’t run for this page; everything below was.

## In a scenario

`overlay: on`, `off` or `toggle` is a scenario step, and a capture includes the panel while it is shown:

**`scenarios/overlay.yaml`**

```yaml
name: overlay
description: The debug overlay shows in a capture, with machine-dependent figures masked so the picture repeats.
window: 640x360
steps:
  - step: 30
  - overlay: on
expect:
  - capture: { reference: refs/overlay.png, tolerance: 2, max-diff: 0.001 }
```

```shell
onegame test --scenario scenarios/overlay.yaml --update-references
onegame test --scenario scenarios/overlay.yaml
```

```text
PASS overlay (410 ms, tick 30, hash 3864c4c5e102f97d)
created reference /tmp/onegame/beacon/scenarios/refs/overlay.png
1 passed, 0 failed
PASS overlay (330 ms, tick 30, hash 3864c4c5e102f97d)
1 passed, 0 failed
```

A headless run masks every figure that depends on the machine or the moment, such as frame times, rates and audio counters, as `--`. That is why the second run matches the reference it made.

## From live control

The `overlay` tool shows or hides the panel and returns its text as `lines`. With the MCP client from [Drive a running game over MCP](https://recursiveai.org/onegame/cookbook/live-control-mcp/):

```text
step {"frames": 30} -> {"frame":30,"tick":30,"hash":"3864c4c5e102f97d"}
overlay {"visible": true} -> {"visible":true,"key":"F3","chord":["Back","Start"],"masked":true,"lines":["debug overlay","frame -- ms","tick 30  entities 1"]}
capture_frame {"path": "shots/overlay.png", "size": "720p"} -> {"path":"/tmp/onegame/beacon/artifacts/shots/overlay.png","width":1280,"height":720,"scale":1,"sha256":"94bab70c49443f1fc2d412f5061d7f179067252fda65996f22a30eaea550d669","renderer":"NVIDIA GeForce RTX 4070","tick":30,"hash":"3864c4c5e102f97d"}
overlay {} -> {"visible":true,"key":"F3","chord":["Back","Start"],"masked":true,"lines":["debug overlay","frame -- ms","tick 30  entities 1"]}
quit {} -> {"frame":30,"tick":30,"hash":"3864c4c5e102f97d"}
```

The capture shows the ship in the middle and a dark panel in the top-right corner with those three lines. A headless game without a server or a sound device has no network or audio lines. `masked: false` shows the real figures, and `key` and `chord` change the bindings while the game runs.

## Not in an export

```shell
onegame export --target linux --json
```

The report says `"devTools":false`, and the exported program contains neither the panel’s text nor the live-control assembly. The export checks this itself: if the program mentions the development tools anyway, it fails with `dev_tools_present` instead of shipping them. Setting `<OneGameDev>true</OneGameDev>` in the project didn’t trigger it here, because the export still built without the tools (`"devTools":false`); the check is a backstop.

## Good to know

- The panel needs the default 2D stage, the one `Draw2D` views use. It is drawn over the finished frame.
- Its text is rebuilt four times a second, which allocates about 10 KB each time and nothing in between.
- `--live` on an exported program exits 5 with `no_dev_tools`, for the same reason.
- To watch the network figures, run a client against a server, as in [Client/server sync with a dedicated server](https://recursiveai.org/onegame/cookbook/client-server-sync/), and press F3 in the client’s window.

More in [Driving a game](https://recursiveai.org/onegame/docs/driving-a-game/).
