Chapter 4. Creating new Minuet's exercises

Minuet's exercises are defined in JSON specification files. The app loads all available files at startup and merges them into the visible exercise tree.

{
  "exercises": [
    {
      "name": "Intervals",
      "root": "29..69",
      "playMode": "scale",
      "userMessage": "Hear the interval and choose your answer",
      "numberOfSelectedOptions": 1,
      "_icon": "minuet-intervals-symbolic.svg",
      "children": [
        {
          "name": "Ascending melodic intervals",
          "and-tags": ["interval", "ascending"],
          "children": [
            {
              "name": "Seconds",
              "or-tags": ["2"],
              "description": "Practice identifying ascending melodic seconds by ear."
            }
          ]
        }
      ]
    }
  ]
}

The top-level object contains an exercises array. Each item in that array is either a category or an exercise leaf. Categories use children to define the next level of the tree.

Useful fields include:

  • name gives every node its visible label.

  • root limits the note range used to generate the prompt.

  • playMode selects scale, chord, or rhythm playback.

  • userMessage customizes the instruction shown to the user.

  • numberOfSelectedOptions controls how many answers may be correct.

  • _icon sets the icon shown in the drawer and exercise browser.

  • and-tags and or-tags help group and filter related nodes.

  • description gives the browser a short explanation for the node.

  • options describes answer choices for a leaf exercise.

  • sequenceFromRoot defines the note offsets for melodic answers.

  • template is used by rhythm exercises to render notation.

The app merges files that share the same category names, so separate specification files can contribute to one visible hierarchy. Install them system-wide or place them in minuet/exercises/ under the generic data location returned by qtpaths --paths GenericDataLocation.