Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/ISSUE_TEMPLATE/compatibility.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Compatibility report
description: How a game ran with sake — working or not.
title: "Compatibility: "
labels: ["compatibility"]
body:
- type: markdown
attributes:
value: |
A game that runs is worth reporting as much as one that does not: these reports are what the README's list of games is made from.
- type: input
id: game
attributes:
label: Game
placeholder: Diablo IV
validations:
required: true
- type: input
id: store
attributes:
label: Store or launcher
placeholder: Steam, Battle.net, the publisher's own installer…
validations:
required: true
- type: dropdown
id: result
attributes:
label: How far did it get?
options:
- It plays
- It plays, with problems
- It starts but cannot be played
- It does not start
validations:
required: true
- type: input
id: version
attributes:
label: sake version
description: In the app menu, About Sake.
placeholder: 0.2.0
validations:
required: true
- type: input
id: mac
attributes:
label: Mac and macOS version
placeholder: MacBook Air (M2), macOS 26.1
validations:
required: true
- type: textarea
id: details
attributes:
label: What you did, and what happened
description: Anything you changed on the way — arguments, environment variables, winecfg settings — and anything that did not work, such as online play or a controller.
- type: textarea
id: log
attributes:
label: Log
description: If it did not work, the title's log from `~/Library/Caches/Sake/build/` (`title-<name>.log`). Paths in it show your macOS user name.
render: text
44 changes: 30 additions & 14 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,28 +123,44 @@ 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/getting-started.md` | Diablo IV from an empty Mac to a keypress; instructions for using sake |
| `docs/troubleshooting.md` | what to do when something goes wrong; instructions, like getting-started |
| `docs/how-it-works.md` | the overview: engine, bottles, titles, the setup steps, what Play does, the patches at a glance |
| `docs/roadmap.md` | where the project stands, what is next, open questions, and the settled Swift/subprocess boundary |
| `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 |
| `docs/runtime.md` | the settings every run needs, starting and stopping a title, controllers, and what each patch fixes and how to tell |
| `docs/gdk.md` | GDK titles: the runtime DLL and the sign-in sake provides in place of Gaming Services |
| `docs/debugging.md` | telling failure states apart, and the instruments and techniques that found things |
| `docs/licensing.md` | what may not be redistributed, and what the app may not do for the user |
| `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 |

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
something itself the section says so and gives the date — keep that distinction, and date
what you add.
Standing rules about that content:

- **`docs/` is written for people first.** An AI reads it too, but it is laid out for somebody
who opens one file to find one thing. A section's first sentence is the rule, the fact or
what to do; the measurement behind it comes after. One topic has one home, and other files
link to it. There is no revision history: a correction replaces the wrong sentence, git keeps
the old one, and a wrong answer that looks right stays only as a trap worth naming. An
answered question leaves Open questions, and its answer goes where the topic lives.
- **Claims in `docs/` carry their source and date**, as a tag at the end —
`(sake, 2026-09-19)`, `(prototype, 2026-09-17)`, `(the owner's report, 2026-09-20)`,
`(read in CrossOver 26.3.0's sources, 2026-09-29)` — or once, in an italic line under the
heading, when a whole section was measured in one sitting. Most findings were measured in
the prototype and not in sake; do not restate those as sake's own, and date 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/`.
- **`docs/getting-started.md` and `docs/troubleshooting.md` are instructions, and stay that
way.** They are 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/`.
- **`runtime.md` and `gdk.md` keep their names.** `patches/*.patch` names the first and
`xgameruntime/src/` the second, and neither can follow a rename: a patch's bytes are the
engine's fingerprint and `xgameruntime/` but its README is the runtime's stamp, so every
user's setup would ask for a rebuild. Keep what those comments point at in the file they name.
- **The README's "Verified by me" is the owner's**: a game goes there once the owner has
played it. A community entry comes from a report and links it.

## Licence boundary

Expand Down
84 changes: 50 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,43 @@ GUI, so none of it takes a terminal.

![The library window: a bottle in the sidebar with the titles in it, one selected, with a Play button and the arguments it starts with](assets/library.png)

## Status
## What runs

Playing here now:
### Verified by me

- **Diablo IV**
- **Steam**
- **Diablo IV** (Battle.net) — start it from the Battle.net launcher
- **Stardew Valley** (Steam)
- **Minecraft Dungeons II** (Steam, 0.2.0+) — party codes work

I wrote sake to play those two, and that is as far as it has been taken — one person, one
Mac. If you get something else running with it I would like to hear about it, and if you
cannot, that is worth hearing too.
That is one person on one Mac, an Apple M5 on macOS 27. The Battle.net and Steam clients
themselves install, sign in and run.

### Verified by the community

Nothing yet — [report it](https://github.com/typester/sake/issues/new?template=compatibility.yml)!
A game that runs is worth hearing about, and so is one that does not.

## What it does

The app answers whether this Mac can do the rest — Apple silicon, Rosetta 2, the Command
Line Tools, Apple's Game Porting Toolkit, room on disk — then walks seven steps, one screen
at a time:
The setup wizard walks seven steps, one screen each. The first checks this Mac — Apple
silicon, Rosetta 2, the Command Line Tools, Apple's Game Porting Toolkit, room on disk — and
the other six build everything else:

1. download the sources and check them against known hashes
2. unpack them and build the tools and libraries Wine is configured against
3. build CrossOver's Wine itself, with the patches in `patches/`
4. guide Apple's D3DMetal in from an image you mounted, and unmount it again
5. build what games made with Microsoft's GDK load in place of Xbox Gaming Services
6. make a bottle — one Wine prefix, which is where a game lives
7. 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, 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
menu has an Uninstall that takes away everything sake made. All of it goes to the Trash, so
it can be put back.
After that the library is where you live. A game goes into a bottle through its own
installer, the one you downloaded, run inside the bottle. A bottle holds titles you added; a
title is a 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 menu has an Uninstall that takes the engine, the bottles and the
caches away. All of it goes to the Trash, so it can be put back.

## Requirements

Expand Down Expand Up @@ -89,10 +93,12 @@ Play button.
For a launcher like Battle.net, start the launcher and press Play inside it. sake
deliberately does not offer a button that starts Diablo IV directly: the client only hands
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.
token. [`docs/runtime.md`](docs/runtime.md#pressing-play-does-two-separable-things) 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.
When something goes wrong, [Troubleshooting](docs/troubleshooting.md) is where to look.

## Why build Wine at all

Expand All @@ -104,7 +110,7 @@ wishful thinking. Upstream Wine does not have it.
**D3DMetal itself is not redistributable**, so sake will never ship it, download it for you,
or take it out of an installed CrossOver — it guides you through downloading Apple's Game
Porting Toolkit yourself, mounts the image inside it, copies out the part it needs, and
unmounts it again. See `docs/licensing.md`.
unmounts it again. See [`docs/licensing.md`](docs/licensing.md).

## What is here

Expand Down Expand Up @@ -133,24 +139,34 @@ Requires the Xcode Command Line Tools. Xcode is not needed, and there is no Xcod
On macOS 27 the Command Line Tools default to the macOS 27.0 SDK, which SwiftUI cannot be
built against without a macro plugin the CLT do not ship. `build-app.sh` detects this and
falls back to a macOS 26 SDK, printing what it did. Override with `SDKROOT` if needed. See
`CLAUDE.md` for the full story.
[`CLAUDE.md`](CLAUDE.md) for the full story.

## Documentation

`docs/` is the real content of this repository. Every claim in it names where and when it was
measured. Much of it is still the prototype's; the sections sake has measured itself say so
and carry their own date.
Using sake:

| 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 |
| `docs/licensing.md` | what may and may not be redistributed, and why D3DMetal is unavoidable |
| `docs/layout.md` | where files go, why importing a 100 GB game costs nothing and removing it returns nothing either, why nothing mutable lives in the app bundle, and what pins a built tree to its path |
- [Getting started](docs/getting-started.md) — Diablo IV from an empty Mac to a character on screen, with screenshots
- [Troubleshooting](docs/troubleshooting.md) — where the logs are, and what the known problems look like

How it works:

- [How sake works](docs/how-it-works.md) — engine, bottles and titles, the setup steps, what Play does, and what sake changes in Wine
- [Licensing](docs/licensing.md) — what sake may not ship or fetch for you, and why D3DMetal cannot be avoided
- [Where files live](docs/layout.md) — the on-disk layout, and why nothing mutable goes in the app

Working on sake:

- [Building Wine](docs/wine-build.md) — CrossOver's sources, the patches, and the configure flags that must stay
- [Running games](docs/runtime.md) — the settings every run needs, and what each patch fixes
- [GDK titles](docs/gdk.md) — the runtime and the Xbox sign-in sake provides in place of Gaming Services
- [Debugging](docs/debugging.md) — telling failure states apart, and the instruments that found things
- [Roadmap](docs/roadmap.md) — where it stands, what is next, and the questions still open
- [Releasing](docs/releasing.md) — how a release is cut

Most of what `docs/` says about Wine was first measured in the shell prototype sake replaced;
each claim says whose measurement it is and when.

## Licence

MIT, except `patches/`: patches against Wine's own source are derivatives of LGPL code and
are LGPL-2.1-or-later. See `docs/licensing.md`.
are LGPL-2.1-or-later. See [`docs/licensing.md`](docs/licensing.md).
Loading
Loading