TrigEdit is the Text Trigger Editor for scmJS, the StarCraft and Brood War map editor that runs in the browser. It shows the map's triggers as text in the syntax of SCMDraft 2's TrigEdit. Text from SCMDraft pastes in, and text from here pastes back into SCMDraft.
The text format itself belongs to the editor, and Triggers ▸ Import Triggers… and Export Triggers… read and write the same text. This plugin is the editing window around it.
TrigEdit comes with scmJS but starts off. Open Plugins ▸ Manage Plugins…, find TrigEdit (marked default) and tick it on.
If it is not in the list, paste
https://github.com/scm-js/plugin-trigedit
and press Add. To pin a version, add a tag: github:scm-js/plugin-trigedit@v1.1.0.
Open a map and choose Triggers ▸ Text Trigger Editor… (Ctrl+Shift+T).
- Compile parses the text and replaces the map's triggers with the result. If a line does not parse, the map is not changed. The line is marked in the gutter and the message shows under the text. Apply does the same and keeps the window open. Compile & Close closes the window once the text has compiled.
- Format parses the text and prints it again in the standard layout.
- Reload discards the text and reads the map again.
- Triggers and Briefing switch between the map's triggers (TRIG) and the mission briefing (MBRF), which uses the same syntax with the briefing actions. Switching reads the map again, so compile first.
- Word wrap wraps long lines.
The text follows SCMDraft 2's TrigEdit:
- Each trigger is a
Trigger("Player 1", "Player 2"){ … }block withConditions:andActions:sections. - A leading
;disables a line. - A
Flags:block holds the trigger flags that SCMDraft has no syntax for. - Units, locations, switches and strings are written by their names in the open map. A name the map does not know prints as a number and parses back.
The scmJS guide has a section on the Text Trigger Editor, and the trigger reference gives the text line for every condition and action.
Some plugins build triggers from something else. TrigScript, for example, builds a block of triggers from its script. Such a plugin tells the editor which triggers in the list are its own, and TrigEdit fences them in comments:
//== Generated by <plugin>: 12 triggers. Edit them there instead — changes here take them out of its hands. ==//
…
//== End of the generated run ==//
The parser treats the fence as a comment, so the text compiles back to the same list, generated triggers included. You can edit inside the fence, but the plugin's next build replaces those triggers.
- The
trigedit.opencommand opens the editor.api.commands.run("trigedit.open", { briefing: true })opens it on the briefing. - The dialog has a
trigedit.textslot.api.ui.dialogSlot("trigedit.text", { mount })adds a row at the left of the footer.host.fields.textis the editor's text as the user sees it, andhost.payload.briefingsays which list is shown. The scmjs.dev plugin adds its Explain, Write… and Ask buttons this way.
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 holds the logic with no UI (the fencing, the error line,
the status line) and has the tests. The plugin uses:
api.triggers.textto print and parseapi.triggers.claimsfor the generated triggerstx.triggers.fromTextandtx.briefing.fromText, inside onedocument.update
The UI is plain DOM using the editor's 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 matches what the source builds.
MIT.