Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use an HTML-based solution to the SharedArrayBuffers problem #6616

Open
Xananax opened this issue Apr 3, 2023 · 6 comments
Open

Use an HTML-based solution to the SharedArrayBuffers problem #6616

Xananax opened this issue Apr 3, 2023 · 6 comments

Comments

@Xananax
Copy link

Xananax commented Apr 3, 2023

Describe the project you are working on

Any web project

Describe the problem or limitation you are having in your project

Currently, a Godot 4 web build requires adding the following headers to an HTML page:

  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: require-corp

This is necessary to unlock SharedArrayBuffers in compliant browsers. SharedArrayBuffers is in turn, necessary for threading.

This is problematic in more than one way:

  • Many providers (Github, Gitlab, ...) do not provide any way to set those headers
  • The issue has extremely low discoverability; it's a recurrent complaint in the discord server (and elsewhere), and people are confused by the error and about how to apply the workarounds.

Juan expressed wanting to restore single threads in the Godot codebase, but I see this as less than ideal for the following reasons:

  • Accessing threads in running applications is unlikely to stay a fringe feature. As WASM becomes more mature, most providers will likely create options to serve pages with those headers. Godot will have created a long-lived tech debt for a temporary ecosystem fit if that is true.
  • The fix is unlikely to come promptly, and I can envision people needing clarification for a long time.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Instead, I suggest adding the MIT-licensed Coi-Service to the HTML template.

This worker-based solution works in the browsers I've tested it in and restores a one-click-export solution to Godot without needing single threads.

The price to pay is an initial reload of the page (as soon as the worker loads, it reloads the entire page). This is usually fast enough not to be noticeable on an average connection. Still, we could work around it with some UX (show an initial 1s loading screen before flashing to the load bar).

If implementing single-threaded Godot was still desirable for other reasons, this fix is easily revertable once single threads are here: remove one line in the HTML template and one javascript file.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

  1. Add the line <script src="coi-serviceworker.min.js"></script> to full-size.html
  2. Add coi-serviceworker.min.js to the html directory
  3. Request thorough testing in many different browsers on many different system.

Maybe add the license if the mention in the minified file isn't sufficient

If this enhancement will not be used often, can it be worked around with a few lines of script?

Anyone can add their template, that is not the issue. It's trivial to do (as demonstrated by the above paragraph).

Is there a reason why this should be core and not an add-on in the asset library?

Despite the fix being easy, many devs lack the experience to make sense of the error or how to work around it.

Even many experienced devs who aren't used to web similarly can't make sense of it.

An alternative to my suggestion would be a public announcement, with a fixed template (but unfortunately that would lack the nice large-scale testing that a feature can bring)

@Calinou Calinou changed the title HTML-based solution to the SharedArrayBuffers problem Use an HTML-based solution to the SharedArrayBuffers problem Apr 4, 2023
@clayjohn
Copy link
Member

clayjohn commented Apr 5, 2023

Even if this isn't the accepted approach for integration into the engine, I could see this being something very useful to add to the documentation as a stop gap solution.

@nisovin
Copy link

nisovin commented Apr 12, 2023

This doesn't entirely resolve the discoverability issue, but I've packaged this Javascript library into a plugin, which makes it pretty easy to use:

https://godotengine.org/asset-library/asset/1818

@umarcor
Copy link

umarcor commented Apr 18, 2023

For the record, work around this limitation in CI (say GitHub Actions or GitLab CI/CD): https://github.com/itsas-taldea/moon/blob/e4c1d959e6e54ef94c1152e9b9daab62ba3611a1/.github/workflows/Pipeline.yml#L107-L112

      # Workaround for SharedArrayBuffer support on GitHub Pages
      # See: https://github.com/godotengine/godot-docs/issues/7084
      - run: |
          cd public/play
          curl -fsSL https://github.com/gzuidhof/coi-serviceworker/raw/master/coi-serviceworker.js > coi-serviceworker.js
          sed -i 's#\(		<script src="index.js"></script>\)#		<script src="coi-serviceworker.js"></script>\n\1#g' index.html

Have a test in https://itsas-taldea.github.io/moon/play/

@Jan-PieterInghels
Copy link

Jan-PieterInghels commented Sep 28, 2023

Using Godot 4.1.1 stable, this fix does not solve the issue on itch.io.
image

I realise that they have their own experimental implementation to solve this, but since that causes other problems I thought I'd give this fix a try.

@nisovin
Copy link

nisovin commented Sep 28, 2023

Using Godot 4.1.1 stable, this fix does not solve the issue on itch.io.

I realise that they have their own experimental implementation to solve this, but since that causes other problems I thought I'd give this fix a try.

I believe this solution can only affect the page with the game. Sites like itch use an iframe, and I believe the containing page also needs some special headers, which this solution cannot provide.

@Atovange
Copy link

To me keeping such an important feature as web exports on iframes, which is the main way web games get consumed online, locked because of multi-threading, which is a feature seldom used, is not right.

I would much rather have lower performance due to single-threading than not being able to make my game be played.

I'm with Juan on this one.

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

No branches or pull requests

7 participants