VS Code extension providing syntax highlighting and IntelliSense for ModularMC — a Regolith filter for structured Minecraft Bedrock addon development.
Any JSON string value prefixed with :: is highlighted as TypeScript:
{
"identifier": "::`my_addon:${weapon.id}`",
"damage": "::weapon.damage",
"repair_items": "::weapon.repairList"
}Any block wrapped in {ts: :} in .lang or .txt files is highlighted as TypeScript:
item.name={ts: `${capitalize(id)}` :}
item.desc={ts: buildDescription(weapon) :}
When editing a file mapped by a _map.ts, pressing Ctrl+Space inside a ":: or {ts: region suggests variables from the scope defined for that entry.
Nested properties are fully supported — typing weapon. suggests all properties of the weapon object:
"damage": "::weapon.",
// ^ suggests: id, name, tier, damage, cooldown, durability ...The extension walks up the directory tree to find the nearest _map.ts that covers the current file, matches it against the source glob of each MAP entry, and extracts the scope statically. Spread operators like ...weapon are resolved using the first element of the source array as a representative shape.
Dynamic values (function calls like capitalize(weapon.name)) appear as <dynamic: capitalize(...)> — they still show as suggestions so you know the key exists.
Ctrl+Click on any scope variable inside a ":: or {ts: region jumps directly to where that key is defined in the _map.ts scope object.
"spell": "::weapon.spell"
// ^ Ctrl+Click → jumps to `spell` key in _map.ts scopeWorks for nested paths too — weapon.id navigates to the id key inside the weapon object.
Inside any _map.ts file, typing inside a MAP array entry object suggests all available fields. Fields already present in the entry are filtered out automatically:
| Field | Type | Description |
|---|---|---|
source |
string |
Source file path relative to module directory |
target |
string | object |
Target path — supports :auto and :autoFlat |
jsonTemplate |
boolean |
Enable :: TypeScript expressions in JSON strings |
textTemplate |
boolean |
Enable {ts: :} TypeScript expressions in text files |
onConflict |
string |
Conflict resolution strategy |
fileType |
string |
Override automatic file type detection |
scope |
object |
Variables available in templates for this entry |
The extension reads your auto-map.ts file and resolves what :auto and :autoFlat evaluate to for any given source file.
Hover over :auto or :autoFlat in a target field to see the resolved path:
{
source: "iron_sword.item.json",
target: ":autoFlat", // hover → BP/items/@team/@proj/iron_sword.item.json
}Inlay hints show the resolved path as ghost text directly on the line — no hover needed:
target: ":autoFlat", → BP/items/@team/@proj/iron_sword.item.jsonCompletion dropdown for target also shows the resolved path in the detail column before you commit.
Resolution uses first match wins — entries in AUTO_MAP are matched top to bottom, so more specific suffixes should appear above general ones. For example iron_sword.item.json matches .item.json before .json.
The difference between the two keywords:
:autoFlat— drops the file directly into the resolved directory, ignoring any subfolders in the source path:auto— preserves the subfolder structure relative to the module directory
Typing inside a target or onConflict string value surfaces all valid options:
target
:autoFlat— flatten matched files into their pack root:auto— automatically resolve target path
onConflict
stop— (default) stop and report an errorskip— skip this entry and continuemerge— deep merge files (JSON only)overwrite— overwrite the existing fileappendEnd— append to end of existing file (text only)appendStart— prepend to beginning of existing file (text only)
The extension also pre-selects the most likely value based on the source field in the same entry:
.langsource →appendEndpre-selecteditem_texture.json,terrain_texture.json,sound_definitions.json→mergepre-selected
The extension validates source values in _map.ts files and reports problems inline:
- Error — a specific (non-glob) source path that doesn't exist on disk
- Warning — a glob pattern that matches no files in the module folder
{
source: "items/sword.item.json", // ← red error if file doesn't exist
source: "**/*.missing.json", // ← yellow warning if no files match
}The following snippets are available in TypeScript files:
| Prefix | Inserts |
|---|---|
map |
export const MAP = [] |
scripts |
export const SCRIPTS = [] |
mapscripts |
Both MAP and SCRIPTS exports |
mapentry |
MAP entry with template and scope |
mapentrysimple |
MAP entry with source and target only |
mapentryconflict |
MAP entry with onConflict |
mapentryfull |
MAP entry with all fields |
onConflict |
onConflict field with value picker |
fileType |
fileType field with value picker |
- VS Code
^1.100.0 - ModularMC Regolith filter
- A
.langlanguage extension (e.g. Blockception's Minecraft Bedrock Development) for.langfile highlighting - An
auto-map.tsfile in the ModularMC root for:auto/:autoFlatresolution
Given a _map.ts like:
export const weapons = [
{ name: "iron_sword", tier: 1, damage: 5, durability: 200 },
{ name: "gold_sword", tier: 2, damage: 7, durability: 100 },
];
export const MAP = [
...weapons.map((weapon) => ({
source: "items/weapon.item.json",
target: `BP/items/${weapon.name}.item.json`,
jsonTemplate: true,
scope: {
weapon: {
...weapon,
id: `my_addon:${weapon.name}`,
displayName: capitalize(weapon.name),
},
},
})),
];When editing items/weapon.item.json, the extension:
- Walks up the directory tree to find the nearest
_map.tsthat covers this file - Matches
items/weapon.item.jsonagainst each entry'ssourceglob - Finds the matching
.map()call and extracts the arrow function body - Resolves
...weaponusing the first element ofweaponsas a representative shape - Evaluates template literals like
`my_addon:${weapon.name}`using those values - Offers the resulting scope as completions inside
"::and{ts:regions
- Scope resolution is static best-effort — complex runtime expressions cannot be fully evaluated
- The JSON
"::syntax only highlights single-line expressions — multiline TS inside a JSON string is not supported by the TextMate grammar engine - Scope completions require the file to be reachable from a
_map.tsvia the source glob :auto/:autoFlatresolution requires anauto-map.tsin a parent directory —@team,@proj, and@namespaceplaceholders are shown as-is since they are runtime values- Diagnostics only check static (non-glob
.map()) entries — dynamic entries using array.map()are skipped
MIT — Pixelmancer