Asynchronous game engine

Client-side JavaScript is non-blocking: all long-running operations are asynchronous. The ROT.Engine loop is well suited to orchestrating the possibly-async coordination of various game actors.

To use the engine, you first need a scheduler that stores your actors and manages their priority. This scheduler is passed to ROT.Engine's constructor. Once the engine is started, it correctly calls the act() method on proper actors (picked by the scheduler). It is possible to recursively stop (lock) the engine, should some operation (such as displaying a dialog or waiting for user input) block the execution. Once all lock levels are unlocked, the engine continues its execution.

var scheduler = new ROT.Scheduler.Simple(); var engine = new ROT.Engine(scheduler); var output = []; /* sample actor: pauses the execution when dead */ var actor1 = { lives: 3, act: function() { output.push("."); this.lives--; if (!this.lives) { scheduler.remove(actor1); engine.lock(); /* pause execution */ setTimeout(unlock, 500); /* wait for 500ms */ } } } scheduler.add(actor1, true); var unlock = function() { /* called asynchronously */ var actor2 = { act: function() { output.push("@"); } } output = []; scheduler.add(actor2, false); /* add second (non-repeating) actor */ engine.unlock(); /* continue execution */ SHOW(output.join("")); } engine.start(); SHOW(output.join(""));

Promises

ROT.Engine is ready for a promise-based async control flow: if any actor returns a "thenable" from its act() method, the engine locks itself and waits for the thenable to get resolved (via its then() method). This feature is independent on the Promise implementation used; feel free to supply your own, use a library or leverage your browser's native Promises.

var scheduler = new ROT.Scheduler.Simple(); var engine = new ROT.Engine(scheduler); var output = []; /* sample actor: pauses the execution when dead */ var actor = { lives: 3, act: function() { var done = null; var promise = { then: function(cb) { done = cb; } } output.push("."); SHOW(output.join("")); this.lives--; /* if alive, wait for 500ms for next turn */ if (this.lives) { setTimeout(function() { done(); }, 500); } return promise; } } scheduler.add(actor, true); engine.start();