feat: build GameHours desktop foundation - #1
Draft
Ayerdi wants to merge 795 commits into
Draft
Conversation
Ayerdi
force-pushed
the
feat/desktop-foundation
branch
from
August 23, 2026 10:06
00ae3da to
651d203
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This draft builds the Windows desktop foundation for GameHours as a local-first, launcher-independent playtime tracker.
PendientesCurrent engineering state
The broad foundation has extensive automated and real-Windows evidence. Suspend/resume remains protected by deterministic tests but is intentionally not claimed as real-machine verified, and the new GSE catalogue-provisioning lifecycle still requires its final real-game validation.
The installed Velopack path is verified on real Windows.
0.2.0-beta.1was installed over the existing application, detected0.2.0-beta.2with one delta, downloaded from the in-app UI while a game was running, shut GameHours down cleanly, applied the update, restarted automatically, re-detected the still-running game and preserved the pre-update session/data. The newly tracked game was not duplicated. Exact evidence is indocs/INSTALLED-UPDATE-VALIDATION-2026-08-29.md.The expanded runtime performance/memory gate is also verified on real Windows. Equal 30-second samples at idle and with a tracked game running remained effectively flat: 0.04% vs 0.07% average CPU, 157.1 vs 156.9 MiB average private memory, 182.8 vs 183.0 MiB average Working Set, 0.01% GC pause in both states, no Gen2 collections, identical 26.0 MiB committed peak and 0.5 MiB fragmentation peak. There is no evidence justifying speculative GC or memory tuning. Exact evidence is in
docs/RUNTIME-PERFORMANCE-VALIDATION-2026-08-29.md.The single-instance behavior is now also verified on real Windows: launching GameHours again while the first instance is running does not start a second tracker/application instance.
Automated validation
Normal PR CI runs locked restore, Release build, the full test suite and a self-contained Desktop publish. On
pull_requestGitHub checks out its generated merge ref, so evidence below distinguishes the branch HEAD from the merge commit actually executed.Latest evidence:
3bf320f9cce4605bd5eeed4280bdbe390780e080;33274156870):successon generated merge refe53c14afb82ca7c85d983c03723a2ba72023c77f(3bf320f9...merged with currentmain);GameHours.Tests✅ — 130/130;GameHours.Windows.Tests✅ — 166/166;win-x64Desktop publish ✅;CI #782 is intentionally not hidden: it rejected the first explicit GSE-confirmation UX because
MessageBoxwas ambiguous between WPF and WinForms. The implementation was corrected to useSystem.Windows.MessageBox, and subsequent CI is green.Earlier relevant evidence includes CI #636 for modern portable GSE runtime-state support, #725/#729 for the Velopack two-version/update-chain path, #736 for install/uninstall data survival and #751 for single-instance/probe regression coverage.
GSE/Goldberg achievement provisioning
The original real-machine diagnosis of
Click the Button(Steam AppID3946950) found GSE configuration but nosteam_settings\achievements.jsoncatalogue and no persisted user achievement state. Broader scanning correctly could not recover data that did not exist.Follow-up research of current GSE/Goldberg and Hydra showed the missing lifecycle step: GSE resolves achievement unlocks against its settings catalogue. GameHours now has a generic, bounded provisioning path for this case, documented in
docs/GSE-ACHIEVEMENT-PROVISIONING-2026-08-29.md.The implementation:
steam_settingsdiscovery and covers flat/common Unreal/Unity/Steamworks layouts pluscoldclient/steam_settings;name,displayName, emptydescriptionand"hidden": "0";Crucially, opening a game detail is read-only. When GSE is detected without catalogue/state, the UI explains the situation. Provisioning occurs only after the user clicks
Actualizar logrosand explicitly accepts a WPF confirmation that names the file being created and explains the historical limitation. Cancelling performs no provisioning write.This can enable GSE/Goldberg to record future unlocks. It does not reconstruct achievements that the emulator never persisted. The real Click installation and
Big Walkremain the final manual validation cases; Big Walk is not claimed fixed until its actual local layout is observed.Single-instance protection
GameHours takes a per-user process lease under its local data directory after Velopack lifecycle hooks but before WPF/SQLite/tracking initialization. A second Desktop launch cannot start a second tracker against the same local database and exits with a clear user-facing message. The lease is released by process/file-handle lifetime rather than a persisted flag.
Automated coverage is green and the behavior has been confirmed on real Windows.
Next real-Windows check
The next focused gate is the GSE lifecycle:
Click the Buttonto the original missing-catalogue condition (the earlier manual experiment created a catalogue that was not in the repack);Actualizar logros, cancel once and verify no file is created;Big Walkif it is recognized as GSE/Goldberg; otherwise use the existing read-only probe to characterize its source before adding any support.Do not expect historical unlocks that were never written by the emulator to appear automatically.
Distribution state
GitHub Releases remains the selected initial beta/stable update origin. Signing is still desirable before broad public distribution, but it is not a blocker for current product development.
Research against comparable open-source desktop/game projects showed that mature OSS projects such as Playnite and Heroic use SignPath Foundation rather than requiring the project to own a commercial Azure/PKI stack. GameHours therefore defers provider provisioning until it is useful for real distribution.
docs/CODE-SIGNING-PROVIDER-DECISION.mdrecords the provider requirements and current alternatives.The existing package/release hardening stays in place: package-content validation, immutable release versions, SHA-256 manifests, GitHub attestations, updater/recovery checks and public upload as the final side effect.
Later distribution gate
Before broad public distribution, select a publicly trusted Authenticode route appropriate for the actual publisher identity, integrate it at Velopack's signing boundary, then verify a signed install/update/recovery cycle and SmartScreen behavior. This is deliberately deferred rather than used to block current GameHours product work.