The Sample Projects folder, Code: Tutorial Tasks contains a series of five tasks that wil introduce you to the basics tools for writing a gorilla task in code. Below, we describe the contents of the tasks and the concepts they introduce.
The 'HelloWorld' task introduces the basic commands that all code-editor tasks in gorilla will need. These are:
import gorilla, imports the gorilla package into your code and allows you to use all the
gorilla.ready, contains the functions to be run or setup once the page is ready for content,
gorilla.run, begins execution of the code editor task and contains the first function to be run,
gorilla.finish, ends the task.
In the HelloWorld task, we display the heading 'HelloWorld' on the screen. We use a
JQuery selector to add this heading to the main div element on the page, with the id
gorilla. Gorilla creates this for you in every task and this div will always be accessible. We also use a timeOut to execute the
gorilla.finish() command after 5 seconds.
gorilla.finish() ends the task and, if your task is part of an experiment in the tree, will return control to the tree and move the participant on to the next node of your experiment.
You can create a basic task like this from the moment you create a new task in the code editor - you don't need to add any other features to the code editor from the toolbox!
The previous task didn't allow us to have much control over where the content we added appeared on the page - not without adding a lot more commands to our jQuery selector. In this task, we introduce 'Templates' to our gorilla code task. To add templates to your task, click on the Toolbox and check the box 'Use Templates'. Templates allow you to control the placement and appearence of elements on your page in more detail. You can also replicate the appearence of Gorilla 'zones' from the Task Builder. This could be useful if you have an experiment using a mix of tasks from the builder and the code editor and want to keep the appearence of your tasks consistent for the participant.
We also introduce the following new Gorilla commands:
gorilla.populate, adds content to your page using your templates and additional arguments,
gorilla.refreshLayout, makes sure that the content of our page is placed correctly.
gorilla.populate functions in a similar way to the jQuery selector we had in the first tutorial task.
The contents of the template 'HelloWorld', along with any additional data in the third arguement, is turned into html and added to the div with the id 'gorilla'. In our HelloWorld template, we define two gorilla zones - one in the top half of our page and the other in the bottom half of the page. You can define the placement of these zones using
These data points replicate the functionality of the handles on the zones in the gorilla task builder.
Rather than end the task using a timeOut, we add a button to the bottom half of our page labelled 'Finish' and bind a
'click' event to it using jQuery.
This event triggers the
In the first HelloWorld task, all of our code was located in
In this task, we put all of the code necessary to run our task inside the function 'DisplayHelloWorld.'
This function is then set to execute once gorilla.run is called.
Dividing the code of our task up into functions will allow us to create more complicated tasks in the future.
In this task, we're going to introduce displaying stimuli to the participant, as well as increasing the number of screens in our task and introduce an altenative to the timeOut from the first task. We will also introduce the use of the style file for the first time. The new gorilla functions added in this task are:
gorilla.initialiseTimer, allows us to use the timing features available in Gorilla,
gorilla.populateAndLoad, an alternative to
gorilla.populateuseful for displaying images and videos,
gorilla.addTimerSequence, an alternative to timeOut which gives us more control and functionality.
In order to use stimuli and add more styling to our code, we need to check 'Use Styling' and 'Use Stimuli' in the Toolbox. In this task, we will display either a blue or orange circle to the user. If the circle is blue, we want the user to click on the circle. If it is orange, we want the user to do nothing.
To do this, we first need to upload our orange and blue circles.
On the stimuli tab, click the 'Add New Stimuli' button to upload new stimuli to your task.
In our 'trial' template we use
stimuli image to include our stimuli on the page.
'stimuli' is an example of a handlebars helper.
In this case it takes the name of our stimuli and puts the address to that stimuli in place of the code in braces.
We pass in the name of the stimuli as part of the third argument in our populateAndLoad call.
gorilla.populateAndLoad works similarly to
gorilla.populate except it waits for all the elements on the template to have loaded and report that they are ready before displaying the templates contents.
This is important if your task consists of larger images or videos that may take some time to buffer and load onto the page.
Our images aren't very large so we don't really need it in this case - we use it just as an example.
populateAndLoad takes as a fourth argument the function you want to run once the template has reported that it has finished loaded and is ready to be displayed.
In this task, we've added a click function to our stimuli image.
In this, we call 'iterateAndProgress' which decides whether we execute another trial or
As well as clicking on the image, there is the case that the participant may not click on the image, if the image is orange.
We use a 'sequence' to control this eventuality, creating it with
A sequence has three functions that can be added to it.
.delay(number), adds a delay or pause to the current sequence. The actions below the sequence won't be executed until the delay finishes,
.then(function), adds a function be run in the sequence,
.run(), indicates that we have added all the elements to the sequence required and that the sequence should be run().
We can add as many
.then functions to the sequence, but the sequence must end with
Sequences are useful when we want to chain a series of actions together such as displaying a fixation and then displaying a stimuli.
In this case, our stimuli executes iterateAndProgress after 3 seconds.
If anything happens that means you want to ignore the contents of the sequence, remember to call
.cancel() on your sequence.
We do this in the click function for our image element.
In this task, we're going to demonstrate how you can control properties of your task from outside of the code, adding in manipulations as can be found in the task builder. We also add one of the most important components of any tasks, the ability to collect data, 'metrics' from the participant and upload them for later review. We'll also demonstrate some more advanced techniques for improving the way our task looks and runs.
The new Gorilla functions added in this task are:
gorilla.manipulation, to access manipulations that we set before running the task,
gorilla.getStopwatch, for using the stopwatch capabilities in Gorilla, typically used for measuring reaction time,
gorilla.metric, to upload data gathered during your experiment.
Manipulations are elements of your task that you will want to change prior to running the task but without having to reqrite your code. You may want to change how many trails the task consists of, what parts of your task you want to use or how easy/hard the task is for the participant. To begin using manipulations, you will need to add them via the toolbox! Once you've done that, click 'Add Manipulation'.
You'll then be asked to enter the details of your manipulation, all of which are explained in the manipulations window.
The part most important for your code is the 'Key'.
This is used to access the value of the manipulation in your task.
In this example, we've created a manipulation called 'Number of Trials' which we'll use to set the number of trials the participant will run through during the task.
We can access the value we set for this in tasks code using
gorilla.manipulation and the key we set for the manipulation, 'noOfTrials' in this case.
This replaces the code form the previous tutorial task where we hard coded the number of trials for the participant to run through.
Next, we'll look at the stopwatch functionality.
At the beginning of our
DisplayTrial() function, after setting up the page to be displayed we call
This starts the internal gorilla stopwatch which can be used to gather reaction time data.
When the participant makes a choice on the screen, we then stop the stopwatch using
gorilla.stopStopwatch() and retrieve the current time using
This leads into the final addition to this task
Similarly to manipulations, in order to gather metrics from your participants, you first need to add the metrics tab from the toolbox and then define the metrics you want to gather.
This is simplier than for manipulations: all you need is to chose a key for the metric and then the title for the column that metric data will then appear in in your data download.
In the code, the call to
gorilla.metric takes as an arguement an object consisting of key/value pairs.
The keys are the keys defined on our metrics tab.
In the tutorial task, we've assigned the value of
gorilla.getStopwatch() to the variable responseTime, which we've then assigned to the key
responseTime in our metrics object.
In this task's code, you'll see that we've divided the code up into distinct functions:
DisplayInstructions() which handles all of the code for our instructions page,
DisplayTrial() for our trial page and
DisplayFinish() for our finish screen.
There are some other functions too such as
generateTrialNumbers(), which is used to randomnly pick two numbers from the set 0 - 9 and
iterateAndProgress() which is used to check if we've reached our maximum number of trials.
Primarily, this is just how I've chosen to arrange my code, fitting with my own style for writing and structuring my code.
There is another reason for this structuring, which will become apparent in the next tutorial task.
You can choose to arrange your code however you want, using whatever techniques you are used to.
For example, the code I've used to generate a random set of digits is of my own creation and not in anyway unique to Gorilla - you're free to right that however you want.
This task is identical to the previous task except that we have replaced our main functions for the instructions, displaying trials and the finish screen with States using the StateMachine. This is a new method for structuring your task which adds additional functionality, making it easier to create more complicated tasks.
For this task we introduce a new package
gorilla/state_machine and a new set of functions:
new stateMachine.StateMachine(), the command to create a new statemachine object,
addState, to add a state to our statemachine,
start, to begin running our statemachine,
transition, to move between states in our statemachine.
Using a statemachine is an easy way to divide up the logic and functionality of our task by defining certain 'states' that our task can be in. For example we have created an instructions state, in which we display the instructions to the participant. We can define everything that can and cannot happen in this state and govern how we move from one state to another.
To begin, and to create our life a lot easier, we create an enumerated list called
State where we list the states we're going to create:
Typescript see's these as the numbers 0, 1 and 2 but the names we've given them are much more helpful for us when writing the code.
Next we create our state machine
var SM = new stateMachine.StateMachine(); and begin adding states to it using the
addState takes a set of arguments, the first being the number associated with the state we are created.
Using our handy enumerated list, this is
We then pass up to three functions to our state:
onEnteris called whenever the state is entered,
onExitis called whenever we leave the state, usually via
onEventis called whenever an event is triggered in the task,
onEventis an important example of how useful a statemachine can be as there may be some events that we want to be available only on certain states. However, this is a more advanced example of the statemachine functionality which we won't go into in this tutorial.
onEnter is where we will usually put all of our state code.
In this case we put almost the same code from our previous tutorial task except, where before we had a call to DisplayTrial we now call
machine is an argument in the
onEnter function which represents the internal
Machine of our state machine.
We can use it to move between states using
It normally takes as an argument the id number of the state we want to move to.
Again, using our enumerated list we denote this as
Almost all the remaining code in our task is the same as before, except using
machine.transition calls instead of our previous function calls.
gorilla.run we use the
Start function to indicate the state we wish to start in, the Instructions state in this case.
This is a simple introduction to the stateMachine and how you can use it to organise and run your trials.
It has a lot more capabilities and functionality than is demonstrated here however.
A much more advanced example is the Corsi Block Tapping task, where we make use of
This is the end of our introductory tutorial series on the gorilla code editor. In this series, we've aimed to introduce to you the fundamental commands required to create a task in gorilla. If you want to see more of this code in action, have a look through the 'Code: Example Tasks' folder in the 'Samples' tab, available on your homepage.
If there is anything in this tutorial series that you feel was unclear, lacking or missing that is important to your understanding of the code editor, please drop us an email.
Further, if you ever have difficulties in implementing your task in gorilla and want some advice, don't hesitate to contact us.