itchio / itch.io

:bug: Public itch.io issues tracker and documentation - use support instead for private information!
https://itch.io/support
240 stars 25 forks source link

"Itch" global isn't defined when launching installed HTML5 game from Itch App #1115

Open jaredkrinke opened 3 years ago

jaredkrinke commented 3 years ago

In my HTML5 game installed via the Itch App (v25.4.1, running on Windows), the "Itch" global doesn't seem to be defined when my JavaScript code runs, or in the Shift+F12 dev tools console. If I type "Itch" into the console, I get the following error:

Uncaught ReferenceError: Itch is not defined

For context, I'm following the "Accessing the API key in HTML5 games" section in the Game Developer Guide -> Manifest Actions documentation. I'm trying to use the Itch user identity in my app (eventually for cloud save functionality). My code (.itch.toml and index.html) are shared here (I always get the "Not launched from Itch app" message, even when I do actually launch from the app):

https://github.com/jaredkrinke/itch-html5-api-sample

I think my TOML file is correct since the Itch App previously flagged a typo, and I fixed that and am no longer seeing any errors.

Curiously, I see the Itch environment initializing in the dev console:

Loaded itch environment!

jaredkrinke commented 3 years ago

Note: I see the same issue with this sample that I just found:

https://github.com/fasterthanlime/sample-html-app

jaredkrinke commented 3 years ago

(If this should be moved from the "itch.io" repository to the "itch" app repository, can someone with write permission transfer the issue over?)

Not super familiar with the code and libraries being used here, but I took a peek:

It looks like performHTMLLaunch sets webPreferences.contextIsolation to true and provides a preload script ("inject-game.ts"). The preload script attempts to modify "global":

const extendedGlobal = global as ExtendedGlobal;
...
    extendedGlobal.Itch = JSON.parse(jsonSource);

According to the following Electron issue, this was previously possible due to a bug, but it is no longer possible:

https://github.com/electron/electron/issues/13134

One solution suggested on StackOverflow is to use win.webContents.executeJavaScript, but I didn't find a way to synchronize that such that it would run before the game code.

jaredkrinke commented 3 years ago

Looks like Electron's contextBridge is designed for exposing preload script objects to the main page:

https://www.electronjs.org/docs/tutorial/context-isolation https://www.electronjs.org/docs/api/context-bridge