Repository navigation
Releases: danielcamilo1/decky-optiscaler
Release list
v0.0.7
FSR 4 on the Steam Deck, and the compatibility list is whole again.
Added
- FSR 4.1.1b — Steam Deck, in the Basic upscaler dropdown. One choice
downloads the community RDNA 2 build of the FidelityFX upscaler, checks it
against a hash pinned in the plugin, puts it next to the game and switches on
the INT8 override that reaches FSR 4 on RDNA 2. Close the game first; it
applies on the next launch. Frame generation is left exactly as it was.
Thanks to @drewboardman, who built this and
tested it on a Deck. - Setup names which upscaler build is in the game folder, identified by its bytes
rather than its version — the community build reports the same 4.1.1 the
released SDK does — and will put the bundled one back.
Fixed
- 297 of the 695 games on the compatibility list were answering "no wiki entry
matched". One row on the wiki was saved without its leading|, which the
parser read as the end of the table, so everything after Metro Exodus was
invisible: Monster Hunter Wilds, the Resident Evil entries, Stalker 2, The
Witcher 3 and 293 others. A row that lost its first character is now read as
the row it is. Bundled list regenerated — 698 entries. - Games listed under Upscaler mods support and Luma Unreal Engine no longer
claim OptiPatcher support they do not have, and their notes are their notes
rather than the images column. Those two tables have one column fewer than the
main one, and were being read as though they did not. - The refreshed list adds Onimusha: Way of the Sword to the games that need
REFramework in place before OptiScaler can do anything. - All six FSR 4 quality presets are offered. The reference INI writes them as one
comma-separated line, of which two were being read, so Quality, Performance,
DRS and Ultra Performance were rejected by the settings writer and never
reached the file. - Choosing an FSR version on RDNA 2 no longer turns on the FSR 4 upgrade path.
That path forces the FP8 model, which such a GPU does not have, and OptiScaler
answers with a silent FSR 3 fallback. - Verification recognises a community upscaler by hash, and reinstalling keeps it
instead of overwriting it with the bundled build. - Replacing the upscaler is atomic and rolls back the DLL, the INI and the
manifest together if any part of it fails. It refuses while the game is
running, and on an install this plugin did not make.
Install
Decky Loader → gear icon → Developer mode → Install Plugin from URL, and paste:
https://github.com/danielcamilo1/decky-optiscaler/releases/download/v0.0.7/Decky-OptiScaler-v0.0.7.zip
Or download the zip below and unpack it into ~/homebrew/plugins/.
v0.0.6
Everything from the 0.0.5.x-testing prereleases, as one release.
Added
- Non-Steam games can be set up. Their folder is taken from the shortcut's
target, since Steam reports no install folder for them. - Games whose wiki entry requires
REFramework say so on the setup
checklist and link the right build. Installing it for you is disabled for
now, until I can gather more information to get it fully working.
Fixed
- A non-Steam game's launch options are read from
shortcuts.vdf, so removing
OptiScaler no longer wipes them. - Settings are read only from the install method this plugin actually performs.
Monster Hunter Wilds would not boot because of this. - Settings hedged by an "if", a "try", an "e.g." or a "desired" are reported
rather than applied. Resident Evil 2 was getting 2× output scaling it never
asked for. - Setup names the OptiScaler overlay's new shortcut key when an entry moves it
off Insert. - Wiki pages with brackets in the name download again — Resident Evil, Dead
Space (2023) and Elden Ring were affected. Bundled list regenerated.
Install
Decky Loader → gear icon → Developer mode → Install Plugin from URL, and paste:
https://github.com/danielcamilo1/decky-optiscaler/releases/download/v0.0.6/Decky-OptiScaler-v0.0.6.zip
Or download the zip below and unpack it into ~/homebrew/plugins/.
v0.0.5.3-testing
Prerelease on the testing branch.
Added
- Non-Steam games can be set up. Their folder is taken from the shortcut's
target, since Steam reports no install folder for them.
Changed
- Automatic REFramework setup is disabled for now, until I can gather more
information to get it fully working. The games that need it still say so and
link the right build, and REFramework installed by 0.0.5.1/0.0.5.2-testing can
still be removed.
Fixed
- A non-Steam game's launch options are read from
shortcuts.vdf, so removing
OptiScaler no longer wipes them.
Install
Decky Loader → gear icon → Developer mode → Install Plugin from URL, and paste:
https://github.com/danielcamilo1/decky-optiscaler/releases/download/v0.0.5.3-testing/Decky-OptiScaler-v0.0.5.3-testing.zip
Or download the zip below and unpack it into ~/homebrew/plugins/.
v0.0.5.2-testing
A prerelease on the testing branch, fixing two games that 0.0.5.1-testing broke.
Bundled OptiScaler release is unchanged at 0.9.4.
Fixed
- Monster Hunter Wilds would not boot. Its wiki page lays out three
mutually exclusive install methods, and the settings miner read all of them.
LoadReshade=truebelongs to METHOD 3 — the arrangement where REFramework's
dll is renamed toReShade64.dllso OptiScaler loads it — and it was applied
on top of METHOD 1's files, which is what this plugin installs. OptiScaler was
told to load aReShade64.dllthat was not there while REFramework was already
loaded throughdinput8.dll. Settings are now read only from the part of a
page describing the method actually performed; everything from the first
"METHOD 2" or "Alternate Method" heading onward is ignored. - Resident Evil 2 was given 2× output scaling it never asked for. The entry
says "If applying Output Scaling is crashing the game, then ... set
Enabled=trueand the desired multiplier (e.g.Multiplier=2.0)" — advice
for a problem you may not have, with an example number — and both keys were
written unconditionally. A setting hedged by an "if", a "try", an "e.g." or a
"desired" is no longer applied; it is reported instead, naming the word that
made it a maybe. "Requires X, otherwise it crashes" is still an instruction,
because a refusal is not free either. - The overlay moving to another key is said out loud. Several REFramework
entries ask forShortcutKey=0x24because REF's own overlay is on Insert too.
Applying it is right — doing it in silence meant Insert stopped opening the
OptiScaler overlay and looked broken, when it had simply moved to Home. The
plan now names the key to press, before it is written. - REFramework only installs
dinput8.dll. Its release notes ask for nothing
else to go into the game folder, so the build stamp stays in the download cache
and is recorded in the manifest instead.
Changed
- REFramework can be removed without removing OptiScaler. It is required for
these games to work, so it is still a compulsory step before the install — but
it is also a 23 MB third-party DLL that hooks the engine and can stop a game
booting, and an all-or-nothing install left no way to find out which of the two
mods was at fault. It is a toggle once installed, and turning it off restores
whateverdinput8.dllthe game shipped with. - A missing
PDPerfPlugin.dllis now a warning, not a quiet row. Without it
the Resident Evil entries do not upscale at all — while OptiScaler loads, live
control connects and the frame rate reads out normally, which is exactly how
this was reported. The setup now says in as many words that the panel will
connect and report normally while nothing on screen changes.
Install
Decky Loader → gear icon → Developer mode → Install Plugin from URL, and paste:
https://github.com/danielcamilo1/decky-optiscaler/releases/download/v0.0.5.2-testing/Decky-OptiScaler-v0.0.5.2-testing.zip
Or download the zip below and unpack it into ~/homebrew/plugins/.
v0.0.5.1-testing
A prerelease on the testing branch. Bundled OptiScaler release is unchanged at
0.9.4.
Added
- Games that need REFramework are set up with it, automatically. Nine
entries on the compatibility list — the Resident Evil titles, Devil May Cry 5,
Monster Hunter Wilds, PRAGMATA — say in prose that OptiScaler does nothing in
that game unless REFramework is
already next to the executable, because REF is what exposes the upscaler the
game will not expose itself. The plugin read straight past that: those games
got an install that reported success, set the launch options, and changed
nothing on screen, with no error anywhere to go looking for. The requirement
is now read out of the entry, stated on the checklist before anything is
written, and the right build is downloaded and installed with OptiScaler as
one step. - The two REFramework builds are told apart, because they are not
interchangeable. praydog's nightly is one unified build for every game it
supports; the pd-upscaler branch is built per game and is what the entries
pairing REF with PureDark's UpscalerBasePlugin need, since that plugin does
not support the unified build. Which one an entry wants is read from the entry
itself — the pd entries name the branch and the plugin, the nightly ones do
not — and only the per-game asset name is curated, because "RE2.zip" is not
reachable from "Resident Evil 2 (2019)" by any matching rule and the wrong
game's build is a crash on launch. A game with no known asset says so and
links the release page rather than falling back to a near-enough one. - REFramework gets a
WINEDLLOVERRIDESentry of its own. For the same
reason OptiScaler's proxy needs one: Proton ships its owndinput8and loads
that in preference to the game folder. The wiki never mentions it — those
pages are written for Windows, where the folder wins — which makes it the one
instruction in the whole set-up that cannot come from the entry, and without
it a set-up that followed the wiki to the letter would put REF in place and
never load it. PDPerfPlugin.dllis named rather than pretended about. PureDark's
UpscalerBasePlugin is on Nexus Mods behind a login, so nothing here can fetch
it, and the pd-upscaler games do not work without it. It gets a row of its own
on the checklist with the link, marked as the user's job, and ticks when the
file turns up next to the executable — an install that reports success and
leaves the game rendering exactly as before is the failure this whole feature
exists to stop, and it would be absurd to reintroduce it one file further
down.- REFramework can be added on its own, to a game already set up or after a
download that failed. A 13 MB download over a handheld's connection is the
part that fails, and making somebody reinstall OptiScaler to retry it is a
poor answer to a flaky network.
Fixed
- Wiki pages whose name contains brackets are downloaded again. The
compatibility list writes[Resident Evil 2 (2019)](Resident-Evil-2-(2019)),
and the link parser stopped at the inner bracket: the page came out as
Resident-Evil-2-(2019, which the wiki does not serve, so the detail page for
every parenthesised title silently never downloaded. Those are exactly the
Resident Evil entries whose settings —Dxgi=false,OverlayMenu=false— and
REFramework instructions live on the page rather than in the notes column, so
automatic set-up had been working from half an entry for them. Dead Space
(2023) and Elden Ring were affected too. - The bundled compatibility list has been regenerated, so an offline Deck
gets the corrected page names rather than the truncated ones.
Changed
- Anything REFramework installs goes through the same contract as every other
file this plugin places: adinput8.dllthe game already had is set aside and
put back on removal, and both REF files are in the manifest, so removing
OptiScaler removes them too.
Install
Decky Loader → gear icon → Developer mode → Install Plugin from URL, and paste:
https://github.com/danielcamilo1/decky-optiscaler/releases/download/v0.0.5.1-testing/Decky-OptiScaler-v0.0.5.1-testing.zip
Or download the zip below and unpack it into ~/homebrew/plugins/.
v0.0.5
Released after testing across the 0.0.4.x-testing prereleases on the testing
branch. Bundled OptiScaler release is unchanged at 0.9.4.
Added
- Removing OptiScaler asks what to do with the Steam launch options.
Installing it is two changes, not one — a folder full of files and a
WINEDLLOVERRIDESentry in Steam — and removing it only ever undid the first.
A game that had been "removed" kept an override for a DLL that was no longer
there, and on the one path that did clear the field it cleared whatever else
the game had in it too. Removing now offers: put back exactly what was there
before the install, take only the OptiScaler override out and keep the rest,
or change nothing. The answer can be remembered. - The launch options are backed up the way files are. Installing records
what Steam was passing beforehand into a plain text file next to the manifest
and the backup folder, and removing takes it out again. Written once per
install, so a reinstall — or the launch-options step being switched off and on
— cannot overwrite the original with the override this plugin itself wrote.
Three states stay distinct, and each means something different: recorded and
empty (the game had none, so the field can be cleared outright), recorded and
not empty (restore it verbatim), and not recorded at all (only the override
this plugin recognises comes out; the rest is not ours to guess about). - A Settings tab on the main page. Both launch-options prompts offer
"Remember my choice", and an answer that can only be given and never taken
back is a trap: every stored answer is listed by name with what it will do and
a row that puts the question back, alongside the switch that stops answers
being kept at all — which also drops the ones already stored, so turning it on
again does not silently restore decisions just disowned. The same tab reports
the compatibility list: how many games are on it, how old it is and where it
came from, and when a refresh is failing, the error, the address and which
certificates were tried, with a button to fetch it again. - The plugin ships a copy of the compatibility list. A Deck that has never
reached the wiki matches games against 685 bundled entries instead of
reporting "no wiki entry matched this game" for every game it owns — which was
indistinguishable from the wiki being broken. It is only a floor: the first
successful fetch replaces it.scripts/fetch_compat_seed.pyrefreshes it
before a release. - The manual setup page states what Steam is passing and what was recorded
before the install. "The plugin cannot read them" and "they are empty" look
identical from the outside.
Changed
- The compatibility list is read from cache and refreshed behind the answer.
A handheld is regularly asleep, offline, or on a network that resolves and
does not route, and the wiki used to sit in front of every question asked of
it: a cache older than a day was thrown away rather than used, so each of
those cost a full timeout before anything appeared. Whatever is on disk is now
returned at once — stale or not — and the refresh runs behind it, single-flight
so opening three games in a row is one download rather than three. Detail
pages follow the same rule. - A refresh that brings something new updates what is on screen. The list
carries a content fingerprint, so "something arrived" is exactly "the
fingerprint changed"; a refresh that brought back the same list redraws
nothing. - A failed refresh cannot make things worse. Nothing is written unless the
download both succeeded and parsed, so a working cache is never turned into an
empty one. The failure is shown next to the list it could not replace, rather
than replacing the list with an error.
Fixed
- Removing OptiScaler no longer leaves its launch options behind. See above.
- The launch options are read from three sources, not one.
SteamClient.Apps.GetAppLaunchOptionsis undocumented and absent from some
client builds entirely, and everything here depended on it. Where it is
missing, every launch-options question answered itself with "cannot tell" and
every action taken on that answer became nothing at all. The app details store
the library's own Properties dialog uses is tried next, and finally
localconfig.vdf— Steam's own record on disk, which depends on no
undocumented method existing. - A wiki that will not download is no longer reported as "your game is not on
the list". The two produced the same empty result and the setup checklist
printed the same sentence for each, so a network fault presented as every game
in the library being unknown to the wiki. They are now separated, the failure
is printed in the words of whatever actually failed, and there is a Try
again button — there was previously no way to retry from the interface at
all. - A stalled connection is retried over IPv4. A router advertising IPv6 it
cannot route is the classic works-on-one-network fault, and Python's urllib
has no Happy Eyeballs to fall back the way a browser does. A server that
answered is not retried, because asking again says the same thing. - The last-resort unverified TLS context no longer builds its own trust
store. It was created withcreate_default_context, which reads the system
certificates — so on the one machine where that is what is broken, the
fallback meant to survive it was the single construction that could throw the
whole chain away.
Install
Decky Loader → gear icon → Developer mode → Install Plugin from URL, and paste:
https://github.com/danielcamilo1/decky-optiscaler/releases/download/v0.0.5/Decky-OptiScaler-v0.0.5.zip
Or download the zip below and unpack it into ~/homebrew/plugins/.
v0.0.4.6-testing
Fixes the stuck "Reading this game's entry…" and the flicker.
One symptom, three faults behind it.
A page the wiki will not serve was asked for constantly
A detail page that failed to download was re-fetched on every question asked about that game — and each attempt is two URLs deep, so a refresh was permanently in flight. The UI reads "a refresh is running" as "the answer may still change", so it never stopped waiting for one that was never going to arrive. A page that fails is now left alone for five minutes: long enough that an unreachable wiki is asked once rather than constantly, short enough that coming back onto a network is noticed.
A pinned entry could never match the watch
A pinned wiki entry answered with metadata it invented, carrying no revision at all. The watch compares revisions — so against a missing one, every check read as "something changed" and the plan reloaded every two seconds, for ever. It now carries the real list metadata, with "pinned by hand" recorded alongside rather than instead of it.
Reloading twice for the same revision is also refused outright now, so a revision the watch can never match costs one reload rather than one every two seconds. The loop is structurally impossible rather than merely fixed.
The flicker
Each of those reloads raised the loading flag, which swapped the whole panel back to "Checking the OptiScaler wiki…" and back again. Only the first answer about a game is a wait worth showing; a refresh behind an answer already on screen replaces it in place.
And pending ≠ still arriving
A page that is pending but no longer being fetched is one the wiki would not serve. The notice stops saying "still reading" about it, and the install goes ahead with the compatibility-list answer — which is the honest outcome.
What you should see
Forza's steps appear immediately and stay put. If its wiki entry cannot be downloaded, the "still reading" line disappears within a few seconds and the install button becomes usable rather than sitting disabled.
Install
Decky Loader → Settings → Developer mode → Install from URL, with the .zip below.
v0.0.4.5-testing
Fixes the "Forza Horizon 5 stays at Checking the OptiScaler wiki…" hang.
What was wrong
v0.0.4.4-testing stopped waiting on stale detail pages but not on missing ones. A page that had never been downloaded was still fetched in front of the answer — two URLs deep, with the second attempt only starting once the first had timed out. On a Deck whose route to the wiki stalls rather than refusing, that is a lookup that never returns.
That is exactly why Expedition 33 worked and Forza Horizon 5 did not: Expedition 33's page was already cached from an earlier session, Forza's was not.
Fixed
- The compatibility-list row answers on its own, and the game's own wiki page arrives behind it — the same rule everything else already followed. Measured against a network stubbed to hang for 30 seconds: the answer comes back in 0.02s.
- When the page lands, the answer is rebuilt. A page arriving moves the same revision a changed list does, so the watch that was already there notices. An unchanged page moves nothing and redraws nothing.
- The install button waits while a page is still arriving, and says why. The page is what names the filename to install as, so acting in that window would install under the default name when the entry says otherwise. It waits only while the watch is running — an unreachable wiki cannot leave it stuck disabled.
- "Checking the OptiScaler wiki…" gives up after 8 seconds. Every answer is meant to come from cache and arrive in milliseconds, so anything near that is a fault. The cause above is fixed; this is so the symptom cannot come back whatever the future cause. A late answer is still applied if it arrives.
What you should see
Both games answer immediately. On a game whose entry has not been downloaded yet, the notice says "Still reading this game's own entry — the steps below may fill in shortly" and the button briefly reads "Reading this game's entry…" before filling in.
Install
Decky Loader → Settings → Developer mode → Install from URL, with the .zip below.
v0.0.4.4-testing
The wiki now answers from disk and refreshes behind you.
Stale-while-revalidate
A handheld is regularly asleep, offline, or on a network that resolves but does not route — and the wiki used to sit in front of every question asked of it. A cache older than a day was thrown away rather than used, so each of those cost a full timeout before anything appeared. Detail pages were worse: a stale one meant two HTTP attempts in front of the answer, and the second only begins after the first has timed out.
- Whatever is on disk is returned at once, stale or not. The network is never on the path of a question you asked.
- The refresh runs behind that answer, single-flight — opening three games in a row is one download, not three. One also starts when the plugin loads.
- If the refresh brings something new, the page updates. The list carries a content fingerprint, so "something arrived" is exactly "the fingerprint changed": the game's plan is rebuilt when it moves, and a refresh that brought back the same list redraws nothing.
- A failed refresh cannot make things worse. Nothing is written unless the download both succeeded and parsed, so a working cache is never turned into an empty one. The failure is shown beside the list it could not replace, rather than replacing it.
The plugin now ships the list
A Deck that has never reached the wiki matches games against 685 bundled entries instead of reporting "no wiki entry matched this game" for every game it owns — which was indistinguishable from the wiki being broken. It is only a floor: the first successful download replaces it.
Settings
Says how old the list is and where it came from — the bundled copy, or a download and when — and, when a refresh is failing behind a list that still works, says that without calling the list broken.
Install
Decky Loader → Settings → Developer mode → Install from URL, with the .zip below.
v0.0.4.3-testing
Launch-options handling from v0.0.4.2-testing is unchanged and confirmed working. This release is about the wiki.
What was wrong
A compatibility list that fails to download and a game that is genuinely not on it produce the same empty result — and the setup checklist printed the same sentence for both: "No wiki entry matched this game." So a network fault presented as every game in your library being unknown to the wiki, with nothing anywhere saying otherwise.
There was also no way to retry from the interface. The backend has had a refresh call since the first release and nothing ever called it.
Fixed
- The two are now told apart. A download failure says so, prints the actual error, and says plainly that it is not the same as your game being missing from the list. A game that really is not on the list reads exactly as before.
- A Try again button, on the checklist and in Settings.
- A stalled connection is retried over IPv4. The classic works-on-one-network fault is a router advertising IPv6 it cannot route: the address resolves, nothing connects, and Python's urllib has no Happy Eyeballs to fall back the way a browser does — so it waits out the timeout every time while everything else on the Deck is fine. A server that answered is not retried.
- The last-resort unverified TLS context no longer builds its own trust store. It was created with
create_default_context, which reads the system certificates — so on the one machine where that is what is broken, the fallback meant to survive it was the single construction that could throw the whole chain away. - Requests time out in 12s rather than 20s, which two attempts still fit inside.
Added
- A Compatibility list section in Settings — how many games are on the list, when it was last downloaded, and when it will not download: the error, the address, and which certificates were tried. Enough to tell a broken network from a broken plugin without opening a log.
If it still does not download
Open Settings on the main plugin page. The error there is the real one — send it over and it will say exactly which of these it is.
Install
Decky Loader → Settings → Developer mode → Install from URL, with the .zip below.