Skip to content
Xnos666Public
forked from BeLikeBrett/WoWPS5

About

World of Warcraft (Forever and Classic Era), the Windows client, running natively on a jailbroken PS5: Wine + vkd3d-proton + RADV in one PS5 app. Bring your own game.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

WoW on PS5

World of Warcraft — Forever and Classic Era — running natively on a jailbroken PlayStation 5

The game's own Windows client runs inside one PS5 app, on Wine, with its DirectX 12 translated to the console's GPU.
No streaming. No Linux. No PC in the loop once it's copied.

Platform Games Wine Graphics License

Install · Play · Launch settings · Troubleshooting · How it works · Build

WoW Forever on a PS5 at 84 frames a second

Entering Durotar The title screen

WoW Forever, captured from a PS5 over Remote Play. The green text in the corner was a debug label used for the recording; it is not part of the release.

Important

A hobby project, not affiliated with or endorsed by Blizzard Entertainment or Sony. The game is not included: you copy your own installation and sign in with your own account on the console. Use it at your own risk.


The games

One app, two clients. Copy either or both; the app starts the one you pick.

WoW Forever WoW Classic Era
Folder _classic_beta_ _classic_era_
Program WowB.exe WowClassic.exe
Client build tested 1.60.1.70205, 70235, 70374 1.15.9.70003
Status ✅ Sign-in, character select, playing in the world, sound, controller 🧪 New: starts on the console and plays its intro; sign-in and the world are being tested
Graphics DirectX 12, as on PC DirectX 12, forced (-d3d12 and GxApi D3D12, set up by the installer)

Both share the Data folder and .build.info, exactly as Battle.net lays them out on a PC.

What's new in this fork

  • Classic Era support. The app knows both clients and starts the first one it finds (Forever, then Classic Era), or the one named by WOWPS5_GAME in the launch settings.
  • install.py --flavor copies only the game you want (_classic_beta_, _classic_era_, or both).
  • install.py --start switches the game the app starts, without copying anything again.
  • No more black screen on a first start. A client with no WTF/Config.wtf asks for your region and language in a window the console cannot show. The installer now writes a short Config.wtf (region, language, GxApi D3D12) for each game that has none, taking your PC's own values when it has them.
  • Faster runtime (from the perf/runtime work): thread priorities on by default (Trade Quarter: about 43 → 57–62 frames a second), no kernel call for memory protection that is already right, and a cache for RtlLookupFunctionEntry. Details in docs/technical-notes.md.

Install it

About 15 minutes of your time, plus the copy (50 to 65 GiB, depending on what you have installed).

What you need

  1. A jailbroken PS5 with a homebrew enabler running (tested: etaHEN with kstuff), and:
    • its FTP server on (port 2121 is the default of the common payloads),
    • ShadowMount (or another way to register an app folder from /data/homebrew),
    • about 70 GB free on the internal drive (more with both games).
  2. A PC on the same network with Python 3 (Linux, macOS or Windows).
  3. Your own World of Warcraft installation, kept up to date by Battle.net, with _classic_beta_ (WoW Forever) and/or _classic_era_ (WoW Classic Era) in it.
  4. The console's address on your network (PS5: Settings → Network → View Connection Status).

Steps

  1. Download the bundle from the latest release and unpack it.

  2. Turn the console on and run your jailbreak, so that FTP and ShadowMount are up.

  3. Run the installer from the unpacked folder. It copies the app, Wine and your game, and can be re-run if it is interrupted:

    # Everything you have installed; the app starts Forever if it is there
    python3 install.py --host 192.168.1.50 --wow "/path/to/World of Warcraft"
    
    # Only Classic Era, and start it
    python3 install.py --host 192.168.1.50 --wow "/path/to/World of Warcraft" --flavor _classic_era_ --start _classic_era_

    --host is the console's address; --wow is your game folder, the one that holds Data and the game folders. Nothing needs editing. Your installation on the PC is only read.

  4. On the console, the app appears on the home screen within a minute (its tile is still called WoW Forever). Start it.

  5. Sign in. Press L3 + R3 (click both sticks) to type with the on-screen keyboard.

The first start, and the first visit to each place, are slower than later ones: the graphics driver compiles the game's shaders once and keeps them.

Switching games

python3 install.py --host 192.168.1.50 --skip-app --start _classic_era_    # Classic Era
python3 install.py --host 192.168.1.50 --skip-app --start _classic_beta_   # WoW Forever
python3 install.py --host 192.168.1.50 --skip-app --start auto             # the first installed

This only rewrites the WOWPS5_GAME line of /data/wowps5/launch.txt; you can also edit that file over FTP yourself.

Installing by hand instead (FileZilla, WinSCP or any FTP program on port 2121)
Copy this To this place on the PS5
the folder title/PPSA99220 /data/homebrew/PPSA99220
the folder runtime/wowps5/wine /data/wowps5/wine
the file runtime/wowps5/ca-certificates.crt /data/wowps5/ca-certificates.crt
the three .reg files in runtime/wowps5/prefix /data/wowps5/prefix/
everything inside runtime/wowps5/prefix/drive_c /data/wowps5/prefix/dosdevices/c:/ (the last folder is named c:, with the colon)
your game's Data folder, .build.info, and _classic_beta_ and/or _classic_era_ /data/wowps5/prefix/dosdevices/c:/Games/World of Warcraft/

From the game folders, leave out WTF, Interface, Cache, Logs and Errors: PC settings do not suit the console, and the game makes these again. Then give each game a WTF/Config.wtf on the console with at least:

SET portal "US"
SET textLocale "enUS"
SET audioLocale "enUS"
SET GxApi "D3D12"

(portal "test" for WoW Forever; use your own region and language.) For Classic Era, also add the two lines from Launch settings.

When the game updates

The console cannot update the game itself. Let Battle.net update it on the PC, close the game on the console, then run the installer again with --skip-app:

python3 install.py --host 192.168.1.50 --wow "/path/to/World of Warcraft" --skip-app

It sends only the files the update changed (a few GiB, not the whole game). If your first copy was made by hand or with release 0.1.0, add --since "YYYY-MM-DD HH:MM" with the time of that copy, once: an update changes files without changing their size, and the installer has to know which are newer.

A new version of this port is installed the same way as the first: unpack the new release and run the installer. Your game, settings and shaders on the console stay.


Playing

Controls

Input What it does
Controller The game's own controller support and console UI
Touchpad Moves the mouse pointer; pressing it is a left click
L3 + R3 (click both sticks together) Opens the PS5 on-screen keyboard. What you type goes into the text box that has focus (login, search, chat), when you confirm
L3 + R3 again, before pressing anything else Opens the keyboard with what you just typed, to fix a mistake: confirming replaces the old text. Confirming an empty keyboard just deletes it
USB keyboard and mouse Work as on a PC (and Esc skips Classic Era's intro cinematic)

Frame rate above 60 (the uncapped mode)

By default a PS5 app gets exactly as many frames as the TV shows. This port adds a second way of presenting to the graphics driver, where the game draws as fast as it can and the screen shows the newest finished frame at each refresh, with no tearing.

To use it, in the game: System → Graphics → turn Vertical Sync off, and set Max Foreground FPS to what you like (or off). The game's frame counter then goes above 60 and input feels more direct; the TV still shows its own refresh rate.

Good to know

  • Leaving the game: use the game's own Exit Game. It takes about ten seconds to close.
  • Settings and add-on data are saved on the console when you leave the game normally.
  • A "system software" message from the PS5 while the game runs can be dismissed.
  • No voice chat.

Launch settings

/data/wowps5/launch.txt on the console, one setting a line, read at every start. Delete the file to return to the defaults.

Line What it does
NAME=value An environment setting for Wine and the game
+argument An argument for the game's program (for example +-d3d12)
# ... A comment
Setting Default
WOWPS5_GAME=<path of the .exe on the console> first installed Which game starts. Classic Era: /data/wowps5/prefix/dosdevices/c:/Games/World of Warcraft/_classic_era_/WowClassic.exe
+-d3d12 — Keeps the client on DirectX 12, the only graphics the port translates. Recommended for Classic Era
PS5_VIDEOOUT_MAILBOX=0 on Removes the uncapped present mode
VKD3D_CONFIG= single_queue Empty turns single-queue mode off
WOWPS5_PRIORITIES=0 on Turns the console thread priorities off
WOWPS5_OSK_CHAT=OPTIONS+L3 off A second keyboard shortcut for chat (Enter, text, Enter)
WINEDEBUG=+loaddll,warn+seh — Wine's debug channels, to the console's log (see below)

A Classic Era setup, as the installer writes it:

# install.py --start: the game the app starts
WOWPS5_GAME=/data/wowps5/prefix/dosdevices/c:/Games/World of Warcraft/_classic_era_/WowClassic.exe
+-d3d12

If something goes wrong

What you see What to do
The installer says there is no FTP server Check the console's address, that the jailbreak ran, and that its FTP server is on port 2121 (--port to change it)
No app on the home screen ShadowMount must be loaded; it looks in /data/homebrew. Removing the tile and letting it be added again also refreshes its name and pictures
A black screen that never ends (Classic Era especially) The client is waiting in its region/language window, which the console cannot show. Close the app and give the game a WTF/Config.wtf with portal, textLocale and audioLocale: run the installer again with --wow (it writes one if there is none), or copy the four lines from Installing by hand
A black screen for a while on the very first start Wait: the first start compiles shaders. Later starts are much faster
Classic Era's intro cinematic cannot be skipped The controller does not skip it. Press Esc on a USB keyboard, or let it finish; it plays only the first time
The game closes on start Make sure the copy finished (run the installer again; it only sends what is missing) and that the client matches the build on your PC
Sign-in fails with BLZ51914400 The client signs in directly, without the Battle.net app (which cannot run on the console), and Blizzard sometimes refuses that. Starting the client directly on a PC then shows the same error: it is on Blizzard's side, not something the port changes
The picture freezes in the world (sound may carry on) Close the game from the PS button and start it again. A crash shows as a frozen picture because the game's crash window is not visible on the console
Lua warnings about SavedVariables, or settings that do not stick Update to the latest release: this was a limit of 250 open files that the port now stays under

Seeing what the console sees

The app writes everything Wine and the game print to the console's kernel log. To read it on your PC, load a klog server payload (for example klogsrv, sent to your ELF loader on port 9021) and follow it on port 3232, or let tools/wine-ps5/klog-record.py keep it in files. Add WINEDEBUG= channels to launch.txt for more: +win,+dialog shows windows the console cannot draw (that is how the hidden region window was found).


How it works

A PS5 app cannot start a second program, has 16 KiB memory pages, may not read its own code, and gets about 250 open files. So the whole of Windows has to live inside one app:

flowchart LR
    subgraph APP["PS5 app PPSA99220 · one process"]
        GAME["WowB.exe<br/>WowClassic.exe<br/><i>your own copy</i>"]
        PE["Wine 11.19<br/>Windows side"]
        UNIX["Wine Unix side<br/>wineserver on a thread<br/>pad · keyboard · sound"]
        MEM["Memory layer<br/>4 KiB pages<br/>executable memory"]
        D3D["vkd3d-proton<br/>D3D12 → Vulkan"]
        RADV["RADV<br/>Mesa, PS5 port"]
        GAME --> PE --> UNIX --> MEM
        GAME -- "D3D12" --> D3D -- "Vulkan" --> RADV
    end
    MEM --> KERNEL[("PS5 kernel")]
    RADV --> GPU[("PS5 GPU")]
Loading
  • One process. Wine's server runs on a thread and its Unix side is linked into the app's executable.
  • Memory. A memory layer gives Windows programs the 4 KiB pages and executable memory they expect, on top of the console's direct memory.
  • Graphics. vkd3d-proton turns the game's DirectX 12 into Vulkan, and RADV (Mesa's driver, in Mihawk's PS5 port) drives the console's GPU, with an added present mode for frame rates above the TV's.
  • Choosing a game. The app looks for _classic_beta_/WowB.exe, then _classic_era_/WowClassic.exe, unless WOWPS5_GAME names one (app/runtime/wine_title.c).

Every change to Wine is one patch against a pinned revision, and each exists for something measured on the console: see docs/technical-notes.md.

What is in this repository

Here What
app/ The PS5 app: the platform side (app/ps5), and what it does around Wine (app/runtime: start-up and game choice, files, sound, controller, on-screen keyboard)
runtime/wine-ps5/ Every change to Wine as one patch, and the memory layer
runtime/radv-ps5/ The uncapped present mode, as a patch to the graphics driver's display code
tools/ Build, install, run and test scripts; the Windows test programs
docs/ Technical notes: what was measured on the console and why each change exists

Not here: the game, anything of an account, and the third-party source (vendor/, fetched at the revisions pinned in dependencies.json).

Building it yourself

The release bundle is the supported way to install. A fresh build has been reproduced (Ubuntu 24.04 under WSL, clang 18, Meson 1.9, LLVM 19 for Mesa's host tool) with tools/build-all.sh, which runs the build steps below in order and fixes what a fresh tree needed; see its header for MESON and LLVM_CONFIG. The original steps:

python3 tools/bootstrap.py                 # pinned sources and host packages into vendor/ and .deps/
cp .env.example .env                       # then set WOW_INSTALL; console settings go in vendor/PS5_Vulkan/.env
bash tools/wine-ps5/build-radv.sh          # the graphics driver with this project's patch
bash tools/wine-ps5/build-console.sh       # Wine's Unix side, the app, and its deployment to the console
python3 tools/wine-ps5/stage-console.py --all --system32   # Wine's Windows side to the console
python3 tools/wine-ps5/stage-game.py       # your game to the console (WOW_FLAVOR=_classic_era_ for only that one)

The host needs Linux with LLVM 23, mingw-w64, meson, ninja and cmake. runtime/wine-ps5/README.md describes the Wine patch; tools/make-bundle.py makes the release bundle from a console where everything works.

Credits and licences

  • BeLikeBrett/WoWPS5 — the original port this fork builds on: Wine in one PS5 app, the memory layer, the uncapped mode, the installer. All the hard parts.
  • Wine (LGPL-2.1-or-later); the patch here is under the same licence.
  • vkd3d-proton (LGPL-2.1).
  • Mesa RADV (MIT) in Mihawk's PS5 port, and his PS5_Vulkan.
  • The PS5 payload SDK and klogsrv.
  • The licence texts of everything the app contains are in the bundle under title/PPSA99220/licenses/. This project's own code is MIT.

World of Warcraft and Blizzard Entertainment are trademarks of Blizzard Entertainment, Inc. PlayStation and PS5 are trademarks of Sony Interactive Entertainment Inc. The pictures used for the app's tile and background are fan-made from publicly available artwork.

About

World of Warcraft (Forever and Classic Era), the Windows client, running natively on a jailbroken PS5: Wine + vkd3d-proton + RADV in one PS5 app. Bring your own game.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages