Skip to content

Ask the store about a game no launcher claims - #66

Merged
corgan2222 merged 2 commits into
mainfrom
feature/gameid-name-search
Aug 13, 2026
Merged

Ask the store about a game no launcher claims#66
corgan2222 merged 2 commits into
mainfrom
feature/gameid-name-search

Conversation

@corgan2222

Copy link
Copy Markdown
Owner

A game bought outside Steam, GOG and Epic — or installed by hand — is in no catalogue on this machine, so it produced no details at all. The executable was the only thing left and it was thrown away.

It now becomes a question:

Executable Term asked
Cyberpunk2077.exe Cyberpunk 2077
TheAscent.exe The Ascent
DOOMEternal.exe DOOM Eternal
FactoryGame-WinGDK-Shipping.exe Factory Game
Frostpunk2_x64.exe Frostpunk 2

The guess is a question, never an answer

This is the only guess in the package, and it is a guess about what to ask. What gets published is the title the store answers with and the id it gave — or nothing at all. Search therefore carries both halves now (Match{AppID, Title}) instead of just the id: where a launcher named the game the launcher's spelling still wins, but where the term came off a file name the store's spelling is the only one anybody checked.

SteamStore already parsed name out of the response and threw it away.

No platform is invented

A game found this way has a title and an id and no platform — none is known. An empty field is left out of every export rather than filled in, which is exactly right: nobody measured it. Its absence is also what distinguishes this case from "GOG named it, the store had no id".

Programs that are never games are not asked about

RTSS hooks whatever presents frames, so browsers, chat windows, capture tools and the launchers themselves turn up here as readily as a game does — and "Origin" would come back as a game called Origin. Those names never leave the machine at all. Generic names (game.exe, launcher.exe) are on the same list for a different reason: they would match something, and whatever they matched would be wrong.

The list is not the safety net — the store's answer is, because a title nobody sells produces no reading. It is there so the names are not sent to somebody else's server in the first place.

Caching is unchanged in shape

Once per term, misses remembered, never waited for. The first poll after a game starts still reports nothing and the id appears on a later one.

Tests

  • TestASearchTermIsWorkedOutFromTheExecutable — ten real-world spellings including the three word boundaries that matter (lower→upper, letter→digit, and the all-caps run that DOOMEternal needs).
  • TestSomeExecutablesAreNeverWorthAskingAbout
  • TestAGameNoLauncherClaimsIsLookedUpByName — asserts the published title is the store's, not the term.
  • TestAnUnknownExecutableStaysUnreportedWhenTheStoreHasNothing — five polls, one request.
  • TestAProgramThatIsNeverAGameNeverReachesTheStore

TestAPathNoLauncherClaimsIsNotAGame kept its assertions but its comment was rewritten: "no launcher claims it" is no longer why a browser is rejected, and a comment that explains the wrong mechanism is worse than none.

Documentation

game-identification.md and how-values-are-obtained.md, both languages — the third source, what now leaves the machine, and the new "title and id but no platform" case under Missing rather than guessed.

A game bought outside Steam, GOG and Epic — or installed by hand — is in
no catalogue on the machine, so it produced no details at all. The
executable was the only thing left, and it was thrown away.

It now becomes a question. Cyberpunk2077.exe asks the store about
"Cyberpunk 2077", MyGame-Win64-Shipping.exe about "My Game". That is the
only guess in the package, and it is a guess about what to ask, never
about what to report: what gets published is the title the store answers
with and the id it gave, or nothing. Search carries both halves now,
because where the term was worked out from a file name the store's
spelling is the only spelling anybody checked.

No platform is reported for such a game. None is known — an empty field
is left out of every export rather than filled in.

Programs that are never games are not asked about at all. RTSS hooks
whatever presents frames, so a browser turns up here as readily as a game,
and "Origin" would come back as a game called Origin.
Steam did not launch it and need not even be installed. But the platform
names where the identity came from rather than the shop the game was
bought from, and Steam's catalogue is what answered — verified live
against Crimson Desert, which no launcher on the machine claims and which
the store resolves to 3321460.

It is also the store the app id belongs to. Publishing an id with no
platform beside it would leave a reader to work out for themselves which
catalogue that number addresses.
@corgan2222
corgan2222 force-pushed the feature/gameid-name-search branch from b03f7fa to b346599 Compare August 13, 2026 03:54
@corgan2222
corgan2222 merged commit ff58f62 into main Aug 13, 2026
8 of 9 checks passed
@corgan2222
corgan2222 deleted the feature/gameid-name-search branch August 13, 2026 03:56
corgan2222 added a commit that referenced this pull request Aug 13, 2026
> Stacked on #66. Base is `feature/gameid-name-search`, so this diff
shows only the grace period.

RTSS reports what is **rendering**. A game that is open is not always
rendering — alt-tab to the desktop and many of them stop presenting
frames. RTSS drops the entry, and the game, its title and its Steam app
id vanish at once: a Home Assistant card that empties and refills every
time somebody switches windows.

The *identity* of the game is now held for fifteen seconds after RTSS
stops reporting it. Long enough to cover looking something up in a
browser and coming back; short enough that a game which really has been
closed is gone before anybody looks.

## Only the identity

Everything that answers a different question keeps answering for itself:

| | While a game is open but not rendering |
|---|---|
| `game`, and the platform, title and app id | held, up to 15 s |
| `game_running` | **false** at once — nothing is rendering |
| `fps`, `frametime` | as measured, which is nothing |
| `game_pid` | dropped — once RTSS lets go, that number may already
belong to somebody else |

That split is the whole design. "Which game is open" is the one thing
alt-tabbing does not change, so holding it is not a stale value — it is
the correct answer to a question the source briefly stopped being able
to answer. "Is it rendering" and "how fast" genuinely did change, and
they say so immediately.

## Not the dashboard's linger

`webui/linger.go` holds panel rows and is explicitly display-only —
nothing it shows reaches an export. This one is different on purpose: it
is a statement about the machine and it is published like any other
reading. Both docs pages say so, so the two are not confused later.

## A rendering game always wins

The remembered game is only ever consulted when nothing is rendering, so
switching between two games never shows the wrong one for fifteen
seconds.

## Tests

- `TestTheOpenGameSurvivesAPauseInRendering` — ten seconds after
rendering stops, the name, title and app id are still there while
`game_running`, the frame rate and the process id behave as above.
- `TestTheOpenGameIsForgottenAfterTheLinger`
- `TestAGameThatStartsRenderingReplacesTheRememberedOneAtOnce`
- `TestNothingIsHeldWhenNoGameHasEverRun`

The clock is injected (`Collector.now`), so none of them wait.

## Documentation

`game-identification.md` and `how-values-are-obtained.md`, both
languages — including a correction: the existing sentence "that lets a
game that has ended fall back to `none`" was no longer the whole truth.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant