Skip to content

feat(hud): decode time in Debug, a Slim layout, and a Command Center that stays out of the way - #283

Merged
papi-ux merged 2 commits into
masterfrom
feat/command-center-hud-revamp
Sep 6, 2026
Merged

feat(hud): decode time in Debug, a Slim layout, and a Command Center that stays out of the way#283
papi-ux merged 2 commits into
masterfrom
feat/command-center-hud-revamp

Conversation

@papi-ux

@papi-ux papi-ux commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • NovaHUD Debug gains DEC (decode time, graded against the frame budget at the target rate), HOST (host processing latency), and IN / OUT (incoming against rendered fps). That is the decode time asked for in [Bug]: 1.4.0 / 1.4.1 not working #275 and the rest of what the legacy Moonlight text knew, inside the HUD.
  • A fourth layout, Slim: one pill with the health bar, the frame rate, and the round trip. Guide + Y cycles Minimal, Performance, Debug, Slim, and the settings preview renders it.
  • Stats Overlay toggled from Command Center works on a stream that started with it off, and the toggle is remembered in Settings. It used to flip an in-memory flag and a View, so the overlay came up empty (the before screenshots show it). Turning it on turns Nova HUD off for the next stream too, and the reverse.
  • NovaHUD reads the decoder's structured sample only. The decoder no longer builds the legacy overlay text on the decode thread while just the HUD is showing, and the HUD publishes once per sample instead of twice. The parts of the HUD whose inputs did not change skip recomposition: the state is immutable, and the strips and chips take only the fields they draw.
  • Command Center keeps Close, Disconnect, and End Session fixed above the scrolling sections, picks the HUD layout with four buttons instead of cycling blind, folds the two opacity preset strips behind their rows, and slides out on Close, B, and Back the way it already did on scrim and drag. Quick keys are built once per open, capabilities are fetched once per session, and the dead AI Auto Quality arm is gone.
  • Removed the unreachable lite, bottom, and lite-dialog variants of the legacy overlay, and the HUD Position setting that nothing read.

Exact candidate

  • Commit: 45166e6
  • Tree: d11c30484ff188a96f69c90c6f9d2e307c741d53
  • Parent: a8df7dc
  • Base: 1895589 (master, Nova 1.4.3)

Verification

  • :app:testNonRoot_gameDebugUnitTest (x86_64): 1609 tests, 0 failures, 0 errors
  • :app:lintNonRoot_gameDebug -PlintFailOnError=true: clean
  • :app:assembleNonRoot_gameDebug (arm64-v8a), installed on the Retroid Pocket 6 as com.papi.nova.debug, paired through Trusted Pair against Polaris 1.4.3 on pc-papi, live Control Ultimate Edition stream at 1920x1080@60 HEVC
  • Device: Command Center first paint unchanged; header stays put while scrolled to Advanced; the picker is disabled with its own caption while the HUD is off, enabled after, and stays in sync with Guide + Y; Slim, Minimal, Performance, and Debug all rendered; Debug read DEC 8.1ms, HOST 2.4ms, IN 60, OUT 58 while the legacy text on the same stream read 9.69 ms decode and 2.2 ms host a few minutes later (same sample field, different moments); Stats Overlay toggled from Command Center on a stream that started with it off showed the text at once, and the choice survived a reinstall and relaunch; opacity rows expand and collapse; End Session tore down cleanly (host log: active sessions 0)
  • Frame stats from dumpsys gfxinfo, 60 s each, the HUD ticking once per second over the static Control title screen:
build HUD mode frames p50 p90 p99 janky slow UI thread
1.4.3 Debug 59 11 ms 13 ms 14 ms 1 1
this branch before the skip pass Debug 60 13 ms 14 ms 16 ms 21 21
this branch before the skip pass Performance 59 11 ms 12 ms 13 ms 0 0
this branch Debug 59 12 ms 13 ms 16 ms 11 11
this branch Performance 60 11 ms 12 ms 14 ms 2 1

Debug carries three more live tiles than before and pays about a millisecond per tick for them. Performance, Minimal, and Slim are unchanged or cheaper. These are single 60 s runs, so a difference of a frame or two is noise. The decode-thread saving (no legacy text built while only the HUD is up) does not show in these numbers by construction; they measure the View layer.

Screenshots and the raw gfxinfo dumps are under ~/.hermes/artifacts/nova/cc-hud-revamp-2026-09-06/ on MacPapi.

Not covered

  • androidTest is not compiled by CI and already fails to compile on master (NovaGameDetailComposeTest, NovaPolarisSyncSheetComposeTest). The two HUD androidTests were not touched and were not run.
  • The companion-display Command Center (the legacy GameMenu on a second screen) is unchanged.
  • Polaris on pc-papi was started as polaris.service for this QA and stopped again afterwards; it was not running before.

…that stays out of the way

NovaHUD reads the decoder's structured sample only. The text path made the decoder
build the legacy overlay string on the decode thread whenever the HUD was up, to
regex out numbers the struct already carried, and it published the HUD twice per
sample. Debug gains DEC (decode time graded against the frame budget at the target
rate), HOST (host processing latency), and IN / OUT (incoming against rendered fps),
which is the rest of what the legacy text knew. A fourth layout, Slim, is one pill
with the health bar, the frame rate, and the round trip; Guide + Y cycles Minimal,
Performance, Debug, Slim, and the settings preview renders it.

Stats Overlay toggled from Command Center used to flip an in-memory flag and a View.
A stream that started with the setting off showed an empty overlay, and Settings
never learned about the toggle. toggleHUD now persists the preference and re-arms
the decoder's text builder. Turning it on turns Nova HUD off for the next stream
too, and the reverse. The unreachable lite, bottom, and lite-dialog variants of the
overlay are gone, and so is the HUD Position setting, which nothing read.

Command Center keeps Close, Disconnect, and End Session fixed above the scrolling
sections, picks the HUD layout with four buttons instead of cycling blind, folds the
two opacity preset strips behind their rows, and slides out on Close, B, and Back
the way it already did on scrim and drag. Quick keys are built once per open, the
Doctor card's action is remembered per diagnosis, capabilities are fetched once per
session, and the dead AI Auto Quality arm is removed.

Source guards pin the new shape: the four-stop ring and picker order, the Debug
tiles, the fixed header, the collapsed presets, the animated exits, and the
persisted toggle.
The Debug layout gained three live tiles, and a 60 s frame-stat run showed the
tick cost moving from 11 ms to 13 ms median with 21 slow UI-thread frames against
1 on 1.4.3. Part of that was avoidable: the diagnostic strip and the layer chips
recomposed every tick because they took the whole state or a List, neither of which
Compose can prove stable, so their text was re-laid out even when it had not changed.

NovaHudUiState and NovaHudLayerHealth are marked immutable, which they were in fact,
and the strips take only the strings and tones they draw. Measured on the Retroid
Pocket 6 over a live 60 fps Control stream: Debug 12 ms median with 11 slow frames,
Performance 11 ms with 1. The remaining millisecond in Debug is the three added
tiles changing their numbers once a second.
@papi-ux
papi-ux merged commit 90ac578 into master Sep 6, 2026
6 checks passed
@papi-ux
papi-ux deleted the feat/command-center-hud-revamp branch September 6, 2026 17:13
papi-ux added a commit that referenced this pull request Sep 7, 2026
Matched client for Polaris 1.4.4. Everything on master since 1.4.3: Wake Host
(#284), the Command Center that leads with the verdict's explanation, the Slim
sparkline bar, and Debug's decode and network rows (#283, #285), the Stats
Overlay fix, and the honest Play and Doctor labels from this branch.

versionName 1.4.4, versionCode 46. The Unreleased section becomes the dated
1.4.4 section with a one-line summary and the same bullets, the store notes for
build 46 fit under 500 code points, and NovaReleaseMetadataTest pins all of it.

The label fixes in the same PR:

Three labels that stopped being true once the surfaces around them changed.

The library's Continue card said Resume whether or not the host was still running
the game. The kicker already told the truth (Continue, Live, or Watch) and the
summary said "Pick up where you left off", but the button promised a resume and
then launched. Resume now appears only while the host is running that game;
otherwise the button says Play. The Watch branch is unchanged.

The Doctor card led the Command Center after #285, and its first line of advice
repeated its own title: "Streaming telemetry looks ready" over "Try first:
Streaming telemetry looks ready. Keep this page open...". The host's first-try
line usually opens by restating the finding, so the state builder now drops that
opening sentence and keeps the advice that follows it. A first-try line that only
restates the title disappears rather than saying it twice; one that merely starts
with the same words as a longer word is left alone.

The Command Center subtitle still promised "Quick keys and controls" when Quick
Keys became the last panel. It now reads "Session controls for Private Stream" and
"Session controls for virtual display streaming"; the generic fallback reads
"Stream health, tuning, and session controls".

HonestLabelsSourceGuardTest pins the hero verb and the subtitles; the Doctor
dedupe has unit coverage for the repeated, bare, unrelated, and prefix-only cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant