Maplint (Map Validation)
Relevant source files
The following files were used as context for generating this wiki page:
Maplint is a Python-based tool designed to prohibit anti-patterns in map files (.dmm) through the enforcement of structured rules. It allows developers to ban specific typepaths, variable edits, or problematic combinations of objects on the same tile. By automating these checks, Maplint ensures map consistency and prevents common mapping errors before they are merged into the repository.
The system operates alongside other mapping utilities such as Map Merger and automated CI scripts that use grep to verify TGM formatting and common spelling mistakes.
Sources: tools/maplint/README.md:3-5, tools/ci/check_grep.sh:42-50
Execution Flow
The Maplint entry point loads lint definitions from YAML files and processes DMM map files. It parses the map structure, iterates through defined lints, and reports any MaplintError encountered during validation.
The diagram shows the high-level process of loading rules and executing them against parsed map data.
Sources: tools/maplint/source/main.py:47-106, tools/maplint/source/lint.py:353-370
Validation Rules
Maplint uses a hierarchy of rules defined in the Rules class. These rules are applied to specific typepaths or subtypes.
Rule Types and Definitions
| Rule Name | Description | Configuration Example |
|---|---|---|
banned | Prohibits a specific typepath or its subtypes entirely. | banned: true |
banned_neighbors | Prevents specific objects from existing on the same tile. | - /obj/item/cat_food |
required_neighbors | Ensures an object is accompanied by another specific type. | - /obj/dogbed |
banned_variables | Restricts or validates variable edits on a type. | allow: ["corgi"] |
ignore | Excludes specific subtypes from triggering neighbor rules. | ignore: [/obj/sign] |
skip_files | Prevents a rule from running on specific map paths. | - _maps/templates |
Sources: tools/maplint/README.md:16-118, tools/maplint/source/lint.py:270-344
Target Matching
Rules match typepaths based on three primary methods:
- Subtype Match: Matches the path and all its children (default).
- Exact Match: Matches only the specific path if prefixed with
=. - Wildcard: Matches all types if defined with
*.
Sources: tools/maplint/README.md:10-24, tools/maplint/source/lint.py:24-40
Conditional Logic (When Clause)
The When system allows rules to be applied only if certain conditions are met. This is managed by the ConditionalRule, WhenCondition, and WhenGroup classes.
The class hierarchy illustrates how individual conditions can be grouped using AND (all) or OR (any) logic.
Sources: tools/maplint/source/lint.py:149-234
Supported Conditions
- Variable State:
{var} is setor{var} is not set. - Value Equality:
{var} is '{value}'or{var} is not '{value}'. - Regex Matching:
{var} like '{regex}'.
Sources: tools/maplint/README.md:129-138, tools/maplint/source/lint.py:164-175
Neighbor and Variable Validation
The AtomNeighbor and BannedVariable classes implement the core logic for tile-occupancy and variable-edit checks.
Neighbor Matching
The AtomNeighbor class determines if a neighbor triggers a rule violation. It supports matching via:
- Path Comparison: Checking if the neighbor is a subtype or exact match.
- Identicality: Using
identical: trueto match only if the path and variable edits are exactly the same. - Regex Patterns: Matching the neighbor's path against a regular expression.
Sources: tools/maplint/source/lint.py:42-88, tools/maplint/README.md:46-60
Variable Restrictions
The BannedVariable class evaluates allow and deny lists for variable values. If a variable is edited in a DMM file, Maplint checks the value against these constraints.
# tools/maplint/source/lint.py:126-147
def run(self, identified: Content) -> str:
if identified.var_edits[self.variable] is None:
return None
if self.allow is not None:
if isinstance(self.allow, list):
if identified.var_edits[self.variable] not in self.allow:
return f"Must be one of {', '.join(map(str, self.allow))}"
elif not self.allow.match(str(identified.var_edits[self.variable])):
return f"Must match {self.allow.pattern}"
Sources: tools/maplint/source/lint.py:126-147, tools/maplint/README.md:73-95
Auxiliary Map Checks
In addition to the Python Maplint tool, the project utilizes shell-based grep checks (check_grep.sh) to catch errors that do not require full DMM parsing:
- TGM Formatting: Ensures maps are saved in the TGM format using Map Merger.
- Spelling: Scans for common typos like "nanotransen" or "centcomm".
- Invalid Procs: Blocks the use of unsupported procs (e.g.,
new,sound,matrix) in map variables. - Comment Sanitization: Removes unexpected comments in map files.
Sources: tools/ci/check_grep.sh:42-84, tools/mapmerge2/README.md:25-33
Summary
Maplint provides a robust framework for maintaining map quality in the BandaStation project. By defining YAML-based rules, developers can enforce complex constraints on object placement and variable configuration. This system, combined with Map Merger and CI grep checks, forms a comprehensive validation pipeline for all map contributions.
Sources: tools/maplint/README.md:3-7, tools/ci/check_grep.sh:305-315