Repository navigation
Conversation
`AnyGame.init(from:)` decoded the storefront tag with `try`, so a tag the
running build does not recognise threw. `GameDataStore` decodes the whole
`[AnyGame]` array in one call and `UserDefaults.decodeAndGet` swallows any
error into `nil`, which the observer then reads as an empty library -- so a
single unreadable row discards every game from every other storefront too.
Measured on 0.6.0 by seeding `games` with one unknown storefront tag plus
one ordinary local game:
0.6.0 0 of 2 survive -- library wiped, local game included
this change 2 of 2 survive -- unknown tag degraded, local untouched
Worth shipping ahead of any new storefront case, because the build that
needs the tolerance is the older one: by the time a new tag exists on disk,
the release that cannot read it is already out.
`Game.storefront` on the base class logs instead of asserting, since a bare
`Game` is now a legitimate decode outcome rather than a programmer error.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Implements most of the Steam Development Roadmap on the current engine. SteamCMD is a native macOS binary and never involves Wine, so installing, updating, verifying and enumerating all work today; Wine is only involved in launching a downloaded title, through the path that already exists. Covers the board's "SteamCMD installation", "Functional signin + steam guard support", "Fetch game list", "Game installing + progress handling", "Game moving", "Game update checker", "Custom install directory" and "SteamCMD autoupdate parser". **Layering.** `ValveDataFormat` and `SteamCMDOutput` are dependency-free readers for Valve's KeyValues format and for SteamCMD's own output. `SteamCMD` drives the binary; `Steam` is the storefront service, the peer of `Legendary`; `SteamGameManager` conforms to `StorefrontGameManager`. **Things that had to be measured rather than assumed**, recorded at the call sites because each one produced wrong behaviour first: - `licenses_print` caps the app IDs it prints per package and says so (`(N in total)`). On a real account 171 of 455 sat behind one elided line, recovered by re-reading that package with `package_info_print`. - `@ShutdownOnFailedCommand` defaults to 1, which abandons every remaining command once one fails. An empty `app_info_print` counts, so a 25-app metadata batch returned exactly one result. - `common/type` casing is inconsistent -- `game` for Terraria and Dota 2, `Game` for Palworld, in one batch -- so it is normalised before the filter that keeps DLC and soundtracks out of a game library. - SteamCMD's bootstrapper output is localised mid-stream, so only its numeric `[ n%]` / `[----]` prefixes are matched, never English words. - `force_install_dir` must precede `login`, or SteamCMD refuses outright. - Exit code 42 *is* the self-update mechanism, handled by `steamcmd.sh`, which is why the script is invoked rather than the binary. - The mobile-authenticator flow reports its outcome on its own line (`Waiting for confirmation...OK`); the `to Steam Public...` line never gains a verdict in that case. - SteamCMD writes its session relative to `HOME`, which by default is the user's real Steam installation. `HOME` is scoped: measured at 15 files written under Mythic's own directory and zero touched in the user's. - Bulk output is read whole rather than streamed. `Process.runStreamed` splits whatever a single `read()` returned, so a line spanning two reads arrives as two fragments; an enumeration that received 188 licence lines parsed 7 of them. Streaming stays for downloads and for signing in. - Concurrent SteamCMD runs share one session directory and corrupt each other rather than failing: two overlapping enumerations returned 4 and 18 app IDs where one returns 455. Runs are serialised, and enumeration collapses concurrent callers onto one task. **Deliberately not attempted.** Titles that authenticate through a live Steam client cannot launch: the client's Chromium 126 helper does not survive the engine's `wine-7.7`. They download correctly and then fail to start, and that failure now explains itself rather than silently doing nothing. `Fetch game list` covers owned titles; see the issue for why a complete list needs one of three separate problems solved first. Localisation: the pt-BR values are only for strings introduced here, added while testing in that locale -- happy to strip them if Crowdin should own them. No existing catalogue entry is modified. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Morialkar
added a commit
to Morialkar/Mythic
that referenced
this pull request
Oct 6, 2026
…#293 MythicApp#273 renamed `Rosetta.exists` to `Rosetta.isInstalled`; MythicApp#293 still called the old name, so the combined branch did not compile. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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.
Implements most of the Steam Development Roadmap on the current engine. SteamCMD is a native macOS binary and never involves Wine, so installing, updating, verifying and enumerating all work today; Wine is only involved in launching a downloaded title, through the path that already exists.
Covers: SteamCMD installation, Functional signin + steam guard support, Fetch game list, Game installing + progress handling, Game moving, Game update checker, Custom install directory, SteamCMD autoupdate parser.
Layering
ValveDataFormatandSteamCMDOutputare dependency-free readers for Valve KeyValues and for SteamCMD output.SteamCMDdrives the binary.Steamis the storefront service — the peer ofLegendary.SteamGameManagerconforms toStorefrontGameManager.Things that had to be measured
Each of these produced wrong behaviour first, so each is recorded at its call site:
licenses_printcaps the app IDs printed per package and says so ((N in total)). On a real account 171 of 455 sat behind one elided line, recovered withpackage_info_print.@ShutdownOnFailedCommanddefaults to1, abandoning every remaining command once one fails. An emptyapp_info_printcounts, so a 25-app metadata batch returned exactly one result.common/typecasing is inconsistent —gamefor Terraria and Dota 2,Gamefor Palworld, in one batch.[ n%]/[----]prefixes are matched, never English words.force_install_dirmust precedelogin, or SteamCMD refuses outright.steamcmd.sh— which is why the script is invoked, not the binary.Waiting for confirmation...OK);to Steam Public...never gains a verdict in that case.HOME, by default the user’s real Steam installation.HOMEis scoped: 15 files written under Mythic’s directory, zero touched in the user’s.Process.runStreamedsplits whatever a singleread()returned, so a line spanning two reads arrives as two fragments — an enumeration that received 188 licence lines parsed 7. Streaming stays for downloads and sign-in, which tolerate fragments.Not attempted
The Steam client's own UI does not run on the engine — its Chromium 126 helper crash-loops on
wine-7.7— so the client can be started but never signs in, and anything needing a Steam auth ticket fails.That is narrower than "cannot launch", which is what I first wrote here and have corrected in #289. The game I tested does launch and run; what fails is online authentication, and it says so itself (
ConnectLoginNoEAS() failed due to the platform OSS giving an empty auth token). A title that never asks for a ticket may well be fine. Launches that do fail now explain themselves instead of silently doing nothing.Verification
Exercised end to end against a real account on Engine 2.6.1, in the app rather than in a harness:
Waiting for confirmation...OK, then[Logged On]with a real SteamIDcommon/typeSuccess! App '1623730' fully installed.appmanifest_<appid>.acf:StateFlags 4,buildid == TargetBuildIDxcodebuildclean andswiftlintclean for every file touched — the three warnings it still reports all predate this branch.The parsing layers additionally carry 67 assertions over verbatim SteamCMD captures, compiled standalone since there is no test target. Not included here (it trips
force_tryunder your.swiftlint.yml); offered in #289.Screenshots
Hosted on a branch of the fork rather than committed here, so they add nothing to this diff.
Library, after enumeration — 103 titles, artwork from Steam's CDN, app ID on each badge:
Import by app ID — the tab that was hidden and
.hidden()upstream. Empty state explains itself rather than asking the CDN for artwork it cannot have:A launch that fails now says so. Previously the operation completed without error, so the UI showed a brief spinner and nothing else:
Interface language is the tester's; the strings this PR adds are English source entries in the catalogue.