Pre-release
AdventureJS Docs Downloads
Score: 0 Moves: 0
Tutorial explaining how to work with Javascript events in AdventureJS. tutorial, events, inputEnter, inputParseBegin, inputParseComplete, inputQueueNext

Advanced Scripting:Javascript Events

AdventureJS fires a few events – by which we mean standard Javascript events that can be detected with event listeners – as opposed to any kind of in-game events. These include:

  • inputEnter: triggers when player presses the return key
  • inputParseBegin: triggers when turn begins parsing
  • inputQueueNext: triggers between queued inputs
  • inputParseComplete: triggers when turn completes

Authors can use event listeners to run custom code. Any event listeners you create will fire asynchronously – which is a way of saying that they exist outside of the AdventureJS game loop. This means they shouldn't be relied upon to modify logic within the current turn, because they may be running out of sync with the game loop. Instead, use them to run logic independently of the game. For example, let's say that you wanted to run a series of tutorials that teaches a player how to play your game. You might use an event listener that checks on the player's status every turn and offers contextual suggestions depending on how well they're advancing through the game. Following are a couple of simple examples.

Examples

This example keeps count of turns and prints messages at certain turn counts.

MyGame.reactor.addEventListener('inputParseComplete', function() {

  // set a global variable if it hasn't already been set
  window.turn_counter = window.turn_counter || 0;
  // just remember that global variables 
  // aren't subject to undo/save/restore
  
  // increment the turn counter after every turn
  window.turn_counter++;

  let msg = ``;
  switch (window.turn_counter) {
    case 10:
      msg = `Thanks for playing my game! `;
      MyGame.print(msg);
      break;
    case 50:
      msg = `Wow, you like me! You really like me! `;
      MyGame.print(msg);
      break;
    case 100:
      msg = `You've played for 100 turns. Congratulations! `;
      MyGame.print(msg);
      break;
    case 500:
      msg = `Wow, you've really been playing for a while now, huh? `;
      MyGame.print(msg);
      break;
    case 1000:
      msg = `Hey, maybe you should turn this off and go to bed...? `;
      MyGame.print(msg);
      break;
    default:
      break;
  }
});

This example prints at randomized frequency from a set of ambient events depending on what room the player is in. (There are other ways to achieve this, but for the sake of the example...)

MyGame.reactor.addEventListener('inputParseComplete', function() {
  var random = Math.random() * 100;
  switch (MyGame.getRoom().name)
  {
    case "Frigid Wastes":
      if( random < 10 )
      {
        MyGame.print(
          "You're struck by a flash of blinding light as
          sunlight reflects off the packed ice.", "random"
        );
      }
      break;
    case "Desert Wastes":
      if( random > 5 && random < 10 )
      {
        MyGame.print(
          "Heat haze shimmers off the distant dunes.", "random"
        );
      }
      else if( random > 10 && random <  15 )
      {
        MyGame.print(
          "You feel the sand shift beneath your feet.", "random"
        );
      }
      break;
  }
});

A note about listeners

Here we offer one important note about event listeners. It's possible to add as many event listeners are you like. However, event listeners never stop listening until you remove them, which can lead to them piling up in potentially undesirable ways. In order to remove an event listener, it must be defined in a specific way. Instead of defining it as an anonymous inline function – like the examples above – you must pass it a reference to another function, as in the following example. Then, pass that same reference to remove the listener.

// pass a reference to addEventlistener
MyGame.reactor.addEventListener('inputParseComplete', countTurns);
  
var countTurns = function() {

  // set a global variable if it hasn't already been set
  window.turn_counter = window.turn_counter || 0;
  // just remember that global variables 
  // aren't subject to undo/save/restore
  
  // increment the turn counter after every turn
  window.turn_counter++;

  let msg = ``;
  switch (window.turn_counter) {
    case 10:
      msg = `Thanks for playing my game! `;
      MyGame.print(msg);
      break;
    case 50:
      msg = `Wow, you like me! You really like me! `;
      MyGame.print(msg);
      break;
    case 100:
      msg = `You've played for 100 turns. Congratulations! `;
      MyGame.print(msg);
      break;
    case 500:
      msg = `Wow, you've really been playing for a while now, huh? `;
      MyGame.print(msg);
      break;
    case 1000:
      msg = `Hey, maybe you should turn this off and go to bed...? `;
      MyGame.print(msg);

      // pass the same reference to remove the listener
      MyGame.reactor.removeEventListener('inputParseComplete', countTurns);

      break;
    default:
      break;
  }
};

Further reference

If you want to call scripts at the beginnings and ends of turns that do run inside the game loop, consider using prescripts and postscripts.

Visit the MDN to learn more about Javascript events and event listeners.