6.4 KiB
Cyberpunk 2077 Vortex extension for Linux (Proton / SteamTinkerLaunch)
A Vortex game extension for Cyberpunk 2077 that works when Vortex itself runs inside a Wine/Proton prefix, e.g. launched through SteamTinkerLaunch on Linux Mint.
Why the community extension crashes here
The official/community extension discovers the game with Vortex's
GameStoreHelper.findByAppId(...). Inside a Proton prefix that helper reads the
Windows Steam client's config:
ENOENT: no such file or directory, open 'C:\Program Files (x86)\Steam\config\libraryfolders.vdf'
SteamTinkerLaunch puts steamclient.dll and friends into
C:\Program Files (x86)\Steam inside the prefix, but never writes
config\libraryfolders.vdf — the real Steam libraries are native Linux
directories such as /home/<user>/.steam/steam and /mnt/<disk>/SteamLibrary.
The read throws, nothing catches it, and Vortex reports it as
unrecoverable error in the renderer, taking the whole UI down.
This extension fixes both halves of that:
- Own discovery. It never calls
GameStoreHelper. It reads the real Linux Steam configuration through Wine'sZ:drive (which maps/), parseslibraryfolders.vdfandappmanifest_1091500.acf, and verifiesbin/x64/Cyberpunk2077.exebefore reporting a game path. - Prefix repair. It recreates the missing
C:\Program Files (x86)\Steam\config\libraryfolders.vdfinside the prefix, pointing at the real libraries asZ:\...paths. That stops Vortex core's own Steam scan from crashing, which also unbreaks other extensions. An existing file is never overwritten unless you ask for it.
Requirements
- Vortex running in a Wine/Proton prefix (tested with the SteamTinkerLaunch
Vortex prefix at
~/.config/steamtinkerlaunch/vortex/compatdata/pfx) - Node.js 22+ on the Linux side, to build and install
- Cyberpunk 2077 installed through Steam
Install
npm install
tools/install-extension.sh
The script builds dist/, copies it to
<prefix>/drive_c/users/steamuser/AppData/Roaming/Vortex/plugins/game-cyberpunk2077-linux/,
and repairs the prefix's libraryfolders.vdf. Restart Vortex afterwards and
manage Cyberpunk 2077 (Linux/Proton).
Options:
| Flag | Effect |
|---|---|
--prefix <path> |
Use a different Wine prefix (default: the SteamTinkerLaunch Vortex prefix) |
--force-shim |
Rewrite libraryfolders.vdf even if one already exists |
--disable-bundled |
Rename Vortex's bundled game-cyberpunk2077 stub to .disabled, so only this extension offers Cyberpunk |
Repairing the prefix alone, without installing the extension:
node scripts/repair-prefix.mjs --dry-run # show what would be written
node scripts/repair-prefix.mjs # write it
Run the repair before starting Vortex if Vortex currently dies on launch.
Uninstall
rm -rf "$HOME/.config/steamtinkerlaunch/vortex/compatdata/pfx/drive_c/users/steamuser/AppData/Roaming/Vortex/plugins/game-cyberpunk2077-linux"
The libraryfolders.vdf shim can stay — Vortex core needs it. Delete it with:
rm "$HOME/.config/steamtinkerlaunch/vortex/compatdata/pfx/drive_c/Program Files (x86)/Steam/config/libraryfolders.vdf"
Configuration
Set CYBERPUNK2077_PATH to a Linux path to skip Steam discovery entirely, for
example a GOG copy:
CYBERPUNK2077_PATH=/mnt/games/GOG/Cyberpunk 2077
The variable has to be visible to the Vortex process inside the prefix, so set it in the SteamTinkerLaunch launch options for Vortex, not just in your shell.
Game id and Nexus downloads
The extension registers the game id cyberpunk2077linux, deliberately different
from the bundled cyberpunk2077 stub so the two can coexist. nexusPageId is
still cyberpunk2077, so mod pages and nxm:// downloads from the Cyberpunk
Nexus section resolve normally.
Mod layouts handled
The installer routes archive contents to the right place and strips wrapper
folders such as Cool Mod v1.2/:
| Archive contains | Installed to |
|---|---|
a game-root tree (archive/, bin/, r6/, red4ext/, mods/, engine/) |
the game directory, wrapper folder stripped |
loose .archive / .archive.xl files |
archive\pc\mod\ |
init.lua plus its folder |
bin\x64\plugins\cyber_engine_tweaks\mods\<folder>\ |
loose .reds files |
r6\scripts\<mod name>\ |
info.json plus archives/ (REDmod) |
mods\<folder>\ |
a bare .dll |
red4ext\plugins\<mod name>\ |
| anything else | copied verbatim, so nothing is silently dropped |
Files that sit beside a detected game-root tree (readmes, screenshots) are left out of the deployment.
Launching the game
Start Cyberpunk 2077 from Steam as usual. Vortex runs in its own prefix, so its "launch game" button would start the executable in the wrong prefix; the extension registers the executable for detection only.
Development
npm test # unit tests (vitest)
npm run typecheck # tsc --noEmit
npm run build # bundle to dist/
node scripts/smoke-load.cjs # load the built bundle with a stubbed vortex-api
The logic is split so it can be tested without Vortex or Wine:
| File | Responsibility |
|---|---|
src/vdf.ts |
Valve KeyValues parser/serialiser |
src/winePath.ts |
Linux ⇄ Z: path translation, separator-aware joins |
src/discovery.ts |
Steam roots, library folders, app install dir, game verification |
src/steamShim.ts |
Builds and writes the libraryfolders.vdf shim |
src/installer.ts |
Maps a mod archive's file list to install instructions |
src/gameart.ts |
Generates the tile artwork and encodes it as a PNG |
src/index.ts |
Vortex registration glue (the only file that touches vortex-api) |
Regenerating the artwork after editing src/gameart.ts:
npm run gameart # rewrites assets/gameart.png
npm run build renders the same image straight into dist/, so the two never
drift; the render is deterministic, so rebuilds produce byte-identical output.
Licence and trademarks
Public domain, released under the Unlicense - see
LICENSE. Copy it, change it, ship it, sell it, no attribution needed.
Cyberpunk 2077 is a trademark of CD PROJEKT S.A.; this is an unofficial modding
tool with no affiliation to CD PROJEKT S.A. or Nexus Mods. No game or Nexus
assets are redistributed here - the tile artwork is generated by
src/gameart.ts and is covered by the same public domain dedication.
