Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,27 @@

## Unreleased

## 1.3.6 - 2026-08-12

Nova 1.3.6 makes host intent visible and recoverable instead of making the player infer it from side effects. Doctor v2 actions now run from Command Center with evidence gating, confirmation, live verification, and Undo: Nova can recheck a suspected network condition, lower bitrate by one guarded step, or gradually restore a clean stream that an older recovery profile left capped (#230).

Play Setup and Polaris Sync now share one server-authoritative launch-mode catalog, including all private and host-display modes, availability, disable reasons, and controller-selectable grouped cards (#212, #213, #221). Explicit per-game choices travel on the launch request for that session only; a game without an override follows the host default, and launching no longer rewrites Polaris' persistent stream mode (#222, #223, #224). Nova also shows one host-served display fallback warning per session and includes the resolved mode in optimization requests while keeping the AI pick advisory (#214, #215).

Reliability work fixes false network/decoder HUD warnings, retries idempotent Polaris actions once after transient TLS failures, and converts malformed host launch responses into recoverable checked errors instead of app crashes (#210, #211, #225). Cached game detail, cold-start Library, and return-from-detail flows settle before requesting focus, declare controller intent, and retry placement so the visible ring and first action agree (#226, #228). Play Setup's explanatory copy now leads with the resolved action rather than a different app default (#229).

A separate benchmark-only build records bounded T3-T4 decode-stage evidence, supports controlled ADB start/stop/export, and remains structurally outside normal release runtime (#209, #216-#220). The public roadmap is refreshed in #227.

### Release packaging

- Bumps the Android app to versionName 1.3.6 and versionCode 38.
- Publishes signed ARM64, ARMv7, and x86_64 APKs plus portable SHA-256 sidecars through the GitHub release workflow.

### Validation notes

- The exact release-prep candidate must pass JVM tests, strict lint, public hygiene, and three-ABI release assembly before merge.
- Final publication remains gated on the exact signed ARM64 artifact: package/version identity, signer continuity, install/launch on the Retroid Pocket 6, controller focus, one explicit per-game launch override without host-default mutation, one Doctor apply/verify/undo flow, and clean stream teardown.
- Gyro/motion sensors remain open under #181. The Thor audio-device inventory is diagnostic evidence, not a claimed routing fix.

## 1.3.5 - 2026-08-08

Performance and polish. The library keeps its poster cache warm across visits, decodes
Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ while you play, and what is safe to do when you leave.
[![License](https://img.shields.io/github/license/papi-ux/nova?style=for-the-badge&color=4c5265&labelColor=1a1a2e)](LICENSE.txt)
[![Release](https://img.shields.io/github/v/release/papi-ux/nova?style=for-the-badge&color=4ade80&labelColor=1a1a2e&label=latest)](https://github.com/papi-ux/nova/releases/latest)

[Why Nova](#why-nova) · [Feature Matrix](#feature-matrix) · [Quick Start](#quick-start) · [Latest Release](#latest-release-v133) · [Install](#install) · [Compatibility](#compatibility) · [Launch Modes](#launch-modes-in-plain-english) · [Tour](#tour) · [Polaris](#use-with-polaris) · [Support](#support-and-bug-reports) · [FAQ](#faq) · [Security](SECURITY.md) · [Changelog](CHANGELOG.md) · [Roadmap](ROADMAP.md)
[Why Nova](#why-nova) · [Feature Matrix](#feature-matrix) · [Quick Start](#quick-start) · [Latest Release](#latest-release-v136) · [Install](#install) · [Compatibility](#compatibility) · [Launch Modes](#launch-modes-in-plain-english) · [Tour](#tour) · [Polaris](#use-with-polaris) · [Support](#support-and-bug-reports) · [FAQ](#faq) · [Security](SECURITY.md) · [Changelog](CHANGELOG.md) · [Roadmap](ROADMAP.md)

**Support**: [Issues](https://github.com/papi-ux/nova/issues) · [Discussions](https://github.com/papi-ux/nova/discussions)

Expand Down Expand Up @@ -107,19 +107,20 @@ Use Nova with any compatible host for normal streaming. Pair it with Polaris whe

If a sleeping host does not report a MAC address, open the host menu and choose **Edit Wake-on-LAN MAC**. Nova stores that address and reuses it for future wake requests, which helps VPN and routed setups where discovery metadata is incomplete.

## Latest release: v1.3.5
## Latest release: v1.3.6

Nova v1.3.5 is a performance and polish release: the library stops redoing work it already did, the stream path stops paying for text nobody is reading, and the controller gets treated as the first-class input it is on the devices Nova actually runs on.
Nova v1.3.6 makes launch intent and recovery actions explicit. Play Setup now speaks the host's complete launch-mode catalog, per-game overrides stay scoped to one session instead of rewriting the host default, and Doctor can apply, verify, and undo the safest supported correction from Command Center.

- **Warm library**: the poster cache survives re-entry instead of being wiped on every load, artwork decodes to per-surface size buckets, image loads run three-wide with cancellation of superseded requests, and artwork connections reuse TLS state over a pooled client instead of a full handshake and RSA client-cert exchange per image.
- **Frame pacing, for real**: the latency-profile selector had been silently overwriting the frame-pacing preference to Balanced since the setting shipped; the preference now reaches the renderer, and stream setup logs the effective mode.
- **Leaner decode path**: perf-overlay text (including four TrafficStats kernel calls a second) builds only when the overlay or HUD is actually showing, a per-frame allocation is hoisted, and the per-frame vsync-offset lookup is cached.
- **Reconnect**: the connection-failure dialog now offers Reconnect on the spot instead of dead-ending with only OK.
- **First focus lands somewhere useful**: Grid and Compact cold starts focus the first card with the ring visible immediately, the Command Center opens on the diagnosis card instead of its own Close button, and the welcome screen pre-focuses its primary action.
- **Feel and finish**: focus ticks and action confirms across posters, buttons, and Command Center rows; the in-stream lock overlay is themed, controller-worded, and pre-focused; pairing snackbars speak human instead of protocol jargon; the Material You preview tile reads the real dynamic palette on Android 12+.
- **Compatibility**: preserves Grid, Compact Grid, List, existing routing and persistence authorities, minSdk 21, targetSdk 36, Polaris integration, Moonlight-compatible hosts, and signed in-place upgrades.
- **Release packaging**: signed ARM64, ARMv7, and x86_64 APKs ship with portable SHA-256 sidecars. VersionCode 37 keeps Obtainium and manual installs on a clean upgrade path.
- **Known issue**: gyro/motion sensors are not detected on some devices (#181). The audio output-device inventory added in v1.3.4's follow-up remains a diagnostic awaiting an AYN Thor capture, not an audio fix.
- **Doctor that can finish the job**: evidence-gated one-click actions can recheck a suspected network problem, lower bitrate by one guarded step, restore a history-capped profile gradually, verify the result against live telemetry, and offer Undo.
- **Every host mode, one vocabulary**: Play Setup and Polaris Sync share the same server-authoritative grouped picker, including unavailable modes and the host's reason. Controller users can reach and select every card.
- **Session-scoped launch overrides**: an explicit per-game mode travels only on that launch. Games without an override follow the host default, and launching no longer rewrites Polaris' persistent stream mode.
- **Clearer launch truth**: Nova surfaces one display-mode fallback warning per session, includes launch mode in optimization requests, and marks the host's advisory AI pick without selecting it for you.
- **Reliability and focus**: idempotent Polaris actions retry once after transient TLS failures; malformed host responses no longer crash launch; cached game detail and cold-start library screens settle and visibly focus the intended controller target.
- **Honest HUD status**: normal network and decoder risk values stay quiet instead of producing false warning chips.
- **Benchmark tooling stays isolated**: a separate non-shipping benchmark variant records bounded client decode-stage evidence and supports controlled ADB export without changing normal release behavior.
- **Compatibility**: preserves minSdk 21, targetSdk 36, existing routing and persistence authorities, Moonlight-compatible hosts, Polaris integration, and signed in-place upgrades.
- **Release packaging**: signed ARM64, ARMv7, and x86_64 APKs ship with portable SHA-256 sidecars. VersionCode 38 keeps Obtainium and manual installs on a clean upgrade path.
- **Known issue**: gyro/motion sensors are not detected on some devices (#181). The Thor audio-device inventory remains diagnostic evidence, not a claimed routing fix.

See the [changelog](CHANGELOG.md) for the full release history.

Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ android {
minSdk 21
targetSdk 36

versionName "1.3.5"
versionCode = 37
versionName "1.3.6"
versionCode = 38

buildConfigField "boolean", "FDROID_BUILD", fdroidBuild.toString()

Expand Down
28 changes: 19 additions & 9 deletions app/src/test/java/com/papi/nova/NovaReleaseMetadataTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,33 @@ class NovaReleaseMetadataTest {
val build = File(root, "app/build.gradle").readText()
val changelog = File(root, "CHANGELOG.md").readText()
val readme = File(root, "README.md").readText()
val releaseScript = File(root, "bin/release.sh").readText()
val storeNotes = File(
root,
"fastlane/metadata/android/en-US/changelogs/37.txt"
"fastlane/metadata/android/en-US/changelogs/38.txt"
)
val storeNotesBody = storeNotes.readText().trimEnd()
val storeNotesBody = if (storeNotes.isFile) storeNotes.readText().trimEnd() else ""

assertTrue(build.contains("versionName \"1.3.5\""))
assertTrue(build.contains("versionCode = 37"))
assertTrue(changelog.contains("## 1.3.5 - 2026-08-08"))
assertTrue(readme.contains("## Latest release: v1.3.5"))
assertTrue(readme.contains("VersionCode 37"))
assertFalse(readme.contains("## Latest release: v1.3.4"))
assertTrue(build.contains("versionName \"1.3.6\""))
assertTrue(build.contains("versionCode = 38"))
assertTrue(changelog.contains("## 1.3.6 - 2026-08-12"))
assertTrue(readme.contains("[Latest Release](#latest-release-v136)"))
assertTrue(readme.contains("## Latest release: v1.3.6"))
assertTrue(readme.contains("VersionCode 38"))
assertFalse(readme.contains("## Latest release: v1.3.5"))
assertTrue(releaseScript.contains("-PnovaAbis=arm64-v8a,armeabi-v7a,x86_64"))
for (asset in listOf(
"Nova-Android-arm64-v8a.apk",
"Nova-Android-armeabi-v7a.apk",
"Nova-Android-x86_64.apk",
)) {
assertTrue(releaseScript.contains(asset))
}
assertTrue(storeNotes.isFile)
assertTrue(
"Google Play release notes must be at most 500 Unicode characters",
storeNotesBody.codePointCount(0, storeNotesBody.length) <= 500,
)
assertTrue(storeNotesBody.startsWith("Nova 1.3.5"))
assertTrue(storeNotesBody.startsWith("Nova 1.3.6"))
}
}
3 changes: 2 additions & 1 deletion bin/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fi

bash scripts/check-public-docs.sh
bash scripts/check-public-surface.sh
./gradlew -PnovaAbis=arm64-v8a,x86_64 assembleNonRoot_gameRelease
./gradlew -PnovaAbis=arm64-v8a,armeabi-v7a,x86_64 assembleNonRoot_gameRelease

git push origin master
git tag -a "$tag" -m "Nova ${tag}"
Expand All @@ -39,6 +39,7 @@ Tagged ${tag}.

GitHub Actions will create or update the public release and upload:
- Nova-Android-arm64-v8a.apk
- Nova-Android-armeabi-v7a.apk
- Nova-Android-x86_64.apk
- matching .sha256 files

Expand Down
2 changes: 2 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/38.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Nova 1.3.6
Play Setup and Polaris Sync now share every host launch mode, with clear availability and session-only game overrides. Doctor can apply, verify, and undo guarded fixes from Command Center. Launch, TLS, HUD, and controller-focus recovery are safer. Benchmark capture remains isolated from normal releases. Includes signed ARM64, ARMv7, and x86_64 APKs with SHA-256 checksums.
1 change: 1 addition & 0 deletions scripts/check-public-docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ required_metadata=(
"$metadata_dir/short_description.txt"
"$metadata_dir/full_description.txt"
"$metadata_dir/changelogs/16.txt"
"$metadata_dir/changelogs/38.txt"
"$metadata_dir/images/icon.png"
"docs/fdroid.md"
)
Expand Down
Loading