diff --git a/CLAUDE.md b/CLAUDE.md index 2b8702b..386b495 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -116,6 +116,7 @@ implementing anything it covers. | file | what it covers | |---|---| +| `docs/getting-started.md` | Diablo IV from an empty Mac to a keypress; the only file here for using sake | | `docs/roadmap.md` | phases, and the settled boundary between Swift and subprocesses | | `docs/wine-build.md` | building Wine; the configure flags that must not be removed | | `docs/runtime.md` | the three settings games need, the Play-button root cause, controllers, failure states | @@ -123,7 +124,7 @@ implementing anything it covers. | `docs/layout.md` | on-disk layout, why nothing mutable goes in the bundle, relocatability | | `docs/releasing.md` | how a release is cut, and the three things it needs that are not in this repository | -Two standing rules about that content: +Three standing rules about that content: - **Claims in `docs/` carry their source and date.** Most were measured in the prototype and not in sake; do not restate those as sake's own behaviour. Where sake has measured @@ -131,6 +132,11 @@ Two standing rules about that content: what you add. - **Do not relitigate the Swift/subprocess boundary** without new information; `docs/roadmap.md` records why it is where it is. +- **`docs/getting-started.md` is instructions, and stays that way.** It is written for somebody + using sake rather than building it: steps rather than prose, and **no dated claims at all** — + what has been run here, what has not, and on which hardware belongs in the files that already + carry it, because a page people follow is where that goes stale first. Screenshots go in + `assets/getting-started/`. ## Licence boundary diff --git a/README.md b/README.md index f30a653..28310ff 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,9 @@ deliberately does not offer a button that starts Diablo IV directly: the client out a login token after that press, so a direct start reaches the game and then fails on the token. `docs/runtime.md` has the measurements behind that. +**[`docs/getting-started.md`](docs/getting-started.md) walks one game through all of this +with screenshots** — Diablo IV, from a Mac with nothing on it to a character on screen. + ## Why build Wine at all The piece that makes DirectX 12 work on macOS is Apple's closed D3DMetal, and the Wine-side @@ -108,8 +111,8 @@ unmounts it again. See `docs/licensing.md`. | `Sources/SakeKit/` | the layout, a subprocess runner, the preflight checks, the source fetcher, the prefix build, the Wine build, the patch step, the D3DMetal step, the bottle, the import, the installer, the titles, starting one, how big a tree is, and the uninstall | | `Sources/sake/` | the SwiftUI app — two windows, kept thin | | `patches/` | the changes sake makes to Wine's own code — LGPL-2.1-or-later, not MIT; `patches/README.md` says where each came from | -| `docs/` | how the thing actually has to work, and what breaks when it doesn't | -| `assets/` | the app icon, the code that draws it, and the screenshot above | +| `docs/` | how the thing actually has to work, what breaks when it doesn't, and how to play one game | +| `assets/` | the app icon, the code that draws it, the screenshot above, and the guide's under `getting-started/` | | `scripts/build-app.sh` | builds `target/Sake.app` | | `scripts/make-icon.sh` | redraws `assets/Sake.icns` | | `scripts/test.sh` | runs the tests | @@ -137,6 +140,7 @@ and carry their own date. | file | what it covers | |---|---| +| `docs/getting-started.md` | the one written for using sake rather than building it: Diablo IV, step by step, with screenshots | | `docs/roadmap.md` | the goal, the phases, and where Swift stops and subprocesses start | | `docs/wine-build.md` | building Wine from CrossOver's sources; the flags that cannot be dropped | | `docs/runtime.md` | creating a prefix, the three settings that make games run, what pressing Play actually does, controllers, taking a bottle down, and how to tell four failure states apart | diff --git a/assets/getting-started/01-this-mac.png b/assets/getting-started/01-this-mac.png new file mode 100644 index 0000000..d84598e Binary files /dev/null and b/assets/getting-started/01-this-mac.png differ diff --git a/assets/getting-started/02-sources.png b/assets/getting-started/02-sources.png new file mode 100644 index 0000000..8cc9cf8 Binary files /dev/null and b/assets/getting-started/02-sources.png differ diff --git a/assets/getting-started/03-libraries.png b/assets/getting-started/03-libraries.png new file mode 100644 index 0000000..b8a11d4 Binary files /dev/null and b/assets/getting-started/03-libraries.png differ diff --git a/assets/getting-started/04-wine.png b/assets/getting-started/04-wine.png new file mode 100644 index 0000000..9be9770 Binary files /dev/null and b/assets/getting-started/04-wine.png differ diff --git a/assets/getting-started/05-d3dmetal.png b/assets/getting-started/05-d3dmetal.png new file mode 100644 index 0000000..1c8df67 Binary files /dev/null and b/assets/getting-started/05-d3dmetal.png differ diff --git a/assets/getting-started/06-bottle.png b/assets/getting-started/06-bottle.png new file mode 100644 index 0000000..6930d22 Binary files /dev/null and b/assets/getting-started/06-bottle.png differ diff --git a/assets/getting-started/07-bottle.png b/assets/getting-started/07-bottle.png new file mode 100644 index 0000000..384b47d Binary files /dev/null and b/assets/getting-started/07-bottle.png differ diff --git a/assets/getting-started/08-install.png b/assets/getting-started/08-install.png new file mode 100644 index 0000000..727e446 Binary files /dev/null and b/assets/getting-started/08-install.png differ diff --git a/assets/getting-started/09-add-title.png b/assets/getting-started/09-add-title.png new file mode 100644 index 0000000..436709f Binary files /dev/null and b/assets/getting-started/09-add-title.png differ diff --git a/assets/getting-started/10-title.png b/assets/getting-started/10-title.png new file mode 100644 index 0000000..661fbe6 Binary files /dev/null and b/assets/getting-started/10-title.png differ diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..1d8bd2e --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,126 @@ +# Getting started: Diablo IV + +Diablo IV on an Apple silicon Mac, from nothing installed to a character on screen. + +## Before you start + +- An Apple silicon Mac with Rosetta 2 — `softwareupdate --install-rosetta`. +- macOS 15 or newer, and the Xcode Command Line Tools — `xcode-select --install`. +- Apple's Game Porting Toolkit `.dmg` — **4.0 beta 2**, which is what the engine here is built + against — from . A free Apple ID is enough. sake + cannot fetch this for you; `docs/licensing.md` says why. +- A Battle.net account that owns Diablo IV, and Blizzard's installer for the client. sake does + not fetch that either. +- About 10 GB free for sake, and about 90 GB more for the game. + +sake keeps the engine and the bottles in `~/Library/Sake`, and downloads, build output and logs +in `~/Library/Caches/Sake`. **Uninstall sake…** in the app menu takes both to the Trash. + +## 1. Install sake + +```sh +brew tap typester/sake +brew install --cask sake +``` + +The app is not notarised, so Gatekeeper stops it the first time: allow it in System Settings > +Privacy & Security, or install with `--no-quarantine`. + +## 2. Set sake up + +Open sake. The wizard opens itself until the six steps are done; afterwards **Set Up…** in the +toolbar brings it back. + +### This Mac + +![The This Mac step with five requirements met](../assets/getting-started/01-this-mac.png) + +Five checks, and nothing below unlocks until they all pass. Install whatever is missing, then +press **Check Again**. + +### Sources + +![The Sources step, eleven downloads waiting](../assets/getting-started/02-sources.png) + +Press **Download**. Eleven files, ten of them checked against a hash sake carries; CrossOver's +own tarball is the exception. Nothing is built yet. + +### Libraries + +![The Libraries step, nine libraries waiting](../assets/getting-started/03-libraries.png) + +Press **Build**. Minutes. SDL2 is one of these, and it is what makes a controller work later. + +### Wine + +![The Wine step, before the build](../assets/getting-started/04-wine.png) + +Press **Build** and leave it alone. The app warns of tens of minutes; on ten cores here it took +4m40s. + +### D3DMetal + +![The D3DMetal step, before installing](../assets/getting-started/05-d3dmetal.png) + +Download Game Porting Toolkit 4.0 beta 2 from Apple, open the `.dmg`, and press **Install**. sake +copies what it needs out of the image and unmounts it. You only need the image once. + +### Bottle + +![The Bottle step, before the bottle is made](../assets/getting-started/06-bottle.png) + +Press **Create**. A bottle is one Windows environment and the game goes inside it. This one is +called `default`. + +## 3. Install the Battle.net client + +Download `Battle.net-Setup.exe` from Blizzard, then select the bottle in the library. + +![The bottle selected, with its buttons](../assets/getting-started/07-bottle.png) + +**Install from an Installer…**, choose the `.exe`, **Install**. Blizzard's installer runs in a +window of its own; click through it as you would on Windows. + +![The Install from an Installer sheet](../assets/getting-started/08-install.png) + +When it closes, the sheet offers **Add a Title…**, which is the next step. + +If Diablo IV is already installed under CrossOver, the bottle offers **Import from CrossOver…** +instead. It clones the game rather than copying it, so it costs no disk. + +## 4. Add the launcher as a title + +![The Add a Title sheet with the launcher chosen and its arguments filled in](../assets/getting-started/09-add-title.png) + +**Add a Title…**, then **Choose Program…**. The panel opens inside the bottle; the launcher is +`Program Files (x86)/Battle.net/Battle.net Launcher.exe`. The name and the arguments fill in by +themselves. **Add**. + +**Leave the arguments alone.** Without `--in-process-gpu` the login form is drawn but never +appears, and without the two ANGLE flags the client's GPU process exits. `docs/runtime.md` has +the measurements. + +## 5. Install the game + +Select the title and press **Play**. Sign in, and install Diablo IV from inside the client: +about 90 GB. + +![A title selected, with Play and the arguments it starts with](../assets/getting-started/10-title.png) + +## 6. Play + +Start Diablo IV from the Battle.net launcher. + +Enjoy! + +## A controller + +Nothing to set up. The engine is built with SDL2, so a controller should work. + +## If it does not start + +- Every run writes a log under `~/Library/Caches/Sake/build` — `title-.log` for a title, + `install-.log` for an installer. The window shows only the last line of it. +- **Wine Tools** on the bottle opens winecfg, regedit, the uninstaller and the task manager. +- `docs/runtime.md` tells four failure states apart by thread count, memory and Metal mappings. + Read that before deciding a build is broken. diff --git a/docs/runtime.md b/docs/runtime.md index 7dddd06..f492599 100644 --- a/docs/runtime.md +++ b/docs/runtime.md @@ -322,14 +322,24 @@ reasonable descriptor and then sends **no input reports at all** until it has be Nintendo's handshake, which lives in SDL's HIDAPI driver. An IOHID-only build gives a controller that is plugged in, visible to macOS, and completely dead in the game. -Verified by playing the game with a Switch Pro Controller over USB, 2026-09-17. Bluetooth -and other pads are untested. +Verified by playing the game with a Switch Pro Controller over USB, 2026-09-17. **The same controller and cable played Diablo IV through sake on 2026-09-20.** Reported by the owner, not instrumented — there is no log of that run. What it settles is that the SDL2 requirement above carries over to sake's own engine and bottle; it is not new evidence about the driver. +**And over Bluetooth on 2026-09-21** — the same pad, no cable, played in the game. The owner's +report again, which is what takes "Bluetooth is untested" off this section. Other pads are +still untested. + +**That pad is an 8BitDo Ultimate 2 Bluetooth Controller**, not Nintendo hardware: it claims +Nintendo's own ids, `Vendor 0x057E / Product 0x2009`, and macOS lists it as `Pro Controller`. +Read here from `system_profiler SPBluetoothDataType`, 2026-09-21. So "Switch Pro Controller" +above is the identity the pad presents rather than who built it — and that identity is the +thing that matters, because the ids are what send it down SDL's Switch driver and Nintendo's +handshake. + Use SDL2 newer than CrossOver's 2.30.12: 2.32.2 fixed a crash initialising with controllers already connected on macOS, 2.32.6 fixed reliability of initializing Switch controllers on macOS, and 2.32.10 fixed thumbstick range and calibration for Switch Pro Controllers by