DMDX Help.


Dynamic Item content notes.


    With the aid of counters, branching and macros DMDX can dynamically generate content.  Here are the prime examples I developed over the years.  Tasks on this page:

Auditory aaabbbaaa task.
The Ultimatum Game.
Repeated items.
Cognitive Bias Modification.
N-Back task.

    Tasks on other pages:

Anagram task.
Probabilistic Selection task.
Subtract 7 stressor.
Corsi Block Tapping task.
The introduction has a number of tasks demonstrated in it.
Point of Gaze eye tracking detection.
Unicode glyph displayer.
Display element rearranger using the mouse.

    Tasks on other pages that aren't dynamic:

Stroop task.
IAT Example.
Multimodal item files.
Other examples.


Auditory aaabbbaaa task:

    Some time ago a task here involved presenting a series of randomly chosen item elements and rather than generate the whole possible set of items and stop once some criteria were met I opted to use macros to determine the selections in a subroutine and have them expand in the actual item tests themselves.  Not only that but the set of stimuli to choose from was to change as the task progressed.  So one set of macros (A to H) determined stimuli that could be chosen (here A to D were four versions of "a" and E to H were four versions of "b") and nine macros (1 to 9) were returned that were used to set  up an item (here in the form of aaabbbaaa).  A track record of what was actually played is made by emitting the text into the output and the macros A to H are redefined as needed as the items are run.  Double tildes (~~) are used for skip display CR indicators in front of item numbers because once you are are using macros 1 to 9 (and 0 although I don't use it here) they would expand in skip display item numbers, not what we want (so ~100 would expand to say DA300 here).  So a double tilde collapses to a single skip display CR indicator.  Pretty sure this sets a record for the all time number of macros in one item file too...

<ep> f60 <nfb> <vm desktop> <id keyboard>
<cr> <eop>

0 "Start" <bu 999>;

~~100 <set c100 = (random 4) + 101> <ib 100>         <!aaabbbaaa>;
~~101 m1+"~A"+ <bu 110>;
~~102 m1+"~B"+ <bu 110>;
~~103 m1+"~C"+ <bu 110>;
~~104 m1+"~D"+;
~~110 <set c100 = (random 4) + 111> <ib 100>;
~~111 m2+"~A"+ <bu 120>;
~~112 m2+"~B"+ <bu 120>;
~~113 m2+"~C"+ <bu 120>;
~~114 m2+"~D"+;
~~120 <set c100 = (random 4) + 121> <ib 100>;
~~121 m3+"~A"+ <bu 130>;
~~122 m3+"~B"+ <bu 130>;
~~123 m3+"~C"+ <bu 130>;
~~124 m3+"~D"+;
~~130 <set c100 = (random 4) + 131> <ib 100>;
~~131 m4+"~E"+ <bu 140>;
~~132 m4+"~F"+ <bu 140>;
~~133 m4+"~G"+ <bu 140>;
~~134 m4+"~H"+;
~~140 <set c100 = (random 4) + 141> <ib 100>;
~~141 m5+"~E"+ <bu 150>;
~~142 m5+"~F"+ <bu 150>;
~~143 m5+"~G"+ <bu 150>;
~~144 m5+"~H"+;
~~150 <set c100 = (random 4) + 151> <ib 100>;
~~151 m6+"~E"+ <bu 160>;
~~152 m6+"~F"+ <bu 160>;
~~153 m6+"~G"+ <bu 160>;
~~154 m6+"~H"+;
~~160 <set c100 = (random 4) + 161> <ib 100>;
~~161 m7+"~A"+ <bu 170>;
~~162 m7+"~B"+ <bu 170>;
~~163 m7+"~C"+ <bu 170>;
~~164 m7+"~D"+;
~~170 <set c100 = (random 4) + 171> <ib 100>;
~~171 m8+"~A"+ <bu 180>;
~~172 m8+"~B"+ <bu 180>;
~~173 m8+"~C"+ <bu 180>;
~~174 m8+"~D"+;
~~180 <set c100 = (random 4) + 181> <ib 100>;
~~181 m9+"~A"+ <bu 190>;
~~182 m9+"~B"+ <bu 190>;
~~183 m9+"~C"+ <bu 190>;
~~184 m9+"~D"+;
~~190 <emit sound files ~1 ~2 ~3 ~4 ~5 ~6 ~7 ~8 ~9> <return>;

~~999  mA+DA1+ mB+DA2+ mC+DA3+ mD+DA4+ <! a1, a2, a3, a4>
       mE+TA5+ mF+TA6+ mG+TA7+ mH+TA8+ <! b1, b2, b3, b4>;

~~1001 <call -100>;
+1002 * <wav 2> ~1 / <wav 2> ~2 / <wav 2> ~3 / <wav 2> ~4 / <wav 2> ~5 / <wav 2> ~6 / <wav 2> ~7 / <wav 2> ~8 / <wav 2> ~9 ;

~~2001 <call -100>;
+2002 * <wav 2> ~1 / <wav 2> ~2 / <wav 2> ~3 / <wav 2> ~4 / <wav 2> ~5 / <wav 2> ~6 / <wav 2> ~7 / <wav 2> ~8 / <wav 2> ~9 ;

~~1 mA+DA5+ mB+DA6+ mC+DA7+ mD+DA8+ <! a1, a2, a3, a4>
    mE+TA1+ mF+TA2+ mG+TA3+ mH+TA4+ <! b1, b2, b3, b4>;

~~3001 <call -100>;
+3002 * <wav 2> ~1 / <wav 2> ~2 / <wav 2> ~3 / <wav 2> ~4 / <wav 2> ~5 / <wav 2> ~6 / <wav 2> ~7 / <wav 2> ~8 / <wav 2> ~9 ;

~~3101 <call -100>;
+3102 * <wav 2> ~1 / <wav 2> ~2 / <wav 2> ~3 / <wav 2> ~4 / <wav 2> ~5 / <wav 2> ~6 / <wav 2> ~7 / <wav 2> ~8 / <wav 2> ~9 ;
 


The Ultimatum Game.


    Another task involved coding Alan Sanfey's (2003) Ultimatum game.  Here a fixed number of offers of various fixed amounts have to be made by a set of fake offerers.  The problem with the obvious solution to picking an offer where one checks to see if one's random choice has been made already is that by the time the last few offers are being made those random numbers are going to have to be rolled an increasing number of times till you get to the last one where every number selected except one will require another shot.  Which can take serious amounts of time for even a moderately large number of offers.  The standard solution is to build an array of offers, shuffle it and then just take offers from the first element to the last which takes the same amount of time for each offer, the trick comes with building an array in DMDX.  I built this solution with a series of pairs of items, the first of every pair being a target for a branch that doesn't get scrambled and the second of the pair which makes the selection which gets scrambled.  While our example only has five offers (one of each of the sizes of offer) in reality many more would be added but the item numbers 100, 101, 102, etc would have to be kept in strict ascending order otherwise when that offer is to be selected our selecting routine will fail when the indexed branch to that item number can't be completed.
    The rest of the task is a subroutine that takes the name, gender indicator, image name and item number from a series of macros setup and scrambled by the body of the item file.  One nice frilly bit, the subroutine uses macro T to indicate a change in the total the subject has accumulated if they accept an offer ("You now have $N" instead of "You have $N").  Another cool thing is the use of macro I in the item number of the item that prompts for a response so the data file has responses and item numbers nicely matching.  Originally this item file used macro 9 instead of macro I due to an misunderstanding of mine, that has now been rectified, the solution being to simply have macro I defined initially with a dummy item number (otherwise you'd get a missing item number message as when a macro is undefined the code leaves the text alone and ~I is indeed an invalid item number whereas having set it to 9 initially it won't throw the error).  Another slight problem I find revisiting this item file is that you can't specify a zero default frame duration these days (DMDX vers 6.0.0.6) given that it trips up so many people, no idea why I would have done so, a default of 1 seems to work just as well.

<ep> <Backgroundcolor 0, 0, 0> <fd 1> <dfm 1.2> <vm desktop>
<WritingColor 255, 255, 255> <id #keyboard> <nfb> <ntl>
<cr> s1 </ep>

$
~1 <bu 0> <set c0=99> <set c4=0> <macro I 9>;
~99 <set c0=c0+1> <ib 0>;
$
$~100; $ ~1<set c1=9><bu 500>;
$~101; $ ~1<set c1=8><bu 500>;
$~102; $ ~1<set c1=7><bu 500>;
$~103; $ ~1<set c1=6><bu 500>;
$~104; $ ~1<set c1=5><bu 500>;
\
$
500 <XY 0.5,0.4> <jpg> "~F" , <fd 90> <XY 0.5,0.8> "~N has been given $10 to split with you." / <ne>;
501 <fd 240> <ocb> <XY 0.5,0.8>
"~N proposes that ~She will keep $%d and give you $%d."
<set c2=10-c1><set c3=c2><sprintf 1,2>/;
~I "Do you accept this offer?" <crp> */ <ne> <bic 502> mT+now +;
~501 <set c3=0> mT++;
502 <set c4=c4+c3> "You have received $%d." <sprintf 3>,
<fd 180> @1 "You ~Thave $%d." <sprintf 4> /
<emit ~N> <emit 2> <emit 3> <emit 4> <return>;

! emits offerer name, offered amount, accepted amount, running total;

0 <XYJustification 1> "Ready to begin?";
$

! macro I sets the item number for the response, macro F is the file name
macro N is the offerer's name, macro S is set to s for female names;

1101 mI+1101+ mF+1+ mN+David+ mS++ <call -99>;

1102 mI+1102+ mF+17+ mN+Katie+ mS+s+ <call -99>;

1103 mI+1103+ mF+16+ mN+Rachel+ mS+s+ <call -99>;

1104 mI+1104+ mF+3+ mN+Josh+ mS++ <call -99>;

1105 mI+1105+ mF+4+ mN+Rick+ mS++ <call -99>;

$
0 "END";
$


Repeated items.


    Another task years ago before the <macro set> operation was added to DMDX required that items be presented in a scrambled order but then be repeated some arbitrary number of items later, a task that had traditionally only been assailable with fixed manually arranged presentation orders per subject in the past.   Because the ability to iterate over a range of counters (see the Probabilistic Selection Task for another example of iteration) with a macro using a subroutine at item 2000 (since superseded by the aforementioned <macro set> command) allows DMDX to process a range of counters as if it were a list (or an array) DMDX can now present an item and remember that it needs to present the same item again at a later date.  This is also the first item file using the new new (as of version 4.0.3.0 anyway) <callstack> functionality that allows nested calls to be made.  The current solution tackles this by having items that don't collect or display anything themselves but instead contain item numbers (macro I) of items that will display stimuli and gather responses and the range (macros L and H) of number of items later they should be repeated at (macro L is the low bound and H the high with the actual number being determined randomly between them).  These items are scrambled and each calls a general processing routine (item 100) that both calls the item that does the actual presentation (hence the need for <callstack>), schedules the item's repeat and stores it in a list of counters that tracks repeats and then checks said list of counters for items that are due to be repeated (item 2150).  Of course, said repeat may be late as it's perfectly possible to schedule multiple items to be displayed at  the same time, the item file will emit the number of the item followed by the message "repeat will be late". 
    Other notable features include the use of counter 96 to determine how many items the script can keep track of that will need repeating. In the past the counters needed for this sort of item file had to be hard coded with reams of initialization
<setcounter> keywords but because we've got the counter to macro routine (item 2000) in there anyway we can build a loop to do the initialization.  Here we actually initialize two ranges of counters, 1 to N for counting down items displayed till repeats are due and counters 101 to 101+N tracking item numbers to be repeated.  Actual determination of how large counter 96's value should be is rather tough to determine (it can't be larger than 95 without changing the item file), no doubt some mathematically inclined individual can tell us what it should be but my guess is that it should be the average number items you expect an item to be delayed.  In my testing using repeat intervals as large as 22 I never saw an element larger than 10 being referenced, if you pick a number that is too low you'll see "no free elements! item ~I not repeated".  As each item is scheduled to be displayed again you will see diagnostics indicating how long that should be.  The actual counter number emitted is only useful for tracking how much of the counter array is being used to track repeats as that's the counter being used to keep track of the scheduling,  the value is how many items in the future it should be repeated.
    The solution as presented in the item file also keeps track of how long the processing of the list takes as there's a good deal of it.  On a 2.8 GHz Core 2 Duo processor for a repeated item list 22 elements long I see about 10 milliseconds of processing per presentation, you see this in the output where counter 97 is emitted.  Note than on a slower machine this time could actually start to impose limits on the ISI so some care is needed.  Also note that where a number of items are needing to be repeated at once the counter 97 processing time will include all of the recent repeated items.  If you don't care about ISI (or you have a similarly fast machine) then you can just bang out all the counter 97 references.
    The only failing of this solution is that when the end of the list of items is reached it will only empty the list of items to be repeated as long as there's a sequential train of them to be repeated.  So if the last item is to be repeated say 20 items later but there's only a few items in the list to be repeated that item won't get displayed as there are no items remaining for it to be correctly displayed the right number of items later.  This is inherent to the task unfortunately, either the item is allowed to be presented out of sequence (sooner than it should be) or filler items must be used for the last part of the run, but here you might get order effects.  If the list was to be depleted and items presented sooner than scheduled I'd just put a loop in calling item 2150 counter 96 times.
    And you don't really want to be turning branch diagnostics on here, because it's iterating over counters each item is going to be emitting something in the order of 20 times counter 96's value worth of diags...

<ep> <fd 60> <azk> <vm desktop> <s 1> <callstack 3>
    <cr> <!branchdiagnostics> <eop>

$
0 "repeated item demo"
    <set c96 = 20> <! declare the size of the repeated item memory>
    <set c99 = 1> <! iteration counter to set up repetition tracking counters>;
~5 <set c999=c99> <call 2000>;
~6 <set c~C = 0> <set c999=c99 + 100> <call 2000>;
~7 <set c~C = 0> <inc 99> <bi -5, c99 .le. c96>;
500 "#######";
$

! first a list of items to call and low and high bounds for repeat;

~500 mI+1000+ mL+3+ mH+5+ <call 100>;
~500 mI+1001+ mL+3+ mH+5+ <call 100>;
~500 mI+1002+ mL+3+ mH+5+ <call 100>;
~500 mI+1010+ mL+18+ mH+22+ <call 100>;
~500 mI+1011+ mL+18+ mH+22+ <call 100>;
~500 mI+1012+ mL+18+ mH+22+ <call 100>;

$
~500 <call 2150> <! deplete remaining repeats>;

500 "Done" L;

! the items themselves (used twice);

+1000 * "picture 1000" ; 500 "#######" <return>;
+1001 * "picture 1001" ; 500 "#######" <return>;
+1002 * "picture 1002" ; 500 "#######" <return>;
+1010 * "picture 1010" ; 500 "#######" <return>;
+1011 * "picture 1011" ; 500 "#######" <return>;
+1012 * "picture 1012" ; 500 "#######" <return>;

~100 <! routine to run the experiment, first display the item> <call ~I>;

~150 <set c99 = 1> <! iterate through our counters looking for a dead element>
    <set c97 = millisectime> ;
~155 <set c999=c99> <call 2000>;
~160 <bi 200, c~C .lt. 1> <! skip out if dead>;
~170 <inc 99> <bi -155, c99 .le. c96> <! look at next element>;
~180 <emit no free elements! item ~I not repeated> <bu 230>;
~200 <set c~C = (random ~H - ~L + 1) + ~L> <! schedule future repeat>;
~205 <emit ~C> <! diags, comment out later if needed>;
~210 <set c999=c99 + 100> <call 2000> <! store item for later repeat>;
~220 <set c~C = ~I>;

~230 <! iterate through our counters looking for items needing repeating>
    <call 2150>;

~240 <set c97 = millisectime - c97> <emit 97> <return>;


~2000 <! routine to set a macro to a counter's value>
    mC++ <set c2099=c999>;
~2099 <set c2098=(c2099 % 10)+2100> <ib 2098>;
~2100 mC+0~C+ <bu 2110>;
~2101 mC+1~C+ <bu 2110>;
~2102 mC+2~C+ <bu 2110>;
~2103 mC+3~C+ <bu 2110>;
~2104 mC+4~C+ <bu 2110>;
~2105 mC+5~C+ <bu 2110>;
~2106 mC+6~C+ <bu 2110>;
~2107 mC+7~C+ <bu 2110>;
~2108 mC+8~C+ <bu 2110>;
~2109 mC+9~C+;
~2110 <set c2099=c2099 / 10> <bi -2099, c2099 .gt. 0>;
~2111 <return>;


~2150 <! iterate through our counters looking for items needing repeating>
    <set c99 = 1> <! iteration counter>
    <set c98 = 0> <! flag set once a repeat is given>;
~2155 <set c999=c99> <call -2000>;
~2160 <bi 2200, c98 .gt. 0 .or. c~C .gt. 1> <! skip items not ready for repeating>;
~2165 <bi 2210, c~C .lt. 1> <! skip dead unused elements>;

~2168 <set c~C = 0> <! flag as repeated (dead)>;
~2170 <set c999=c99 + 100> <call -2000>;
~2175 <!repeat the item needed> <set c97 = millisectime - c97> <ic ~C> <inc 98>;
~2180 <set c97 = millisectime - c97> <bu 2210>;

~2200 <bi 2208, c~C .gt. 1> <! won't have repeated in time>;
~2200 <bi 2210, c~C .lt. 1> <! and it's not dead>;
~2202 <set c999=c99 + 100> <call -2000>;
~2203 <emit ~C> <emit repeat will be late> <bu 2210>;
~2208 <dec ~C> <! not repeated yet so decrement it's counter>;
~2210 <inc 99> <bi -2155, c99 .le. c96> <! look at next element>;
~2220 <bi -2150, c98 .gt. 0> <! repeat if a repeat displayed>;
~2230 <return>;

0 <! won't ever get executed but will stop DMDX quitting at end of subroutine before this>;
$


Cognitive Bias Modification.


    This problem involves presenting randomly selected images in pairs from different lists and probing them, keeping everything (reasonably) balanced on a left right basis.  It's interesting here because each item is completely fabricated and I thought of a new way to do that.  The problem with synthesized items is that they must satisfy the requirements for an item's syntax before the macros making them up have expanded as the branching code will scan the whole item file looking for items without expanding macros. Having a leading zero turns out to satisfy the branching code and for the correct response indicator you can use the in item keyword variants (here <crp> and <crn> are used).  So here there's one item with the item number 0~s~t~p~x~y~z that gathers all the data (when this item file is fully blocked out well over 500 of them).

   The item file uses a trick I've used before to randomize a list on a single use basis (the 10000 series items), only tweak here was including leading zeroes on the indexes less than 10 so the index can expand in a number as with more significant digits (the x, y and z macros in the item number and some of the branches).  Catch-22 there was that the routine DMDX uses to evaluate expressions takes a leading zero to signify an octal number and of course 08 isn't octal and that evaluates to zero.  Oops.  So the code is careful to expand them within larger numbers when used in the calculated index.

   This item file is also taken at a early stage in development, it's just using text fillers for the graphics it will eventually have and only the practice items are functional, the training and post assessment tasks are only loosely sketched in.

<ep>
<vm desktop>
<msfd 500> <!nfb> <cr> <xyjustification 1>
<id keyboard> <mpr +h> <mnr +g> <t 1000>
<!branchdiagnostics> <callstack 3>
<scramble 1>
<eop>
$0 "practice"
ms+1+ <! Use set A images>
<set c1=0><set c101=0><set c102=0><set c103=0><set c104=0><set c105=0><set c106=0>;$

! in the following macros a, b and p code for positive, negative or neutral images with 1, 2 or 3 with the exception that p (the probe) can have the value 4 coding for either;
! macros c and d code for lists to use to pick those images from;

~1 mc+01+ ma+2+ md+02+ mb+3+ mp+4+ <call 999> <! Pull from list 1 a negative image paired with neutral image from list 2 and probe either>;
~1 mc+01+ ma+2+ md+02+ mb+3+ mp+4+ <call 999> <! Pull from list 1 a negative image paired with neutral image from list 2 and probe either>;
~1 mc+01+ ma+2+ md+02+ mb+3+ mp+4+ <call 999> <! Pull from list 1 a negative image paired with neutral image from list 2 and probe either>;

~1 mc+03+ ma+1+ md+04+ mb+3+ mp+4+ <call 999> <! Pull from list 3 a positive image paired with neutral image from list 4 and probe either>;
~1 mc+03+ ma+1+ md+04+ mb+3+ mp+4+ <call 999> <! Pull from list 3 a positive image paired with neutral image from list 4 and probe either>;
~1 mc+03+ ma+1+ md+04+ mb+3+ mp+4+ <call 999> <! Pull from list 3 a positive image paired with neutral image from list 4 and probe either>;

~1 mc+05+ ma+1+ md+06+ mb+2+ mp+4+ <call 999> <! Pull from list 5 a positive image paired with negative image from list 6 and probe either>;
~1 mc+05+ ma+1+ md+06+ mb+2+ mp+4+ <call 999> <! Pull from list 5 a positive image paired with negative image from list 6 and probe either>;
~1 mc+05+ ma+1+ md+06+ mb+2+ mp+4+ <call 999> <! Pull from list 5 a positive image paired with negative image from list 6 and probe either>;
\
$!0 "training task";$
! for cat A initial assessment we'd have 48 of the following;
!~1 mc+07+ ma+1+ md+08+ mb+2+ mp+1+ <call 999> <! Pull from list 7 a positive image paired with negative image from list 8 and probe positive>;
!~1 mc+09+ ma+1+ md+010+ mb+2+ mp+1+ <call 999> <! Pull from list 9 a positive image paired with negative image from list 10 and probe positive>;
! for cat B initial assessment we'd have 48 of the following;
!~1 mc+07+ ma+3+ md+08+ mb+2+ mp+3+ <call 999> <! Pull from list 7 a neutral image paired with negative image from list 8 and probe neutral >;
!~1 mc+09+ ma+3+ md+010+ mb+2+ mp+3+ <call 999> <! Pull from list 9 a neutral image paired with negative image from list 10 and probe neutral >;
! for cat C initial assessment we'd have 32 of the following;
!~1 mc+07+ ma+2+ md+08+ mb+3+ mp+4+ <call 999> <! Pull from list 7 a negative image paired with neutral image from list 8 and probe either >;
!~1 mc+09+ ma+1+ md+10+ mb+3+ mp+4+ <call 999> <! Pull from list 9 a positive image paired with neutral image from list 10 and probe either >;
!~1 mc+11+ ma+1+ md+12+ mb+2+ mp+4+ <call 999> <! Pull from list 11 a positive image paired with negative image from list 12 and probe either >;
$!0 "ratings";$
\
! and all the preceding 12+ lines would have to be repeated 6 times with new lists;

!0"post assessment task"
ms+2+ <! Use set B images>;
! for post assessment we'd have 32 of the following, lists 33 through 37 having 1..16 in them twice;
!~1 mc+33+ ma+2+ md+34+ mb+3+ mp+4+ <call 999> <! Pull from list 7 a negative image paired with neutral image from list 8 and probe either >;
!~1 mc+35+ ma+1+ md+36+ mb+3+ mp+4+ <call 999> <! Pull from list 9 a positive image paired with neutral image from list 10 and probe either >;
!~1 mc+37+ ma+1+ md+38+ mb+2+ mp+4+ <call 999> <! Pull from list 11 a positive image paired with negative image from list 12 and probe either >;
\
$! chain to the anagram;
0"end"l;

! so 999 will ib on c1~c * 100 + 10000 into scrambled lists that set macro i to 01 through 48 (some lists can be 01 through 32 and others 01..16 twice);
! then plug that macro into a branch into a list of image names (selected by macro s) based on macro a;
! same for macro d and macro b;
! then reverse left for right, probe the macro p image (or either if 4), finally one or two dots;
! item number is stpxxyyzz with s being 1 for set A images, 2 for set B, t being odd if the target was on the left (right being even) and t being > 1 if two dots were used (<= 1 if one dot) and p will be a 1, 2, or 3 depending on which image type was probed. xx would be 1 to 48 for positive image identifier (00 if not used), yy same for negative and zz for neutral;


~999 mx+00+ my+00+ mz+00+ <! Setup defaults and test if probe specified>
<bi 1010, ~p .ne. 4>;
~1002 <bi 1006, random(2)> <! Assign probe to either>;
~1003 mp+~a+ <bu 1010>;
~1006 mp+~b+;
~1010 me+~c+ mf+~a+ mh+l+ <call 8000> <! Select and setup left half>;
~1020 me+~d+ mf+~b+ mh+r+ <call 8000> <! Select and setup right half>;
~1030 <bi 1040, random(2)> <! swap left for right>;
~1032 mw+~a+ ma+~b+;
~1034 mb+~w+ mw+~l+ ml+~r+;
~1036 mr+~w+;
~1040 mq+<crp> ".."+ <set c1 = (random 2) * 2> <bi 1050, c1 .gt. 0> <! pick one or two dots>;
~1045 mq+<crn> "."+;
~1050 mo+.75+ <bi 1060, ~p .eq. ~b> <! flag probe on left or right>;
~1055 mo+.25+ <set c1 = c1 | 1>;
~1060 <set c100 = 1070 + c1> <ib 100>;
~1070 mt+0+ <bu 1080>;
~1071 mt+1+ <bu 1080>;
~1072 mt+2+ <bu 1080>;
~1073 mt+3+;
~1080;
0~s~t~p~x~y~z <xy .5, .5> "+" / <xy .25, .5> "~l", <xy .75, .5> "~r" / <xy ~o, .5> ~q * <return>;


! the selector routine, macro e is the list to use (from either macro c or d), macro f is the image type (either macro a or b) and macro h is the half of the screen (macro l or r);
! NOTE the careful way macro and e and i are used with calc. They can have leading zeros, if calc evaluates them it thinks they're octal so they're expanded in larger numbers;
~8000 <inc 1~e> <set c100 = 1~e00 + c1~e> <ic 100> <! Get selection from relevant list >;
~8010 <bu 801~f> <! Remember for item number>;
~8011 mx+~i+ <bu 8020>;
~8012 my+~i+ <bu 8020>;
~8013 mz+~i+;
~8020 <set c100 = 7000 + ~s * 1000 + 500 + ~f * 100 + 1~i> <ic 100> <! Get the name that's been picked>;
~8030 m~h+~n+ <! Remember in macro l or macro r>;
~1 <return>;


! the set A positive names;
~8701 mn+setApositive01+ <return>;
~8702 mn+setApositive02+ <return>;
~8703 mn+setApositive03+ <return>;
~8704 mn+setApositive04+ <return>;
~8705 mn+setApositive05+ <return>;
~8706 mn+setApositive06+ <return>;
~8707 mn+setApositive07+ <return>;
~8708 mn+setApositive08+ <return>;
~8709 mn+setApositive09+ <return>;
~8710 mn+setApositive10+ <return>;
~8711 mn+setApositive11+ <return>;
~8712 mn+setApositive12+ <return>;
~8713 mn+setApositive13+ <return>;
~8714 mn+setApositive14+ <return>;
~8715 mn+setApositive15+ <return>;
~8716 mn+setApositive16+ <return>;
~8717 mn+setApositive17+ <return>;
~8718 mn+setApositive18+ <return>;
~8719 mn+setApositive19+ <return>;
~8720 mn+setApositive20+ <return>;
~8721 mn+setApositive21+ <return>;
~8722 mn+setApositive22+ <return>;
~8723 mn+setApositive23+ <return>;
~8724 mn+setApositive24+ <return>;
~8725 mn+setApositive25+ <return>;
~8726 mn+setApositive26+ <return>;
~8727 mn+setApositive27+ <return>;
~8728 mn+setApositive28+ <return>;
~8729 mn+setApositive29+ <return>;
~8730 mn+setApositive30+ <return>;
~8731 mn+setApositive31+ <return>;
~8732 mn+setApositive32+ <return>;
~8733 mn+setApositive33+ <return>;
~8734 mn+setApositive34+ <return>;
~8735 mn+setApositive35+ <return>;
~8736 mn+setApositive36+ <return>;
~8737 mn+setApositive37+ <return>;
~8738 mn+setApositive38+ <return>;
~8739 mn+setApositive39+ <return>;
~8740 mn+setApositive40+ <return>;
~8741 mn+setApositive41+ <return>;
~8742 mn+setApositive42+ <return>;
~8743 mn+setApositive43+ <return>;
~8744 mn+setApositive44+ <return>;
~8745 mn+setApositive45+ <return>;
~8746 mn+setApositive46+ <return>;
~8747 mn+setApositive47+ <return>;
~8748 mn+setApositive48+ <return>;
! the set A negative names;
~8801 mn+setAnegative01+ <return>;
~8802 mn+setAnegative02+ <return>;
~8803 mn+setAnegative03+ <return>;
~8804 mn+setAnegative04+ <return>;
~8805 mn+setAnegative05+ <return>;
~8806 mn+setAnegative06+ <return>;
~8807 mn+setAnegative07+ <return>;
~8808 mn+setAnegative08+ <return>;
~8809 mn+setAnegative09+ <return>;
~8810 mn+setAnegative10+ <return>;
~8811 mn+setAnegative11+ <return>;
~8812 mn+setAnegative12+ <return>;
~8813 mn+setAnegative13+ <return>;
~8814 mn+setAnegative14+ <return>;
~8815 mn+setAnegative15+ <return>;
~8816 mn+setAnegative16+ <return>;
~8817 mn+setAnegative17+ <return>;
~8818 mn+setAnegative18+ <return>;
~8819 mn+setAnegative19+ <return>;
~8820 mn+setAnegative20+ <return>;
~8821 mn+setAnegative21+ <return>;
~8822 mn+setAnegative22+ <return>;
~8823 mn+setAnegative23+ <return>;
~8824 mn+setAnegative24+ <return>;
~8825 mn+setAnegative25+ <return>;
~8826 mn+setAnegative26+ <return>;
~8827 mn+setAnegative27+ <return>;
~8828 mn+setAnegative28+ <return>;
~8829 mn+setAnegative29+ <return>;
~8830 mn+setAnegative30+ <return>;
~8831 mn+setAnegative31+ <return>;
~8832 mn+setAnegative32+ <return>;
~8833 mn+setAnegative33+ <return>;
~8834 mn+setAnegative34+ <return>;
~8835 mn+setAnegative35+ <return>;
~8836 mn+setAnegative36+ <return>;
~8837 mn+setAnegative37+ <return>;
~8838 mn+setAnegative38+ <return>;
~8839 mn+setAnegative39+ <return>;
~8840 mn+setAnegative40+ <return>;
~8841 mn+setAnegative41+ <return>;
~8842 mn+setAnegative42+ <return>;
~8843 mn+setAnegative43+ <return>;
~8844 mn+setAnegative44+ <return>;
~8845 mn+setAnegative45+ <return>;
~8846 mn+setAnegative46+ <return>;
~8847 mn+setAnegative47+ <return>;
~8848 mn+setAnegative48+ <return>;
! the set A neutral names;
~8901 mn+setAneutral01+ <return>;
~8902 mn+setAneutral02+ <return>;
~8903 mn+setAneutral03+ <return>;
~8904 mn+setAneutral04+ <return>;
~8905 mn+setAneutral05+ <return>;
~8906 mn+setAneutral06+ <return>;
~8907 mn+setAneutral07+ <return>;
~8908 mn+setAneutral08+ <return>;
~8909 mn+setAneutral09+ <return>;
~8910 mn+setAneutral10+ <return>;
~8911 mn+setAneutral11+ <return>;
~8912 mn+setAneutral12+ <return>;
~8913 mn+setAneutral13+ <return>;
~8914 mn+setAneutral14+ <return>;
~8915 mn+setAneutral15+ <return>;
~8916 mn+setAneutral16+ <return>;
~8917 mn+setAneutral17+ <return>;
~8918 mn+setAneutral18+ <return>;
~8919 mn+setAneutral19+ <return>;
~8920 mn+setAneutral20+ <return>;
~8921 mn+setAneutral21+ <return>;
~8922 mn+setAneutral22+ <return>;
~8923 mn+setAneutral23+ <return>;
~8924 mn+setAneutral24+ <return>;
~8925 mn+setAneutral25+ <return>;
~8926 mn+setAneutral26+ <return>;
~8927 mn+setAneutral27+ <return>;
~8928 mn+setAneutral28+ <return>;
~8929 mn+setAneutral29+ <return>;
~8930 mn+setAneutral30+ <return>;
~8931 mn+setAneutral31+ <return>;
~8932 mn+setAneutral32+ <return>;
~8933 mn+setAneutral33+ <return>;
~8934 mn+setAneutral34+ <return>;
~8935 mn+setAneutral35+ <return>;
~8936 mn+setAneutral36+ <return>;
~8937 mn+setAneutral37+ <return>;
~8938 mn+setAneutral38+ <return>;
~8939 mn+setAneutral39+ <return>;
~8940 mn+setAneutral40+ <return>;
~8941 mn+setAneutral41+ <return>;
~8942 mn+setAneutral42+ <return>;
~8943 mn+setAneutral43+ <return>;
~8944 mn+setAneutral44+ <return>;
~8945 mn+setAneutral45+ <return>;
~8946 mn+setAneutral46+ <return>;
~8947 mn+setAneutral47+ <return>;
~8948 mn+setAneutral48+ <return>;
! the set B positive names;
~9701 mn+setBpositive1+ <return>;
! through 9716;
! the set B neutral names;
~9801 mn+setBneutral1+ <return>;
! through 9816;
! the set B neutral names;
~9901 mn+setBneutral1+ <return>;
! through 9916;
$
! the set A selecting lists;
\
$~10101;$~1 mi+01+ <return>;
$~10102;$~1 mi+02+ <return>;
$~10103;$~1 mi+03+ <return>;
$~10104;$~1 mi+04+ <return>;
$~10105;$~1 mi+05+ <return>;
$~10106;$~1 mi+06+ <return>;
$~10107;$~1 mi+07+ <return>;
$~10108;$~1 mi+08+ <return>;
$~10109;$~1 mi+09+ <return>;
$~10110;$~1 mi+10+ <return>;
$~10111;$~1 mi+11+ <return>;
$~10112;$~1 mi+12+ <return>;
$~10113;$~1 mi+13+ <return>;
$~10114;$~1 mi+14+ <return>;
$~10115;$~1 mi+15+ <return>;
$~10116;$~1 mi+16+ <return>;
$~10117;$~1 mi+17+ <return>;
$~10118;$~1 mi+18+ <return>;
$~10119;$~1 mi+19+ <return>;
$~10120;$~1 mi+20+ <return>;
$~10121;$~1 mi+21+ <return>;
$~10122;$~1 mi+22+ <return>;
$~10123;$~1 mi+23+ <return>;
$~10124;$~1 mi+24+ <return>;
$~10125;$~1 mi+25+ <return>;
$~10126;$~1 mi+26+ <return>;
$~10127;$~1 mi+27+ <return>;
$~10128;$~1 mi+28+ <return>;
$~10129;$~1 mi+29+ <return>;
$~10130;$~1 mi+30+ <return>;
$~10131;$~1 mi+31+ <return>;
$~10132;$~1 mi+32+ <return>;
$~10133;$~1 mi+33+ <return>;
$~10134;$~1 mi+34+ <return>;
$~10135;$~1 mi+35+ <return>;
$~10136;$~1 mi+36+ <return>;
$~10137;$~1 mi+37+ <return>;
$~10138;$~1 mi+38+ <return>;
$~10139;$~1 mi+39+ <return>;
$~10140;$~1 mi+40+ <return>;
$~10141;$~1 mi+41+ <return>;
$~10142;$~1 mi+42+ <return>;
$~10143;$~1 mi+43+ <return>;
$~10144;$~1 mi+44+ <return>;
$~10145;$~1 mi+45+ <return>;
$~10146;$~1 mi+46+ <return>;
$~10147;$~1 mi+47+ <return>;
$~10148;$~1 mi+48+ <return>;
\
$~10201;$~1 mi+01+ <return>;
$~10202;$~1 mi+02+ <return>;
$~10203;$~1 mi+03+ <return>;
$~10204;$~1 mi+04+ <return>;
$~10205;$~1 mi+05+ <return>;
$~10206;$~1 mi+06+ <return>;
$~10207;$~1 mi+07+ <return>;
$~10208;$~1 mi+08+ <return>;
$~10209;$~1 mi+09+ <return>;
$~10210;$~1 mi+10+ <return>;
$~10211;$~1 mi+11+ <return>;
$~10212;$~1 mi+12+ <return>;
$~10213;$~1 mi+13+ <return>;
$~10214;$~1 mi+14+ <return>;
$~10215;$~1 mi+15+ <return>;
$~10216;$~1 mi+16+ <return>;
$~10217;$~1 mi+17+ <return>;
$~10218;$~1 mi+18+ <return>;
$~10219;$~1 mi+19+ <return>;
$~10220;$~1 mi+20+ <return>;
$~10221;$~1 mi+21+ <return>;
$~10222;$~1 mi+22+ <return>;
$~10223;$~1 mi+23+ <return>;
$~10224;$~1 mi+24+ <return>;
$~10225;$~1 mi+25+ <return>;
$~10226;$~1 mi+26+ <return>;
$~10227;$~1 mi+27+ <return>;
$~10228;$~1 mi+28+ <return>;
$~10229;$~1 mi+29+ <return>;
$~10230;$~1 mi+30+ <return>;
$~10231;$~1 mi+31+ <return>;
$~10232;$~1 mi+32+ <return>;
$~10233;$~1 mi+33+ <return>;
$~10234;$~1 mi+34+ <return>;
$~10235;$~1 mi+35+ <return>;
$~10236;$~1 mi+36+ <return>;
$~10237;$~1 mi+37+ <return>;
$~10238;$~1 mi+38+ <return>;
$~10239;$~1 mi+39+ <return>;
$~10240;$~1 mi+40+ <return>;
$~10241;$~1 mi+41+ <return>;
$~10242;$~1 mi+42+ <return>;
$~10243;$~1 mi+43+ <return>;
$~10244;$~1 mi+44+ <return>;
$~10245;$~1 mi+45+ <return>;
$~10246;$~1 mi+46+ <return>;
$~10247;$~1 mi+47+ <return>;
$~10248;$~1 mi+48+ <return>;
\
$~10301;$~1 mi+01+ <return>;
$~10302;$~1 mi+02+ <return>;
$~10303;$~1 mi+03+ <return>;
$~10304;$~1 mi+04+ <return>;
$~10305;$~1 mi+05+ <return>;
$~10306;$~1 mi+06+ <return>;
$~10307;$~1 mi+07+ <return>;
$~10308;$~1 mi+08+ <return>;
$~10309;$~1 mi+09+ <return>;
$~10310;$~1 mi+10+ <return>;
$~10311;$~1 mi+11+ <return>;
$~10312;$~1 mi+12+ <return>;
$~10313;$~1 mi+13+ <return>;
$~10314;$~1 mi+14+ <return>;
$~10315;$~1 mi+15+ <return>;
$~10316;$~1 mi+16+ <return>;
$~10317;$~1 mi+17+ <return>;
$~10318;$~1 mi+18+ <return>;
$~10319;$~1 mi+19+ <return>;
$~10320;$~1 mi+20+ <return>;
$~10321;$~1 mi+21+ <return>;
$~10322;$~1 mi+22+ <return>;
$~10323;$~1 mi+23+ <return>;
$~10324;$~1 mi+24+ <return>;
$~10325;$~1 mi+25+ <return>;
$~10326;$~1 mi+26+ <return>;
$~10327;$~1 mi+27+ <return>;
$~10328;$~1 mi+28+ <return>;
$~10329;$~1 mi+29+ <return>;
$~10330;$~1 mi+30+ <return>;
$~10331;$~1 mi+31+ <return>;
$~10332;$~1 mi+32+ <return>;
$~10333;$~1 mi+33+ <return>;
$~10334;$~1 mi+34+ <return>;
$~10335;$~1 mi+35+ <return>;
$~10336;$~1 mi+36+ <return>;
$~10337;$~1 mi+37+ <return>;
$~10338;$~1 mi+38+ <return>;
$~10339;$~1 mi+39+ <return>;
$~10340;$~1 mi+40+ <return>;
$~10341;$~1 mi+41+ <return>;
$~10342;$~1 mi+42+ <return>;
$~10343;$~1 mi+43+ <return>;
$~10344;$~1 mi+44+ <return>;
$~10345;$~1 mi+45+ <return>;
$~10346;$~1 mi+46+ <return>;
$~10347;$~1 mi+47+ <return>;
$~10348;$~1 mi+48+ <return>;
\
$~10401;$~1 mi+01+ <return>;
$~10402;$~1 mi+02+ <return>;
$~10403;$~1 mi+03+ <return>;
$~10404;$~1 mi+04+ <return>;
$~10405;$~1 mi+05+ <return>;
$~10406;$~1 mi+06+ <return>;
$~10407;$~1 mi+07+ <return>;
$~10408;$~1 mi+08+ <return>;
$~10409;$~1 mi+09+ <return>;
$~10410;$~1 mi+10+ <return>;
$~10411;$~1 mi+11+ <return>;
$~10412;$~1 mi+12+ <return>;
$~10413;$~1 mi+13+ <return>;
$~10414;$~1 mi+14+ <return>;
$~10415;$~1 mi+15+ <return>;
$~10416;$~1 mi+16+ <return>;
$~10417;$~1 mi+17+ <return>;
$~10418;$~1 mi+18+ <return>;
$~10419;$~1 mi+19+ <return>;
$~10420;$~1 mi+20+ <return>;
$~10421;$~1 mi+21+ <return>;
$~10422;$~1 mi+22+ <return>;
$~10423;$~1 mi+23+ <return>;
$~10424;$~1 mi+24+ <return>;
$~10425;$~1 mi+25+ <return>;
$~10426;$~1 mi+26+ <return>;
$~10427;$~1 mi+27+ <return>;
$~10428;$~1 mi+28+ <return>;
$~10429;$~1 mi+29+ <return>;
$~10430;$~1 mi+30+ <return>;
$~10431;$~1 mi+31+ <return>;
$~10432;$~1 mi+32+ <return>;
$~10433;$~1 mi+33+ <return>;
$~10434;$~1 mi+34+ <return>;
$~10435;$~1 mi+35+ <return>;
$~10436;$~1 mi+36+ <return>;
$~10437;$~1 mi+37+ <return>;
$~10438;$~1 mi+38+ <return>;
$~10439;$~1 mi+39+ <return>;
$~10440;$~1 mi+40+ <return>;
$~10441;$~1 mi+41+ <return>;
$~10442;$~1 mi+42+ <return>;
$~10443;$~1 mi+43+ <return>;
$~10444;$~1 mi+44+ <return>;
$~10445;$~1 mi+45+ <return>;
$~10446;$~1 mi+46+ <return>;
$~10447;$~1 mi+47+ <return>;
$~10448;$~1 mi+48+ <return>;
\
$~10501;$~1 mi+01+ <return>;
$~10502;$~1 mi+02+ <return>;
$~10503;$~1 mi+03+ <return>;
$~10504;$~1 mi+04+ <return>;
$~10505;$~1 mi+05+ <return>;
$~10506;$~1 mi+06+ <return>;
$~10507;$~1 mi+07+ <return>;
$~10508;$~1 mi+08+ <return>;
$~10509;$~1 mi+09+ <return>;
$~10510;$~1 mi+10+ <return>;
$~10511;$~1 mi+11+ <return>;
$~10512;$~1 mi+12+ <return>;
$~10513;$~1 mi+13+ <return>;
$~10514;$~1 mi+14+ <return>;
$~10515;$~1 mi+15+ <return>;
$~10516;$~1 mi+16+ <return>;
$~10517;$~1 mi+17+ <return>;
$~10518;$~1 mi+18+ <return>;
$~10519;$~1 mi+19+ <return>;
$~10520;$~1 mi+20+ <return>;
$~10521;$~1 mi+21+ <return>;
$~10522;$~1 mi+22+ <return>;
$~10523;$~1 mi+23+ <return>;
$~10524;$~1 mi+24+ <return>;
$~10525;$~1 mi+25+ <return>;
$~10526;$~1 mi+26+ <return>;
$~10527;$~1 mi+27+ <return>;
$~10528;$~1 mi+28+ <return>;
$~10529;$~1 mi+29+ <return>;
$~10530;$~1 mi+30+ <return>;
$~10531;$~1 mi+31+ <return>;
$~10532;$~1 mi+32+ <return>;
$~10533;$~1 mi+33+ <return>;
$~10534;$~1 mi+34+ <return>;
$~10535;$~1 mi+35+ <return>;
$~10536;$~1 mi+36+ <return>;
$~10537;$~1 mi+37+ <return>;
$~10538;$~1 mi+38+ <return>;
$~10539;$~1 mi+39+ <return>;
$~10540;$~1 mi+40+ <return>;
$~10541;$~1 mi+41+ <return>;
$~10542;$~1 mi+42+ <return>;
$~10543;$~1 mi+43+ <return>;
$~10544;$~1 mi+44+ <return>;
$~10545;$~1 mi+45+ <return>;
$~10546;$~1 mi+46+ <return>;
$~10547;$~1 mi+47+ <return>;
$~10548;$~1 mi+48+ <return>;
\
$~10601;$~1 mi+01+ <return>;
$~10602;$~1 mi+02+ <return>;
$~10603;$~1 mi+03+ <return>;
$~10604;$~1 mi+04+ <return>;
$~10605;$~1 mi+05+ <return>;
$~10606;$~1 mi+06+ <return>;
$~10607;$~1 mi+07+ <return>;
$~10608;$~1 mi+08+ <return>;
$~10609;$~1 mi+09+ <return>;
$~10610;$~1 mi+10+ <return>;
$~10611;$~1 mi+11+ <return>;
$~10612;$~1 mi+12+ <return>;
$~10613;$~1 mi+13+ <return>;
$~10614;$~1 mi+14+ <return>;
$~10615;$~1 mi+15+ <return>;
$~10616;$~1 mi+16+ <return>;
$~10617;$~1 mi+17+ <return>;
$~10618;$~1 mi+18+ <return>;
$~10619;$~1 mi+19+ <return>;
$~10620;$~1 mi+20+ <return>;
$~10621;$~1 mi+21+ <return>;
$~10622;$~1 mi+22+ <return>;
$~10623;$~1 mi+23+ <return>;
$~10624;$~1 mi+24+ <return>;
$~10625;$~1 mi+25+ <return>;
$~10626;$~1 mi+26+ <return>;
$~10627;$~1 mi+27+ <return>;
$~10628;$~1 mi+28+ <return>;
$~10629;$~1 mi+29+ <return>;
$~10630;$~1 mi+30+ <return>;
$~10631;$~1 mi+31+ <return>;
$~10632;$~1 mi+32+ <return>;
$~10633;$~1 mi+33+ <return>;
$~10634;$~1 mi+34+ <return>;
$~10635;$~1 mi+35+ <return>;
$~10636;$~1 mi+36+ <return>;
$~10637;$~1 mi+37+ <return>;
$~10638;$~1 mi+38+ <return>;
$~10639;$~1 mi+39+ <return>;
$~10640;$~1 mi+40+ <return>;
$~10641;$~1 mi+41+ <return>;
$~10642;$~1 mi+42+ <return>;
$~10643;$~1 mi+43+ <return>;
$~10644;$~1 mi+44+ <return>;
$~10645;$~1 mi+45+ <return>;
$~10646;$~1 mi+46+ <return>;
$~10647;$~1 mi+47+ <return>;
$~10648;$~1 mi+48+ <return>;
\
! another 26 lists through 13248;

! the set B selecting lists;
$~13301;$~1 mi+01+ <return>;
! through 13316 and then;
$~13317;$~1 mi+01+ <return>;
! through 13332;
\
! 5 more times through 13832;

$!stop DMDX from exiting;$


N-Back task.


    Perhaps the mother of all dynamic item files (at least until the Corsi Block Tapping task was done anyway) is the classic N-Back task.  Here DMDX has to keep track of what was presented up to the three items ago and base the correctness of the response on that.  The juicy stuff is in the last block starting at item 10 (or 100) where there's a subroutine that takes a number of parameters and performs all the various different iterations of the task based on degree of backedness, whether to use feedback and so on.  The items before it simply control the flow of the experiment by calling item 100 (or 10 later on) with various parameters.  It's been a while since I wrote this item file but I think the videotime shenanigans were because the script was written with remote testing in mind but at the time the <msctrfd> keyword hadn't been created and there was no way to time frames across items when you didn't know the refresh rate at scripting time.  Here when calling item 100 (or 10 later on) macro N is set to the N-back level, counter 4 is set to the number of items with feedback and counter 5 is set with the total items to be presented.  Call item 10 for full auto operation with the parameters set as indicated, call item 100 for semi auto operation with feedback with macro N set to the N-back level, counters 4 and 5 set to 1 and counter 7 with the selected display in it (1..8).

    Note that as the task is coded here it's limited to at maximum N-back depth of three.  If you want a deeper level see the paragraph at the end of this section that details the edits that are necessary.

<ep> <! V6>
<dwc 255255255> <dbc 000000000>
<fd 30> <vm desktop> <id keyboard> <id mouse>
<nfb> <cr> <t 2980> <branchdiagnostics 0> <delay 0>
<eop>
1 <set c10 = videotime> <line -1> "N-back task" <msfd 2980> / !
<! Nasty kluge to determine isi in ticks>;
~1 <set c10 = videotime - c10>;
0 <line -1> "N-back task",
<line 1> "Hit space to begin" <umnr> <umpr> <mpr +A> <mpr +button 0> <mr +button 1>;
!~1 <! Just for testing, comment out if you want to see the practice> <set c7 = 0> <bu 4000>;

0 <inst .1,.1,.8> "1 back task" <inst nl>, <inst nl>,
"with ", "feedback" <inst nl>, <inst nl>, "Hit space to begin" <bu 1010>;
~1000;
0 <inst .1,.1,.8> "1 back task" <inst nl>, <inst nl>,
"Let's ", "try ", "that ", "again! " <inst nl>, <inst nl>, "Hit space to begin";
~1010 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 10>;
~1 <bi -1000, c13 .eq. 0>;
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 3> <call 100>;
~1 <bi -1000, c13 .eq. 0>;
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 2> <call 100>;
~1 <bi -1000, c13 .eq. 0>;
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 2> <call 100>;
~1 <bi -1000, c13 .eq. 0>;
0 <inst .1,.1,.8> "1 back task" <inst nl>, <inst nl>,
"Congratulations! ", "Let's ", "see ", "if ", "you ", "can ", "do ", "that ", "again! " <inst nl>, <inst nl>, "Hit space to begin";
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 4> <call 10>;
~1 <bi -1000, c13 .eq. 0>;
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 100>;
~1 <bi -1000, c13 .eq. 0>;
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 3> <call 100>;
~1 <bi -1000, c13 .eq. 0>;
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 3> <call 100>;
~1 <bi -1000, c13 .eq. 0>;
0 <inst .1,.1,.8> "1 back task" <inst nl>, <inst nl>,
"Congratulations! ", "Let's ", "see ", "if ", "you ", "can ", "do ", "that ", "again! " <inst nl>, <inst nl>, "Hit space to begin";
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 2> <call 10>;
~1 <bi -1000, c13 .eq. 0>;
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 4> <call 100>;
~1 <bi -1000, c13 .eq. 0>;
~1 mN+1+ <set c4 = 1> <set c5 = 1> <set c7 = 4> <call 100>;
~1 <bi -1000, c13 .eq. 0>;


0 <inst .1,.1,.8> "2 back task" <inst nl>, <inst nl>,
"with ", "feedback" <inst nl>, <inst nl>, "Hit space to begin" <bu 2010>;
~2000;
0 <inst .1,.1,.8> "2 back task" <inst nl>, <inst nl>,
"Let's ", "try ", "that ", "again! " <inst nl>, <inst nl>, "Hit space to begin";
~2010 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 2> <call 10>;
~1 <bi -2000, c13 .eq. 0>;
~1 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 3> <call 100>;
~1 <bi -2000, c13 .eq. 0>;
~1 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 100>;
~1 <bi -2000, c13 .eq. 0>;
~1 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 4> <call 100>;
~1 <bi -2000, c13 .eq. 0>;
~1 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 100>;
~1 <bi -2000, c13 .eq. 0>;
0 <inst .1,.1,.8> "1 back task" <inst nl>, <inst nl>,
"Congratulations! ", "Let's ", "see ", "if ", "you ", "can ", "do ", "that ", "again! " <inst nl>, <inst nl>, "Hit space to begin";
~1 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 2> <call 10>;
~1 <bi -2000, c13 .eq. 0>;
~1 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 3> <call 100>;
~1 <bi -2000, c13 .eq. 0>;
~1 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 100>;
~1 <bi -2000, c13 .eq. 0>;
~1 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 4> <call 100>;
~1 <bi -2000, c13 .eq. 0>;
~1 mN+2+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 100>;
~1 <bi -2000, c13 .eq. 0>;


0 <inst .1,.1,.8> "3 back task" <inst nl>, <inst nl>,
"with ", "feedback" <inst nl>, <inst nl>, "Hit space to begin" <bu 3010>;
~3000;
0 <inst .1,.1,.8> "3 back task" <inst nl>, <inst nl>,
"Let's ", "try ", "that ", "again! " <inst nl>, <inst nl>, "Hit space to begin";
~3010 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 2> <call 10>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 3> <call 100>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 100>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 4> <call 100>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 100>;
~1 <bi -3000, c13 .eq. 0>;
0 <inst .1,.1,.8> "1 back task" <inst nl>, <inst nl>,
"Congratulations! ", "Let's ", "see ", "if ", "you ", "can ", "do ", "that ", "again! " <inst nl>, <inst nl>, "Hit space to begin";
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 2> <call 10>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 3> <call 100>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 100>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 4> <call 100>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 1> <call 100>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 3> <call 100>;
~1 <bi -3000, c13 .eq. 0>;
~1 mN+3+ <set c4 = 1> <set c5 = 1> <set c7 = 3> <call 100>;
~1 <bi -3000, c13 .eq. 0>;



~4000;
0 <inst .1,.1,.8> "1 back task" <inst nl>, <inst nl>,
"without ", "feedback" <inst nl>, <inst nl>, "Hit space to begin";
~1 mN+1+ <set c4 = 0> <set c5 = 20> <call 10>;

0 <inst .1,.1,.8> "2 back task" <inst nl>, <inst nl>,
"without" , "feedback" <inst nl>, <inst nl>, "Hit space to begin";
~2 mN+2+ <set c4 = 0> <set c5 = 20> <call 10>;

0 <inst .1,.1,.8> "3 back task" <inst nl>, <inst nl>,
"without ", "feedback ", <inst nl>, <inst nl>, "Hit space to begin";
~3 mN+3+ <set c4 = 0> <set c5 = 20> <call 10>;
0 "Done" <lf>;

! call item 10 for full auto operation with macro N with N-back level, counter 4 number of items with feedback and counter 5 with total items to be presented;
! call item 100 semi auto with feedback macro N N-back, counter 4 = 1, counter 5 = 1 and counter 7 with the selected display in it (1..8);
~10 <set c1 = 0> <set c2 = 0> <set c3 = 0>;
~100 <bi 102, c4 .gt. 0> <! Suppress blank display if feedback to be given>;
~101 mF+/+ <bu 103>;
~102 mF++;
~103 <bi 300, c7 .ne. 0> <! If continuing (selection already made) skip selection>;
~104 <bi 290, c~N .eq. 0> <! If just starting pick filler>;
~105 <set c6 = random 10> <bi 200, c6 .ge. 3> <! Do an n-back or filler?>;
~110 <set c7 = c~N> <bu 300>;
~200 <bi 220, c~N .ne. c1> <! Decide if picking a filler that isn't one of two or not>;
~205 <set c7 = 1 + random 7> <bi 300, c7 .lt. c~N> <! Pick a filler that isn't the n-back>;
~210 <inc 7> <bu 300>;
~220 <set c7 = 1 + random 6> <bi 245, c~N .gt. c1> <! Pick a filler that isn't the n-back or a repeat>;
~225 <bi 300, c7 .lt. c~N>;
~230 <inc 7> <bi 300, c7 .lt. c1>;
~235 <inc 7> <bu 300>;
~245 <bi 300, c7 .lt. c1>;
~250 <inc 7> <bi 300, c7 .lt. c~N>;
~255 <inc 7> <bu 300>;
~290 <bi 299, c1 .eq. 0> <! Starting fillers can be anything>;
~292 <set c7 = 1 + random 7> <bi 300, c7 .lt. c1> <! Pick a starting filler that isn't a repeat>;
~294 <inc 7> <bu 300>;
~299 <set c7 = 1 + random 8>;
~300 <set c11 = videotime + c10> <! Time of next trial>
<set c6 = 300 + c7> <ib 6> <! Branch to one of the items>;
+301 <msfd 500> * "A" / <msfd 2480> ~F <bu 400>;
+302 <msfd 500> * "B" / <msfd 2480> ~F <bu 400>;
+303 <msfd 500> * "C" / <msfd 2480> ~F <bu 400>;
+304 <msfd 500> * "D" / <msfd 2480> ~F <bu 400>;
+305 <msfd 500> * "E" / <msfd 2480> ~F <bu 400>;
+306 <msfd 500> * "F" / <msfd 2480> ~F <bu 400>;
+307 <msfd 500> * "G" / <msfd 2480> ~F <bu 400>;
+308 <msfd 500> * "H" / <msfd 2480> ~F <bu 400>;
~400 <bic 450> <! Determine if response was correct>;
~410 <bi 480, c7 .eq. c~N>;
~420 <emit correct> <set c13 = 1> <bu 500> <! Skip feedback if no response was appropriate>;
~450 <bi 460, c7 .eq. c~N>;
~455 <emit incorrect> <set c13 = 0> <bi 500, c4 .le. 0> <! Skip feedback if it's been done or not allowed>;
490 @2 "Uh oh! You responded but shouldn't have." <msfd 1000> / / <bu 500>;
~460 <emit correct> <set c13 = 1> <bi 500, c4 .le. 0> <! Skip feedback if it's been done or not allowed>;
470 @2 "Congratulations! You caught the repeat!" <msfd 1000> / / <bu 500>;
~480 <emit incorrect> <set c13 = 0> <bi 500, c4 .le. 0> <! Skip feedback if it's been done or not allowed>;
490 @2 "Uh oh! You should have responded but didn't." <msfd 1000> / /;
~500 <set c12 = c11 - videotime> <bi 509, c12 .le. 0> <! Fixed isi>;
501 <ctrfd 12> /;
~509 <set c3 = c2> <set c2 = c1> <set c1 = c7> <set c7 = 0> <dec 4> <dec 5> <bi -100, c5 .gt. 0>;
~510 <return>;
! comment to stop dmdx auto exiting when 510 executes;

    As mentioned earlier as the task is coded here it's limited to at maximum a N-back depth of three, to achieve a deeper level certain edits are required. The problem is that I didn't leave any space to expand the backedness of the task, counters 1 through 3 are used to remember the previous states however counter 4 is used as a feedback counter/flag and counter 5 is the number of trials and counter 6 is used for selecting the target to display.  So you'll have to move all the counter 4, 5 and 6 references elsewhere and while you're at it you might as well move counter 7 too.  I recommend making those counters 40, 50, 60 and 70 just to make life easy.  Be aware when you're doing that that
<ib>, <dec> and <inc> are referencing counter numbers so item 210 for instance will want to <inc 70> and not <inc 7> like it currently is or if you're using a current version of DMDX <inc c70>.  Other items include (but may not be limited to) 230, 235, 250, 255, 294, 300 where <ib 6> will be <ib 60> or if you're using a current version of DMDX <ib c60>, 509 where <dec 4> <dec 5> will want to be <dec c40> <dec c50> (assuming a current version of DMDX).  Item 10 is going to want to set those extra memory counters to zero (say counters 6 through 3), and you will need to expand item 509 that updates counters to handle your larger backedness with <set c6=c5> <set c5=c4> <set c4=c3>.  And of course when you call the thing you're not going to be using counter 4 or 5 anymore...

~1 mN+1+ <set c40 = 0> <set c50 = 30> <call 10>;

    And if you wanted to add more targets you'll not only want to add more 300 series items to display them but there are four random number generators you'll need to modify.  In item 205 that seven in random 7 will want to become N-1 (because it knows it doesn't want to pick the N-back target) where N is your new number of targets (not the degree of N-backedness), item 220's will be N-2 (because it's looking for a target in a set that has both an N-back it doesn't want to select because it's not supposed to be an N-back item and it also must not repeat the last target leaving six possible outcomes in the original as it stands here), 292 will be N-1 again (picking a target not used last time) and 299 will be N (completely unrestricted choice).






DMDX Index.