Skip to content

Fix/non steam installs support - #48

Open
issaloubani wants to merge 5 commits into
rphsoftware:masterfrom
issaloubani:fix/non-steam-installs
Open

Fix/non steam installs support#48
issaloubani wants to merge 5 commits into
rphsoftware:masterfrom
issaloubani:fix/non-steam-installs

Conversation

@issaloubani

Copy link
Copy Markdown

Okay. This PR fixes a handful of bugs and introduces more bugs for future releases (~ ̄▽ ̄)~ (ohh read all of the PR message and enjoy the show 😊).

Note for anyone who isn't a dev: nothing here changes how you use OneLoader, you can stop reading (❁´◡`❁) . Though let's be honest, nobody reads a PR body ㄟ( ▔, ▔ )ㄏ (right ? 👀)

Decrypted Version / Non-Steam Support

Oneloader now supports already decrypted versions (non-Steam versions, annnd I won't ask how you got them (●'◡'●) , but naah this also has legitimate cases, I hope (゜ー゜) ).

Oneloader when starting the game assumes you have an argv[0]. This is the Steam decryption key, so using it to decide "is this Steam?" is a bit circular on a copy that doesn't have one (*  ̄︿ ̄).

Two things were broken because of that:

  • encryption.js always read data/System.KEL to bootstrap the asset key. No such file, so it throws during startup and _modloader_encryption is undefined forever.
  • every injection point used the encrypted names, so a mod's Items.json was filed as data/items.KEL while the game politely asked for data/items.json. Never matched. Mods silently did nothing, which is a fun thing to debug.

Detection now checks for data/System.KEL (MY FAVVVV KEL 😍, but naah I love all the characters (YES even Sweetheart 👀)). Every RPG Maker MV game has a System.json, so on an encrypted copy its Kel-flavoured twin is always sitting at a known path. .AUBREY, .HERO and .OMORI work as signals too, but those filenames vary so you'd be listing directories instead of checking one path (so I picked KEL to check 👀, fight me in the comments (●'◡'●) )

Encrypted installs keep AES + rpgmaker XOR exactly as before. Plaintext ones get pass-through and stock RPG Maker MV names. The Steam launch argument is only demanded of Steam builds now, since a plaintext copy starts without one.

The language mount point also comes from the game's own Text_Language_Processor parameters in both branches, and plugins.js is read relative to the game directory rather than the working directory. The old relative read quietly fell back to "en" whenever the process started anywhere else 🙃

Steam and playtest rule sets come out byte for byte identical to before. I actually checked, I didn't just say it.

argv crashes any launch without arguments

Speaking of argv[0], here's the fun part. The argv shadow was built as [key]. No key means [undefined], an array of length 1 holding absolutely nothing. Then:

argv.length > 0 && argv[0].split('&')   // Utils.isOptionValid

( THE FOLLOWING IS A CLAUDE SENTENCE, and I couldn't do it better than him :-) )
Length check passes ✅ then .split runs on nothing 💀 First caller is SceneManager.preferableRendererType, i.e. step two of boot, i.e. before Graphics exists, i.e. see the next section about why you couldn't read the error (. ❛ ᴗ ❛.)

Empty argv is now [].

Boot errors are readable now (related to #45, #46)

Graphics.printError throws inside _clearUpperCanvas when it runs before the canvases exist. So when the game dies early, the error handler dies while handling the error, and the thing you actually see is the handler's corpse: Cannot read property 'getContext' of undefined. Every single time. Regardless of cause.

Which is why a solid chunk of the open issues are just screenshots of that same message, unanswerable since 2021 (#6 says "latest.log is also unhelpful", #45 says the error is literally drawn on top of itself). Love that for us ㄟ( ▔, ▔ )ㄏ

The real stack now goes to latest.log before printError gets to bury it, along with any script that fails to load. This isn't a repair for #45 or #46, but those people can finally post something that names a cause instead of vibes.

Fixes #44 (ReferenceError: FPSMeter is not defined)

main.js appends one <script> per plugin, and normally the browser's load event politely waits for those to run. OneLoader replaces index.html and calls window.onload() by hand, so nothing waits, and the engine boots with zero of the game's plugins loaded.

It then reaches Graphics._createFPSMeter and asks for a global that a plugin was going to replace roughly 30ms later w(゚Д゚)w

This is not a decrypted-copy problem. It's a race, so it hits anyone whose scripts resolve slowly, Steam included (see #45, on Wine). Plugin scripts are now tracked and awaited before boot. Failed ones resolve too so a single broken plugin can't stall startup, with a 60s cap so it can never hang outright.

Also adds js/libs/fpsmeter.js to the script list. It ships with the game, it's part of the stock RPG Maker MV library set, OneLoader just never loaded it (●'◡'●)

Also, while I was in there

Image deltas had .rpgmvp hardcoded in five places, so .olid patching pointed at a filename that only exists on encrypted builds. That was broken under --test too, where pictures are already mounted as .png. Free bug fix for people who never touched a decrypted copy in their life (❁´◡`❁)


Each commit explains its own change if you want the details (THANK YOUU CLAUDYYY (●'◡'●), what I call claude 😊), I'm not retyping all of it here 👀

Call it 1.6 or don't, I'm a PR message not a person (ask Issa about the version, or fight him (. ❛ ᴗ ❛.) )

SEEE YAAAAA

here is a picture of a cat drinking coffe (ME AT 1 AM doing this PR (. ❛ ᴗ ❛.))
8988ac2ec2a19814b18f727d30ba8dd7

Disclaimer: This was test ONLY on my version (1.0.8d) I KNOW it needs more testing, feel free to tell me if anything isn't working 😊

The install type came from argv[0], which on Steam is the asset decryption
key. That is circular on a copy that has no key, and two things broke because
of it:

  - encryption.js always read data/System.KEL to get the asset key. On a
    plaintext install that file does not exist, so it threw during startup
    and left _modloader_encryption undefined.
  - every injection point used the encrypted names (.KEL, .PLUTO, .HERO,
    .AUBREY, .OMORI, .rpgmvp). A game asking for stock RPG Maker MV names
    matched nothing in the overlay, so mods silently did nothing.

The install is now detected from whether data/System.KEL is on disk, and the
targets and encryption follow from that:

  steam      .KEL/.PLUTO/.HERO/.AUBREY/.OMORI  + AES / rpgmaker XOR
  plaintext  stock RPG Maker MV names          + pass-through

Only Steam builds are asked for a launch argument now, since a non-Steam copy
starts without one.

The language mount point also comes from the game's own
Text_Language_Processor parameters in both branches, and plugins.js is read
relative to the game directory rather than the working directory. The old
relative read quietly fell back to "en" any time the process started
somewhere else.

Steam and playtest rule sets come out byte for byte the same as before.
Image deltas had .rpgmvp hardcoded in five places, so .olid patching pointed
at a file name that only exists on the encrypted Steam build. Take the
extension from the active configuration instead.

That also fixes image deltas under --test, where pictures were already
mounted as .png while the delta applier still looked for .rpgmvp.
Non-Steam copies launch with no arguments, so the shadowed argv came out as
[undefined]: length 1, holding nothing. Utils.isOptionValid checks
argv.length > 0 and then calls argv[0].split('&'), which throws.

The first caller is SceneManager.preferableRendererType, which runs at the
second step of boot, before Graphics exists. Graphics.printError then threw
on its own inside _clearUpperCanvas, so what actually surfaced was "Cannot
read property 'getContext' of undefined" and the real cause was gone.
Graphics.printError throws inside _clearUpperCanvas when it runs before the
canvases exist. Anything failing during SceneManager.initialize therefore
reports as "Cannot read property 'getContext' of undefined" whatever the
actual cause was, so every early boot failure looks the same and none of them
name anything.

Wrap SceneManager.catchException so the true stack reaches latest.log first.
Scripts that fail to load, and anything escaping window.onload(), are logged
as well.
main.js calls PluginManager.setup, which appends one <script> per plugin.
Normally the browser's load event holds off until those have run, so every
plugin is applied before SceneManager.run. The loader replaces index.html and
calls window.onload() itself, which loses that guarantee, and
SceneManager.initialize ended up running against a stock engine with none of
the game's overrides applied.

On OMORI that showed up as "FPSMeter is not defined". A plugin replaces
Graphics._createFPSMeter and it had not run yet, so the stock version asked
for a global the game never loads. The plugin scripts turned up about 30ms
after the crash.

Each plugin script is now tracked as it is queued, and awaited before boot.
Failed loads resolve as well, so one broken plugin cannot stall startup, and a
60s race guard stops the boot hanging outright.

js/libs/fpsmeter.js is added to the script list too. It ships with the game
and belongs to the stock RPG Maker MV library set, but the loader never loaded
it, so the vanilla path had nothing to fall back on.

The five second isInTestMode sleep works around the same problem. Left it
alone, since it also covers playtest asset loading.
@rphsoftware

Copy link
Copy Markdown
Owner

AI slop.
The comments in the code are a whole bunch of unnecessary, redundant text.

Also:
Unencrypted copies of the game are supported, in the exact ONE condition where it makes sense: An RPGMaker playtest environment. For literally every other scenario, you should be using an encrypted copy. All legitimate, and a vast majority of pirated copies of the game are properly encrypted and oneloader works just fine on them, because they don't violate this assumption.

One condition where plaintext might seem enticing is an "SDK Build" - but even then it's needless. Just launch the game with the key passed into argv.

For the other fixes, I will have a look at them and see if they are actually needed. Again, a lot of the assumptions in oneloader hold for the ancient version of nw.js we are on, and the specific environment omori sets up and needs. I am open to improvements regarding the bootup flow, and will likely cherrypick the error handling changes (without the unnecessary AI garbage comments).

@issaloubani

issaloubani commented Aug 17, 2026

Copy link
Copy Markdown
Author

@rphsoftware
About the AI part, yes. Since it was a new codebase I had to resort to Claude.

As for the playtest part, even when bypassing the argv, Oneloader had issues related to FPS meter, and multiple crashes. So no idea if my version (OMORI1.0.8d) was related to this.

Oneloader can also be applied for a playtest version right ? If yes then my version of the game is the issue not Oneloader.

Again, for the AI part, this one is on my end. I need time to get properly accustomed to a new codebase.

Hit me up if anything came up 🫡

Happy to help even a little 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ReferenceError FPSMeter is not defined

2 participants