A plugin for scmJS, the browser-based StarCraft 1 / Brood War map editor. It is the Text Trigger Editor: the map's triggers as text, in the syntax of SCMDraft 2's TrigEdit, so text from SCMDraft pastes in and text from here pastes back out.
The format itself — the printer and the parser — belongs to the editor, and File ▸ Import Triggers / Export Triggers read and write the same text. This plugin is the editor around it: a Triggers / Briefing switch, Compile, Format and Reload, word wrap, a gutter that marks the line that did not parse, and a comment fence around every run of triggers another plugin generates, so you can see which rows a rebuild will replace.
In scmJS: Plugins ▸ Manage Plugins…, paste
https://github.com/scm-js/plugin-trigedit
and press Add. It is normally already in that list, marked default; tick it on if it
is off. To pin a version, add a ref: github:scm-js/plugin-trigedit@v1.0.0.
Triggers ▸ Text Trigger Editor…, or Ctrl+Shift+T, with a map open.
- Compile parses the text and puts the result into the map, replacing the list. The map is untouched when a line does not parse: the line is marked in the gutter and the message is under the editor. Apply is the same without closing; Compile & Close closes when it compiled.
- Format parses and prints the text again, in the printer's own layout.
- Reload throws the text away and reads the map again.
- Triggers / Briefing switches between the map's triggers (TRIG) and the mission briefing (MBRF), which uses the same syntax with the briefing action set. Switching re-reads the map, so compile first.
- Word wrap wraps long lines instead of scrolling sideways.
The text follows SCMDraft 2's TrigEdit: one Trigger("Player 1", "Player 2"){ … } block
per trigger with Conditions: and Actions: sections, a leading ; disabling a line, and
a Flags: block for the trigger flags SCMDraft has no syntax for. Names are the map's own
— units, locations, switches and strings resolve against the open map — and a name the
map does not know prints as a bare number and parses back. The editor's guide has a
section on the syntax.
A plugin that builds triggers from something else — TrigScript builds a block from its script — tells the editor which run of the list is its. This editor fences that run in comments:
//== Generated by the trigger script: 12 triggers. Edit them there instead — changes here take them out of its hands. ==//
The fence is a comment to the parser, so the text compiles back to the same list, generated triggers included. Editing inside the fence works, but the next build of the script will replace the whole run.
- The
trigedit.opencommand opens the editor:api.commands.run("trigedit.open", { briefing: true })for the briefing. - The dialog offers the
trigedit.textslot.api.ui.dialogSlot("trigedit.text", { mount })puts a row at the left of the footer;host.fields.textis the editor's text as the person sees it, andhost.payload.briefingsays which list is shown. This is how the scmjs.dev plugin adds its Explain, Write… and Ask buttons.
npm install
npm run typecheck # tsc over plugin.ts and text.ts
npm test # vitest: the fencing and the words
npm run build # esbuild → dist/plugin.js, the bundle the editor loadsplugin.ts is the dialog; text.ts is the pure half (the fencing, the error line, the
status line) and has the tests. The editor is reached through api.triggers.text (print
and parse), api.triggers.claims (the generated runs) and tx.triggers.fromText /
tx.briefing.fromText inside one document.update. Plain DOM in the editor's own widget
classes, plus a scoped stylesheet.
CI type-checks, tests and rebuilds dist/plugin.js on every push to main; at a v* tag
it checks that the committed bundle is what the source builds to.
MIT.