<commit_before># Creating an Experiment: The Timeline

To create an experiment using jsPsych, you need to specify a timeline that describes the structure of the experiment. The timeline is an ordered set of trials. You must create the timeline before launching the experiment. Most of the code you will write for an experiment will be code to create the timeline. This page walks through the creation of timelines, including very basic examples and more advanced features.

## A single trial

To create a trial, you need to create an object that describes the trial. The most important feature of this object is the `type` parameter. This tells jsPsych which plugin to use to run the trial. For example, if you want to use the [html-keyboard-response plugin](../plugins/html-keyboard-response) to display a short message, the trial object would look like this:

```javascript
var trial = {
	type: jsPsychHtmlKeyboardResponse,
	stimulus: 'Welcome to the experiment.'
}
```

The parameters for this object (e.g., `stimulus`) will depend on the plugin that you choose. Each plugin defines the set of parameters that are needed to run a trial with that plugin. Visit the documentation for a plugin to learn about the parameters that you can use with that plugin.

To create a timeline with the single trial and run the experiment, just embed the trial object in an array. A timeline can simply be an array of trials.

```javascript
var timeline = [trial];

jsPsych.run(timeline);
```

To create and run a simple experiment like this complete the [hello world tutorial](../tutorials/hello-world.md).

## Multiple trials

Scaling up to multiple trials is straightforward. Create an object for each trial, and add each object to the timeline array.

```javascript
// with lots of trials, it might be easier to add the trials
// to the timeline array as they are defined.
var timeline = [];

var trial_1 = {
	type: jsPsychHtmlKeyboardResponse,
	stimulus: 'This is trial 1.'
}
timeline.push(trial_1);

var trial_2 = {
	type: jsPsychHtmlKeyboardResponse,
	stimulus: 'This is trial 2.'
}
timeline.push(trial_2);

var trial_3 = {
	type: jsPsychHtmlKeyboardResponse,
	stimulus: 'This is trial 3.'
}
timeline.push(trial_3);
```

## Nested timelines

Each object on the timeline can also have it's own timeline. This is useful for many reasons. One is that it allows you to define common parameters across trials once and have them apply to all the trials on the nested timeline. The example below creates a series of trials using the [image-keyboard-response plugin](../plugins/image-keyboard-response/), where the only thing that changes from trial-to-trial is the image file being displayed on the screen.

```javascript
var judgment_trials = {
	type: jsPsychImageKeyboardResponse,
	prompt: '<p>Press a number 1-7 to indicate how unusual the image is.</p>',
	choices: ['1','2','3','4','5','6','7'],
	timeline: [
		{stimulus: 'image1.png'},
		{stimulus: 'image2.png'},
		{stimulus: 'image3.png'}
	]
}
```

In the above code, the `type`, `prompt`, and `choices` parameters are automatically applied to all of the objects in the `timeline` array. This creates three trials with the same `type`, `prompt`, and `choices` parameters, but different values for the `stimulus` parameter.

You can also override the values by declaring a new value in the `timeline` array. In the example below, the second trial will display a different prompt message.

```javascript
var judgment_trials = {
	type: jsPsychImageKeyboardResponse,
	prompt: '<p>Press a number 1-7 to indicate how unusual the image is.</p>',
	choices: ['1','2','3','4','5','6','7'],
	timeline: [
		{stimulus: 'image1.png'},
		{stimulus: 'image2.png', prompt: '<p>Press 1 for this trial.</p>'},
		{stimulus: 'image3.png'}
	]
}
```

Timelines can be nested any number of times.

## Timeline variables

A common pattern in behavioral experiments is to repeat the same procedure/task many times with slightly different parameters. A procedure might be a single trial, but it also might be a series of trials. For example, a task might involve a fixation cross appearing, followed by a blank screen, followed by an image for a short duration, followed by a prompt and a text box to report on some aspect of the image.

One shortcut to implement this pattern is with the nested timeline approach described in the previous section, but this only works if all the trials use the same plugin type. Timeline variables are a more general solution. With timeline variables you define the procedure once (as a timeline) and specify a set of parameters and their values for each iteration through the timeline.

What follows is an example of how to use timeline variables. The [simple reaction time tutorial](../tutorials/rt-task.md) also explains how to use timeline variables.

Suppose we want to create an experiment where people see a set of faces. Perhaps this is a memory experiment and this is the phase of the experiment where the faces are being presented for the first time. In between each face, a fixation cross is displayed on the screen. Without timeline variables, we would need to add many trials to the timeline, alternating between trials showing the fixation cross and trials showing the face and name. This could be done efficiently using a loop or function to create the timeline, but timeline variables make it even easier - as well as adding extra features like sampling and randomization.

Here's a basic version of the task with timeline variables.

```javascript
var face_name_procedure = {
	timeline: [
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: '+',
			choices: "NO_KEYS",
			trial_duration: 500
		},
		{
			type: jsPsychImageKeyboardResponse,
			stimulus: jsPsych.timelineVariable('face'),
			choices: "NO_KEYS",
			trial_duration: 2500
		}
	],
	timeline_variables: [
		{ face: 'person-1.jpg' },
		{ face: 'person-2.jpg' },
		{ face: 'person-3.jpg' },
		{ face: 'person-4.jpg' }
	]
}
```

In the above version, there are four separate trials defined in the `timeline_variables` parameter. Each trial has a variable `face` and a variable `name`. The `timeline` defines a procedure of showing a fixation cross for 500ms followed by the face and name for 2500ms.  This procedure will repeat four times, with the first trial showing `'person-1.jpg'`, the second `'person-2.jpg'`, and so on. The variables are referenced within the procedure by calling the `jsPsych.timelineVariable()` method and passing in the name of the variable.

What if we wanted to add an additional step to the task where the name is displayed prior to the face appearing? (Maybe this is one condition of an experiment investigating whether the order of name-face or face-name affects retention.) We can add another variable to our list that gives the name associated with each image. Then we can add another trial to our timeline to show the name.

```javascript
var face_name_procedure = {
	timeline: [
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: '+',
			choices: "NO_KEYS",
			trial_duration: 500
		},
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: jsPsych.timelineVariable('name'),
			trial_duration: 1000,
			choices: "NO_KEYS"
		},
		{
			type: jsPsychImageKeyboardResponse,
			stimulus: jsPsych.timelineVariable('face'),			
			choices: "NO_KEYS",
			trial_duration: 1000
		}
	],
	timeline_variables: [
		{ face: 'person-1.jpg', name: 'Alex' },
		{ face: 'person-2.jpg', name: 'Beth' },
		{ face: 'person-3.jpg', name: 'Chad' },
		{ face: 'person-4.jpg', name: 'Dave' }
	]
}
```

### Using in a function

Continung the example from the previous section, what if we wanted to show the name with the face, combining the two variables together? 
To do this, we can use a [dynamic parameter](dynamic-parameters) (a function) to create an HTML-string that uses both variables in a single parameter.
The value of the `stimulus` parameter will be a function that returns an HTML string that contains both the image and the name. 

```javascript
var face_name_procedure = {
	timeline: [
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: '+',
			choices: "NO_KEYS",
			trial_duration: 500
		},
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: jsPsych.timelineVariable('name'),
			trial_duration: 1000,
			choices: "NO_KEYS"
		},
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: function(){<commit_msg>Update dynamic parameters link<commit_after># Creating an Experiment: The Timeline

To create an experiment using jsPsych, you need to specify a timeline that describes the structure of the experiment. The timeline is an ordered set of trials. You must create the timeline before launching the experiment. Most of the code you will write for an experiment will be code to create the timeline. This page walks through the creation of timelines, including very basic examples and more advanced features.

## A single trial

To create a trial, you need to create an object that describes the trial. The most important feature of this object is the `type` parameter. This tells jsPsych which plugin to use to run the trial. For example, if you want to use the [html-keyboard-response plugin](../plugins/html-keyboard-response) to display a short message, the trial object would look like this:

```javascript
var trial = {
	type: jsPsychHtmlKeyboardResponse,
	stimulus: 'Welcome to the experiment.'
}
```

The parameters for this object (e.g., `stimulus`) will depend on the plugin that you choose. Each plugin defines the set of parameters that are needed to run a trial with that plugin. Visit the documentation for a plugin to learn about the parameters that you can use with that plugin.

To create a timeline with the single trial and run the experiment, just embed the trial object in an array. A timeline can simply be an array of trials.

```javascript
var timeline = [trial];

jsPsych.run(timeline);
```

To create and run a simple experiment like this complete the [hello world tutorial](../tutorials/hello-world.md).

## Multiple trials

Scaling up to multiple trials is straightforward. Create an object for each trial, and add each object to the timeline array.

```javascript
// with lots of trials, it might be easier to add the trials
// to the timeline array as they are defined.
var timeline = [];

var trial_1 = {
	type: jsPsychHtmlKeyboardResponse,
	stimulus: 'This is trial 1.'
}
timeline.push(trial_1);

var trial_2 = {
	type: jsPsychHtmlKeyboardResponse,
	stimulus: 'This is trial 2.'
}
timeline.push(trial_2);

var trial_3 = {
	type: jsPsychHtmlKeyboardResponse,
	stimulus: 'This is trial 3.'
}
timeline.push(trial_3);
```

## Nested timelines

Each object on the timeline can also have it's own timeline. This is useful for many reasons. One is that it allows you to define common parameters across trials once and have them apply to all the trials on the nested timeline. The example below creates a series of trials using the [image-keyboard-response plugin](../plugins/image-keyboard-response/), where the only thing that changes from trial-to-trial is the image file being displayed on the screen.

```javascript
var judgment_trials = {
	type: jsPsychImageKeyboardResponse,
	prompt: '<p>Press a number 1-7 to indicate how unusual the image is.</p>',
	choices: ['1','2','3','4','5','6','7'],
	timeline: [
		{stimulus: 'image1.png'},
		{stimulus: 'image2.png'},
		{stimulus: 'image3.png'}
	]
}
```

In the above code, the `type`, `prompt`, and `choices` parameters are automatically applied to all of the objects in the `timeline` array. This creates three trials with the same `type`, `prompt`, and `choices` parameters, but different values for the `stimulus` parameter.

You can also override the values by declaring a new value in the `timeline` array. In the example below, the second trial will display a different prompt message.

```javascript
var judgment_trials = {
	type: jsPsychImageKeyboardResponse,
	prompt: '<p>Press a number 1-7 to indicate how unusual the image is.</p>',
	choices: ['1','2','3','4','5','6','7'],
	timeline: [
		{stimulus: 'image1.png'},
		{stimulus: 'image2.png', prompt: '<p>Press 1 for this trial.</p>'},
		{stimulus: 'image3.png'}
	]
}
```

Timelines can be nested any number of times.

## Timeline variables

A common pattern in behavioral experiments is to repeat the same procedure/task many times with slightly different parameters. A procedure might be a single trial, but it also might be a series of trials. For example, a task might involve a fixation cross appearing, followed by a blank screen, followed by an image for a short duration, followed by a prompt and a text box to report on some aspect of the image.

One shortcut to implement this pattern is with the nested timeline approach described in the previous section, but this only works if all the trials use the same plugin type. Timeline variables are a more general solution. With timeline variables you define the procedure once (as a timeline) and specify a set of parameters and their values for each iteration through the timeline.

What follows is an example of how to use timeline variables. The [simple reaction time tutorial](../tutorials/rt-task.md) also explains how to use timeline variables.

Suppose we want to create an experiment where people see a set of faces. Perhaps this is a memory experiment and this is the phase of the experiment where the faces are being presented for the first time. In between each face, a fixation cross is displayed on the screen. Without timeline variables, we would need to add many trials to the timeline, alternating between trials showing the fixation cross and trials showing the face and name. This could be done efficiently using a loop or function to create the timeline, but timeline variables make it even easier - as well as adding extra features like sampling and randomization.

Here's a basic version of the task with timeline variables.

```javascript
var face_name_procedure = {
	timeline: [
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: '+',
			choices: "NO_KEYS",
			trial_duration: 500
		},
		{
			type: jsPsychImageKeyboardResponse,
			stimulus: jsPsych.timelineVariable('face'),
			choices: "NO_KEYS",
			trial_duration: 2500
		}
	],
	timeline_variables: [
		{ face: 'person-1.jpg' },
		{ face: 'person-2.jpg' },
		{ face: 'person-3.jpg' },
		{ face: 'person-4.jpg' }
	]
}
```

In the above version, there are four separate trials defined in the `timeline_variables` parameter. Each trial has a variable `face` and a variable `name`. The `timeline` defines a procedure of showing a fixation cross for 500ms followed by the face and name for 2500ms.  This procedure will repeat four times, with the first trial showing `'person-1.jpg'`, the second `'person-2.jpg'`, and so on. The variables are referenced within the procedure by calling the `jsPsych.timelineVariable()` method and passing in the name of the variable.

What if we wanted to add an additional step to the task where the name is displayed prior to the face appearing? (Maybe this is one condition of an experiment investigating whether the order of name-face or face-name affects retention.) We can add another variable to our list that gives the name associated with each image. Then we can add another trial to our timeline to show the name.

```javascript
var face_name_procedure = {
	timeline: [
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: '+',
			choices: "NO_KEYS",
			trial_duration: 500
		},
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: jsPsych.timelineVariable('name'),
			trial_duration: 1000,
			choices: "NO_KEYS"
		},
		{
			type: jsPsychImageKeyboardResponse,
			stimulus: jsPsych.timelineVariable('face'),			
			choices: "NO_KEYS",
			trial_duration: 1000
		}
	],
	timeline_variables: [
		{ face: 'person-1.jpg', name: 'Alex' },
		{ face: 'person-2.jpg', name: 'Beth' },
		{ face: 'person-3.jpg', name: 'Chad' },
		{ face: 'person-4.jpg', name: 'Dave' }
	]
}
```

### Using in a function

Continung the example from the previous section, what if we wanted to show the name with the face, combining the two variables together? 
To do this, we can use a [dynamic parameter](..overview/dynamic-parameters/) (a function) to create an HTML-string that uses both variables in a single parameter.
The value of the `stimulus` parameter will be a function that returns an HTML string that contains both the image and the name. 

```javascript
var face_name_procedure = {
	timeline: [
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: '+',
			choices: "NO_KEYS",
			trial_duration: 500
		},
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: jsPsych.timelineVariable('name'),
			trial_duration: 1000,
			choices: "NO_KEYS"
		},
		{
			type: jsPsychHtmlKeyboardResponse,
			stimulus: function(){
{'fraction_non_alphanumeric': 0.08203660645084362, 'fraction_numerical': 0.009062183270732726, 'mean_word_length': 4.321700507614213, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2611405', 'n_tokens_mistral': 5030, 'n_tokens_neox': 4498, 'n_words': 2254}