Possible feature for aether to help implement web workers?


#1

I am developing a game using codecombat/aether. It is going well. However currently aether is running in the same page as the rest of the game. I would like to run the user generated code in a web worker but have been struggling, conceptually, how to implement this. Currently I am passing to the aether.createMethod() generated method controller objects that allows the user code to interact with the game world. User code is run each tick. It seams to me if I want to use a web worker I need to rewrite large portions of my code to be asynchronous. However, I don’t want to make the user code asynchronous (i.e. user should be able to call $bot.MoveTo(x,y) and $map.get(x,y) for example). This seams like a difficult task that I’m hesitant to start without a good plan.

I keep thinking that this is perhaps something aether could help with. My tick loop looks something like this, using aether’s yieldAutomatically:

var method = aether.createMethod();
var generator = method($consoleInterface, $playerInterface, $mapInterface);
aether.sandboxGenerator(generator);

var c = 0, result = { done: false };
while (!result.done && c++ < 200000) {
  result = generator.next();
}

I could imagine a mechanism in aether that handles the web worker guest <-> host communication allowing for the guest to send a message to the host, requesting a synchronous function call on the host then waiting for a response, then calling generator.next().

Does this sound feasible? Does it look like a reasonable feature request for aether?

(sorry if this should be on github instead of here)


#2

Hey Hypercubed, sorry I missed this until now. It’s quite a difficult problem! I think the best way to go is to run all of the game code in the web worker, and only send the state you need to visualize to the main thread. So then your game engine is still synchronous, and is still running in one thread, but it’s just the thread that isn’t going to block the UI. This is how CodeCombat does it, anyway.

You also don’t want to send too many messages in between the web worker and the main thread, because it’s not the fastest interface in the world–you definitely wouldn’t want to do it many thousands of times per second. CodeCombat also runs all the world in advance and then can control state playback separately on the main thread, but you can probably just send one “frame” to the main thread and visualize that if you don’t need time travel.


#3

No problem Nick. Thank you for replying.

I’ve been considering the codecombat approach for my game but it could be complicated. I’m my case there is more real time user interaction with the simulation and the simulation might not be deterministic. That also means removing my game engine from the angular framework (I don’t think I want all of angular running in a webworker). This is all certainly workable but in the mean time I’ve been trying to consider how the aether yielding machine could help and perhaps add a not too complicated (but likely not too efficient) default webworker for safety.

Thank you again for the reply. aether was a great help in my project and I haven’t even began to use all the capabilities.


#4

You kind of need to manually specify how state is transferred between the web worker and the main thread, anyway, because you can’t just serialize whatever you want across web worker boundaries. So you either 1) define the interface between user code and game engine such that the user code’s function calls all somehow proxy to the main thread, serialized, and get the results, serialized, and the user code is running on the web worker–or you 2) run the entire game engine on the web worker and just figure out how to serialize the state you’re going to draw. I don’t know all of your API endpoints, but it seems like (1) is harder to do anyway, not to mention vastly less performant.

The point of running the user code in the web worker is for performance or security? If it’s just security, you could just punt until later. Players will be able to hack out and steal sessions, but it’s not that easy, and until you have a bunch of players, no one will care enough to do so. Plus, until you have players’ email addresses stored, the damage they can do with malicious code isn’t too terrible…