scmJS docs

api.document

DocumentApi

The open map: what it says, and the three ways of writing to it — edit (terrain and objects, one undo entry), update (the tables every dialog's OK writes) and sections (raw bytes). Opening, saving, exporting and closing are here too.

Members

isOpen

isOpen(): boolean;

info

info(): DocumentInfo | null;

scenario

scenario(): Scenario | null;

The live scenario, for reading. Writing to it directly bypasses undo, dirty tracking and repaints — use edit.

edit

edit<R>(label: string, build: (tx: EditTransaction) => Sync<R>): EditResult;

Run build against a transaction and record what it did as one undo entry. Operations apply as they are called, so later ones see earlier ones' results. Returns an all-zero result with changed: false when no map is open.

build is synchronous — see Sync. Await what you need (graphics, a pick, a fetch) before the call, then write in one go.

// One undo entry called "Fill", however many operations it takes.
const result = api.document.edit("Fill", (tx) => {
  tx.stampTerrain({ x0: 0, y0: 0, x1: 8, y1: 8 }, terrainId);
  tx.placeUnit(api.consts.unit.startLocation, 0, 4 * api.consts.tile, 4 * api.consts.tile);
});
api.ui.status(`${result.tiles} tiles, ${result.units} units`);

update

update<R>(label: string, build: (tx: UpdateTransaction) => Sync<R>): UpdateResult;

The second kind of write: the tables and settings that live outside the undo model — triggers, the string table, switch names, the scenario's own properties — as one transaction, the way a settings dialog's OK applies its whole form at once. Operations apply as they are called; the commit marks the map modified and bumps what the chrome reads. There is no undo entry: keep your own if you need one. build is synchronous, as edit's is.

api.document.update("Rename", (tx) => {
  tx.properties({ name: "Lost Temple", description: "Four players." });
});

undo

undo(): string | null;

redo

redo(): string | null;

history

history(): DocumentHistory;

The undo and redo stacks' tops — the labels the Edit menu shows — and their depths, without moving anything.

open

open(file: File | Blob | Uint8Array, fileName?: string): Promise<boolean>;

Open a map file (.scx / .scm / .chk) in place of the current one, the way File ▸ Open does: when the open map has unsaved changes and Preferences say to ask, the Close Scenario dialog comes first and the user may cancel. Resolves true once the file is the open document, false when the user kept the current map or the file could not be read (the status bar says why).

create

create(options: NewDocumentOptions): Promise<boolean>;

A blank map in place of the current one, the way File ▸ New makes one: flat ground of the tileset's default terrain (or terrainId), an ISOM lattice to match, every section a fresh map needs. Goes through the same unsaved-changes gate as open. Resolves true once the new map is the open document, false when the user kept the current one.

export

export(options?: ExportOptions): Promise<File | null>;

The open map as a file, as Save would write it — the remembered save options, the archive extras included — unless saveOptions says otherwise. Null when no map is open.

save

save(options?: SaveDocumentOptions): Promise<boolean>;

File ▸ Save: write the map back where it came from with the options last confirmed for it — into the file when the browser gave a handle, else through the browser's save dialog or as a download; a map with no file yet goes through the Save dialog. Resolves true once written, false when the user dismissed a dialog or the write failed (the status bar and a toast say so).

saveAs

saveAs(options?: SaveDocumentOptions): Promise<boolean>;

File ▸ Save As (or Save Copy As with copy): the Save dialog, resolving as save does.

close

close(): Promise<boolean>;

File ▸ Close: through the same unsaved-changes gate as open. Resolves true once the map is closed (isOpen() is then false), false when the user kept it.

renderImage

renderImage(options?: Partial<MapImageOptions>): Promise<Blob | null>;

A picture of the map as File ▸ Export ▸ Image draws it, as a PNG. pixelsPerTile is the one dial (32 is the game's art 1:1, 1 is a minimap); the other options default as the dialog's do. Needs the tileset graphics — without them, or without a map, null.

resize

resize(options: ResizeDocumentOptions): ResizeResult | null;

Scenario ▸ Resize / Crop Map: a transaction outside the undo model that drops both history stacks (as the dialog does). Content keeps its place relative to anchor (a 3 × 3 grid, row-major, 4 = centre, the default); the new ground is terrainId (the tileset's default when omitted); objects outside the new bounds are dropped, locations clamped unless clampLocations is false. Null with no map.

changeTileset

changeTileset(options: ChangeTilesetOptions): Promise<ChangeTilesetResult | null>;

Scenario ▸ Map Properties ▸ Tileset: change ERA and lay the terrain again with the new tileset's terrain (tile numbers do not carry across tilesets; the doodads go with them, everything else stays). Waits for the new graphics so the fill uses real tiles. Like resize, a transaction outside the undo model. Null with no map.

extras

readonly extras: ExtrasApi;

sections

readonly sections: SectionsApi;

Types

Declarations only this group names.

CombineModetype

type CombineMode = 
/** Zeroed fixed buffer, each occurrence copied over the front in file order. */
"overlay"
/** Every occurrence's records are kept, in file order. */
 | "append"
/** Only the last occurrence is used. */
 | "last"
/** Only the first occurrence is used. */
 | "first";

How the game combines repeated occurrences of a section. Which mode applies is a per-section fact (see sections/registry.ts), not something the container can infer.

TerrainPicktype

type TerrainPick = {
	kind: "terrain";
	id: number;
	variation?: number;
} | {
	kind: "tile";
	id: number;
};

What Replace Terrain matches or writes: a flat terrain type (by ISOM id) or one exact tile.

Boundsinterface

interface Bounds
left: number
top: number
right: number
bottom: number

LocationPatchinterface

interface LocationPatch
name?: string
left?: number
top?: number
right?: number
bottom?: number
elevationFlags?: number

SectionKnowledgeinterface

interface SectionKnowledge

What the registry knows about a section name, sized for one map.

name: string
what: string

"Placed units", "String table", …

mode: CombineMode

How the game combines repeated occurrences.

size: number | null

The fixed buffer the game reads the section into, for this map's size; null when the length varies.

stride: number | null

The record length of a list section, or null.

modelled: boolean

Whether the editor decodes the section into its model and re-encodes it on save.

SectionInfointerface

interface SectionInfo

One occurrence of a section in the file, as Save would write it.

index: number

Position in the file's section list — what the byte-level calls take.

name: string

The four characters as stored ("VER " keeps its space); junk in a protected map.

offset: number

Byte offset of the eight-byte chunk header within the CHK.

size: number

Payload length.

declaredSize: number

The length field as written; differs from size only when the file ended early.

truncated: boolean
occurrence: number

Which occurrence of this name it is, 0-based, and how many the file has.

occurrences: number
dirty: boolean

Whether the editor has unsaved changes it will encode into this section on save.

spec: SectionKnowledge | null

The registry entry, or null for a section the editor has never heard of.

RebuildResultinterface

interface RebuildResult

What rebuildSections did: the parser's remarks and the sections actually re-encoded.

warnings: string[]
rebuilt: string[]

PlayerPatchinterface

interface PlayerPatch
type?: number
race?: number
color?: number

COLR index 0–15 (playable slots).

rgb?: [ number, number, number ] | null

A CRGB custom colour, or null to go back to the palette colour (playable slots).

force?: number

0-based force (playable slots).

ForcePatchinterface

interface ForcePatch
name?: string
allied?: boolean
alliedVictory?: boolean
sharedVision?: boolean
randomStart?: boolean
flags?: number

The whole flag word, applied before the booleans.

players?: number[]

0-based playable slots the force should contain (others keep theirs); moves them from their forces.

UnitTypePatchinterface

interface UnitTypePatch
useDefault?: boolean

Explicitly back to (or off) the dat defaults; setting any number below turns it off.

name?: string

Custom name; "" restores the default.

hitPoints?: number
shields?: number
armor?: number
buildTime?: number
mineralCost?: number
gasCost?: number
weapons?: { id: number; damage?: number; bonus?: number; }[]
available?: { player: number | "default"; value: boolean | "default"; }[]

PUNI: player 0-based or "default" (the default column); value true / false, or "default" to follow the default column again.

UpgradePatchinterface

interface UpgradePatch
useDefault?: boolean
mineralCost?: number
mineralFactor?: number
gasCost?: number
gasFactor?: number
timeCost?: number
timeFactor?: number
levels?: { player: number | "default"; start?: number; max?: number; useDefault?: boolean; }[]

player 0-based or "default"; useDefault: true puts a player back on the default column.

TechPatchinterface

interface TechPatch
useDefault?: boolean
mineralCost?: number
gasCost?: number
researchTime?: number
energyCost?: number
state?: { player: number | "default"; available?: boolean; researched?: boolean; useDefault?: boolean; }[]

player 0-based or "default"; useDefault: true puts a player back on the default column.

ResizeResultinterface

interface ResizeResult
dx: number
dy: number
unitsDropped: number
spritesDropped: number
doodadsDropped: number
locationsClamped: number
isomRebuilt: boolean

True when ISOM was reconstructed from the tiles; false when it is the flat fill's lattice.

CuwpSlotPatchinterface

interface CuwpSlotPatch

A slot patch the way the dialog and the plugin API both apply one: only the named fields move.

hitPointsPercent?: number | null

null leaves the field at the unit's default (clears its valid bit); a number sets it and the bit.

shieldsPercent?: number | null
energyPercent?: number | null
resources?: number | null
hangar?: number | null
cloaked?: boolean | null

null leaves the state alone; a boolean forces it.

burrowed?: boolean | null
inTransit?: boolean | null
hallucinated?: boolean | null
invincible?: boolean | null

ArchiveCompressiontype

type ArchiveCompression = "none" | "zlib" | "pkware";

How the members of a map archive are compressed.

MapFormattype

type MapFormat = "scx" | "scm" | "chk";

SaveOptionsinterface

interface SaveOptions
format: MapFormat
compression: ArchiveCompression

How every archive member is compressed; ignored for a bare .chk.

encrypt: boolean

Encrypt the members as StarEdit does. Every StarCraft build reads it.

omitExtras: string[]

Archive members left out of the file, by name.

stripTerrainEditing: boolean

Leave out ISOM, TILE and DD2: the terrain-editing data the game never reads.

stripBookkeeping: boolean

Leave out IVER, IVE2, IOWN, UPUS, SWNM and WAV: editor bookkeeping the game never reads.

stripUnknown: boolean

Leave out sections whose names the format reference does not know.

mergeRepeats: boolean

Collapse a section that occurs more than once into the bytes the game would act on.

dropTrailing: boolean

Drop bytes after the last section header the file could parse.

ChangeTilesetResultinterface

interface ChangeTilesetResult
from: number
to: number
doodadsDropped: number
spritesDropped: number

Overlay sprites that belonged to the dropped doodads.

refilled: boolean

StartLayouttype

type StartLayout = "ring" | "corners";

StartPlacementResultinterface

interface StartPlacementResult
changes: UnitChange[]
placed: ({ x: number; y: number; } | null)[]

Per player (0-based), where the start location landed, or null when nothing within reach fit.

removed: number

Synctype

type Sync<T> = T extends PromiseLike<unknown> ? "a transaction builder must be synchronous: await before document.edit() / update(), not inside it" : T;

A transaction builder's return type: whatever it likes, so long as it is not a promise.

Everything asynchronous in this API is a promise — await it. The two transaction builders (document.edit and document.update) are the exception, and deliberately so: their operations apply as they are called and one commit closes the transaction when the builder returns, so an async builder would commit the part of its work that ran before the first await and leave the rest to land outside the entry, breaking undo without an error. Do the awaiting before the call:

await api.tileset.load();                       // the async part, first
api.document.edit("Fill", tx => tx.stampTerrain(rect, id));  // then the write

TypeScript refuses an async builder because of this type; runTransaction and runUpdate also catch one at runtime, for a plugin written in plain JavaScript.

DocumentInfointerface

interface DocumentInfo
name: string
description: string
width: number
height: number
tileset: TilesetId
era: number

ERA as stored (the tileset is era & 7).

version: number

CHK VER: 59 original, 63 hybrid, 205 Brood War, 206 Remastered.

fileName: string | null
modified: boolean

EditResultinterface

interface EditResult

What one document.edit changed, per list.

changed: boolean
tiles: number
isom: number
units: number
sprites: number
doodads: number
locations: number
fog: number
notes: string[]

MapFileFormattype

type MapFileFormat = "scx" | "scm" | "chk";

ExportOptionsinterface

interface ExportOptions
format?: MapFileFormat

The container: the open file's (else scx) — scx / scm archives, chk the bare scenario.

fileName?: string

The file's name; defaults to the open file's, or the scenario name plus the format.

saveOptions?: Partial<Omit<SaveOptions, "format">>

Compression, encryption and what is left out: over the options Save last used for this map (or its defaults — PKWARE and encryption for a new map, the way it was opened for an opened one), so the bytes are what Save would write unless you say otherwise.

SaveDocumentOptionsinterface

interface SaveDocumentOptions

document.save / saveAs.

copy?: boolean

Write a copy: the document keeps its own name, handle and clean state.

ChangeTilesetOptionsinterface

interface ChangeTilesetOptions
tileset: TilesetId
terrainId?: number

ISOM id of the terrain the map is refilled with; the tileset's default when omitted.

keepTiles?: boolean

Keep the tile numbers and change only ERA (what SCMDraft's switch does).

ExtrasApiinterface

interface ExtrasApi

The files stored in the map archive next to staredit\scenario.chk: custom sounds, graphics, and anything a plugin wants to keep with the map. Names are archive paths with backslashes (staredit\wav\hello.wav). They are written on Save.

list(): string[]
get(name: string): Uint8Array | null
set(name: string, bytes: Uint8Array): void

Add or replace a member; marks the map modified.

remove(name: string): boolean

Remove a member; true when there was one.

DocumentHistoryinterface

interface DocumentHistory

What document.history() answers.

undo: string | null

Label of the entry Undo would take back; null with nothing to undo.

redo: string | null
undoDepth: number
redoDepth: number

ResizeDocumentOptionsinterface

interface ResizeDocumentOptions

Scenario ▸ Resize / Crop Map's form. Width and height are clamped to 1…256, the anchor to 0…8.

width: number
height: number
anchor?: number

3 × 3 grid, row-major: 0 top-left … 4 centre … 8 bottom-right. Default 4.

terrainId?: number

ISOM id of the terrain for the new area (a TerrainType.id); the tileset's default when omitted.

clampLocations?: boolean

Pull locations that hang past the new edge back inside; default true.

NewDocumentOptionsinterface

interface NewDocumentOptions

File ▸ New's form: size, tileset, and the two strings the dialog asks for.

width: number
height: number
tileset: TilesetId
name?: string

Untitled Scenario when omitted.

description?: string
terrainId?: number

ISOM id of the terrain to fill with; the tileset's default ground when omitted.

startLocations?: number

Start locations to lay down for players 1..N, as tx.placeStartLocations would. Part of making the map, so a fresh scenario has no history to undo them from.

startLayout?: StartLayout

RawEditResultinterface

interface RawEditResult

What a raw section edit reported: the parser's remarks about the file it produced.

warnings: string[]

Warnings from parsing the edited file (a truncated section, no usable DIM, …); empty when it read cleanly.

SectionsApiinterface

interface SectionsApi

The scenario file at the byte level: every section occurrence in the order Save would write them, with the bytes it would write — unsaved edits already encoded — and raw edits to any of them.

A raw edit is a different kind of transaction from document.edit: the edited file is parsed again from scratch and installed as the open document, so the change reaches every part of the editor whether or not it models the section — and, as with Resize, the undo history is dropped and every selection cleared. The map is marked modified and the "document" event fires. Keep your own undo if you need one.

Indices are positions in list() and shift when a section is inserted or removed before them; take a fresh list() after every edit.

list(): SectionInfo[]

Every occurrence in file order; empty without a map.

bytes(index: number): Uint8Array

A copy of one occurrence's payload.

combined(name: string): Uint8Array | null

The bytes the game acts on for a name — repeated occurrences combined the way the game combines them (SectionKnowledge.mode) — or null when the file has none.

file(): Uint8Array

The whole CHK as Save would write it (the archive extras are document.extras).

spec(name: string): SectionKnowledge | null

What the editor knows about a section name, sized for the open map; null for an unknown name.

known(): SectionKnowledge[]

Every section the editor knows, sized for the open map.

write(index: number, bytes: Uint8Array): RawEditResult

Replace one occurrence's payload.

rename(index: number, name: string): RawEditResult

Rename one occurrence (four characters; shorter names are padded with spaces).

insert(index: number, name: string, bytes: Uint8Array): RawEditResult

Insert a section before index (list().length appends).

remove(index: number): RawEditResult
move(from: number, to: number): RawEditResult

Move the occurrence at from so that it sits at to.

replaceFile(bytes: Uint8Array): RawEditResult

Replace the whole CHK, the way File ▸ Open reads one.

trailing(): Uint8Array | null

Bytes after the last chunk the reader could parse — what follows a chunk header with a negative length, say. Save writes them back as they are; a replaceFile without them drops them. Null when the file ends cleanly.

required(): string[]

The sections a file of the open map's revision must carry to load, as Check Map tests them (STRx in place of STR on a Remastered file).

defaults(name: string): Uint8Array | null

The bytes File ▸ New would write for a section on a map of this size, tileset and revision — StarEdit's defaults for a settings table, the fixed VCOD, an empty list, null terrain. Null for a section the editor cannot produce: one it does not model, or an optional one a new map has no value for (CRGB, SWNM).

rebuild(names?: string[]): RebuildResult

Re-encode sections from the editor's model, the way Save writes a dirty one, and install the result like any other raw edit. This is what turns a protected file back into a plain one: repeated occurrences collapse into one, a truncated or oversized section comes back at the size the model encodes to, a string table whose offsets point nowhere is rewritten with every string the editor could read. Names the editor does not model, and modelled ones whose model is absent (no ISOM, no settings table), are left as they are and missing from rebuilt; omit names for every modelled section the map has a model for.

IsomRebuildResultinterface

interface IsomRebuildResult

What tx.rebuildIsom did.

created: boolean

The map had no usable ISOM, so one was created.

changed: number

Lattice values that changed (every one of a created section).

diamonds: number

Diamonds the rebuild resolved from the tiles.

unresolved: number

Diamonds it had to guess — under doodads or off the edge.

Cellstype

type Cells = Rect | Iterable<number>;

Cells for the bulk terrain operations: a tile rect, or cell indices (y * width + x).

EditTransactioninterface

interface EditTransaction
readonly scenario: Scenario
readonly width: number
readonly height: number
tileAt(x: number, y: number): number

MTXM (what the game draws) at a cell.

groundAt(x: number, y: number): number

TILE (the ground without doodads) at a cell.

setTile(x: number, y: number, id: number): void

One tile into both sections.

setTiles(cells: Cells, id: number): number

Many tiles into both sections; returns how many changed.

stampTerrain(cells: Cells, terrainId: number, variation?: number): number

The Rect brush: flat left/right pairs by column parity, one random variation per pair (variation pins it). Needs the tileset graphics; returns tiles changed.

fillFlat(rect: Rect, terrainId: number): number

Lay terrain the way a new map is laid over rect, ISOM lattice included when the map has one.

paintIsom(d: Diamond, terrainId: number, extent?: number): boolean

The isometric brush on one diamond: sets its ISOM value and regenerates the tiles around it, cliffs and shores included. Needs ISOM and the tileset; returns whether the terrain could be painted there.

rebuildIsom(): IsomRebuildResult | null

Reconstruct the ISOM section from the tiles — for a map that arrived without one, or whose lattice no longer matches after Rect / Tile edits: exact for terrain that was laid down isometrically, a best guess under doodads and for hand-placed tiles. A missing or wrongly sized ISOM is created (undo removes it again); an existing one gets only the diamonds that differ. Needs the tileset graphics; null without them.

makeUnit(unitId: number, owner: number, x: number, y: number): UnitRecord

A StarEdit-style unit record (fresh serial, valid/used masks) centred on map pixels.

addUnits(records: UnitRecord[]): number[]
removeUnits(indices: number[]): number
updateUnits(indices: number[], patch: (u: UnitRecord) => Partial<UnitRecord>): number
placeUnit(unitId: number, owner: number, x: number, y: number): number

A unit the way the Units palette places one: a building snaps its placement box to the tile grid (when the palette's Snap to grid is on), anything else lands where you say, and nothing leaves the map. No placement checks — ask canPlaceUnit first if you want them. Returns the record's index.

canPlaceUnit(unitId: number, x: number, y: number): boolean

Whether the Units palette's placement checks, with its current options, allow a unit of this type centred there.

makeSprite(kind: SpriteKind, id: number, owner: number, x: number, y: number, opts?: { flipped?: boolean; disabled?: boolean; }): SpriteRecord
addSprites(records: SpriteRecord[]): number[]
removeSprites(indices: number[]): number
placeSprite(kind: SpriteKind, id: number, owner: number, x: number, y: number, opts?: { flipped?: boolean; disabled?: boolean; }): number

makeSprite + addSprites in one, kept on the map; returns the record's index.

placeDoodad(doodadId: number, tx: number, ty: number, owner?: number): number

Stamp a doodad (a dddata.bin id) at a tile; returns its record index, or -1 when unknown or off the map.

removeDoodads(indices: number[]): number
addLocation(bounds: Bounds, name?: string, elevationFlags?: number): number

A location in the lowest free slot (pixel bounds); returns the slot, or -1 when the table is full.

editLocation(index: number, patch: LocationPatch): boolean
removeLocations(indices: number[]): number
setFog(cells: Cells, players: number, mode: FogMode): number

Set ("fog") or clear the players bits (bit n = player n + 1) over cells; creates MASK on first use.

replaceTerrain(from: TerrainPick, to: TerrainPick, rect?: Rect): number

Tools ▸ Replace Terrain: every tile matching from (a flat terrain by ISOM id, or one exact tile) becomes to, over rect or the whole map; pairs are laid as the Rect brush lays them. Returns tiles changed. Terrain picks need the graphics.

fillArea(x: number, y: number, fill: { terrainId: number; } | { tileId: number; }, match?: "terrain" | "tile"): number

The bucket fill: the 4-connected area around (x, y) of the same terrain type (match: "terrain", the Rect fill) or the same exact tile ("tile"), laid with terrainId as the Rect brush would, or set to tileId. Returns tiles changed.

placeBlend(x: number, y: number, side: Side, id: number): boolean

The Blend brush: id goes on the cell beside the anchor tile on side (terrain.blendCandidates ranks what fits). Returns whether the cell was on the map.

tilesFromIsom(): number | null

What StarEdit does after an isometric edit: regenerate every tile from the ISOM lattice (the reverse of rebuildIsom). Needs ISOM and the graphics; returns tiles changed, or null without them.

mirror(cells: Cells): number[]

The cells and their images under the symmetry mode (Tools ▸ Symmetry…), each once — what the built-in brushes paint over. With the mode off, the cells as given.

mirrorPoint(px: number, py: number): { x: number; y: number; }[]

A map pixel and its images under the symmetry mode, the original first.

moveUnits(indices: number[], dx: number, dy: number, snap?: boolean): number

Shift units by a pixel delta; buildings re-snap to the grid when snap (the palette's option when omitted). Returns records changed.

placeStartLocations(options: { players: number; layout?: StartLayout; margin?: number; replace?: boolean; }): StartPlacementResult

Tools ▸ Auto-place Start Locations: one per player on a ring or in the corners, each moved to the nearest spot the placement checks accept; replace removes the existing ones first. Players count from 1.

updateSprites(indices: number[], patch: (r: SpriteRecord) => Partial<SpriteRecord>): number
moveSprites(indices: number[], dx: number, dy: number): number

Shift sprites by a pixel delta, clamped to the map. Returns records changed.

updateDoodads(indices: number[], patch: { owner?: number; disabled?: number; }): number

Change a doodad's owner or disabled flag (its tiles stay). Returns records changed.

restoreAnywhere(): boolean

Put Anywhere (slot 63) back to the whole map; returns whether it had to move.

invertFog(players: number): number

Flip every tile's fog bit for players; returns tiles changed.

copyFog(from: number, to: number): number

Copy one player's fog (0-based) onto the players in the to bit mask (bit n = player n + 1); returns tiles changed.

floodFog(x: number, y: number, player: number, players: number, mode: FogMode): number

Fog or clear the connected area around (x, y) that shares player's fog state, for players; returns tiles changed.

note(text: string): void

A line for the status bar, appended to the label.

UpdateResultinterface

interface UpdateResult

What one document.update changed: every section it marked dirty, in the order the operations touched them, and changed false when they were all no-ops.

changed: boolean
sections: string[]
notes: string[]

TriggerListUpdateinterface

interface TriggerListUpdate

TRIG or MBRF as a list. Operations apply as they are called, like document.edit's.

list(): TriggerRecord[]

The list as it stands, cloned.

count(): number
set(list: TriggerRecord[]): void

Replace the whole list.

add(trigger: TriggerRecord, at?: number): number

Insert one (at the end without at); returns its index.

replace(index: number, trigger: TriggerRecord): boolean

Replace one record; false when there is none at index.

remove(indices: number[]): number
move(from: number, to: number): boolean
fromText(source: string, options?: { replace?: boolean; }): number

Parse the text format (triggers.text.print's inverse) and append the result, or replace the list with replace: true. Strings the text names are interned as it parses. Throws with the line number when the text does not parse.

StringsUpdateinterface

interface StringsUpdate

The string table. Nothing is ever renumbered: set overwrites a slot (every record pointing at it sees the new text) and intern appends rather than reusing a slot something else may share.

list(): (string | null)[]
intern(text: string): number

The index of text: an identical entry when there is one, else a new one. 0 for "".

set(index: number, text: string): void

Overwrite one slot.

apply(list: (string | null)[]): void

Install a whole table; unreferenced trailing blanks are dropped, other indices keep their place.

import(text: string): { replaced: number; added: number; }

File ▸ Import ▸ Strings: index<TAB>text lines (exchange.formatStrings writes them) set in place, indices past the end appended. Returns how many were replaced and added.

SwitchesUpdateinterface

interface SwitchesUpdate
names(): string[]
setName(index: number, name: string): void

Name a switch (0-based); "" clears the name. Creates SWNM on the first one.

UpdateTransactioninterface

interface UpdateTransaction

The second kind of write (see document.update): the tables and settings the editor's own dialogs edit. Operations apply to the scenario as they are called — a string interned on one line is there for the trigger added on the next — and the commit at the end marks the map modified and tells the chrome to re-read.

readonly scenario: Scenario
readonly triggers: TriggerListUpdate

TRIG.

readonly briefing: TriggerListUpdate

MBRF, the mission briefing's own list of the same records.

readonly strings: StringsUpdate
readonly switches: SwitchesUpdate

SWNM.

properties(patch: { name?: string; description?: string; }): void

SPRP: the scenario's name and description ("" restores the file-name default).

readonly players: PlayersUpdate

OWNR / SIDE / COLR / CRGB / FORC: the Player Settings and Player Colors dialogs.

readonly forces: ForcesUpdate

FORC: the Force Settings dialog.

readonly unitTypes: UnitTypesUpdate

UNIS / UNIx and PUNI: the Unit Settings dialog.

readonly upgrades: UpgradesUpdate

UPGS / UPGx and UPGR / PUPx: the Upgrade Settings dialog.

readonly techs: TechsUpdate

TECS / TECx and PTEC / PTEx: the Technology Settings dialog.

readonly sounds: SoundsUpdate

WAV and the archive's sound files: the Sound Editor.

readonly cuwp: CuwpUpdate

UPRP / UPUS: the Create Unit with Properties slots (Triggers ▸ Unit Properties Slots…).

setVersion(version: MapVersion, extendedStrings?: boolean): void

Scenario ▸ Map Revision: VER / TYPE and, moving to or from Remastered, the string table's width.

note(text: string): void

A line for the status bar, appended to the label.

PlayersUpdateinterface

interface PlayersUpdate
list(): PlayerSlotView[]

All 12 slots, 0-based, with the effective colour and force.

set(slot: number, patch: PlayerPatch): boolean

Patch one slot; colours and forces apply to the eight playable slots only.

ForcesUpdateinterface

interface ForcesUpdate
list(): ForceView[]
set(force: number, patch: ForcePatch): boolean

UnitTypesUpdateinterface

interface UnitTypesUpdate
get(unitId: number): UnitTypeView

The effective row for a units.dat id — the dat's numbers where the type is on "use default".

set(unitId: number, patch: UnitTypePatch): boolean

Patch one type. Setting any number turns "use default" off for it (seeding the untouched columns from the dat, as the dialog does); useDefault: true puts it back. Hit points are whole points. name is the custom name ("" restores the default); available edits PUNI.

UpgradesUpdateinterface

interface UpgradesUpdate
get(upgradeId: number): UpgradeView
set(upgradeId: number, patch: UpgradePatch): boolean

TechsUpdateinterface

interface TechsUpdate
get(techId: number): TechView
set(techId: number, patch: TechPatch): boolean

SoundsUpdateinterface

interface SoundsUpdate
list(): SoundRow[]

The 512 WAV slots in use, joined with the archive (present says whether the file is there).

add(path: string, bytes?: Uint8Array): number

Put path (staredit\wav\name.wav, or just name.wav) in the first free slot — the existing slot when it is already listed — and, with bytes, store the file in the archive. Returns the slot, or -1 when all 512 are taken.

remove(slot: number, deleteFile?: boolean): boolean

Clear a slot; with deleteFile, remove the archive member too.

CuwpUpdateinterface

interface CuwpUpdate

The 64 Create Unit with Properties slots. A slot is addressed 0-based here; the action that uses one stores the number 1-based (target = slot + 1), as CuwpSlotView.index

    1. A view's field is null where the created units keep the type's default.
list(): CuwpSlotView[]
get(index: number): CuwpSlotView | null
set(index: number, patch: CuwpSlotPatch, used?: boolean): boolean

Patch one slot: a number sets the field and its "applied" bit, null clears the bit; a boolean forces a special state, null leaves it to the unit. used is StarEdit's "in use" tick, on by itself once the slot sets anything.

clear(index: number): boolean

Back to an empty, unticked slot.

Seen in

scmJS 0.1.0 · Generated from the repository. StarCraft and Brood War are trademarks of Blizzard Entertainment; this project ships none of their data.