AGS engine Web port

Started by eri0o, Wed 26/05/2021 02:45:17

Previous topic - Next topic

Crimson Wizard

There's an experimental build with a supposed fix, but I do not know what would be the convenient thing to download for test.

Here's a full Editor downloads:
https://cirrus-ci.com/task/6188279393943552

Here's emscripten only part:
https://cirrus-ci.com/task/5906804417232896

Manu

Thanks guys for all the fixes!

Crimson Wizard

Please tell if it works? @Dungeonation

I released a new 3.6.0 update with these fixes last night.

Dungeonation

Quote from: Crimson Wizard on Sun 26/03/2023 19:20:45Please tell if it works? @Dungeonation

I released a new 3.6.0 update with these fixes last night.

Touch on mobile is PERFECT with this, and everything else aside from fullscreen weirdness on iOS (but that's okay!) is working great! This is awesome!

eri0o

#124
Experimental fix to Safari Fullscreen problem (PR link)

ericoporto.github.io/agsjs/ | ags_3.6.1.2_safari_experiment.zip



You can test in the above link and placing a local game or using the downloadeable package at right locally to replace your launcher html, ags.js and ags.wasm.

What it does is, for Safari, it disables the regular AGS handle of Fullscreen (and SDL and Emscripten too), so switching to fullscreen/windowed in game will do nothing. But the button for entering fullscreen has its behavior working differently in Safari, where it should work with macOS Safari.

There is a problem though that for iPhone, even though it doesn't support fullscreen, fullscreen actually works, but it has the default impossible to override behavior of exiting fullscreen on down swipe... Which will make your game exit fullscreen pretty quickly if you do swipe-like gestures in your game. There is also an issue that apparently, on iPhone, this Fullscreen only works in other browser than Safari itself, even though they are all Safari behind the scenes.  ???

I didn't have an iPad to test, but on newer models it looks like the Safari there is a bit between iPhone and macOS in features and it should have the Fullscreen working - but possibly with the swipe down to exit Fullscreen enabled too...

The implementation is not clean, ideally I think this needs to be fixed upstream (SDL or Emscripten), but I can't figure it out where things are wrong...

(about sound on iPhone I am trying to figure it out wth is going on...)

Ah right, the game can't show a keyboard in the web port (for mobile) but you also can't have an in-game keyboard or iPhone will detect and show a pop-up "keyboards are not allowed in Fullscreen" and then exit Fullscreen and show another pop-up asking if the website is trying to ask you for passwords. So avoid any sort of text entry. :/

Dungeonation

Hey, this is a bit of a strange question, but would it be possible to include a .js based API wrapper in a web exported game and write a plugin to call functions from it? And how would I go about it, if so?

eri0o

For now you would need to rebuild ags from source with your plugin added there.

Last time I checked there wasn't a reasonable way to load wasm from other wasm - there is a hacky dynload way in Emscripten that has issues in working crossplatform, and any JS calls need to have been implemented on the main binary (so you can load dynamically for the purpose of saving user bandwidth but you still need to beforehand know everything you can load and have the JS bindings already there). This can be alright if it's a purely logical plugin that does no direct access - e.g. no "filesystem" access -, like agsblend.

Dungeonation

#127
The API wrapper is purely .js files, and the plugin would just be calling its JavaScript functions, it's fairly simple stuff like unlocking achievements on Newgrounds.
Would I still need to rebuild from source to make that possible?

eri0o

#128
So far AGS has no way to communicate to the outside world, and as far as I can tell most people are ok with this - they can play games without depending on a server that may die. So there's a conceptual question there - and also the maintenance of this as platforms keep changing, there's a whole new burden of maintaining this all and cementing them in engine versions often doesn't make sense. There is also the compliance with privacy laws, what does it mean, do we need to ask user permission?

If what you mention is simple, the easiest way to do is to make yourself an AGS plugin, build AGS with it built-in for in the wasm build of the engine and use it. This will make you have it your way and avoid any philosophical discussions.

I don't feel strongly towards it, I am usually the kind of person that blocks cookies, ads and anything that pings home. :/

There is a way to do it that is just a bit of JS for achievements. You get the achievements before the game is loaded and then write in the MEMFS a text file with the said achievements. Later when the player gets an achievement, you edit this file adding a new achievement. Then in JS tou check in the fs sync call for the file.

Use FS.readFile and FS.writeFile from here: https://emscripten.org/docs/api_reference/Filesystem-API.html#filesystem-api

Dungeonation

Looking into it more, I know exactly how Newgrounds API support for Web AGS could be possible.
The API is HTML/JavaScript, you put the .js file for it in what would be your game's .zip, reference it in the index.html body:
Code: ags
<script src="NewgroundsIO.min.js"></script>
...and start using its functions in index.html's javascript...in this case, ags.js is what is used.
Then we start to use WebAssembly (ags.wasm) and run into a bit of a snag. I don't know much about WebAssembly but I wonder if it's possible for ags.js to listen for custom functions being called in the WebAssembly AGS engine, pass the arguments over, and have ags.js then call those API functions...
Some of the API functions return values, too...It would be very hacky but if it's possible to create a WebAssembly-JavaScript bridge like that, it just might work.

And as for the API itself, it's quite benign, if you cannot connect to the API or you're not logged into Newgrounds, the game plays as normal.

Marion

Hi my friends. I am trying to export my game in HTML format in order to make it playable via browser.
But as it's not really a game but an interactive story, it has a lot of big pictures. The compiled file is about 200Mo. And the loading is very slow... I am afraid the players won't have the patience.
Is there a way I can make the loading faster in the browser ? Thank you very much 🙂 (I have already checked the sprite storage optimization and the ressource splitting. I use AGS 3.99)

uma

Hi there thank you so much for your work on this. Ability for build for web is something I've hoped for in AGS and it's fantastic to have the option to build straight from the editor!

I have a couple of questions that I could not find the answer to with a search.

First, could someone advise why game hosted on itch my load correctly on a pc, but on a Mac or android large parts of the graphics don't load? On mine, the rooms and sprite's are not loading, only text and a button (the only elements which are not either black or white, if that's relevant), and the rest the screen is black. Everything else is running.

Secondly, I would really like to make my game work as well as possible on this format. It's currently 140mb and using about 2gb ram to run in either chrome or Firefox. It drags a bit but does eventuall run smoothly on my old x260. I have 5 frames for each room, which are drawn at 1080. Before I start downsizing the graphics, is it more likely the resolution, number of frames, or indeed something else entirely that's the main culprit for things being slow? Apologies if this isn't a thing can be answered like this, I thought I should ask before redrawing everything! Thanks!

eri0o

#132
Which version of the AGS Editor are you using? Can you share a link of your hosted game on itch - you can make it private and share the password.

The memory limit is usually actually lower, around 500MB of "storage" (it's in RAM). And don't expect to change soon - it's at least three years to get 64-bit support in wasm in major browsers.

I don't know what is a x260, is this a phone? For some reason browsers with touch require a resting finger on screen to give more processing priority to the browser.

About resolution, it probably doesn't matter performance wise but it depends how you are building your rooms and everything. The web engine is naturally slower than the native one - there is a big refactor in AGS handling of loops that could unlock a 3x speed up in the web port but that's kinda it. The issue of resolution is more that the resolution that the game runs depends on a few things right now - the browser gives a fake resolution to AGS. Getting the real resolution right now AND keeping windowed/fullscreen toggle working requires a bugfix in Emscripten - and then adjust the SDL code with it. I haven't gone that road, there is a lot of effort to merge things in these things in the upstream.

I am between a place and another and may adjust the text later, but the short is that without access to game and knowing the version there isn't much to do. As an example someone here sent me a private message and for whatever reason their game had a mysterious character in acsetup.cfg that made AGS give a weird error. Rewriting the acsetup.cfg and reencoding it made the game work.

Crimson Wizard

Quote from: eri0o on Tue 26/09/2023 20:29:08The web engine is naturally slower than the native one - there is a big refactor in AGS handling of loops that could unlock a 3x speed up in the web port but that's kinda it.

Could you please elaborate on this, as this is something I was not aware of? By "loops" I presume this has something to do with the game update handled differently depending on the state, but what makes web engine slower there?

eri0o

The web port runs c++ code built to wasm, in the browser wasm VM. The wasm VM has no direct access to the browser, or the DOM, so the way it works it can map to some JavaScript functions in the JavaScript VM.  Then the JavaScript code gets to call the browser stuff. This means the browser can only take input and draw things on the screen when these other things are not running - there are no threads or different process here.

The AGS engine has lots of internal loops, so we can't easily give the priority to the browser and back to the engine - the general idea of Emscripten kinda expects you have only one loop and then you just give control to the browser and back in one place in this single loop - like it gets to a certain line, the wasm VM stops and call JS and then the browser draws updates the frame and return to the VM.

Now AGS has - for now - lots of different internal loops, and there is a port, so how did I do this. So Emscripten has a sort of solution to this, called Asyncify, what it does is it analyzes the code for each time you destruct your app state - like assign a value to a variable - and then it finds points with hints (I am using SDL_Delay for this) to create points where it saves the stack state and then later once it gets called back it rewinds the wasm VM to that state - all of this is actually done adding extra instructions along the code. Later there is an optimization step that tries to recoup a lot of this lost performance, and it's really good at figuring unneeded instructions. Still, all of this gets a performance impact.

If AGS had only a single internal loop (like löve and a few other engines), the port could be done without using Asyncify at all, it would build faster, but above all, it would run faster - not a lot faster, 2 or 3 times of what it performs now.

The idea of the refactoring is the issue #1349. In SDL3, some ports (like the Apple stuff) may support inverted loops (additionally to the current approach), according to SDL#6785, so these platforms would benefit from this too.

Crimson Wizard

#135
Quote from: eri0o on Wed 27/09/2023 00:39:22If AGS had only a single internal loop (like löve and a few other engines), the port could be done without using Asyncify at all, it would build faster, but above all, it would run faster - not a lot faster, 2 or 3 times of what it performs now.

Ah, but 2-3 times may be a massive difference (like 10 -> 30 fps, moving from non-playable to pretty playable). I wish I knew how impactful this is earlier.
Then this should be given a higher priority.

eri0o

#136
@uma , your game use a very high frequency graphics with alternating black and white pixels at full hd, what is happening is in browsers that advertise a lower resolution than their real resolution, the game is rendered in that resolution instead, so the discrete pixels are decimated (or downsampled). This is like, if you go from 1920x1080 to a 960x540 resolution, you get only the even (or odd) set o pixels, but because you use alternated black/white pixels, you will get either only the black or only the white pixels - which makes some graphics disappear. This means that your game will only really work if run at the EXACT resolution it's made - or bigger, but then some moiré pattern occurs when the pixels are resized. I don't have a solution for this, perhaps using bilinear will help - but this means the graphics won't be sharp or look exact like you want it to.

I have an idea to get the full resolution of the device the browser is running ignoring what it advertises, that could maybe help, but this would work by fully getting rid of the in-engine (script API) for alternating between windowed and Fullscreen, instead this would only work by using the external button (the gear engine). What I would do is I would directly use the JavaScript API for Fullscreen instead of SDL and Emscripten (which currently are very buggy).

Now the issue is you mentioned you have the issue on macOS, and this kinda should not happen. Do you get this issue on Safari in macOS? Can you tell me the exact model of your MacBook? Is this using an external monitor? Can you tell me the specific resolution of the monitor?

uma

#137
Quote from: eri0o on Fri 29/09/2023 02:24:11@uma , your game use a very high frequency graphics with alternating black and white pixels at full hd, what is happening is in browsers that advertise a lower resolution than their real resolution, the game is rendered in that resolution instead, so the discrete pixels are decimated (or downsampled). This is like, if you go from 1920x1080 to a 960x540 resolution, you get only the even (or odd) set o pixels, but because you use alternated black/white pixels, you will get either only the black or only the white pixels - which makes some graphics disappear. This means that your game will only really work if run at the EXACT resolution it's made - or bigger, but then some moiré pattern occurs when the pixels are resized. I don't have a solution for this, perhaps using bilinear will help - but this means the graphics won't be sharp or look exact like you want it to.

I have an idea to get the full resolution of the device the browser is running ignoring what it advertises, that could maybe help, but this would work by fully getting rid of the in-engine (script API) for alternating between windowed and Fullscreen, instead this would only work by using the external button (the gear engine). What I would do is I would directly use the JavaScript API for Fullscreen instead of SDL and Emscripten (which currently are very buggy).

Now the issue is you mentioned you have the issue on macOS, and this kinda should not happen. Do you get this issue on Safari in macOS? Can you tell me the exact model of your MacBook? Is this using an external monitor? Can you tell me the specific resolution of the monitor?

thankyou! Where are you referring when you mentioning "bilinear" please? I'm obvious familiar with this for scaling graphics, but ive not noticed it as an option within AGS.
With the problems displaying on mac and android they are both showing the same graphics (i.e things that are anything other than black or white, which completely tracks with what you're saying). On android (Galaxy Note 10+) this is the same for both 1520x720 and for 2280x1080, but with significant load times for the latter. Friends mas is a 2011 MBP, 1080 x800 (this is older than I had expected!)

As a practical solution, am I understanding correctly that re-doing the graphics at a lower resolution will help, at the very least with the load times? I'd really like to keep the 5 frames of bg animation for each room, though I'm sure thats a bit part of the games bloat as I'm not working in a particularly element way.
I could probable change a couple of things and shift to 8bit colour if that would also help.

Crimson Wizard

Quote from: uma on Thu 05/10/2023 09:40:17As a practical solution, am I understanding correctly that re-doing the graphics at a lower resolution will help, at the very least with the load times? I'd really like to keep the 5 frames of bg animation for each room, though I'm sure thats a bit part of the games bloat as I'm not working in a particularly element way.

What are these 5 frames of room animations doing? Usually I suggest to see if these may be broken into separate smaller objects.

uma

Quote from: Crimson Wizard on Thu 05/10/2023 13:18:59
Quote from: uma on Thu 05/10/2023 09:40:17As a practical solution, am I understanding correctly that re-doing the graphics at a lower resolution will help, at the very least with the load times? I'd really like to keep the 5 frames of bg animation for each room, though I'm sure thats a bit part of the games bloat as I'm not working in a particularly element way.

What are these 5 frames of room animations doing? Usually I suggest to see if these may be broken into separate smaller objects.

It's a first person game with only about 40% of the screen used for what I'd think of as the "room" in a regular 3rd person p&c with the rest being UI. The other 60% of those 5 images is mostly empty white space, with some "noise" behind where the UIs sit to give them some life. I knew this was inefficient when I started but I couldn't see how how to get a room background image to be anything other than stretched across the whole screen, and equally wasn't sure how to animate UI elements, so I padded all the backgrounds.

SMF spam blocked by CleanTalk