SuperAPI AI Directory

maafw-interface

Coding & development

View repository

Updated 10-16 05:57

About this skill

MaaFW interface.json (PI V2) development

interface.json is the project's standardized external declaration: general-purpose GUIs, packaging and distribution, and toolchains all rely on it to recognize the project. Field semantics are always routed to MaaLLMWiki 's 3.3-ProjectInterfaceV2协议 and the official schema (interface.schema.json); do not fill them in from memory (when the maallmwiki skill is installed, it carries the complete routing process).

This article only covers the three things routing cannot provide:Selection decisions(when to use what),Silent failure surfaces(field interactions that do not error but simply do not take effect),Workflow and verification techniques. The field dictionary (enums, default values, field lists) is not copied in this article; all version annotations in the text are historical facts about "which version this mechanism has existed since", not a snapshot of the current version.

Dual-track versioning to prevent confusion:interface_version is fixed at the number 2(the JSON structure major version; compatibility additions do not touch it); the PI protocol separately has semantic version v2.x.y (evolving independently of MaaFW releases) — judging "whether the target Client supports a certain field" depends on the latter, and where the protocol currently stands is subject to the original changelog and is not hardcoded.

Hard guardrails

  1. External contract: field changes = user-visible behavior changes; software updates follow the release convention of the github field (general-purpose UIs only update the resource release); do not invent your own update channel.
  2. resource / Bundle layering(the definition comes from the official glossary "Terminology Explanation"; "resource pack" in the wording of "ProjectInterface V2" refers to resource entries, not Bundles):
    • Bundle: a folder stored according to the standard pipeline / model / image structure;path[] each entry of pipeline/ points to a Bundle root directory (not the
    • resource entry: the declaration unit (name / label / option); what users select in the Client is this.
    • controller / resource declarationscannotbe merged via import — the resource root is always declared by the main interface.
  3. Do not invent fields: if you are unsure about enums, default values, or version support, route to the schema and the original protocol text; prefer writing less and using defaults.
  4. i18n completeness:$ keys starting with languages must have corresponding keys in the translation file pointed to by languages ; if
  5. Secret hygiene: interface.json is distributed with resources, so plaintext secrets must not be written into it;password input fields must not default(hard-rejected by the schema), and must not go into presets (a protocol recommendation; the schema does not validate it — it relies on discipline).

Workflow

When writing from scratch, follow the order 1→7; when adding or modifying in an existing project, first see "Modifying an existing project" below.

  1. Skeleton:interface_version: 2 + name / version; adb's screenshot/input methods are not configured, and the framework automatically detects and selects the best. Two controller decisions (enums and default values routed to the schema):
    • Target form(Android device / desktop window / mac app / gamepad…) determines type, and use a unique name identifier (for resource / task / option / pretask filter lists to reference by name ).
    • Screenshot scaling baseline(the resolution space in which recognition and coordinates live: short side locked / long side / Expand / original resolution) — this is the scaling of framework screenshots, not the game's own UI scaling; if none is configured, the default is 720 short side (maafw-pipeline 's baseline resolution is taken from here).
  2. How to organize resource differencesChoose one of four:
    • Let the user choose → multiple resource entries (declaration layer).
    • Overlay within the same resource → path[] has a base Bundle + difference Bundle, and the difference Bundle only contains override files.
    • Difference-bound controller → controller.attach_resource_path(v2.2.0+) is attached after all of that resource's Bundles are loaded.
    • The whole package serves only a certain controller → the resource entry's controller list (by name) — the Client only shows applicable resources for selection.
    • Publishing with hash validation (v2.6.0+) note: the value iscalculated after loading only the Bundles in path Bundle in — if the packaging script includes attached Bundles in the calculation, it will falsely report a warning; a mismatch only warns and does not block, debug/pre-release versions can skip it, and if unset no validation is performed.
  3. Task: one task per user-visible feature:
    • entry write the pipeline node name— a cross-file reference between interface and pipeline, not a file name.
    • When there are many features, use group(v2.4.0+) to group them.
    • task-level resource / controller filtering references by name (not type).
  4. Options and presets: define adjustable parameters at the top level option and reference them level by level;preset(v2.3.0+) is a snapshot of task selections + option values. For control selection, task-level pipeline_override(hardcoded in that task, not going through user selection), the override priority of the four-level option declaration, applicability filtering, silent pitfalls, and wiring examples, see references/options.md。
  5. Subprocess— let the Client start the program for you; the two fields are chosen bytiming:
    • Resident during task execution, handling Custom recognition/action logic → agent(the Client starts a subprocess such as python ./agent/main.py and communicates with it; for whether to use Custom, see maafw-custom)。
    • Run one-time preparation before connecting the device(such as launching an emulator, environment self-check) → pretask(v2.7.0+, only connects to the Controller after it finishes; a non-zero exit aborts startup); can declare controller / resource filtering (v2.8.1+) — the protocol only stipulates that the Client mayhide/gray out inapplicable items, and does not guarantee skipping execution; "only run on a certain controller" must be self-determined within the program.
    • The CWD of both is the directory containing interface.json.
    • pretask.option only serializes the option values as the final argument passed to the program,does not participate in pipeline_override merging。
    • The agent subprocess reads Client-side context via the PI_* environment variable (v2.5.0+); the variable may be absent, so the subprocess must be fault-tolerant.
  6. Long-tail fields:setting(settings partition),telemetry(telemetry), etc.—just know they exist; when needed, route to the original text.
  7. Splitting and validation:
    • When the task volume is large, import[] splitting (for silent pitfalls see references/options.md)。
    • Static validation runs scripts: for projects with dev-tools (generated by create-maa-project), run pnpm check—validate interface.json against the official schema,tasks/ import fragments under and each Bundle's pipeline file; misspelled fields, illegal types, and enum values are caught here (import fragments placed outside tasks/ are not within the validation scope); projects without this infrastructure fall back to attaching schema associations in the editor.
    • Verify option branches' override landing points one by one (overrides are targeted by node name; renaming a node = silent disconnection)。
    • Runtime validation (Client can load, tasks can run through, overrides actually take effect) is beyond this skill—hand off to maafw-debug。

Modifying existing content

For rename-type operations, search all references across the entire repository before acting—the consequences of missing changes vary: missing changes to option key names in the reference implementation interface load failure(can be caught), the rest are mostly silent disconnections:

  • renaming pipeline node names:task.entry, task-level and option pipeline_override are all targeted by node name and must all be synchronized (for the rest of the reference list on the pipeline side see maafw-pipeline modification track).
  • Renaming option keys / case names: missing key name changes → reference implementation load failure; missing case name changes → preset preset value or default_case silently falls through. Reference scope: the four levels task / controller / resource / global_option,setting[].option、pretask[].option, and nested cases' option[]、preset[].task[].option。
  • Renaming controller / resource name: synchronize resource[].controller, task / pretask / option's controller[] and resource[] filter list—mismatch in the option applicability list will cause that option as a whole tosilently fail。
  • Newly added import files: first check the main file and existing split files for option keys with the same name—same name means the later imported file prevails, and the main file is overridden.

Review checklist

  • interface_version is 2; each task.entry is resolvable in the merged pipeline.
  • option reference keys exist and match character by character—task-level dangling references in the reference implementation directlyfail to load(not silent); invalid references in existing configurations are discarded after a warning.
  • option applies to the current controller / resource—when not applicable, the entire option (including nested sub-items)silently fails(v2.3.1; the number one cause of "the option didn't take effect" (empirical value), mechanism see references/options.md applicability filtering).
  • For multi-level references to the same option, deduce the final value according to override order (task > controller > resource > global, later overrides earlier); multiple checkbox cases merge in definition order.
  • path[] Every entry is a Bundle root directory (not pipeline/ subdirectory); import splits have no option keys with the same name (same name means the later import prevails, see silent pitfalls of splitting in references/options.md)。
  • languages the file exists and $ keys are fully covered; password has no default, does not enter preset, and there is no plaintext key in the full text.
  • The field versions used must be compatible with the PI support version of the target Client, and routing should be checked item by item—protocol inclusion ≠ schema / reference implementation / target Client already supports it; test in practice before release.

In-depth reading (as needed)

  • references/options.md — control selection criteria, declaration hierarchy and override order, applicability filtering (v2.3.1), minimal wiring examples, silent pitfalls of preset and import

Field-level details,PI_* variable tables and version changes are all routed to "ProjectInterface V2" and the official schema.