Add Clair Obscur: Expedition 33 via new METHOD=external

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>
This commit is contained in:
2026-07-21 16:58:05 -04:00
co-authored by Claude Opus 4.8
parent efaab8bd32
commit 0833cf8495
14 changed files with 277 additions and 5 deletions
+6 -1
View File
@@ -6,6 +6,7 @@ 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). - **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. - **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. 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.
@@ -15,6 +16,7 @@ Most force **Hor+ FOV** (a wider screen shows you *more* rather than zooming in)
|---|---|---|---| |---|---|---|---|
| [Gundam Breaker 4](games/GundamBreaker4/) | Unreal Engine 4.27 | SUWSF | ✅ Confirmed working at 5120×1440 | | [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 | | [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 ## Install
@@ -40,6 +42,7 @@ Config-file tweaks (e.g. UE4's `AspectRatioAxisConstraint=MaintainYFOV`) typical
|---|---| |---|---|
| `games/<Game>/SUWSF.ini` | Patch definitions (SUWSF games) | | `games/<Game>/SUWSF.ini` | Patch definitions (SUWSF games) |
| `games/<Game>/plugin/` | C# plugin source + prebuilt DLL (BepInEx 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) | | `games/<Game>/game.conf` | Game metadata (appid, exe, paths, launch option) |
| `install.sh` | Generic installer / uninstaller | | `install.sh` | Generic installer / uninstaller |
| `tools/build_release.sh` | Builds a per-game drop-in release zip | | `tools/build_release.sh` | Builds a per-game drop-in release zip |
@@ -54,7 +57,9 @@ Config-file tweaks (e.g. UE4's `AspectRatioAxisConstraint=MaintainYFOV`) typical
## Adding a game ## Adding a game
1. `mkdir games/<GameName>` with a `game.conf` (copy GB4's as a template) and a `SUWSF.ini`. 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` or `bepinex`. 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. 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/`). 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/`).
+8
View File
@@ -32,6 +32,14 @@ them; all runtime patching is performed by SUWSF.
- Used only for runtime inspection while developing a fix; it is NOT part of any - Used only for runtime inspection while developing a fix; it is NOT part of any
release package and is not required by end users. release package and is not required by end users.
## ClairObscurFix (the entire Expedition 33 fix)
- Author: **Lyall** — https://github.com/Lyall/ClairObscurFix
- License: MIT (see `vendor/ClairObscurFix/LICENSE`)
- Files: `vendor/ClairObscurFix/**` — vendored **unmodified**
- Version: v0.0.10 (upstream repo is archived)
- The ultrawide fix for Clair Obscur: Expedition 33 is entirely Lyall's work.
This repo contributes only a 32:9-tuned `ClairObscurFix.ini` and packaging.
## Patch patterns ## Patch patterns
The `AspectRatioAxisConstraint` (HOR+) and `ConstrainAspectRatio` (pillarbox) The `AspectRatioAxisConstraint` (HOR+) and `ConstrainAspectRatio` (pillarbox)
byte patterns in `games/*/SUWSF.ini` are adapted from the UE4 fixes in byte patterns in `games/*/SUWSF.ini` are adapted from the UE4 fixes in
+49
View File
@@ -0,0 +1,49 @@
;;;;;;;;;; General ;;;;;;;;;;
[Developer Console]
; Set "Enabled" to true to enable the console.
; By default you can access it with the key "Tilde".
Enabled = false
[Skip Intro Logos]
; Skips splash screen logos, epilepsy warning and autosave warning.
Enabled = false
[Uncap Cutscene FPS]
; Removes 30fps cap in cutscenes.
Enabled = true
[Adjust Resolution Checks]
; Adjusts resolution checks to use the monitor's maximum supported resolution, rather than the "native" resolution.
Enabled = true
[Background Audio]
; Set "Enabled" to true to allow audio to continue playing when the game window has lost focus.
Enabled = false
;;;;;;;;;; Ultrawide/Narrower ;;;;;;;;;;
[Cutscene Letterboxing]
; Set "Enabled" to true to re-enable pillarboxing/letterboxing in cutscenes.
Enabled = false
[Fix Movies]
; Crops letterboxing from pre-rendered movies at ultrawide resolutions.
Enabled = true
[Center HUD]
; Set "Enabled" to true to center certain parts of the HUD to 16:9 at ultrawide resolutions.
Enabled = true
; Adjust "AspectRatio" to set the aspect ratio of the HUD. i.e 1.77778 for 16:9, 2.33333 for 21:9 etc
AspectRatio = 1.77778
;;;;;;;;;; Graphics ;;;;;;;;;;
[Disable Subtitle Blur]
; Set "Enabled" to true to disable the background blur on cutscene subtitle lines.
Enabled = false
[Sharpening]
; Adjust "Strength" to control the intensity of the forced post-process sharpening.
; Valid range: 0 to 2.0 Game Default = 1.0
Strength = 0
+76
View File
@@ -0,0 +1,76 @@
# Clair Obscur: Expedition 33 — UltraWide
⚠️ **Awaiting first-launch verification at 5120×1440.**
- **Engine:** Unreal Engine 5 — **no DRM** (no SteamStub; `.text` entropy 6.74)
- **Steam AppID:** 1903340
- **Executable:** `SandFall-Win64-Shipping.exe`
- **Method:** `external` — vendored third-party fix + our 32:9 config
## We did not write this fix
The ultrawide work here is **[ClairObscurFix](https://github.com/Lyall/ClairObscurFix) by [Lyall](https://github.com/Lyall)** (MIT), vendored unmodified. It is mature and already handles the hard parts; reimplementing it would be duplicated effort for no benefit. **All credit for the fix itself goes to Lyall.**
What this repo adds is the **32:9 configuration** verified on a Samsung 49" G93SC, packaging, and a one-command installer consistent with the other games here.
> The upstream repo is **archived**, so it will not receive further updates. Vendoring it here means the version you need stays available.
## Install (Linux / Proton)
```bash
./install.sh Expedition33
```
Then **required** — Steam → Properties → Launch Options:
```
WINEDLLOVERRIDES="dsound=n,b" %command%
```
Set **5120×1440** fullscreen in-game.
## Install (Windows)
Extract the release zip into `…\Expedition 33\Sandfall\Binaries\Win64\`.
## Our 32:9 config
`ClairObscurFix.ini` ships with upstream defaults **except**:
| Option | Upstream | Ours | Why |
|---|---|---|---|
| `[Center HUD] Enabled` | `false` | **`true`** | At 5120px wide, HUD elements anchored to screen edges end up absurdly far apart |
Everything else is left at upstream defaults, which are already ultrawide-friendly:
| Option | Default | Effect |
|---|---|---|
| `Cutscene Letterboxing` | `false` | No bars in cutscenes |
| `Fix Movies` | `true` | Crops letterboxing from pre-rendered video |
| `Adjust Resolution Checks` | `true` | Uses the monitor's max resolution rather than "native" |
| `Uncap Cutscene FPS` | `true` | Removes the 30fps cutscene cap |
### Tuning
Edit `…/Sandfall/Binaries/Win64/ClairObscurFix.ini` (requires a restart — this fix has no live reload):
- **HUD too cramped?** Raise `[Center HUD] AspectRatio` from `1.77778` (16:9) to `2.33333` (21:9) — usually the sweet spot at 32:9.
- **Prefer the HUD spanning the full width?** Set `[Center HUD] Enabled = false`.
- **Want cinematic bars back?** `[Cutscene Letterboxing] Enabled = true`.
## Uninstall
```bash
./install.sh Expedition33 uninstall
```
## Status / open questions
The game has an official ultrawide fix as of patch **1.2.3**, so some of this may be redundant. Unverified at 32:9:
- [ ] Does it launch correctly under Proton at 5120×1440?
- [ ] Is `Center HUD` at 16:9 right, or is 21:9 better?
- [ ] Any remaining pillarboxing in cutscenes or pre-rendered movies?
- [ ] Is the camera FOV Hor+ (see more) or Vert- (zoomed)?
If a gap remains that ClairObscurFix doesn't cover, *that* is where this repo would add its own patch.
+19
View File
@@ -0,0 +1,19 @@
# Clair Obscur: Expedition 33 — metadata for ../../install.sh
TITLE="Clair Obscur: Expedition 33"
APPID=1903340
EXE="SandFall-Win64-Shipping.exe"
COMMON_SUBDIR="Expedition 33/Sandfall/Binaries/Win64"
ENGINE="Unreal Engine 5 (no DRM)"
# Fix method: EXTERNAL — we ship an upstream third-party fix (MIT) plus our own
# 32:9-tuned config. We deliberately do NOT reimplement it; see README.md.
METHOD="external"
VENDOR_PAYLOAD="ClairObscurFix/Sandfall/Binaries/Win64" # contents copied into the exe dir
EXTERNAL_CONFIG="ClairObscurFix.ini" # our tuned copy overrides upstream's
EXTERNAL_FILES="ClairObscurFix.asi ClairObscurFix.ini dsound.dll"
LOADER="dsound.dll"
LAUNCH_OPTION='WINEDLLOVERRIDES="dsound=n,b" %command%'
PREFIX_INI=""
STATUS="Vendored ClairObscurFix (MIT) + 32:9 config — awaiting first-launch verification"
+17 -3
View File
@@ -109,7 +109,9 @@ METHOD="${METHOD:-suwsf}"
if [ "$ACTION" = "uninstall" ]; then if [ "$ACTION" = "uninstall" ]; then
echo "[+] Uninstalling..." echo "[+] Uninstalling..."
if [ "$METHOD" = "bepinex" ]; then if [ "$METHOD" = "external" ]; then
for f in $EXTERNAL_FILES; do [ -f "$GAMEDIR/$f" ] && rm -v "$GAMEDIR/$f"; done
elif [ "$METHOD" = "bepinex" ]; then
rm -vf "$GAMEDIR/winhttp.dll" "$GAMEDIR/doorstop_config.ini" "$GAMEDIR/.doorstop_version" \ rm -vf "$GAMEDIR/winhttp.dll" "$GAMEDIR/doorstop_config.ini" "$GAMEDIR/.doorstop_version" \
"$GAMEDIR/changelog.txt" "$GAMEDIR/BepInEx/plugins/$PLUGIN_DLL" "$GAMEDIR/changelog.txt" "$GAMEDIR/BepInEx/plugins/$PLUGIN_DLL"
# leave BepInEx/ itself: the user may have other mods installed # leave BepInEx/ itself: the user may have other mods installed
@@ -125,7 +127,15 @@ if [ "$ACTION" = "uninstall" ]; then
fi fi
# --- install ------------------------------------------------------------------ # --- install ------------------------------------------------------------------
if [ "$METHOD" = "bepinex" ]; then if [ "$METHOD" = "external" ]; then
SRC="$HERE/vendor/$VENDOR_PAYLOAD"
[ -d "$SRC" ] || { echo "[!] missing vendored payload: $SRC"; exit 1; }
cp -v "$SRC"/* "$GAMEDIR/" 2>/dev/null || true
# our tuned config wins over the upstream default
if [ -n "${EXTERNAL_CONFIG:-}" ] && [ -f "$GAMES_DIR/$GAME/$EXTERNAL_CONFIG" ]; then
cp -v "$GAMES_DIR/$GAME/$EXTERNAL_CONFIG" "$GAMEDIR/$EXTERNAL_CONFIG"
fi
elif [ "$METHOD" = "bepinex" ]; then
BEPZIP=$(ls "$HERE"/vendor/BepInEx_win_x64_*.zip 2>/dev/null | head -1) BEPZIP=$(ls "$HERE"/vendor/BepInEx_win_x64_*.zip 2>/dev/null | head -1)
PLUGIN="$GAMES_DIR/$GAME/$PLUGIN_DLL" PLUGIN="$GAMES_DIR/$GAME/$PLUGIN_DLL"
[ -f "$BEPZIP" ] || { echo "[!] missing BepInEx zip in vendor/"; exit 1; } [ -f "$BEPZIP" ] || { echo "[!] missing BepInEx zip in vendor/"; exit 1; }
@@ -156,7 +166,11 @@ apply_ini
cat <<EOF cat <<EOF
[+] Installed ($METHOD): $([ "$METHOD" = "bepinex" ] && echo "BepInEx + $PLUGIN_DLL + $LOADER" || echo "SUWSF.asi, SUWSF.ini, $LOADER") [+] Installed ($METHOD): $(case "$METHOD" in
bepinex) echo "BepInEx + $PLUGIN_DLL + $LOADER" ;;
external) echo "$EXTERNAL_FILES" ;;
*) echo "SUWSF.asi, SUWSF.ini, $LOADER" ;;
esac)
NEXT (Proton) — REQUIRED, or the loader is ignored and the fix won't apply in gameplay. NEXT (Proton) — REQUIRED, or the loader is ignored and the fix won't apply in gameplay.
Steam > right-click ${TITLE:-$GAME} > Properties > Launch Options: Steam > right-click ${TITLE:-$GAME} > Properties > Launch Options:
+11 -1
View File
@@ -19,7 +19,17 @@ OUT="dist/${GAME}_UltraWide_Fix"
rm -rf "$OUT" "$OUT.zip" rm -rf "$OUT" "$OUT.zip"
mkdir -p "$OUT" mkdir -p "$OUT"
if [ "$METHOD" = "bepinex" ]; then if [ "$METHOD" = "external" ]; then
SRC="vendor/$VENDOR_PAYLOAD"
[ -d "$SRC" ] || { echo "[!] missing vendored payload: $SRC"; exit 1; }
cp "$SRC"/* "$OUT/" 2>/dev/null || true
[ -n "${EXTERNAL_CONFIG:-}" ] && [ -f "$GDIR/$EXTERNAL_CONFIG" ] && cp "$GDIR/$EXTERNAL_CONFIG" "$OUT/"
# ship the upstream license alongside, as MIT requires
UPLIC="vendor/$(dirname "$VENDOR_PAYLOAD" | cut -d/ -f1)/LICENSE"
[ -f "$UPLIC" ] || UPLIC="vendor/${VENDOR_PAYLOAD%%/*}/LICENSE"
[ -f "$UPLIC" ] && cp "$UPLIC" "$OUT/UPSTREAM-LICENSE.txt"
echo "[+] Packaged vendored external fix + our config"
elif [ "$METHOD" = "bepinex" ]; then
BEPZIP=$(ls vendor/BepInEx_win_x64_*.zip 2>/dev/null | head -1) BEPZIP=$(ls vendor/BepInEx_win_x64_*.zip 2>/dev/null | head -1)
[ -f "$BEPZIP" ] || { echo "[!] missing BepInEx zip in vendor/"; exit 1; } [ -f "$BEPZIP" ] || { echo "[!] missing BepInEx zip in vendor/"; exit 1; }
[ -f "$GDIR/$PLUGIN_DLL" ] || { echo "[!] missing prebuilt plugin $GDIR/$PLUGIN_DLL"; exit 1; } [ -f "$GDIR/$PLUGIN_DLL" ] || { echo "[!] missing prebuilt plugin $GDIR/$PLUGIN_DLL"; exit 1; }
BIN
View File
Binary file not shown.
View File
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Lyall
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Binary file not shown.
@@ -0,0 +1,49 @@
;;;;;;;;;; General ;;;;;;;;;;
[Developer Console]
; Set "Enabled" to true to enable the console.
; By default you can access it with the key "Tilde".
Enabled = false
[Skip Intro Logos]
; Skips splash screen logos, epilepsy warning and autosave warning.
Enabled = false
[Uncap Cutscene FPS]
; Removes 30fps cap in cutscenes.
Enabled = true
[Adjust Resolution Checks]
; Adjusts resolution checks to use the monitor's maximum supported resolution, rather than the "native" resolution.
Enabled = true
[Background Audio]
; Set "Enabled" to true to allow audio to continue playing when the game window has lost focus.
Enabled = false
;;;;;;;;;; Ultrawide/Narrower ;;;;;;;;;;
[Cutscene Letterboxing]
; Set "Enabled" to true to re-enable pillarboxing/letterboxing in cutscenes.
Enabled = false
[Fix Movies]
; Crops letterboxing from pre-rendered movies at ultrawide resolutions.
Enabled = true
[Center HUD]
; Set "Enabled" to true to center certain parts of the HUD to 16:9 at ultrawide resolutions.
Enabled = false
; Adjust "AspectRatio" to set the aspect ratio of the HUD. i.e 1.77778 for 16:9, 2.33333 for 21:9 etc
AspectRatio = 1.77778
;;;;;;;;;; Graphics ;;;;;;;;;;
[Disable Subtitle Blur]
; Set "Enabled" to true to disable the background blur on cutscene subtitle lines.
Enabled = false
[Sharpening]
; Adjust "Strength" to control the intensity of the forced post-process sharpening.
; Valid range: 0 to 2.0 Game Default = 1.0
Strength = 0
Binary file not shown.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 ThirteenAG
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.