Working on Wesnoth in the browser (via Emscripten)

Discussion of all aspects of the game engine, including development of new and existing features.

Moderator: Forum Moderators

Post Reply
aidanhs
Posts: 7
Joined: December 3rd, 2015, 8:03 pm

Working on Wesnoth in the browser (via Emscripten)

Post by aidanhs »

This is the second thread with grand plans for emscripten (the first being http://forums.wesnoth.org/viewtopic.php?t=39842).
Briefly: this would theoretically provide a vanilla Wesnoth experience by just visiting a website in any browser. You would even be able to play against native clients in multiplayer!

However, I'll be honest - this is pretty ambitious. I've ported a number of things to Emscripten before but this is my first time with something graphical and a project so large.
In terms of failure I estimate a 30% chance of me losing interest within the next year and stopping working on it, 5% chance of me still actively working on it after a year, 60% chance of me realising the game will be unplayable in the browser (i.e. too big) and 5% chance of success.

I do have some initial progress:

Code: Select all

scons: Reading SConscript files ...
Building Wesnoth version 1.13.1+dev
Mkdir("build")
---[checking prerequisites]---
[...]
Checking for Simple DirectMedia Layer library version >= 2.0.0... yes
Checking for SDL2_net library... yes
Checking for Boost iostreams library version >= 1.34.1... yes
Checking for gzip support in Boost Iostreams... yes
Checking for bzip2 support in Boost Iostreams... yes
Checking for Boost random library version >= 1.40.0... yes
Checking for Boost smart_ptr library... yes
Checking for Boost system library... yes
Checking for Boost filesystem library version >= 1.44.0... yes
Checking for Boost locale library... yes
GOOD: Base prerequisites are met
i.e. I've been able to compile boost, gzip, bzip2, sdl2 and sdl2 supporting libraries with Emscripten and make them available to the compilation process. Parts of this were done already by the emscripten ecosystem, parts I had to do myself.

Now for some speculation - assuming (by some miracle) it all works out, I need to figure out how it should be released. The 'problem' is licensing.
Wesnoth is GPL2 and I'd like to stay in the spirit of that. However, there is a complexity with the client-server split - any client will always need to be released under the GPL (which is good), but one could imagine an unscrupulous entity splitting up the client and server over the network and making closed source changes to the server.
This can happen already, but the possibility of putting it in the browser makes it a more tantalising proposition - if you added an extension to the client to be able to dynamically modify functionality based on messages from the server (i.e. a 'push' addon system) you could send proprietary extensions to the client without needing to worry about the GPL. This is not what I would like to see.

One thought I had was to release any work I do (build scripts, patches to Wesnoth) under the AGPL. This of course means that my changes cannot be contributed back to Wesnoth itself, but nor can my changes be built on top of to create a closed-source Wesnoth. This is all academic if I don't end up releasing, but I'm interested in any comments.
User avatar
iceiceice
Posts: 1056
Joined: August 23rd, 2013, 2:10 am

Re: Working on Wesnoth in the browser (via Emscripten)

Post by iceiceice »

Hi,

I have worked a lot with emscripten in the last year, glad to hear someone interested in this idea :) IIRC Ancestral was often proposing to port the entire game to node.js but that did not get much traction. However cross-compiling to js would be pretty neat imo, and honestly wesnoth is a great candidate for this kind of thing since the art is already not so many bytes in size.

If you already cross-compiled boost, then kudos, that is a big step of getting the deps and it means you are good enough at this that you can obtain any deps you need I guess.

The most obvious challenges in my mind are:
1. Emscripten networking is strictly based on websockets, however, porting the wesnoth multiplayer server to use websockets would be a big challenge.
2. Wesnoth makes heavy use of C++ exceptions, for internal messaging and such. :doh: This is not very friendly to emscripten, which first of all has only a very slow emulation of C++ exceptions, and second of all at various points in times wasn't fully standards compliant. By default if you turn on any optimizations, emcc will disable the use of C++ exceptions and terminate the process if an exception is ever thrown. You can enable exceptions with a special compiler flag, but the bigger question is whether the game will be playable with the resulting slowdown. I honestly have no idea whether it will or won't. Edit: Actually I guess one of the big reasons they disable exceptions is because, exception support means adding exception handling code to every single function, and this makes your resulting program significantly larger. Usually in emscripten when you optimize it, you are doing everything you can to make the resulting program small, so that the user doesn't have to download so much crap, and because the JIT compiler may just reject any functions that are larger than some threshold so you won't get native speeds for such functions, depending on what browser you are working with.
3. Wesnoth has a *very* strange main loop arrangement. Normally, when the game is running, the main loop is controlled by something called "play_controller" and the "play_slice" function is the "main loop iteration body". However, when a dialog in the new GUI2 system is activated, it hijacks the main loop and then the main loop runs strictly through the GUI2 code. In emscripten, as I guess you know, there technically is no main loop, instead you indicate to the system what function is currently the "main loop iteration body". So you would have to untangle a mess of play controller / gui implementation code and often change the "main loop function" in response to user input if you want it to run in emscripten like it does natively. This would require you learning quite a bit about the wesnoth code base unfortunately.

Otherwise though, wesnoth uses SDL libs strictly for images, sound, input, etc., and all these are well supported by emscripten. Also, wesnoth is basically single-threaded except for the networking part. So you shouldn't have any problems with that. If you can overcome these issues then I guess it should work :) At least I didn't think of any more issues.

WRT licensing -- I tend to agree that wesnoth should mostly remain under GPL. I also agree that AGPL is preferable if no one else is opposed.
Not all the devs / historical devs are actually fans of the GPL though, you can find several who would say that we should use a more permissive license.
Also there's all these questions about legitimacy of distributing GPL stuff on the Apple app store.

In short I think you should feel free to license your work however you like, and you shouldn't expect a lot of pushback from anyone here, imo. We have talked some times about changing the license but its hard and many of the original creators are not easily findable anymore. So relicensing even if we wanted to isn't terribly likely, although it is brought up from time to time so who knows.
fendrin
Posts: 31
Joined: September 10th, 2009, 10:45 am

Re: Working on Wesnoth in the browser (via Emscripten)

Post by fendrin »

Emscripten and exceptions?
Especially those going through some lua execution.

I have heard people speaking about c++ code written completely exception free to run properly via emscripten.
So yes, porting Wesnoth to run in emscripten is probably ambitious.

Still emscripten is a fascinating piece of technique.

About the licencing problem, I guess the Wesmere project (see link in my signature) comes with the exact same problem.
So I am searching for a solution as well.
The AGPL seems to solve it.

I haven't decided which license to use yet.
"Wesnoth has many strong points but team and users management are certainly not in them." -- pyrophorus
"The thing a project in the true spirit of open source has to fear is not forking, but clean-room re-implementation. When that happens, you know something is wrong."
aidanhs
Posts: 7
Joined: December 3rd, 2015, 8:03 pm

Re: Working on Wesnoth in the browser (via Emscripten)

Post by aidanhs »

iceiceice wrote:If you already cross-compiled boost, then kudos, that is a big step of getting the deps and it means you are good enough at this that you can obtain any deps you need I guess.
I confess, I was feeling pretty happy after managing to get boost working.
Then this weekend I had a shot at Pango and my eyes were opened. Pango depends on cairo and glib. Cairo depends on harfbuzz, fontconfig and pixman. Fontconfig depends on libxml.
It was pretty bad. Glib gets a special mention for being particularly diabolical (why does a font library need to depend on something providing networking!?). The deps are nearly all done now I think, but I'm going to take a few weeks off.
The most obvious challenges in my mind are:
1. Emscripten networking is strictly based on websockets, however, porting the wesnoth multiplayer server to use websockets would be a big challenge.
2. Wesnoth makes heavy use of C++ exceptions, for internal messaging and such. :doh: This is not very friendly to emscripten, which first of all has only a very slow emulation of C++ exceptions, and second of all at various points in times wasn't fully standards compliant. By default if you turn on any optimizations, emcc will disable the use of C++ exceptions and terminate the process if an exception is ever thrown. You can enable exceptions with a special compiler flag, but the bigger question is whether the game will be playable with the resulting slowdown. I honestly have no idea whether it will or won't. Edit: Actually I guess one of the big reasons they disable exceptions is because, exception support means adding exception handling code to every single function, and this makes your resulting program significantly larger. Usually in emscripten when you optimize it, you are doing everything you can to make the resulting program small, so that the user doesn't have to download so much crap, and because the JIT compiler may just reject any functions that are larger than some threshold so you won't get native speeds for such functions, depending on what browser you are working with.
3. Wesnoth has a *very* strange main loop arrangement. Normally, when the game is running, the main loop is controlled by something called "play_controller" and the "play_slice" function is the "main loop iteration body". However, when a dialog in the new GUI2 system is activated, it hijacks the main loop and then the main loop runs strictly through the GUI2 code. In emscripten, as I guess you know, there technically is no main loop, instead you indicate to the system what function is currently the "main loop iteration body". So you would have to untangle a mess of play controller / gui implementation code and often change the "main loop function" in response to user input if you want it to run in emscripten like it does natively. This would require you learning quite a bit about the wesnoth code base unfortunately.

Otherwise though, wesnoth uses SDL libs strictly for images, sound, input, etc., and all these are well supported by emscripten. Also, wesnoth is basically single-threaded except for the networking part. So you shouldn't have any problems with that. If you can overcome these issues then I guess it should work :) At least I didn't think of any more issues.
This is all very helpful, thanks. Networking is a long term plan, so I'm not worrying about that now. I'll have to see how exceptions and the main loop turn out, but it's good to know in advance that the main loop in particular may require a lot of patience.
It's very encouraging to know that wesnoth is singlethreaded as well, so thanks again - I had to hack loads of libraries to disable threads (not well supported in emscripten right now) and was worried I'd be breaking something in the long run. Sounds like I'm safe for now.
User avatar
iceiceice
Posts: 1056
Joined: August 23rd, 2013, 2:10 am

Re: Working on Wesnoth in the browser (via Emscripten)

Post by iceiceice »

aidanhs wrote:The deps are nearly all done now I think, but I'm going to take a few weeks off.
Wow, I didn't even know that it was possible to build pango on emscripten, I certainly never heard of that :)

You know, maybe you should consider to try to incorporate some of that into the "emscripten-ports" system?

https://github.com/emscripten-ports
https://kripken.github.io/emscripten-si ... jects.html

The emscripten ports are the libs you can get automatically by doing e.g.

Code: Select all

-s USE_SDL=2 
etc.
I was thinking to try to create / help maintain ports for libxml and pcre, because those are CEGUI deps and thus fairly popular.
Even just cairo is pretty ambitious, if you know how to make a cairo port I think it would help a ton of people out :)
I think it is compatibly licensed?
aidanhs
Posts: 7
Joined: December 3rd, 2015, 8:03 pm

Re: Working on Wesnoth in the browser (via Emscripten)

Post by aidanhs »

iceiceice wrote:Wow, I didn't even know that it was possible to build pango on emscripten, I certainly never heard of that :)

You know, maybe you should consider to try to incorporate some of that into the "emscripten-ports" system?

https://github.com/emscripten-ports
https://kripken.github.io/emscripten-si ... jects.html

The emscripten ports are the libs you can get automatically by doing e.g.

Code: Select all

-s USE_SDL=2 
etc.
I was thinking to try to create / help maintain ports for libxml and pcre, because those are CEGUI deps and thus fairly popular.
Even just cairo is pretty ambitious, if you know how to make a cairo port I think it would help a ton of people out :)
I think it is compatibly licensed?
Yes, when I can positively demonstrate that these libraries work, I'll see about contributing back (I've already contributed back a bit to ports as a result of doing this). At the moment though, they've just built - whether they work is another matter!

On the subject of building:

Code: Select all

$ emscons scons -j3 boostdir=$(pwd)/../boost/dist/include ctool=emcc cxxtool=em++ history=false
[...much time passes...]
em++ -o wesnothd build/release/server/ban.o build/release/server/forum_user_handler.o build/release/server/game.o build/release/server/input_stream.o build/release/server/metrics.o build/release/server/player.o build/release/server/player_network.o build/release/server/proxy.o build/release/server/room.o build/release/server/room_manager.o build/release/server/sample_user_handler.o build/release/server/simple_wml.o build/release/server/user_handler.o build/release/server/server.o build/release/libwesnoth_core.a build/release/libwesnothd.a -lm -lSDL2_net -lboost_iostreams -lboost_random -lboost_system -lboost_filesystem -lboost_locale
WARNING:root:emcc: cannot find library "SDL2_net"
WARNING:root:emcc: cannot find library "boost_iostreams"
WARNING:root:emcc: cannot find library "boost_random"
WARNING:root:emcc: cannot find library "boost_system"
WARNING:root:emcc: cannot find library "boost_filesystem"
WARNING:root:emcc: cannot find library "boost_locale"
scons: done building targets.
i.e. the scons build process for wesnoth completes successfully. Obviously there's still loads to do (foremost of which is to fix those warnings which shouldn't be too hard) and there's not a chance it'll run as-is, but it's nice evidence of some progress.
User avatar
iceiceice
Posts: 1056
Joined: August 23rd, 2013, 2:10 am

Re: Working on Wesnoth in the browser (via Emscripten)

Post by iceiceice »

Code: Select all

em++ -o wesnothd  ...
Hmm, it looks there like you are building "wesnothd", which is the multiplayer server target? Probably you can disable that, I would be surprised if it worked in the browser... That may solve some of your warnings.
aidanhs
Posts: 7
Joined: December 3rd, 2015, 8:03 pm

Re: Working on Wesnoth in the browser (via Emscripten)

Post by aidanhs »

iceiceice wrote:Hmm, it looks there like you are building "wesnothd", which is the multiplayer server target? Probably you can disable that, I would be surprised if it worked in the browser... That may solve some of your warnings.
Yeah, that was just the first time the build completed all the way through so I figured I'd post. I have now disabled wesnothd.

In other news, a touch more progress:
screenshot.png
(no, that's not just an image embedded in the page!)
aidanhs
Posts: 7
Joined: December 3rd, 2015, 8:03 pm

Re: Working on Wesnoth in the browser (via Emscripten)

Post by aidanhs »

Exactly one year later (check the date) I'm back! The delay is because I had to rewrite the Emscripten optimizer because its memory usage was killing my computer and making development impossible.

Anyway, some progress to share:
screenshot.png
Yes, that is a full progress bar, with all of
  • "Initializing user interface"
  • "Loading game configuration"
  • "Verifying cache"
  • "Reading files and creating cache"
  • "Reading unit files"
  • "Reinitialize fonts for the current language"
  • "Searching for installed add-ons"
Successfully completed - it's just failing on actually displaying the title screen.
aidanhs
Posts: 7
Joined: December 3rd, 2015, 8:03 pm

Re: Working on Wesnoth in the browser (via Emscripten)

Post by aidanhs »

Got the title screen! Though fontconfig clearly needs some work...
screenshot.png
aidanhs
Posts: 7
Joined: December 3rd, 2015, 8:03 pm

Re: Working on Wesnoth in the browser (via Emscripten)

Post by aidanhs »

After some fighting with pango, fontconfig, harfbuzz...
Screenshot from 2017-03-14 21-23-12.png
Post Reply