This document describes the current tracking adapter at tasks/tracking/src/index.ts.
The Tracking task is implemented using the createTaskAdapter factory:
export const trackingAdapter = createTaskAdapter({
manifest: { taskId: "tracking", ... },
run: runTrackingTask,
terminate: async () => { /* module + cursor cleanup */ },
});run(context): Runs the main Tracking task logic (pursuit or MOT) using a native animation loop, managing DRT scopes viaTaskModuleRunner.terminate(): Stops all active task modules and resets the cursor.
tracking is a continuous mouse-tracking task for long trials.
Primary output is binned performance for each trial:
- inside vs outside sample counts per bin
- mean absolute cursor distance from target boundary per bin (inside =
0)
tracking/defaulttracking/drt_demotracking/mot_demo
The task runs natively (not a jsPsych plugin trial), with:
- intro / block / end instruction screens via core
waitForContinue - per-trial animation loop (
requestAnimationFrame) in a centered display frame - optional DRT embeds using core
DrtControllerwithscope: "block" | "trial" - renderer backend selection via
display.rendererBackend("canvas"or"pixi")
Cursor behavior:
pursuit(mouse-tracking): cursor is visible (crosshair).motvisual tracking: cursor is hidden during cue/tracking and shown again for response selection.
task.titletask.drt(ortask.embeds.drt): base DRT config for all blocks
instructions.pages(preferred): string or string[]- aliases:
introPages,intro,screens
- aliases:
instructions.preBlockPages: string or string[]instructions.postBlockPages: string or string[]instructions.endPages: string or string[]instructions.blockIntroTemplate: supports{nTrials}and{phase}
Setting a slot to "" (or arrays containing only blank strings) clears that slot.
Example:
{
"instructions": {
"pages": [
"Welcome.",
"Track the target continuously."
],
"preBlockPages": "Keep your cursor active throughout the block.",
"postBlockPages": "Block complete. Brief pause.",
"endPages": "Tracking task complete."
}
}aperturePxframeBackgroundframeBordercanvasBackgroundshowCrosshairrendererBackend:"canvas" | "pixi"(defaults to"canvas")
mode:"pursuit" | "mot"(defaults to"pursuit")durationMssampleIntervalMsbinMsstoreRawSamplestargetshape:"circle" | "square"sizePxcolorOncolorOffborderColorborderWidthPx
motionmode:"waypoint" | "chaotic"- waypoint fields:
speedPxPerSec,minSegmentPx,arriveThresholdPx - chaotic fields:
speedPxPerSec,directionJitterRadPerSec
motobjectCount,targetCount,objectRadiusPxcueDurationMsresponseMaxDurationMs(0= no timeout)responseFinishKeycueTargetColor,cueDistractorColor,trackingColorresponseSelectedColor,responseUnselectedColorobjectBorderColor,objectBorderWidthPxresponsePromptText
labelphasetrialsmanipulation(optional single manipulation id)manipulations(optional ordered manipulation id list)manipulationPool(optional pool id; draws one manipulation bundle fromplan.manipulationPools)trialDurationMs(block override fortrialDefaults.durationMs)sampleIntervalMsbinMsstoreRawSamplestarget(block override)motion(block override)mode(block override)mot(block override)beforeBlockScreens(alias:preBlockInstructions)afterBlockScreens(alias:postBlockInstructions)drt(orembeds.drt) block-level DRT override
plan.manipulations[]entries support:id(required)overrides(deep-merged into block config when selected)
plan.manipulationPoolsentries support participant-seeded shuffled bundle draws:poolId: [ [\"manipA\"], [\"manipB\", \"manipC\"], ... ]
- Unknown manipulation ids fail fast during config parsing.
- Resolved manipulation ids are emitted as a joined
manipulationIdstring on block/trial outputs.
Saved JSON payload includes:
records: one row per trialtrialBins: one row per trial-binrawSamples: optional high-frequency samples when enableddrt.scopeRecords: DRT runtime exports per active scopedrtTransformEstimates: flattened transform estimates from DRT eventseventLog
CSV export (tracking_trials) contains trial-level summary rows.
When mode is "mot":
- dots move continuously during cue and tracking phases
- cue phase marks targets with a distinct color
- tracking phase removes cue distinction (all dots share a color)
- response phase freezes motion, allows click toggles, and confirms via
responseFinishKey - trial rows include
motHits,motMisses,motFalseAlarms,motCorrectRejections, andmotAccuracy