Language support for Minecraft Metascript (.mms) files, and for the book (.mmsbook, where --- starts a page) and chat text (.mmstext) files a TextFile(...) reads.
- Diagnostics for errors, lint findings and every raw command, checked against the Minecraft command tree.
- Editing help:
- completion, hover and signature help
- go to definition, find references and rename; go to definition on a built-in Template, Blueprint or Type opens the prelude, and on a vanilla id (a noise, density function, loot table, tag and so on) opens vanilla's own JSON file, both read-only
- Fixes:
- quick fixes
- "Fix all" (
source.fixAll.mms)
- "Extract to a declaration" for inline values (
refactor.extract), which then opens the rename box on the new name
- Expand: an Expand lens above each Blueprint instance (such as a CustomItem) and each Commands Template call, and MMS: Expand at Cursor, show the code it writes in a read-only document beside the source.
- Tests: the project's
Test declarations are in VS Code's Testing view. They run in the same interpreter as mms test, and a failing expect is reported at its line.
- Formatting with the opinionated formatter (format on save is on by default for
.mms).
- Semantic highlighting.
- Previews: click Preview above a noise, density function, noise settings, surface rule or dimension to see it rendered beside the editor (density, blocks, 3D, biome map; Top turns a side slice into a view straight down from the camera), or above a loot table, recipe or biome to inspect it. A Book previews as its pages (each page of a
.mmsbook file has a lens that opens the book there), a chat text as the message, and a template pool as the pieces it draws from. Above a jigsaw structure it shows which pools join which, or (Simulation) one layout grown the way the game does, in 3D, with a layout seed and a slice to see inside. The panel stays on that declaration while you edit elsewhere and redraws as you type; click another Preview to switch. MMS: Open Preview to the Side (the button in the editor title, or Ctrl+K V) opens it on the declaration at the cursor. Vanilla worldgen the pack refers to is fetched from GitHub (mcmeta).
- Build into a world: the MMS icon in the activity bar opens a side bar. In World, choose a Minecraft world (worlds from the Minecraft launcher's, Prism Launcher's and MultiMC's saves folders are listed, most recently played first, or browse to any world folder) and click Build into world. It saves the project's files and runs
mms build --world: the data pack goes to <world>/datapacks/<namespace> and the resource pack, if there is one, is merged into <world>/resourcepacks/resources.zip, keeping the files other projects built into the same world. The result stays in the view under the button, with what to do in the game next, worked out from what changed: run /reload when only functions, loot tables, recipes, advancements and similar changed (with a Copy /reload button), or exit and rejoin the world when worldgen, dimensions, other registry entries or the resource pack changed. There are no pop-up notifications while the view is open; the status bar says it briefly, and a failed build only pops up a notification when the side bar is closed. Each project remembers its world. Tick Build on save (the mms.buildOnSave setting) to build on every save, and mms.savesFolders to list worlds from other launchers. For worldgen work, tick Reset changed dimensions: each build then deletes the saved chunks of the project's dimensions whose worldgen changed (mms build --reset-dimensions), so they generate again with the new terrain when you go there. The Dimensions list under it has Reset terrain… in each dimension's ⋯ menu to reset one whatever changed. Leave the world first; a build that has a dimension to reset while Minecraft has the world open writes nothing and says so. The overworld, nether and end are only reset from the menu, and the old chunks are kept in the world's mms-reset folder until the next reset.
- Structures from the world: the Structures view lists what structure blocks saved in it (
<world>/generated/<namespace>/structure), each marked new, imported or changed in world, with buttons to import it (or Import N for all the new and changed ones), copy the call that adds it to a pool, such as Piece("tower/base") for structures/tower/base.nbt (or StructureFile(...) for a file elsewhere), and show the project copy. Imports go to the project's structures folder (mms.structuresFolder). A structure that is imported but that no StructureFile(...) call uses (the unused-asset lint) is marked Not used in yellow, with the call to add to a template pool; unused .nbt files in the project that this world did not save are listed too. After you save a piece again in the game it shows as changed; import it again to update it. Delete from world removes a save from the world (after asking, to the trash where possible), for a piece saved under the wrong name; the project's imported copy stays. With many structures the list is grouped into folders by the / in their ids, like the folders they are saved in (village/houses/small and village/houses/big go under village/houses, village/well under village); a folder is only made where two or more share it, each folder has its own Import N button, and folders open by themselves only when they hold something new, changed or not used. Only the list is grouped: files and ids keep their names. This makes building jigsaw pieces in game and wiring them up in MMS a loop.
- A separate world for structures: structures come from the build world unless you pick another one with Use a separate world… in Structures (or MMS: Choose World to Import Structures From). Build pieces in a creative world and build the pack into a test world: builds never write to the structure world, and it can stay open while you leave and rejoin the test world. Use the build world instead goes back to one world, as does picking the structure world as the build world. Each project remembers both worlds.
- Pack explorer: Pack in the same side bar lists the files the project generates, as the web editor's Pack tab does: the data pack, the resource pack and the custom items. Click a file to read it (it follows your edits); the buttons beside a file open its preview or go to the declaration that wrote it.
- Jigsaw blocks: Jigsaw in the same side bar sets up a jigsaw block and copies a
/give command for it, so jigsaw blocks in pieces built in the game get the right ids without typing them into the jigsaw screen. The fields are the game's: Label (the item's name in the hotbar, optional), Target pool (the project's template pools), Target hole (the jigsaw names the chosen pool's pieces have come first), Name, Replace with (the block it turns into) and Alignment (rollable or aligned, which matters for blocks facing up or down). The name lists are the project's JigsawHole declarations, plus names the pieces use that are not declared; a name or target that is not declared says so, with Declare it, which adds JigsawHole <name> next to the others. Paste the command in the game in creative mode, as an operator; the block faces the way you place it. Copied blocks are kept under Recent, and In structures lists the jigsaw blocks of the pack's structure files, by piece. Click a row to load it into the form, or use its copy icon to copy its command straight away.
mms.json support: completion, hover docs and validation for the project file, including every lint rule id and severity. This works without the language server.
Setup
Install Minecraft Metascript (minecraftmetascript.mms) from the VS Code Marketplace, or from Open VSX in Cursor, VSCodium and other editors. VS Code updates it for you. Every change merged to main is published as a pre-release: click Switch to Pre-Release Version on the extension's page to get those.
The extension runs the mms language server. The stores serve a platform-specific build that includes mms, so there is nothing else to install. They exist for Windows, macOS and Linux (including Alpine), on x64 and arm64. The same builds (mms-<platform>-<version>.vsix, such as mms-darwin-arm64-1.0.0.vsix) are on the releases page.
The extension uses the first of:
mms.path, if you set it. ~ and ${workspaceFolder} work in it.
- The
mms bundled with the extension.
mms on your PATH, then ~/go/bin (where go install puts it, which VS Code launched from the macOS Dock may not have on its PATH).
The universal mms-<version>.vsix has no mms in it and uses the PATH; download mms for your platform from the same release. To run a local build of the language server, run go build ./cmd/mms in engine/ and set mms.path to the full path of the binary, such as /Users/you/mms/engine/mms. The World view's builds use the same mms.
The extension starts when a folder contains an mms.json or when you open a .mms file. If the server cannot start, a notification says why; fix it and run MMS: Restart Language Server (also use it after updating mms). MMS: Show Language Server Output shows the server log.
Building
The preview panel uses the same Svelte components as the web editor, from packages/preview. All three are one npm workspace: run npm ci in the repository root. npm run build bundles the extension (esbuild), the panel (Vite, into out/webview) the World and Structures views' page (webview/World.svelte, into out/world) and the Jigsaw view's page (webview/Jigsaw.svelte, into out/jigsaw). Those two pages wrap WorldTool and JigsawTool from packages/preview, which the web editor's World and Jigsaw tabs show too.
npm run package makes the universal .vsix, without mms. npm run package:targets makes one .vsix per VS Code platform with mms cross-compiled into bin/ (it needs Go); pass targets to make only some, such as npm run package:targets -- linux-x64 darwin-arm64. MMS_VERSION sets the version mms version prints. Flags such as --pre-release go on to vsce package.
Publishing
.github/workflows/release.yml publishes to the VS Code Marketplace (publisher minecraftmetascript) and Open VSX (namespace minecraftmetascript) with trusted publishing: both stores trust that workflow file in this repository, so there are no tokens. A v* tag publishes that version. Each push to main that changes the extension or the engine publishes a pre-release one minor version ahead of the latest tag, with the workflow's run number as the patch: after v0.5.0 they are 0.6. (scripts/version.mjs). A pre-release is always newer than the release before it.
Credits
Previews are rendered with Deepslate by Misode, and read vanilla worldgen from Misode's mcmeta. The license notices of everything the extension bundles are in out/third-party-licenses.txt, written by npm run build.
License
Same as the MMS repository.
| |