Runtime debug overlay
The runtime network debug overlay and its console commands.
Assumes you have finished quick-start.
One section below is generated, not typed. § Rows is generated from the kit's own row list, one line per row in the order the panel draws them (the two
Validatorrows' source reads "the overlay's log sink"), and the two bitmasks in § Commands are computed fromEUKOverlaySection's bit order. The page is checked against that list cell by cell, so the table and the panel cannot drift.
How to read the brackets. A bracket after a statement says how it is known and on which engine:
[source-read 5.x]— read in that engine's source;[measured 5.x]— observed by the kit's own tests on that engine;[unverified]— not yet confirmed.
What it shows
A small text panel in one corner of each local player's screen that answers why did that
interaction not happen? while you play: which object you are focused on and why it is or is not
usable, what request is in flight, what the server decided and why, who holds a lock and where you
are in its queue, and which UK-VAL rule lines this machine has logged. Most lines are one named,
documented value from a getter the kit already ships; the Header rows come from engine calls, and
the Validator rows are derived from this machine's log. The panel adds no replicated property and
no RPC, and it only reads — it never changes the state it shows.
Turning it on. Two switches, both needed:
- Tick Enable Debug Overlay — the setting
bEnableDebugOverlayin Project Settings → Plugins → UK Interaction → Diagnostics. It is off by default; while it is off,UK.Overlay 1,UK.Overlay.DumpandUK.Overlay.Sectionsonly log a line telling you to turn it on. - Open the console and type
UK.Overlay 1(UK.Overlay 0hides it again). Or tick Show On Start in the same settings group (Overlay.bShowOnStart) to have the panel up from the first frame — the only way to catch aUK-VALline logged atBeginPlay.
The panel never takes input: it cannot be clicked, focused or tabbed to, and it adds no key of its own. If you want a key, bind one in your project to the console command.
The one-frame lag. The panel refreshes at a fixed rate (Overlay.RefreshHz, default 10 per
second) from a tickable object, and the engine ticks those objects before the late tick group the
kit's detection runs in. So a refresh shows the previous frame's focus and detection — a
one-frame lag that is invisible at ten refreshes a second, and the reason a value you just changed
can appear one frame late. [source-read 5.6 / 5.7 / 5.8]
Where it exists. The overlay is its own module, UKInteractionDebug, loaded on game clients
(a listen host included) and in the editor, in every build configuration except Shipping and
Test. It is absent from Shipping and Test builds, from a
dedicated server (no local player, so no panel), and from the Lite edition; in those the UK.Overlay
commands do not exist.
Settings (Project Settings → Plugins → UK Interaction → Diagnostics → Overlay):
| Setting | Default | Range | What it does |
|---|---|---|---|
bShowOnStart | off | — | Panel up from the first frame |
RefreshHz | 10 | 1 – 30 | Refreshes per second |
Corner | TopLeft | four corners | Which corner the panel sits in (the prompt is bottom-centre) |
Opacity | 0.82 | 0 – 1 | Backing opacity |
FontSize | 10 | 8 – 16 | Monospace point size — the lever if the panel is too tall |
ZOrder | 1000 | 0 – 10000 | Draw order; above the prompt by default |
EnabledSections | all twelve | bitmask | Which sections are shown (§ Commands) |
EventHistoryLines | 8 | 0 – 64 | Length of the event history; 0 removes it |
ValidatorHistoryLines | 4 | 0 – 32 | Captured rule lines kept; 0 leaves only the count |
A hand-edited value outside its range is clamped when it is read.
Cost. The measured cost (c_snapshot, about 60–70 µs per refresh on the development machine
the kit is measured on, standing in for reference hardware, at 10 refreshes a second) covers
building the snapshot and its change check only. The on-screen part of a refresh — writing the
panel's text and Slate's layout and paint — is not measured yet, and while a hold or a lock
reservation is running the panel's timers change every refresh, so the text is rewritten every
refresh during those moments. Averaged over frames, that snapshot cost is about 11 µs per frame at
10 refreshes a second and 60 fps, inside the kit's 20 µs per-frame budget for the panel.
[measured 5.8, advisory] The panel is off by default, so none of this is paid until you turn it
on.
Commands
| Command | What it does |
|---|---|
UK.Overlay 0 / UK.Overlay 1 | Hides / shows the panel. The variable starts at -1, which means "not set — follow Show On Start". |
UK.Overlay.Dump | The text alternative: everything the panel shows, as UK-OVL lines in the log — one line per row, taken now, whatever the refresh rate. Use it to paste the panel into a bug report or to grep a session log. |
UK.Overlay.Sections <mask> | Shows only some sections for this session. The mask is an integer, decimal digits only, 0–4095, one bit per section in the order of § Rows (Header is bit 0, Validator the last); anything else is rejected with a Warning. With no argument the command prints a hint. |
While Enable Debug Overlay is off, only UK.Overlay 1, UK.Overlay.Dump and
UK.Overlay.Sections log a line (telling you to turn it on) and do nothing else; UK.Overlay 0
logs nothing. A UK.Overlay value other than -1, 0 or 1 (for example UK.Overlay 5) logs a
Warning whether the setting is on or off, and is read as -1.
While the game is paused, UK.Overlay 0 / UK.Overlay 1 take effect when it unpauses: the
panel is refreshed by a tick that does not run while paused, so it keeps the last rows it drew.
UK.Overlay.Dump works at any time and always reads the state now.
With every section on, the panel is taller than a 1080p screen at the default font size and clips
at the bottom — which is where Lock and Validator sit. Two recipes trim it:
Triage — Header, Focus, Pending, Active, Events, Lock, Validator. Sized for a
1080p screen at FontSize 10 with every source present; if it still clips on yours, lower
FontSize.
UK.Overlay.Sections 2675
Prompt — Header, Focus, Prompt, Input: for "why is there no prompt?".
UK.Overlay.Sections 387
Row grammar
Every row the panel shows is also one log line when you run UK.Overlay.Dump, in exactly this
grammar — the panel and the dump carry the same text, byte for byte:
^UK-OVL ([A-Z][A-Za-z]+)\.([A-Za-z_][A-Za-z0-9_]*(?:\[[0-9]+\])?)=(.*)$
Group 1 is the section, group 2 the key (for counter rows the field's own name; for every row,
§ Rows' source column gives the line), group 3 the value. The value may itself contain =, so split on the first = after the key.
Examples:
UK-OVL Focus.target=BP_Door
UK-OVL Pending.hold_s=2.00
UK-OVL Protocol.RejectedByReason=OutOfRange=2;Locked=1
UK-OVL Lock.stats_Admitted=—
Rows
Twelve sections, always in this order. history[i] and last[i] stand for one row per kept line,
oldest first.
| Section.key | source | machine |
|---|---|---|
Header.version | Source/UKInteraction/Public/UKInteractionConstants.h:189 | both |
Header.netmode | engine:UWorld::GetNetMode | both |
Header.player | engine:ULocalPlayer::GetControllerId | both |
Header.role | engine:AActor::GetLocalRole | both |
Header.refresh_hz | Source/UKInteraction/Public/UKInteractionSettings.h:394 | both |
Header.profile | Source/UKInteraction/Private/Interactor/UKInteractorComponent.cpp:88 | both |
Focus.state | Source/UKInteraction/Public/Interactor/UKInteractorComponent.h:292 | owner |
Focus.target | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:153 | owner |
Focus.preset | Source/UKInteraction/Public/Interactable/UKInteractableComponent.h:236 | owner |
Focus.usability | Source/UKInteraction/Public/Interactable/UKInteractableComponent.h:218 | owner |
Focus.interactable_state | Source/UKInteraction/Public/Interactable/UKInteractableComponent.h:402 | owner |
Focus.distance_cm | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:191 | owner |
Focus.prompt_text | Source/UKInteraction/Public/Interactable/UKInteractableComponent.h:240 | owner |
Focus.denial | Source/UKInteraction/Public/Interactor/UKInteractorComponent.h:233 | owner |
Detection.TickCount | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:248 | owner |
Detection.GatherCount | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:252 | owner |
Detection.FocusChangedCount | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:256 | owner |
Detection.OriginFallbackCount | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:260 | owner |
Detection.RegisteredCount | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:265 | owner |
Detection.OverlapHits | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:269 | owner |
Detection.PoolSize | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:273 | owner |
Detection.bPoolTruncated | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:277 | owner |
Detection.CandidateCount | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:281 | owner |
Detection.RejectedByReason | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:285 | owner |
Detection.UsabilityCalls | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:289 | owner |
Detection.LosTraces | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:293 | owner |
Detection.LosBlocked | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:297 | owner |
Detection.LosCacheHits | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:301 | owner |
Detection.SweepCount | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:305 | owner |
Detection.DetectionMicroseconds | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:309 | owner |
Detection.BroadcastMicroseconds | Source/UKInteraction/Public/Interactor/UKDetectionTypes.h:313 | owner |
Protocol.RequestsSent | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:250 | both |
Protocol.Accepted | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:253 | both |
Protocol.Completed | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:256 | both |
Protocol.Rejected | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:259 | both |
Protocol.Cancelled | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:262 | both |
Protocol.LocalRejected | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:266 | both |
Protocol.StaleResolves | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:270 | both |
Protocol.HoldMismatchCount | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:274 | both |
Protocol.Retractions | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:277 | both |
Protocol.RejectedByReason | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:280 | both |
Protocol.Received | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:285 | both |
Protocol.ServerRejected | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:288 | both |
Protocol.ServerRejectedByReason | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:291 | both |
Protocol.ThrottleViolations | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:294 | both |
Protocol.ThrottleDropped | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:298 | both |
Protocol.TargetUnresolved | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:302 | both |
Protocol.EndIgnored | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:306 | both |
Protocol.HoldsCompleted | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:309 | both |
Protocol.HoldsCancelled | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:312 | both |
Protocol.ServerLosTraces | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:315 | both |
Protocol.PendingSerial | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:321 | both |
Protocol.PendingPhase | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:324 | both |
Protocol.ReleasedRecords | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:328 | both |
Protocol.LastResolveLatencySeconds | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:331 | both |
Protocol.PredictedTickMicroseconds | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:341 | both |
Protocol.ActiveSerial | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:347 | both |
Protocol.LastOriginDivergenceCm | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:351 | both |
Protocol.ValidationMicroseconds | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:355 | both |
Protocol.ValidationLosMicroseconds | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:359 | both |
Protocol.ValidationApplyMicroseconds | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:363 | both |
Protocol.HoldTickMicroseconds | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:367 | both |
Pending.serial | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:382 | owner |
Pending.target | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:385 | owner |
Pending.phase | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:388 | owner |
Pending.hold_s | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:391 | owner |
Pending.elapsed_s | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:394 | owner |
Active.serial | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:404 | authority |
Active.target | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:407 | authority |
Active.hold | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:410 | authority |
Active.hold_s | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:413 | authority |
Active.elapsed_s | Source/UKInteraction/Public/Protocol/UKProtocolTypes.h:416 | authority |
Events.last_interactor | Source/UKInteraction/Public/Interactor/UKInteractorComponent.h:541 | both |
Events.last_interactable | Source/UKInteraction/Public/Interactable/UKInteractableComponent.h:496 | both |
Events.history[i] | Source/UKInteraction/Public/Events/UKInteractionFunctionLibrary.h:86 | both |
Prompt.PublishCount | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:292 | owner |
Prompt.GlyphResolveCount | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:296 | owner |
Prompt.WhyNotShownCount | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:300 | owner |
Prompt.WhyNotDroppedCount | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:304 | owner |
Prompt.bWidgetCreated | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:308 | owner |
Prompt.bWidgetOnScreen | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:312 | owner |
Prompt.bTickerActive | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:316 | owner |
Prompt.LastDeviceKind | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:320 | owner |
Prompt.LastPublishMicroseconds | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:324 | owner |
Prompt.visible | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:84 | owner |
Prompt.why_not | Source/UKInteractionClient/Public/Prompt/UKPromptTypes.h:131 | owner |
Input.bBound | Source/UKInteractionClient/Public/UKInputTypes.h:83 | owner |
Input.bContextActive | Source/UKInteractionClient/Public/UKInputTypes.h:87 | owner |
Input.bEnhancedInputComponent | Source/UKInteractionClient/Public/UKInputTypes.h:95 | owner |
Input.LastDeviceKind | Source/UKInteractionClient/Public/UKInputTypes.h:105 | owner |
Lock.policy | Source/UKInteraction/Public/Interactable/UKInteractionPreset.h:109 | both |
Lock.holder | Source/UKInteraction/Public/Interactable/UKInteractableState.h:79 | both |
Lock.queue | Source/UKInteraction/Public/Lock/UKLockTypes.h:50 | both |
Lock.my_position | Source/UKInteraction/Public/Lock/UKInteractionLockComponent.h:79 | both |
Lock.reservation_s | Source/UKInteraction/Public/Lock/UKInteractionLockComponent.h:87 | both |
Lock.stats_Admitted | Source/UKInteraction/Public/Lock/UKLockTypes.h:70 | authority |
Lock.stats_QueuedNew | Source/UKInteraction/Public/Lock/UKLockTypes.h:74 | authority |
Lock.stats_QueuedRepeat | Source/UKInteraction/Public/Lock/UKLockTypes.h:78 | authority |
Lock.stats_Locked | Source/UKInteraction/Public/Lock/UKLockTypes.h:82 | authority |
Lock.stats_Expired | Source/UKInteraction/Public/Lock/UKLockTypes.h:86 | authority |
Lock.stats_PrunedInvalid | Source/UKInteraction/Public/Lock/UKLockTypes.h:90 | authority |
Lock.stats_ClearedOnDisable | Source/UKInteraction/Public/Lock/UKLockTypes.h:94 | authority |
Lock.stats_MaxQueueObserved | Source/UKInteraction/Public/Lock/UKLockTypes.h:98 | authority |
Lock.stats_ArbitrateMicroseconds | Source/UKInteraction/Public/Lock/UKLockTypes.h:102 | authority |
Lock.stats_EndedMicroseconds | Source/UKInteraction/Public/Lock/UKLockTypes.h:106 | authority |
Pickup.Takes | Source/UKInteraction/Public/Interactable/Presets/UKPickupSubsystem.h:65 | authority |
Pickup.AlreadyTakenRejected | Source/UKInteraction/Public/Interactable/Presets/UKPickupSubsystem.h:69 | authority |
Pickup.Respawned | Source/UKInteraction/Public/Interactable/Presets/UKPickupSubsystem.h:73 | authority |
Pickup.Destroyed | Source/UKInteraction/Public/Interactable/Presets/UKPickupSubsystem.h:77 | authority |
Pickup.DisabledByTake | Source/UKInteraction/Public/Interactable/Presets/UKPickupSubsystem.h:81 | authority |
Pickup.RespawnSkippedAlreadyEnabled | Source/UKInteraction/Public/Interactable/Presets/UKPickupSubsystem.h:85 | authority |
Pickup.MarkerHealed | Source/UKInteraction/Public/Interactable/Presets/UKPickupSubsystem.h:89 | authority |
Pickup.MarkerAlreadyPending | Source/UKInteraction/Public/Interactable/Presets/UKPickupSubsystem.h:93 | authority |
Validator.count | the overlay's log sink | both |
Validator.last[i] | the overlay's log sink | both |
What each section means
Header
Which machine this panel belongs to: the net mode (Standalone, ListenServer, Client), the
local player's controller id, the pawn's role (Authority, AutonomousProxy, …), the kit version,
the refresh rate and whether UK.Protocol.Profile is on
(protocol.md § UK.Protocol.Profile). Read it first: every other
row is a statement about this machine.
Focus
What the local interactor is focused on and what that object says about itself: its preset, its
usability and state, the distance, the resolved prompt text, and the last reason a press was
refused locally before anything was sent (Focus.denial, the reason On Interact Denied
reported).
Which machine? On Interact Denied — Local machine.
Detection, Protocol, Pending, Active, Events
Detection is the interactor's detection counters, one row per field of FUKDetectionStats.
Protocol is FUKProtocolStats: the client group on the player's own machine, the authority group
on the server, and both on a listen host. Pending is the request this client has in flight and
Active the interaction the server is running. Events is the last event on the interactor and on
the focused object, each rendered the way events.md describes, followed by a short
history (EventHistoryLines). The timing rows (…Microseconds) are filled only while
UK.Protocol.Profile is on.
Prompt, Input
The sample prompt's counters and state — including bWidgetCreated / bWidgetOnScreen and the
why-not line — and the input binding's state, both from the local player's own machine
(prompt.md, input.md).
Lock
The focused object's lock (lock.md): the policy, the holder, the queue in order, your
own place in it, the time left on a reservation, and — on the server only — the lock's counters,
each keyed stats_<Field>. A client does not have the counters, so its panel shows — for every
stats_ row, never 0.
Lock.my_position is 1-based: 1 is first in line, and 0 means you are not in the
queue at all.
On a client, reservation_s is measured on the client's estimate of server time
(AGameStateBase::GetServerWorldTimeSeconds()), which trails the server briefly; it can therefore
read slightly above the lock's ReservationSeconds for a moment after a reservation starts. The
server's own panel is exact. A client with no game state yet shows —.
Pickup
The pickup scheduler's counters. They exist on the server only, so a client's panel shows —.
Validator
The rule lines this machine has logged — count, then the last few (ValidatorHistoryLines) —
with the same UK-VAL-NNN token the editor and the rest of these documents use, so you can search
once.
The Validator row counts UK-VAL lines from the log of the machine the panel runs on. On a listen
host that includes the authority-only checks (UK-VAL-026, -041, -101, -110 to -113). A remote
client — of a listen or a dedicated server — never sees those; read them in the server's log. A
dedicated server has no local player and therefore no panel. In PIE with Run Under One Process
every instance shares one log, so a client window also counts the server's lines — that is PIE, not
your shipped game.
The panel reads the log as it refreshes and does not wait for lines still being written, so it can
trail the log by up to one refresh. UK.Overlay.Dump waits for the log first, so a dump is always
current.
Placeholders
A row whose source does not exist on this machine shows — (an em dash): no lock component on the
focused object, no authority, no focus, a pickup scheduler that is inactive on a client. A section
whose source is missing shows its header with — in its first row — never a blank, and never a
stale value left over from the last object you looked at. — means this machine does not know;
0 always means counted, and zero.
A section you turned off with EnabledSections is not drawn at all, so a hidden section and an
empty one never look alike.
Known gaps
Recorded so you can read every claim on this page as narrowly as it was proven.
- Engine coverage. The overlay is written for every supported engine with no version gates. In one line: "supported on 5.6–5.8; multiplayer end-to-end suite run on all three". The session tests that drive the panel end to end have run on the engines that sentence names as run, and on no other.
- Nothing on the panel is pixel-tested. Every automated run is headless, so what is tested is
the text — the same lines
UK.Overlay.Dumpwrites. Font, colour, corner and opacity are not asserted by any test; the screenshot above is the on-screen record, taken in an editor session by hand. - Whether the triage recipe fits a 1080p screen is derived, not measured. It is sized for it at
the default font size and sits on the margin;
FontSizeis the lever if it clips. - Split-screen. Two local players in one process each get their own panel and their own rows, which is tested. Where each panel lands inside its player's part of the screen has not been checked on screen.
- The on-screen part of a refresh is not measured — only the snapshot is (§ What it shows › Cost).
- Development builds only. The overlay is not in
ShippingorTestbuilds, not on a dedicated server, and not in the Lite edition — by design, so it can never reach a player.