About the JS function "ASLEvent"

I'm working on something with Quest that uses JavaScript frequently, with Quest sending values to a JS function and JS functions passing them back to Quest. ASLEvent only being able to take one string parameter functions really limits what I can do with this. Only being able to get a string back means I have to do annoying conversions and type checking, as I'm sending back and forth multiple data types.

This, combined with the fact that Quest script processing and JavaScript processing seem to be asynchronous makes it even harder to work with. For example, if I were to run Quest Function 1 that calls JS Function (that in turn calls another Quest function that sets object attributes), and then call Quest Function 2 the line after, Quest Function 2 would run before or in the middle of the JS function, causing errors in some situations.

It would be nice if there was a more graceful approach to having Quest and JavaScript communicate, because things that should be very simple end up becoming a hassle.


K.V.

Hello,

If you post some code, we can probably help you smooth things over.

(I've been learning to make better use of ASLEvents this week, myself.)


K.V.

One thing at a time


Thing 1:

ASLEvent only being able to take one string parameter functions really limits what I can do with this.

You have to set your Quest function up to split a single parameter into however many you need.

  <function name="SetName" parameters="param">
    params = Split(param,"|")
    first = params[0]
    last = params[1]
    player.firstname = first
    player.lastname = last
  </function>

The JS:

getName = function(){
  var firstName = prompt("What is your first name?");
  var lastName = prompt("What is your last name?");
  ASLEvent('SetName',firstName+'|'+lastName);
};


K.V.

Thing 2

For example, if I were to run Quest Function 1 that calls JS Function (that in turn calls another Quest function that sets object attributes), and then call Quest Function 2 the line after, Quest Function 2 would run before or in the middle of the JS function, causing errors in some situations.

Example 1:

Let's put this in the start script:

JS.eval ("getName = function(){  var firstName = prompt('What is your first name?');  var lastName = prompt('What is your last name?');  ASLEvent('SetName',firstName+'|'+lastName);  ASLEvent ('ShowName','');};")
JS.getName ()

And here are our two functions being called by ASLEvent()s:

  <function name="SetName" parameters="param">
    params = Split(param,"|")
    first = params[0]
    last = params[1]
    player.firstname = first
    player.lastname = last
  </function>
  <function name="ShowName">
    msg (player.firstname +" "+player.lastname)
  </function>

Note that the ShowName function doesn't have any parameters. Because of that, the ASLEvent() will not work. And, if there is a way to call a function from an ASLEvent() which doesn't take any parameters, I haven't figured out how to do it.

So, let's add a worthless parameter to the ShowName() function, and add a worthless parameter to the ASLEvent(), just to appease Quest:

Revised start script:

JS.eval ("getName = function(){  var firstName = prompt('What is your first name?');  var lastName = prompt('What is your last name?');  ASLEvent('SetName',firstName+'|'+lastName);  ASLEvent ('ShowName','bs_value');};")
JS.getName ()

Revised ShowName() function:

  <function name="ShowName" parameters="bs_value">
    msg (player.firstname +" "+player.lastname)
  </function>

Now, that works.

...but I'm calling everything from JS!

What if we wanted to just call ShowName() normally? And what if we didn't want to use that useless bs_parameter?

Let's strip some things down.

We'll remove the ASLEvent() calling ShowName() from the JS function and remove the parameter from the ShowName() function while we're at it.

Then, we'll add a SetTurnTimeout(1), and that script will call the normal Quest function after the ASLEvent() has been called, and everything will work out.

Revised start script:

JS.eval ("getName = function(){  var firstName = prompt('What is your first name?');  var lastName = prompt('What is your last name?');  ASLEvent('SetName',firstName+'|'+lastName);};")
JS.getName ()
SetTurnTimeout (1) {
  ShowName
}

Re-revised function:

  <function name="ShowName">
    msg (player.firstname +" "+player.lastname)
  </function>

Now, that works.


Would you like to know how I figured that out?

I didn't, really.

I added an ASLEvent to the start script of my game.

My game has a turn script, which is enabled when play begins, but doesn't actually fire until you've entered your first command. (That's just how turn scripts work. They don't fire when the game loads. They fire after the first turn has been taken.)

So, I noticed that my turn script was firing BEFORE entering my first command when I had an ASLEvent() in my start script, and I began to piece things together.

In fact, if you call 2 ASLEvent()s in your start script, the turn script will fire TWICE!!!


Before I go changing things around, I'll show you the output I get right now, with a single ASLEvent() in the start script.

The only thing I haven't shown you is the turn script:

  <turnscript name="turnscript">
    <enabled />
    <script>
      msg ("Running the turnscript.")
    </script>
  </turnscript>

Here's what I get:

image


Here's the entire code for that, just for archival purposes (and to avoid confusion):

<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="ASLEvents">
    <gameid>0414da24-6327-456f-bcb6-53f1d0246587</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
    <start type="script">
      JS.eval ("getName = function(){  var firstName = prompt('What is your first name?');  var lastName = prompt('What is your last name?');  ASLEvent('SetName',firstName+'|'+lastName);};")
      JS.getName ()
      SetTurnTimeout (1) {
        ShowName()
      }
    </start>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <enter type="script">
    </enter>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
  </object>
  <turnscript name="turnscript">
    <enabled />
    <script>
      msg ("Running the turnscript.")
    </script>
  </turnscript>
  <function name="SetName" parameters="param">
    params = Split(param,"|")
    first = params[0]
    last = params[1]
    player.firstname = first
    player.lastname = last
  </function>
  <function name="ShowName">
    msg (player.firstname +" "+player.lastname)
  </function>
</asl>

Okay, let's flip back to the first way I had it working, just to show how the turn script is firing once for each ASLEvent().

The entire code:

<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="ASLEvents">
    <gameid>0414da24-6327-456f-bcb6-53f1d0246587</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
    <start type="script">
      JS.eval ("getName = function(){  var firstName = prompt('What is your first name?');  var lastName = prompt('What is your last name?');  ASLEvent('SetName',firstName+'|'+lastName);  ASLEvent ('ShowName','bs_value');};")
      JS.getName ()
    </start>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <enter type="script">
    </enter>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
  </object>
  <turnscript name="turnscript">
    <enabled />
    <script>
      msg ("Running the turnscript.")
    </script>
  </turnscript>
  <function name="SetName" parameters="param">
    params = Split(param,"|")
    first = params[0]
    last = params[1]
    player.firstname = first
    player.lastname = last
  </function>
  <function name="ShowName" parameters="bs_value">
    msg (player.firstname +" "+player.lastname)
  </function>
</asl>

image


So...

This is what I've (sort of) figured out so far:

  • It's best to only call one ASLEvent() at a time.

  • An ASLEvent() can only handle one parameter (and I think it HAS TO pass a single parameter), but a Quest function can split that up into however many parameters you want (and you can call numerous Quest functions from a Quest function, if necessary).

  • Use a SetTurnTimeout(1) to nest the Quest script you want to invoke AFTER an ASLEvent() which sets attributes which will be needed in the Quest script.


Things I don't know:

  • How would I know? (Ha-ha!)

Anyone else have any input concerning ASLEvent()s?

(I'm sure I've forgotten something, and I've even more certain I'm unaware of something.)


K.V.

Resources:


JavaScript to Quest with ASLEvent
docs.textadventures.co.uk/quest/ui-callback.html
JavaScript to Quest with ASLEvent. We can think of the game as two distinct parts , the game world, handled by Quest, and the user interface, handled by JavaScript in the browser window (even the desktop version uses a browser). The JS object can be uses to pass information and commands from Quest to JavaScript; how ...


Quest 5 - Documentation
docs.textadventures.co.uk/quest/
... (simple options you can set from the game object); Display verbs · Custom commands and status pane (adding extra panes to your game); Simple Customisation · Customisation part 1 (three pages that explore customisation in detail); Customisation part 2 · Customisation part 3 · ASLEvent: Handling events in JavaScript ...


Using Javascript
docs.textadventures.co.uk/quest/using_javascript.html
To do this, the button must have an attribute, “onclick”, with some Javascript code, using the special function ASLEvent : ASLEvent("ProcessButtonClick", id);. This is Javascript calling a ProcessButtonClick function which should be defined in the Quest game. It passes a parameter - the id of the button clicked - to indicate ...


Adding a Dialogue Panel
docs.textadventures.co.uk/quest/ui-dialogue.html
This will be done with the special JavaScript function ASLEvent , which is provided by Quest. A complication here is that that can only take two paramters; the name of the Quest function to use, and a string. Either we need to use it numerous times, once for each value, or use it once but send it all the data in a single string.


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums