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
Add: support for emscripten (play-OpenTTD-in-the-browser) #8355
Conversation
Would it be possible to add support for reading and writing data to/from the |
Not as far as I know. Browsers sandbox everything, and I would assume security wouldn't let access to the users disks. This is also one of the reasons I would love to add Cloud Saves, as that would solve this too :) What is possible, how-ever, is to allow uploading of a savegame, and I am sure it is also possible to make a "Download savegame" button which uses the normal browser flow to download a file. But that is not really user-friendly :) (and currently also very low on the list to check out) |
Note that storing too much data in local storage may result in a warning or error from the browser, and the excess data may not be written correctly. The limit in this case can be as low as 5 MB (or even lower). |
But local storage is an LRU, and files can be evicted for many reasons. But for now, it will do fine. But here too, Cloud Saves are kinda mandatory to really make this shine :) |
0800b47
to
9278e9f
Compare
bc94a9a
to
9538d61
Compare
b92d1a5
to
b514738
Compare
52ba48d
to
424bb55
Compare
6d8b697
to
b33c9f2
Compare
0043db8
to
9954e9b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Told you i'd find things :)
da07f25
to
47e7d4d
Compare
This commit prepares for the next commit, as Emscripten needs to have a way to trigger a single iteration of the main loop. To keep the real changes more clear, this commit only unrolls the loop, and makes no changes to the logic itself.
Emscripten compiles to WASM, which can be loaded via HTML / JavaScript. This allows you to play OpenTTD inside a browser. Co-authored-by: milek7 <me@milek7.pl>
This mode doesn't wrap the mouse constantly, but requests SDL to lock the mouse pointer. This is needed, as with Emscripten you are not allowed to change the mouse poisition (only to lock it into place).
…wser When a developer attaches the "preview" label, a build is created and published on https://preview.openttd.org/. After that, new pushes to the PR are automatically build (as long as the "preview" label exists). If a non-developer attaches the "preview" label, it will be removed.
Instructions now suggest using build-host, etc. It is easier to just ignore all build* folders.
47e7d4d
to
8ac1e92
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh my.
@TrueBrain Question: is it necessary to disable the "Add server" button on Emscripten? I understand that it can obviously only work with WebSocket-based servers, but what if the URL for my WebSocket server is unpredictable? It would be great to have a way of changing it without needing to rebuild the client every time. |
The main issue is the common user. If we leave it enabled, they will be confused thinking they can join normal servers with it. They cannot. Ideally we would have WebSocket enabled for all servers. Or that the masterserver returns a list of servers that do have a WebSocket proxy. But we are far away from that :D I can see two ways for you to solve your problem in the here and now:
This is also one of the reasons we still don't have a "Play Now" button on the frontpage. There is more work to do for Emscripten before it can go mainstream. Currently it really is to provide previews in Pull Requests :) PRs to improve that situation are very welcome ;) |
Makes sense. Thanks for the quick reply! For now I will just re-enable the button. However, I would like to help work on a better solution if possible. |
(depends on OpenTTD/bananas-server#39 before "online content" will work out-of-the-box)
(#7510 was used as inspiration for this PR. Different choices were made, as this PR is more self-contained and doesn't rely on custom Dockerfiles; there is nothing wrong with the approach taken in #7510, I just prefer a different one myself)
Running
To compile, first make a "build-host" folder in which you build "tools" for the host (we run this in the Docker container, to avoid library mismatches):
Next, use the following line in a new build folder to generate the WASM / JavaScript / HTML files:
This produces the following files:
Which combined are the full game, which you can run in a browser. You do need a HTTP server to run it, even if used locally. Browsers don't allow XHR requests with
file://
. (pro-tip:python3 -m http.server
)Reasoning
The idea behind adding Emscripten is that we could produce these kind of binaries on Pull Request (after a trusted contributor okays it, to prevent abuse), so new features can be tested quickly, and bug-fixes can be reviewed all from within the browser. This Pull Request puts down the groundwork for this. It is also the reason no other external libraries are used, like for example there is no support for LZMA compression (emscripten doesn't have a port available for this).
If we would add LZMA support, we could extend this as a "Play Now" features on our website (and for example, reddit could do the same, and CityMania, or-whatever community wants to drag in players quickly). It creates a smooth and simple experience for new players to jump in.
Design choices
asyncify
mode, where a sleep does a "context switch" to Javascript world, allowing for the canvas to be drawn. There are two significant issues with this approach:asyncify
, SDL2 is not v-sync'd, meaning mouse movement etc feels laggy and distorted. Frames are drawn when-ever. With the current Pull Request, it is v-sync'd, that is: when ever the browser indicates an animation frame should happen, OpenTTD does a tick and draws the screen. This feels significant less laggy.Also applied is a commit that adds workarounds in our codebase for those bugs; they are very ugly, and should be considered a hack. But for now, it works, and once emscripten caught up with these issues, the hacks can be removed.
pre.js
and is documented in comments (openttd_server_list
).Known-bugs
asyncify
does not resolve this issue, but still restricts us to ~120 fps.Example of preview
TrueBrain#19