Way to measure decision time?

Hey everyone!
My name is Haydn and I'm currently a university student in my final year studying sound for games and apps.

For one of my final pieces I'm doing an experiment on how different types of music affect the types of decisions a player might make. More specifically, I'm looking to see whether different levels of intensity in music cause players to take more active actions or more passive actions (i.e. will high-tempo music make someone more likely to "run" as opposed to "hide").

I decided to use Quest as my testing ground due to the ability to create choose your own adventure stories and having the ability to embed music into the page, which is what made me notice the scripting side of things.
This gave me an idea; would I be able to measure how long it takes for a person to make a decision?

I've had a quick look around but as I am not very familiar with the scripting of Quest I was wondering how I would go about making a timer system that would measure how long a person spends on each decision page, and then be able to post the times for each decision at the end?

If anyone can help that would be amazing! Thanks in advance!


Io

It would technically be possible. You'd rig a timer to Start whenever a decision is presented, and when a decision is made, part of the 'decision made' code would stop the timer. Said timer would tick up a Variable every so-often, and with some dictionary-shenanigens you could assign it to different Decisions.

I'm not an expert on Dictionaries, though. The syntax confuses me, but go have a look through!


You didn't say if you're using Quest in gamebook or text adventure mode.

Timers don't work properly in gamebook mode. But I think you could do this in javascript.

Assuming you're doing this in gamebook mode, you'd want to modify three of the core functions:
You'd want to add lines to the beginning of the function HandleCommand so that it records or otherwise handles the time taken:

if (IsRegexMatch ("^\d+:", command)) {
  colon = Instr (command, ":")
  time = ToInt (Left (command, colon))
  command = Trim (Mid (command, colon + 1))
  // Insert whatever code you want here to process or log the time.
  // The variable `command` will be the name of the page clicked on, and `time` will be the time taken
}if (command = "undo") {
  // ignore
}
else {
  newpage = GetObject(command)
  if (newpage = null) {
    msg ("Error - no page named '" + command + "'")
  }
  else {
    if (not game.clearlastpage and HasAttribute(player.parent, "options")) {
      if (DictionaryContains(player.parent.options, command)) {
        optiontext = StringDictionaryItem(player.parent.options, command)
        msg ("<b>" + optiontext + "</b>")
        msg ("")
      }
      JS.disableAllCommandLinks()
    }
    player.parent = GetObject(command)
  }
}

Then you need to modify the javascript, so that the frontend interface will measure and send the time taken. You could do this by adding lines to the function InitInterface:

if (game.setcustomwidth) {
  JS.setGameWidth(game.customwidth)
}
if (not game.showborder) {
  JS.hideBorder()
}
if (game.setcustompadding) {
  JS.setGamePadding(game.custompaddingtop, game.custompaddingbottom, game.custompaddingleft, game.custompaddingright)
}
SetBackgroundColour(game.defaultbackground)
SetForegroundColour(game.defaultforeground)
SetLinkForegroundColour(game.defaultlinkforeground)
JS.SetMenuBackground(game.menubackground)
JS.SetMenuForeground(game.menuforeground)
JS.SetMenuHoverBackground(game.menuhoverbackground)
JS.SetMenuHoverForeground(game.menuhoverforeground)
JS.SetMenuFontName(game.menufont)
JS.SetMenuFontSize(game.menufontsize + "pt")
JS.panesVisible(false)
JS.uiHide("#location")
JS.uiHide("#txtCommandDiv")
JS.eval("$(function(){var e=new Date;$(document).off('click','.commandlink'),$(document).on('click','.commandlink',function(){var a=$(this);if(!a.hasClass('disabled')&&canSendCommand){a.data('deactivateonclick')&&(a.addClass('disabled'),a.data('deactivated',!0));sendCommand((new Date()-e)+':'+a.data('command'))}}),EndOutputSection=function(a){$('.'+a+' .commandlink').length&&(e=new Date);var n=$.inArray(a,_outputSections);-1!=n&&(_outputSections.splice(n,1),createNewDiv('left'))}});")

(The javascript there is a little hard to read; uncompressed it would look like this:

$(function () {
  var decisiontimer = new Date();
  $(document).off("click", ".commandlink");
  $(document).on("click", ".commandlink", function () {
    var $this = $(this);
    if (!$this.hasClass("disabled") && canSendCommand) {
      if ($this.data("deactivateonclick")) {
        $this.addClass("disabled");
        $this.data("deactivated", true);
      }
      var timetaken = new Date();
      timetaken -= decisiontimer;
      var cmd = timetaken.toString() + ":" + $this.data("command");
      sendCommand(cmd);
    }
  });

  EndOutputSection = function(name) {
    // if this is an "options" output section, we restart the timer.
    if ($("."+name+" .commandlink").length) {
      decisiontimer = new Date();
    }
    var index = $.inArray(name, _outputSections);
    if (index != -1) {
      _outputSections.splice(index, 1);
      createNewDiv("left");
    }
  };
});

That modifies the javascript so that the string sent to the Quest backend, instead of the name of the page it should be going to, is a string like "294:page17".
The time in this case is in milliseconds, so if you want it in seconds divide by 1000. The timer is reset every time the browser has finished outputting a section which includes a page link, and is recorded when the player clicks on the link. So in the case of the web player, you're not including any lag while the player waits for their response.

You could do something similar with a text adventure (I put green boxes around the code I added to those functions; the existing functions are different for TA, but the bits you add should be the same. Although in that case, it would only work for command links, not for other types of input)


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

Support

Forums