SakeTami
clickteam_phi
clickteam_phi

patreon


August 2022 update

Hey folks,
Got Lacewing HTML5 up and running. Soon your IO games will be taking over the internet!

This is still a work-in-progress. There were a number of technical difficulties...

HTML5 DarkEdif

The HTML5 runtime has no DarkEdif SDK, it can't reuse the C++ code, and the SDK has a lot of useful abilities. Without it, you're missing:

While not having it is one thing, I also have to be aware that if I write in the missing functions, when I add a second DarkEdif ext, I either have repeating code - meaning any flaw could mistakenly left unfixed - or I end up having a second DarkEdif extension overwrite or otherwise conflict with the first one.

So I'll have to write a clever way for DarkEdif extensions to detect each other, their SDK versions, and not override each other.

WebSockets

HTML5 is limited to WebSockets, which run over HTTP/HTTPS, but only initially. A HTTP request is sent with headers to request upgrade to WebSockets, and HTTP response is exchanged to approve it.

From that point on HTTP is thrown out, and the data is then exchanged in WebSocket format (RFC 6455), which has its own protocol format with headers and encoding, and potential compression.

More importantly, if a connection is started with HTTPS and thus secured with SSL, it remains encrypted during the WebSocket packet exchanges. This works in Blue HTML5 too, so you'll have encrypted Lacewing if you're using the secure WebSockets port. Specifically, a peer message is encrypted from sender to server; it's not necessarily encrypted on the way to the receiver client, unless they're also using WebSocket HTTPS.

Since liblacewing's webserver has HTTP/HTTPS already, and they're complicated to work with, I modified liblacewing's webserver to hand off websocket connections.
Currently, it's hacky to use it, since liblacewing is hard-coded to expect response data in pieces and then submit one big response while generating HTTP headers, rather than short back-and-forths.

Since websocket protocol isn't HTTP, that's just the initial part, then that doesn't work once WebSocket has been established. Right now I'm bypassing the response mechanism and queuing by writing using an internal liblacewing function with a flag to ignore the fact I'm skipping the buffering part.

I'll clean it up later once all the features work

Combining WebSockets and raw sockets

I initially wanted both WebSockets and Lacewing Relay to be able to connect over the same port. While that's technically doable, it would be painful, because it's quite complicated to get HTTPS working and I'd rather not reinvent the wheel; and we're talking four different protocol parsing, encryption, compression etc handshakes all through the same connection; namely, raw Lacewing, HTTP, HTTPS, and WebSocket.

It'll take too long and at the moment, it's not worth the payoff. At best, it'll make running host actions easier.

WebSocket is designed to use HTTP/HTTPS on their native ports, to avoid firewall complications, and let you host actual webserver in the same server alongside websockets. However, Blue doesn't have a webserver part, so the latter point is moot. Maybe I could one day spin off the webserver into its own object, and finally complete the trilogy of Lacewing Blue with Lacewing Blue Webserver.

Blasted messages in a non-UDP environment

UDP isn't available in web browsers. The only alternative for UDP is WebRTC, which is still TCP, but with a "send within x milliseconds or discard" setting.
It's not exactly UDP, since it's underlying connection is still TCP, which means any overloaded devices along the route won't discard it. But WebRTC is meant for video and audio data, and is peer-to-peer as well, so it's not a perfect fit.
(There was also RTMFP, but that was Flash-only.)

But, I wanted UDP to be implemented transparently, so you can use the same Fusion events, or very similar in both HTML5 and Windows.
If UDP wasn't available on HTML5, you'd have to avoid UDP (all Blasted messages) entirely on any other platforms to have cross-platform compatibility. For games, that's a crippling limitation, as sending position shouldn't be over TCP, but redesigning a core element of the game for HTML5 port is convoluted.

So, I've made it transparent, so right now, you code your Blast actions as normal. HTML5 sends and receives pseudo-UDP messages over TCP instead, with single bit of the Lacewing header modified. The server translates all UDP <-> pseudo-UDP as needed, and the Blasted actions will always produce Blasted events.

The obvious issue with this workaround is that UDP will drop messages if overloaded, and pseudo-UDP won't. But this shouldn't be a problem, since 99% of the time UDP is transferred, so if you're overloading on pseudo-UDP events, you'd be overloading on plain UDP, since there's the same number of events.

Lacewing Blue already implements a "message queue overloaded" warning system, covering this scenario anyway by generating an error whenever the queued messages exceed what is expected. So if this problem does occur, you'll get an error instead of a gradually increasing visual lag.

Multi-threaded Bluewing HTML5 Client?

The benefit of multithreading is that a connection could be dropped by the client being slow to respond. For example, if you open a popup or file dialog on Windows in Relay or Blue in single-threaded mode, the connection can't respond to the server; the main thread froze at the dialog opening line, and couldn't move on to Blue's message processing code, until the dialog is closed.

After five seconds of being ignored, the server will decide the client program is no longer usable and disconnect it.

So on Windows, Android and co., multithreading allows the client to stay connected, by the secondary thread replying instantly to pings, and queuing the user messages for the main thread. However, in HTML5, the browser itself keeps the WebSocket alive, responding to WebSocket pings and queuing messages. So, is a secondary thread necessary if all its roles are already carried out by the browser?

Surprisingly, JavaScript does support multithreading, in the form of Web Workers. These can't access the main webpage, only using a messaging system to communicate with the main thread which in turn can mess with the webpage; but Web Workers have a benefit, in that they're very fast, not having to run any other task like UI.

But again, is there any point if there's nothing for the second thread to do that the browser itself isn't already doing? At the moment, HTML5 will be single-threaded, but there is a possibility of multithreaded in the future, if that will be of any benefit.

Memory addresses and files

The issue with memory addresses in JavaScript is there aren't any. Data can be stored in an ArrayBuffer, and this can be wrapped into a Blob.

However, you can only load from a Blob with an asynchronous request, meaning it runs in a secondary thread... which means the main thread is free to mess about with the output location while the request runs. For example, if I add an integer to the to-send binary message, then add a Blob, then add another integer, I have no way of confirming the second integer is before or after the Blob, despite the order of actions.

I've fixed this at the moment by locking the send message while a Blob loading request is happening, but this is far from ideal.

With HTML5 files (also represented as Blobs), the same process will happen. I'm planning to do the same thing I did for the LZMA2 object: allow URL download, allow Blob URL opening, and allow the user to be prompted to open a file.

Meanwhile, for saving, I'm planning the same LZMA2 pattern: allow uploading to a URL via POST, make the received binary accessible with a Blob URL for passing to other extensions in the app, and allow saving to local disk via a browser download.

The complicated part of all of this, is that Blobs can't be deleted until you're done loading from them, or the load will fail. And if they're not deleted at all, the memory usage of the webpage just climbs. So it's a difficult thing to manage.

Bluewing HTML5 Server?

The only way you get a HTML5/JavaScript server is by using Node.JS, and then you're not running browser JavaScript anymore. It won't run in a browser, but in a custom JS engine, like Enscriptem.

Fusion doesn't build to target Node.JS, so unlike writing a Lacewing translator around WebSocket, I would have to rewrite the entire liblacewing and Lacewing Blue codebase in JavaScript... for Fusion, a coding tool which won't even build apps that run in Node.JS anyway. So it's safe to say Bluewing HTML5 Server won't be necessary.

Future development

At the moment, Lacewing Blue HTML5 should be done by end of October, hopefully sooner, but I'm not falling into the optimism bias. I'm going on family holiday in August for two weeks, so I won't be working then.

The issue is not really getting the client to work on all A/C/E, and more making sure the hacks I've done in the server are smoothed out. Of course, the webserver has two servers running under it (HTTP, and HTTPS), which brings it to a total of three servers, each with their client lists; raw Bluewing, HTTP and HTTPS servers, and in scenarios like disconnects, frame switches, etc, I'm not entirely sure everything will behave with consistent, well-defined behaviour, being I basically interrupt the middle of some connection-handling processes and skip parts entirely.

I am aiming to not just get a consistent server, but also flesh out the HTML5 client, add any necessary code to the Windows client for HTML5-specific options (like handling the blob URLs), and of course, update the Lacewing documentation for the new HTML5 version.

I also have to write all the changes into the bluewing-cpp-server and MMF2Exts repositories. So if I get hit by a satellite, others can mousey on in my place.

Thanks for your patronage!
~ Phi

Comments

Interesting, the question would be how are all the html5 MP games my kids are playing on their chromebooks (when they should be doing schoolwork) communicating? I shall switch on chrome inspector next time to find out.

Thanks for the update. Sorry I didn't understand much but if in the end lacewing html is user-friendly ( accessible ) it will be great

therickman


More Creators