Task Schema
Task Schema
Usage of resource/tasks
and description of each field
Tips
Please note that JSON files do not support comments. The comments in this document are for demonstration purposes only. Do not copy them directly into your JSON files.
Complete Field Reference
{
"TaskName": { // Task name, using @ may indicate a special task, default values will differ, see Special Task Types below
"baseTask": "xxx", // Use xxx task as template to generate tasks, see Base Task in Special Task Types for details
"algorithm": "MatchTemplate", // Optional, indicates the recognition algorithm type
// Default is MatchTemplate when not specified
// - JustReturn: No recognition, directly execute action
// - MatchTemplate: Match image
// - OcrDetect: Text recognition
// - FeatureMatch: Feature matching
"action": "ClickSelf", // Optional, indicates action after recognition
// Default is DoNothing when not specified
// - ClickSelf: Click on recognized position (random point within target area)
// - ClickRect: Click on specified area, corresponds to specificRect field, not recommended
// - DoNothing: Do nothing
// - Stop: Stop current task
// - Swipe: Swipe, corresponds to specificRect and rectMove fields
// - Input: Input text, requires algorithm to be JustReturn, corresponds to inputText field
"sub": ["SubTaskName1", "SubTaskName2"],
// Optional, subtasks, not recommended. Will execute each subtask after completing current task
// Can be nested, with subtasks having their own subtasks. Be careful not to create infinite loops
"subErrorIgnored": true, // Optional, whether to ignore subtask errors
// Default false when not specified
// When false, if a subtask errors, subsequent tasks won't execute (equivalent to current task erroring)
// When true, subtask errors don't affect execution
"next": ["OtherTaskName1", "OtherTaskName2"],
// Optional, indicates tasks to execute after completing current task and subtasks
// Will check from first to last and execute first matching task
// Default is to stop after completing current task when not specified
// For identical tasks, second recognition won't occur after first:
// "next": [ "A", "B", "A", "A" ] -> "next": [ "A", "B" ]
// JustReturn type tasks must not be in non-last positions
"maxTimes": 10, // Optional, maximum execution count for this task
// Default is infinity when not specified
// After reaching max count, will execute exceededNext if present, otherwise stop
"exceededNext": ["OtherTaskName1", "OtherTaskName2"],
// Optional, tasks to execute after reaching maximum execution count
// When not specified, stops after max count; when specified, executes these instead of next
"onErrorNext": ["OtherTaskName1", "OtherTaskName2"],
// Optional, tasks to execute when an error occurs
"preDelay": 1000, // Optional, delay in milliseconds after recognition before executing action; default 0
"postDelay": 1000, // Optional, delay in milliseconds after executing action before recognizing next; default 0
"roi": [0, 0, 1280, 720], // Optional, recognition area in format [x, y, width, height]
// Auto-scales to 1280 * 720 resolution; default [0, 0, 1280, 720] when not specified
// Try to specify this to reduce recognition area, improve performance and recognition speed
"cache": true, // Optional, whether to use cache for this task, default true
// After first recognition, will always check at same position, greatly improves performance
// Only suitable for targets whose position never changes, set false if target position may change
"rectMove": [0, 0, 0, 0], // Optional, target movement after recognition, not recommended. Auto-scales to 1280 * 720
// For example, if A is recognized but actual click target is 10 pixels below in 5 * 2 area,
// can use [0, 10, 5, 2], but if possible try to directly recognize target position instead
// Additionally, when action is Swipe, indicates endpoint (required)
"reduceOtherTimes": ["OtherTaskName1", "OtherTaskName2"],
// Optional, reduces execution count of other tasks after execution
// For example, if you used a sanity potion, previous blue start button click didn't work, so reduce by 1
"specificRect": [100, 100, 50, 50],
// Required when action is ClickRect, indicates specified click area (random point within)
// Required when action is Swipe, indicates starting point
// Auto-scales to 1280 * 720 resolution
// When algorithm is "OcrDetect", specificRect[0] and specificRect[1] represent grayscale threshold limits
"specialParams": [int, ...], // Parameters for special recognizers
// Optional when action is Swipe, [0] for duration, [1] for extra swipe toggle
"highResolutionSwipeFix": false, // Optional, whether to enable high-resolution swipe fix
// Currently only needed for stage navigation which doesn't use unity swipe method
// Default is false
/* Fields below only valid when algorithm is MatchTemplate */
"template": "xxx.png", // Optional, image file to match, can be string or string list
// Default "TaskName.png"
// Template files can be in template folder or subfolders, recursive search when loading
"templThreshold": 0.8, // Optional, threshold score for image template matching, can be number or number list
// Default 0.8, check actual score in logs
"maskRange": [1, 255], // Optional, grayscale mask range for matching. array<int, 2>
// For example, paint parts of image that shouldn't be recognized black (grayscale 0)
// Then set [1, 255] to ignore black parts during matching
"colorScales": [ // Required when method is HSVCount or RGBCount, color mask ranges
[ // list<array<array<int, 3>, 2>> / list<array<int, 2>>
[23, 150, 40], // Structure is [[lower1, upper1], [lower2, upper2], ...]
[25, 230, 150] // Inner layer is int for grayscale,
], // or array<int, 3> for three-channel color (RGB or HSV based on method)
... // Middle layer array<*, 2> is color (or grayscale) lower and upper limits
], // Outer layer represents different color ranges, recognition area is their union on template image
"colorWithClose": true, // Optional when method is HSVCount or RGBCount, default true
// Whether to use morphological closing on mask range for color counting
// Closing fills small black dots, generally improves color matching but set false for text
"method": "Ccoeff", // Optional, template matching algorithm, can be list
// Default is Ccoeff when not specified
// - Ccoeff: Color-insensitive template matching, corresponds to cv::TM_CCOEFF_NORMED
// - RGBCount: Color-sensitive template matching,
// Binary thresholds target area and template using colorScales,
// Calculates similarity using F1-score in RGB color space,
// Then dot products result with Ccoeff result
// - HSVCount: Similar to RGBCount, but uses HSV color space
/* Fields below only valid when algorithm is OcrDetect */
"text": [ "接管作战", "代理指挥" ], // Required, text to recognize, match is successful if any one matches ("接管作战" = "Take over operation", "代理指挥" = "Proxy command")
"ocrReplace": [ // Optional, replacements for commonly misrecognized text (supports regex)
[ "千员", "干员" ], // ("千员" = "thousand staff", "干员" = "operator")
[ ".+击干员", "狙击干员" ] // (".+击干员" = "any-hit operator", "狙击干员" = "sniper operator")
],
"fullMatch": false, // Optional, whether text recognition requires exact match (no extra characters), default false
// When false, substring is sufficient: e.g., text: [ "开始" ], recognized "开始行动" is success
// When true, must recognize exactly "开始", not one character more
"isAscii": false, // Optional, whether text content is ASCII characters
// Default false
"withoutDet": false, // Optional, whether to skip detection model
// Default false
/* Fields below only valid when algorithm is OcrDetect and withoutDet is true */
"useRaw": true, // Optional, whether to use original image for matching
// Default true, false for grayscale matching
"binThreshold": [140, 255], // Optional, threshold for grayscale binarization (default [140, 255])
// Pixels with grayscale out of range are considered background, excluded from text area
// Final text foreground includes pixels in [lower, upper] range
/* Fields below only valid when algorithm is JustReturn and action is Input */
"inputText": "A string text.", // Required, text to input as string
/* Fields below only valid when algorithm is FeatureMatch */
"template": "xxx.png", // Optional, image file to match, can be string or string list
// Default "TaskName.png"
"count": 4, // Required feature point count (threshold), default = 4
"ratio": 0.6, // KNN matching algorithm distance ratio, [0 - 1.0], higher means looser matching, easier line connection. Default 0.6
"detector": "SIFT", // Feature point detector type, options: SIFT, ORB, BRISK, KAZE, AKAZE, SURF; default = SIFT
// SIFT: High computational complexity, has scale and rotation invariance. Best effect.
// ORB: Very fast computation, has rotation invariance but no scale invariance.
// BRISK: Very fast computation, has scale and rotation invariance.
// KAZE: Suitable for 2D and 3D images, has scale and rotation invariance.
// AKAZE: Fast computation, has scale and rotation invariance.
}
}
Special Task Types
Template Task (@
Type Task)
Template task and base task are collectively called template tasks.
Allows using task "A" as template, with "B@A" representing a task generated from "A".
If task "B@A" is not explicitly defined in
tasks.json
, then addB@
prefix tosub
,next
,onErrorNext
,exceededNext
,reduceOtherTimes
fields (orB
if task name begins with#
), all other parameters match task "A". For example, if task "A" has:"A": { "template": "A.png", ..., "next": [ "N1", "N2" ] }
This would be equivalent to defining:
"B@A": { "template": "A.png", ..., "next": [ "B@N1", "B@N2" ] }
If task "B@A" is defined in
tasks.json
, then:- If "B@A" has different
algorithm
from "A", derived class parameters are not inherited (onlyTaskInfo
parameters inherited) - For image matching tasks, if
template
not explicitly defined, usesB@A.png
(not inheriting "A" template name); otherwise any derived parameters not explicitly defined inherit directly from "A" - For
TaskInfo
base class parameters (common to all task types likealgorithm
,roi
,next
, etc.), if not explicitly defined in "B@A", inherit directly from "A" except for the five fields mentioned above which get "B@" prefixed when inherited
- If "B@A" has different
Base Task
Base task and template task are collectively called template tasks.
Tasks with baseTask
field are base tasks.
Base task logic takes precedence over template task. This means "B@A": { "baseTask": "C", ... }
has no relation to task A.
Any parameter not explicitly defined uses the corresponding parameter from baseTask
without prefix, except template
which remains "TaskName.png"
when not explicitly defined.
Multi-File Tasks
If a task defined in a later-loaded file (e.g., foreign server tasks.json
, called File 2) is also defined in an earlier-loaded file (e.g., CN server tasks.json
, called File 1), then:
- If File 2's task has no
baseTask
field, it directly inherits fields from File 1's same-name task. - If File 2's task has a
baseTask
field, it doesn't inherit fields from File 1's same-name task, but overwrites them instead.
Virtual Task (#
Task)
Virtual tasks are also called sharp tasks (#
type tasks).
Tasks with #
in name are virtual tasks. #
can be followed by next
, back
, self
, sub
, on_error_next
, exceeded_next
, reduce_other_times
.
Virtual Task Type | Meaning | Simple Example |
---|---|---|
self | Parent task name | "A": {"next": "#self"} where "#self" interpreted as "A" "B": {"next": "A@B@C#self"} where "A@B@C#self" interpreted as "B" 1 |
back | Task name before # | "A@B#back" interpreted as "A@B" "#back" directly appears will be skipped |
next, sub, etc. | Field of task name before # | For example with next :"A#next" interpreted as Task.get("A")->next "#next" directly appears will be skipped |
Note1: "XXX#self"
has same meaning as "#self"
.
Simple Example
{
"A": { "next": ["N1", "N2"] },
"C": { "next": ["B@A#next"] },
"Loading": {
"next": ["#self", "#next", "#back"]
},
"B": {
"next": ["Other", "B@Loading"]
}
}
Results in:
Task.get("C")->next = { "B@N1", "B@N2" };
Task.get("B@Loading")->next = { "B@Loading", "Other", "B" };
Task.get("Loading")->next = { "Loading" };
Task.get_raw("B@Loading")->next = { "B#self", "B#next", "B#back" };
Some Use Cases
- When several tasks have
"next": [ "#back" ]
,"Task1@Task2@Task3"
means executeTask3
, thenTask2
, thenTask1
in sequence.
Other Related Cases
{
"A": { "next": ["N0"] },
"B": { "next": ["A#next"] },
"C@A": { "next": ["N1"] }
}
In this case, "C@B" -> next
(i.e., C@A#next
) is [ "N1" ]
, not [ "C@N0" ]
.
Runtime Task Modification
Task.lazy_parse()
loads JSON task configuration files at runtime. Lazy_parse rules match Multi-File Tasks.Task.set_task_base()
modifies a task'sbaseTask
field.
Usage Example
Consider this task configuration:
{
"A": {
"baseTask": "A_default"
},
"A_default": {
"next": ["xxx"]
},
"A_mode1": {
"next": ["yyy"]
},
"A_mode2": {
"next": ["zzz"]
}
}
The following code changes task "A" based on mode value, also affecting tasks that depend on "A", like "B@A":
switch (mode) {
case 1:
Task.set_task_base("A", "A_mode1"); // Basically equivalent to directly replacing A with A_mode1 content
break;
case 2:
Task.set_task_base("A", "A_mode2");
break;
default:
Task.set_task_base("A", "A_default");
break;
}
Expression Calculation
Symbol | Meaning | Example |
---|---|---|
@ | Template task | Fight@ReturnTo |
# (unary) | Virtual task | #self |
# (binary) | Virtual task | StartUpThemes#next |
* | Repeat multiple tasks | (ClickCornerAfterPRTS+ClickCorner)*5 |
+ | Task list merge (in next-type attributes, only first occurrence of same-name tasks kept) | A+B |
^ | Task list difference (in first but not second, order preserved) | (A+A+B+C)^(A+B+D) (result is C ) |
Operators @
, #
, *
, +
, ^
have precedence: #
(unary) > @
= #
(binary) > *
> +
= ^
.
Schema Validation
This project configures JSON schema validation for tasks.json
, schema file is docs/maa_tasks_schema.json
.
Visual Studio
Configured in MaaCore.vcxporj
, works out of the box. Prompts are somewhat cryptic with some missing information.
Visual Studio Code
Configured in .vscode/settings.json
, use VSCode to open the project folder to use. Better prompt quality.