diff --git a/README.md b/README.md index 7ad92db..f30a653 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,8 @@ at a time: 6. put a game in it — its own installer, the one you downloaded, runs inside the bottle After that the library is where you live. A bottle holds titles you added; a title is a -program in that bottle, its name, and the arguments it starts with. Picking a program that +program in that bottle, its name, the arguments it starts with and any environment of its +own. Picking a program that carries `libcef.dll` fills those arguments in with what a Chromium client needs, because that is the one thing this stack is known to require and easy to forget. A title's name and arguments can be changed afterwards, a bottle can be renamed or thrown away, and the app diff --git a/docs/layout.md b/docs/layout.md index 208fe05..8db839d 100644 --- a/docs/layout.md +++ b/docs/layout.md @@ -96,7 +96,8 @@ after `~/.wine`, kills nothing of the user's and exits 0. ### Which is why the titles added by hand live in the prefix `sake-titles.json`, at the root of the bottle, holds what somebody added to the library -themselves — a name, the arguments, and the executable **relative to `drive_c`**. Nothing +themselves — a name, the arguments, the environment, and the executable **relative to +`drive_c`**. Nothing in it names the prefix, so it inherits everything the section above measured: a rename stays a `moveItem`, and throwing the bottle away takes its titles with it. Keeping the list under `~/Library/Sake` instead would make both of those an operation on two places @@ -106,6 +107,11 @@ Wine ignores what it does not recognise at a prefix's root — it keeps its own `.update-timestamp` there — and a bottle nobody has added anything to has no `sake-titles.json` at all. +**A field added to that file has to be optional going in.** `TitleStore.load()` turns any +decoding failure into an empty list rather than an error, so a required field would empty +the library of every bottle written before it existed, with nothing said. `environment` +was added that way on 2026-09-21 and the tests pin it. + **This file is the whole of it.** sake has no titles of its own to merge with: a bottle shows what somebody added to it and nothing else, so the file is the answer rather than one half of it. diff --git a/docs/roadmap.md b/docs/roadmap.md index 35e0c42..352d87d 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -111,7 +111,9 @@ patches in `patches/`. `runtime.md` has the measurement and what to look for. What the second title taught about profiles: Steam needed **nothing** per-title once the engine could host a swapchain across processes — no flags, no environment, no registry. The three Chromium flags sake offers are Battle.net's, measured on its 32-bit CEF, and Steam's -client cannot even take them. So a title profile is still name, executable and arguments, +client cannot even take them. So a title profile was name, executable and arguments until +2026-09-21, when it gained an environment of its own — `runtime.md` has what that may and +may not set — and the argument suggestion is a heuristic for one launcher rather than a rule for Chromium. Nothing yet knows that starting Diablo IV directly fails on the token — `runtime.md` says so, the app does not. @@ -252,7 +254,17 @@ easier to read than it was interleaved with `configure` flags. after an uninstall are all judgements, and all in the app target — `scripts/test.sh` only reaches `SakeKit`. `CLAUDE.md` says logic in a view stops being tested; this is the same thing one layer down. Either these move behind types that do not know about SwiftUI, or - the app target gets tests of its own. + the app target gets tests of its own. `typedEnvironment()`, added 2026-09-21, is another + of these: which variable names a title may not set is a judgement, and it lives in the app + target where the tests cannot reach it. +- **Two buttons say "Check Again" in the setup wizard.** The bottom bar adds one when the + step is the machine step, and `primary` adds another because that step is not done, so + both render the same verb. The comment above the first says it is there for the step + "worth repeating after it has passed" — which is the condition the code does not check. + Found 2026-09-21, not fixed. +- **Editing a title moves it to the end of the sidebar.** `TitleStore.add()` filters the id + out and appends, so saving Options reorders the library. Harmless and confusing, and it + cost a measurement on 2026-09-21: a row addressed by index was no longer the row it was. - **Where the CrossOver version lives.** It is a knob users may need — a newer CrossOver may fix or break a given game — but exposing it invites them to pick a combination nobody has run. Steam gave the knob a concrete reason on 2026-09-20: two of sake's patches are diff --git a/docs/runtime.md b/docs/runtime.md index ac12819..7dddd06 100644 --- a/docs/runtime.md +++ b/docs/runtime.md @@ -303,6 +303,14 @@ about the token. Implication for sake: a "launch the game directly" button cannot work for this title on its own. The launcher's own flow has to be driven at least once per session. +**There is a third way in that nobody here has tried.** Blizzard installs its own +`Diablo IV Launcher.exe` beside the game, and the desktop shortcut the installer leaves +points at that with no arguments at all — read out of +`drive_c/users/Public/Desktop/Diablo IV.lnk` on 2026-09-21, 250 bytes, target and working +directory and nothing else. So "start Diablo IV" as a title in sake need not mean starting +`Diablo IV.exe`: it can mean starting the launcher Blizzard ships, which talks to the +client the way the Play button does. **Untested** — the shortcut was read, not run. + ## Controllers need SDL2 `winebus.sys` has two backends. **IOHID** is built either way and handles anything behaving