Expedition 33 is UE5 with no DRM, but a mature MIT-licensed fix already exists: ClairObscurFix by Lyall. Rather than reimplement it, install.sh gains a third method that vendors a third-party fix unmodified and layers our own tuned config on top, with the upstream license shipped in the release zip as MIT requires. Upstream is archived, so vendoring also keeps it available. Our only change vs upstream defaults is [Center HUD] Enabled = true, since at 5120px wide the edge-anchored HUD elements end up absurdly far apart. Install/uninstall round-trip verified against a scratch game dir, including that our tuned ini overrides the vendored default. Credit to Lyall is recorded in THIRD_PARTY.md, the game README, and the repo README's method table. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
69 lines
4.5 KiB
Markdown
69 lines
4.5 KiB
Markdown
# UltraWidePatches
|
||
|
||
Ultrawide (**32:9 / 21:9**) fixes for PC games that ship with poor or no ultrawide support — built and tested on a **Samsung 49" Odyssey G93SC (5120×1440)**, and **Proton/Linux-first**.
|
||
|
||
Fixes use whichever approach the engine calls for:
|
||
|
||
- **SUWSF + Ultimate ASI Loader** — runtime memory patching, for Unreal titles (and anything DRM-wrapped, where static patching is impossible).
|
||
- **BepInEx plugin** — a proper C# mod, for Unity titles with the Mono backend.
|
||
- **External** — where a good third-party fix already exists, it is vendored (license permitting) with our tuned config and full credit, rather than reimplemented.
|
||
|
||
Most force **Hor+ FOV** (a wider screen shows you *more* rather than zooming in) and fix UI that assumes 16:9. Some games already render correctly and only need UI work — [Burglin' Gnomes](games/BurglinGnomes/) is one, and the fix deliberately leaves its camera alone.
|
||
|
||
## Supported games
|
||
|
||
| Game | Engine | Method | Status |
|
||
|---|---|---|---|
|
||
| [Gundam Breaker 4](games/GundamBreaker4/) | Unreal Engine 4.27 | SUWSF | ✅ Confirmed working at 5120×1440 |
|
||
| [Burglin' Gnomes](games/BurglinGnomes/) | Unity 6 (Mono) | BepInEx plugin | ✅ Confirmed working at 5120×1440 |
|
||
| [Clair Obscur: Expedition 33](games/Expedition33/) | Unreal Engine 5 | External ([ClairObscurFix](https://github.com/Lyall/ClairObscurFix) by Lyall) | ⚠️ Awaiting first-launch verification |
|
||
|
||
## Install
|
||
|
||
```bash
|
||
./install.sh # list available patches
|
||
./install.sh GundamBreaker4 # install one
|
||
./install.sh GundamBreaker4 uninstall
|
||
```
|
||
|
||
The installer finds the game across your Steam libraries, drops the loader + patch next to the executable, and applies any config-level tweak (with a backup). **It never modifies game files.**
|
||
|
||
> **Proton users:** each game needs a `WINEDLLOVERRIDES` launch option or the loader is silently ignored — the installer prints the exact line for that game. This is the single most common reason a fix "doesn't work."
|
||
|
||
Windows users can extract a release zip straight into the game's exe folder; no launch option needed.
|
||
|
||
## Why runtime patching
|
||
|
||
Config-file tweaks (e.g. UE4's `AspectRatioAxisConstraint=MaintainYFOV`) typically fix menus but **revert once gameplay loads**, because the game re-sets the camera per view. Many shipping executables are also DRM-encrypted on disk (GB4's is SteamStub-wrapped, `.text` entropy 8.0), which makes static exe patching impossible. Patching the *decrypted image in memory* solves both problems at once.
|
||
|
||
## Repo layout
|
||
|
||
| Path | What |
|
||
|---|---|
|
||
| `games/<Game>/SUWSF.ini` | Patch definitions (SUWSF games) |
|
||
| `games/<Game>/plugin/` | C# plugin source + prebuilt DLL (BepInEx games) |
|
||
| `games/<Game>/*.ini` | Our tuned config for a vendored external fix |
|
||
| `games/<Game>/game.conf` | Game metadata (appid, exe, paths, launch option) |
|
||
| `install.sh` | Generic installer / uninstaller |
|
||
| `tools/build_release.sh` | Builds a per-game drop-in release zip |
|
||
| `tools/publish.sh` | Pushes + cuts a Gitea release |
|
||
| `tools/dump_decrypted.py` | Dumps a DRM-decrypted image from a running process |
|
||
| `tools/aob.py` | Verifies/derives byte patterns against a dump |
|
||
| `tools/read_protonlog.sh` | Confirms ASI injection + per-patch match counts |
|
||
| `tools/unity_diag.cs`, `tools/unity_uitune.cs` | UnityExplorer console diagnostics/tuners |
|
||
| `vendor/SUWSF-x64/` | Upstream SUWSF 2.3.0 + Ultimate ASI Loader (MIT) |
|
||
| `vendor/BepInEx_win_x64_*.zip` | Upstream BepInEx 5.4.23.5 (LGPL-2.1) |
|
||
|
||
## Adding a game
|
||
|
||
1. `mkdir games/<GameName>` with a `game.conf` (copy GB4's as a template) and a `SUWSF.ini`.
|
||
2. Set `METHOD=` in `game.conf` to `suwsf`, `bepinex`, or `external`.
|
||
**Check for an existing fix first** — if a good one exists and its license
|
||
allows redistribution, vendor it with credit instead of rewriting it.
|
||
3. **Unreal:** start from the UE4 patterns in [`games/GundamBreaker4/SUWSF.ini`](games/GundamBreaker4/SUWSF.ini) — they match across many UE4 titles. If a pattern misses, use `tools/dump_decrypted.py` + `tools/aob.py` to derive the exact bytes.
|
||
4. **Unity:** install BepInEx + UnityExplorer and inspect live with [`tools/unity_diag.cs`](tools/unity_diag.cs) / [`tools/unity_uitune.cs`](tools/unity_uitune.cs), then write a plugin (copy `games/BurglinGnomes/plugin/`).
|
||
|
||
## License
|
||
|
||
MIT — see [LICENSE](LICENSE). Bundled third-party components (SUWSF, Ultimate ASI Loader) are MIT and credited in [THIRD_PARTY.md](THIRD_PARTY.md). You must own the games; nothing here modifies or circumvents copy protection.
|