Skip to content

Configuration File

You can store all your MSLint configurations in a file called mslint.json. It is divided into two parts : some global parameters and an array of configuration objects for the linter.

json
{
  "cwd": "/absolute/path/to/working/directory",
  "patterns": [
    "path/to/directory/to/lint",
    "path/to/file/to/lint.Script.txt",
    "can/also/be/a/glog/pattern/**/*.Script.txt"
  ],
  "verbose": true,
  "displayStats": true,
  "reportUnusedDisableDirective": true,
  "reportDisableDirectiveWithoutDescription": true,
  "linter": [
    {
      "files": ["path/to/directory/to/lint/**/*.Script.txt"],
      "ignores": ["**/*.NoLint.Script.txt"],
      "msApiPath": "path/to/maniascript/doc.h",
      "rules": {
        "no-empty": "error"
      }
    }
  ]
}

Global configuration

  • cwd - An absolute path that will be used as the root for all relatives paths. If not specified, the folder where the mslint command is executed will be used instead.
  • patterns - An array of glob patterns listing the files to lint. If the command line also provide some patterns, they will be merged with the ones from the configuration files.
  • verbose - Displays information about the lint as it progresses.
  • displayStats - Displays lint statistics at the end.
  • reportUnusedDisableDirective - Report disable directive comments like // @mslint-disable-line if no errors would have been reported on that line anyway.
  • reportDisableDirectiveWithoutDescription - Report disable directive comments like // @mslint-disable-line if they don't have a description.

Linter configuration

The array of objects used to configure the linter is quite similar to the system used by ESLint. Configuration objects that appear later in the array override configuration objects that appear earlier in the array. You can compute a configuration for a given file by traversing all the configuration objects in the array to find the ones that match the filename. Matching is done by specifying glob patterns in files and ignores properties on each configuration object.

Configuration object

  • files - An array of glob patterns specifying the files to which the configuration object should apply. If not specified, the configuration object applies to all files matched by any other configuration object.
  • ignores - An array of glob patterns specifying the files to which the configuration object should not apply. If not specified, the configuration object applies to all files matched by files.
  • msApiPath - Path to a custom ManiaScript API header file.
  • rules - An object that contains the configured rules.

Specifying files and ignores

You can use a combination of files and ignores to determine which files the configuration object should apply to and which it should not.

By default MSLint matches **/*.Script.txt. So configuration objects that don't specify files or ignores will apply to all ManiaScript files passed to MSLint. For example:

json
{
  "linter": [
    {
      "rules": {
        "no-empty": "error"
      }
    }
  ]
}

In this case, the no-empty rule is enabled for all .Script.txt files. So if you pass Example.Script.txt to MSLint, the no-empty rule will be applied. If you pass a non-ManiaScript file, like Example.txt, the no-empty rule is not applied because there are no configuration objects that match that filename.

If you define files in your configuration object, then only files that match one of the patterns in the array will be affected by the msApiPath and rules defined in the object. For example, if you run mslint on the Scripts folder with this configuration:

json
{
  "linter": [
    {
      "files": ["Scripts/MyDir/**/*.Script.txt"],
      "msApiPath": "path/to/maniascript/doc.h",
      "rules": {
        "no-empty": "error"
      }
    }
  ]
}

Only the ManiaScript files in the Scripts/MyDir directory and its subdirectories will be linted with the path/to/maniascript/doc.h ManiaScript API file and the no-empty rule. All other files will be ignored.

If you want to do the same but ignore files ending with .NoLint.Script.txt, you can add ignores like this:

json
{
  "linter": [
    {
      "files": ["Scripts/MyDir/**/*.Script.txt"],
      "ignores": ["**/*.NoLint.Script.txt"],
      "rules": {
        "no-empty": "error"
      }
    }
  ]
}

If you define ignores without defining files, then the configuration object will be applied to all files except those specified in ignores. For example:

json
{
  "linter": [
    {
      "ignores": ["**/*.NoLint.Script.txt"],
      "rules": {
        "no-empty": "error"
      }
    }
  ]
}

This configuration object applies to all files (ManiaScript or not) except those ending in .NoLint.Script.txt. It is like setting files to **/*.

You can also ignore files globally by adding a configuration object that only defines ignores like this:

json
{
  "linter": [
    {
      "ignores": ["Actions/*"]
    }
  ]
}

This configuration specifies that all files in the Actions directory should be ignored. This glob pattern is added after the default patterns defined by MSLint, which are ["**/node_modules/", ".git/"].

Cascading configuration objects

If more than one configuration object matches a given filename, the configuration objects are merged, with later objects overriding earlier objects if there is a conflict. For example:

json
{
  "linter": [
    {
      "files": ["**/*.Script.txt"],
      "msApiPath": "path/to/maniascript/doc.h",
      "rules": {
        "no-empty": "error",
        "no-lonely-if": "error"
      }
    },
    {
      "files": ["Scripts/Modes/**/*.Script.txt"],
      "msApiPath": "path/to/another/maniascript/doc.h",
      "rules": {
        "no-lonely-if": "warn",
        "no-negated-condition": "error"
      }
    }
  ]
}

With this configuration, all ManiaScript files will be linted using the path/to/maniascript/doc.h API file, except those in the Scripts/Modes directory which will use path/to/another/maniascript/doc.h instead. For rules, all ManiaScript files will generate an error for the no-empty and no-lonely-if rules. But files in the Scripts/Modes folder will generate a warning instead of an error for the no-lonely-if rule and will apply the no-negated-condition rule in addition to the no-empty rule.

In practice, all ManiaScript files in the Scripts/Modes directory will use this configuration object:

json
{
  "msApiPath": "path/to/another/maniascript/doc.h",
  "rules": {
    "no-empty": "error",
    "no-lonely-if": "warn",
    "no-negated-condition": "error"
  }
}

While all the other ManiaScript files will use this configuration object:

json
{
  "msApiPath": "path/to/maniascript/doc.h",
  "rules": {
    "no-empty": "error",
    "no-lonely-if": "error"
  }
}

Configuring msApiPath

You can provide a custom ManiaScript API header file to the ManiaScript parser. It will be used to parse your scripts correctly (e.g. get access to all valid class names). You can generate a header file using the game executable and the /generatescriptdoc argument: Trackmania.exe /generatescriptdoc=doc.h.

Configuring rules

You can select the rules you want to apply to your scripts by defining a rules object in the configuration object. Each key in the object is the name of a rule, and the value is a configuration for that rule. For example:

json
{
  "linter": [
    {
      "rules": {
        "id-length": "error"
      }
    }
  ]
}

This configuration object enables the id-length rule with a severity of "error".

Rule severities

There are three severity levels you can use for a rule:

  • "error" - The reported problem should be treated as an error. When using the MSLint CLI, errors cause the command to exit with a non-zero code.
  • "warn" - The reported problem should be treated as a warning. When using the MSLint CLI, warnings are reported but do not change the exit code. If only warnings are reported, the exit code will be 0.
  • "off" - Disables the rule.

Rule options

In addition to the severity, you can also give the rules some options. To do this, use an array where the first value is the severity and the second value is a configuration object for the rule.

json
{
  "linter": [
    {
      "rules": {
        "id-length": ["error", { "minimum": 10 , "maximum": 100 }]
      }
    }
  ]
}

With this configuration the id-length rule is enabled, but will produce an error for variable names shorter than 10 characters or longer than 100 characters.

Rule Configuration

For more information about the available options, see the documentation for the rule you want to configure.

Cascading rule configuration

If more than one configuration object specifies the same rule, the rule configurations are merged, with the later ones taking precedence over the earlier ones.

json
{
  "linter": [
    {
      "rules": {
        "id-length": ["error", { "minimum": 10 , "maximum": 100 }]
      }
    },
    {
      "rules": {
        "id-length": ["warn", { "maximum": 50 }]
      }
    }
  ]
}

In this example, the final configuration for the id-length rule will be ["warn", { "maximum": 50 }]. You can change just the severity only by defining a string instead of an array:

json
{
  "linter": [
    {
      "rules": {
        "id-length": ["error", { "minimum": 10 , "maximum": 100 }]
      }
    },
    {
      "rules": {
        "id-length": "warn"
      }
    }
  ]
}

In this case the final configuration for id-length will be ["warn", { "minimum": 10 , "maximum": 100 }].

Using predefined configurations

MSLint provides two predefined configurations for the linter:

  • "mslint:recommended" - Enables the rules that MSLint recommends to avoid the most common problems in ManiaScript.
  • "mslint:all" - Enables all rules that ship with MSLint.

To use one of these predefined configurations, include it at the beginning of the "linter" array. Later configuration objects will allow you to further customize the configurations.

json
{
  "linter": [
		"mslint:recommended",
    {
      "rules": {
        "id-length": ["error", { "minimum": 10 , "maximum": 100 }]
      }
    }
  ]
}