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
4 changes: 3 additions & 1 deletion .SRCINFO
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pkgbase = vortex-linux
pkgdesc = Community build of Vortex with generic Linux compatibility patches
pkgver = 2.9.0
pkgrel = 2
pkgrel = 3
url = https://github.com/Arkazzae/VortexLinux
install = vortex.install
arch = x86_64
Expand Down Expand Up @@ -94,6 +94,7 @@ pkgbase = vortex-linux
source = 0035-linux-backslash-archive-paths.patch
source = 0036-linux-appimage-nxm-links.patch
source = 0037-linux-case-consistent-folders.patch
source = 0038-linux-default-wine-prefix.patch
source = vortex.sh
source = vortex.desktop
source = README.md
Expand Down Expand Up @@ -146,6 +147,7 @@ pkgbase = vortex-linux
sha512sums = SKIP
sha512sums = SKIP
sha512sums = SKIP
sha512sums = SKIP
sha512sums = 935db5c6cee19f2c016e67168bfae7b491044735de76c673abb3b125dd325fd5e779d7efe12ba80178d46689ae70a25e558a3fa846417d44c5f4ca256e7f4bf2
sha512sums = e3f31d298a2b674b54c7fc89fb3f06d9645fc5879a54f2ebf2ea20e9ee7ae55f1bfe3284c1f90a591d6be2d6bcd251790ddc27771d65303e7a6a56d331df4632
sha512sums = 2161dfa1cf027cdc074de7195b5f206b17ebd829ae415b9e7c9ee5f06d3952b6583030022dbe0d6e9221b5c577c411d7cd5322241f6d2299d9c886641215699b
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ publishes a new Vortex version, taking any pending notes with it.

## Unreleased

- A game added by hand, outside Steam and Heroic, runs in Wine's default
prefix (`$WINEPREFIX` or `~/.wine`) instead of failing with "The game's Wine
prefix is unavailable". The message now also says where to set a different
prefix: edit the game on the Dashboard, Environment Variables. (#22)

## 2.9.0-2 - 2026-10-22

- Mods whose archives use Windows backslashes between folders install
Expand Down
4 changes: 3 additions & 1 deletion PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pkgname=vortex-linux
pkgver=2.9.0
pkgrel=2
pkgrel=3
pkgdesc="Community build of Vortex with generic Linux compatibility patches"
arch=('x86_64')
url="https://github.com/Arkazzae/VortexLinux"
Expand Down Expand Up @@ -138,6 +138,7 @@ _patches=(
'0035-linux-backslash-archive-paths.patch'
'0036-linux-appimage-nxm-links.patch'
'0037-linux-case-consistent-folders.patch'
'0038-linux-default-wine-prefix.patch'
)

source=(
Expand Down Expand Up @@ -211,6 +212,7 @@ sha512sums=(
'SKIP'
'SKIP'
'SKIP'
'SKIP'
# Keep integrity checks for binaries downloaded outside this repository.
'935db5c6cee19f2c016e67168bfae7b491044735de76c673abb3b125dd325fd5e779d7efe12ba80178d46689ae70a25e558a3fa846417d44c5f4ca256e7f4bf2'
'e3f31d298a2b674b54c7fc89fb3f06d9645fc5879a54f2ebf2ea20e9ee7ae55f1bfe3284c1f90a591d6be2d6bcd251790ddc27771d65303e7a6a56d331df4632'
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ The selected game determines which prefix Vortex uses. Steam’s per-game Proton
selection takes precedence over its default selection. Heroic’s game settings
select Wine, Proton or UMU; Flatpak tools run inside the Heroic Flatpak.

For a manually added Wine game, set `WINEPREFIX` in its environment settings.
A game added by hand runs in Wine's default prefix, `$WINEPREFIX` or `~/.wine`.
For another prefix, edit the game on the Dashboard and set `WINEPREFIX` under
Environment Variables.
`VORTEX_COMPAT_PREFIXES` can list additional prefixes, separated by colons, for
lookups without a selected game. If several prefixes match, Vortex reports the
ambiguity instead of choosing by modification time.
Expand Down
103 changes: 103 additions & 0 deletions patches/0038-linux-default-wine-prefix.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
diff --git a/src/renderer/src/util/compatibilityPaths.ts b/src/renderer/src/util/compatibilityPaths.ts
--- a/src/renderer/src/util/compatibilityPaths.ts
+++ b/src/renderer/src/util/compatibilityPaths.ts
@@ -85,9 +85,21 @@ function resolveGamePrefix(game: CompatibilityGame): string | null | undefined {
return installation.prefix;
}
}
+ if (!game.store) return defaultWinePrefix();
return undefined;
}

+/**
+ * A game added by hand has no store to ask, so it lives where plain Wine runs
+ * everything: $WINEPREFIX, or ~/.wine when that isn't set.
+ */
+function defaultWinePrefix(): string | undefined {
+ const prefix = path.resolve(
+ expandHome(process.env.WINEPREFIX || path.join(os.homedir(), ".wine")),
+ );
+ return fs.existsSync(path.join(prefix, "drive_c")) ? prefix : undefined;
+}
+
interface IUserPathMapping {
linuxRoot: string;
windowsRoot: string[];
@@ -329,7 +341,7 @@ export function resolveExtensionUserPathSync(input: string): string {
function unavailablePrefix(): Error {
return Object.assign(
new Error(
- "The selected game's Wine/Proton user profile is unavailable. Launch the game once, or configure its WINEPREFIX.",
+ "The selected game's Wine/Proton user profile is unavailable. Launch the game once, or edit the game on the Dashboard and set WINEPREFIX under Environment Variables.",
),
{ code: "ENOENT" },
);
diff --git a/src/renderer/src/util/compatibilitySelection.test.ts b/src/renderer/src/util/compatibilitySelection.test.ts
--- a/src/renderer/src/util/compatibilitySelection.test.ts
+++ b/src/renderer/src/util/compatibilitySelection.test.ts
@@ -172,6 +172,30 @@ describe.runIf(process.platform === "linux")("selected compatibility prefix", ()
expect(resolveWindowsUserPathSync(path.join(documents, relative))).toBe(expected);
});

+ it("uses Wine's default prefix for a game added by hand", () => {
+ vi.stubEnv("WINEPREFIX", "");
+ const wine = path.join(home, ".wine");
+ const user = path.join(wine, "drive_c/users", os.userInfo().username);
+ fs.mkdirSync(path.join(user, "Documents"), { recursive: true });
+ const game = { path: path.join(home, "Games/Example"), executable: "Example.exe" };
+ setCompatibilityGameProvider(() => game);
+ expect(resolveWindowsUserPathSync(path.join(documents, relative))).toBe(
+ path.join(user, "Documents", relative),
+ );
+
+ const exported = path.join(home, "exported-prefix");
+ fs.mkdirSync(path.join(exported, "drive_c/users/steamuser/Documents"), { recursive: true });
+ vi.stubEnv("WINEPREFIX", exported);
+ resetCompatibilityPathCache();
+ expect(resolveWindowsUserPathSync(path.join(documents, relative))).toBe(
+ path.join(exported, "drive_c/users/steamuser/Documents", relative),
+ );
+
+ // A store game that wasn't launched yet keeps asking for its own prefix.
+ setCompatibilityGameProvider(() => ({ ...game, store: "steam" }));
+ expect(() => resolveWindowsUserPathSync(path.join(documents, relative))).toThrow(/unavailable/);
+ });
+
it("keeps native game paths and Vortex state outside Proton", () => {
const gamePath = path.join(home, "native");
fs.mkdirSync(gamePath);
diff --git a/src/renderer/src/util/linux/gameTools.test.ts b/src/renderer/src/util/linux/gameTools.test.ts
--- a/src/renderer/src/util/linux/gameTools.test.ts
+++ b/src/renderer/src/util/linux/gameTools.test.ts
@@ -171,6 +171,19 @@ describe.runIf(process.platform === "linux")("game tool runner", () => {
resolveGameTool("Tool.exe", [], { env: { WINEPREFIX: path.join(root, "missing") } }),
).rejects.toThrow(/prefix is unavailable/);
});
+ it("runs a game added by hand in Wine's default prefix", async () => {
+ vi.stubEnv("WINEPREFIX", "");
+ const manual = { path: path.join(root, "Games/Example"), executable: "Example.exe" };
+ const game = path.join(manual.path, manual.executable);
+ write(game, "MZ");
+ await expect(resolveGameTool(game, [], {}, manual)).rejects.toThrow(/Environment Variables/);
+ fs.mkdirSync(path.join(root, ".wine/drive_c"), { recursive: true });
+ resetCompatibilityPathCache();
+ const command = await resolveGameTool(game, [], {}, manual);
+ expect(command.executable).toBe("wine");
+ expect(command.args).toEqual([game]);
+ expect(command.options.env.WINEPREFIX).toBe(path.join(root, ".wine"));
+ });
it("does not launch a Steam tool in a different Wine prefix", async () => {
proton("Proton 10.0");
const other = path.join(root, "other");
diff --git a/src/renderer/src/util/linux/gameTools.ts b/src/renderer/src/util/linux/gameTools.ts
--- a/src/renderer/src/util/linux/gameTools.ts
+++ b/src/renderer/src/util/linux/gameTools.ts
@@ -47,7 +47,7 @@ export async function resolveGameTool(
const prefix = options.env?.WINEPREFIX ?? selectedGamePrefix(game);
if (!prefix || !fs.existsSync(path.join(prefix, "drive_c"))) {
throw new Error(
- "The game's Wine prefix is unavailable. Launch the game once or configure WINEPREFIX for this tool.",
+ "The game's Wine prefix is unavailable. Launch the game once, or edit the game or tool on the Dashboard and set WINEPREFIX under Environment Variables.",
);
}
if (game?.store === "steam") {
Loading