scmJS docs

Shared types

The declarations more than one group names — everything else is documented on the page of the group that uses it.

ChkSectioninterface

interface ChkSection

CHK is a flat stream of chunks: 4-byte name, int32 length, then that many bytes.

StarCraft applies chunks sequentially into fixed-size buffers, so a section that appears twice is not "last one wins" — the later copy overwrites only as many bytes as it carries. Protected maps lean on this constantly, so the reader keeps every occurrence in file order and layer() reproduces the overwrite semantics.

name: string

4-character chunk name, latin1. May contain junk in protected maps.

offset: number

Byte offset of the chunk's name within the CHK.

declaredSize: number

Length field as written, which may disagree with data.length when truncated.

data: Uint8Array
truncated?: boolean

Set when the declared size ran past the end of the file.

ChkFileinterface

interface ChkFile
sections: ChkSection[]
trailing?: Uint8Array

Bytes after the last parseable chunk header, if any.

TextEncodingtype

type TextEncoding = "utf-8" | "euc-kr" | "shift_jis" | "gbk" | "big5" | "windows-1251" | "windows-1252";

The byte encodings a map's text can be in, and how to tell which one a file used.

StarEdit wrote the string table in whatever code page Windows was running — EUC-KR (CP949) on a Korean machine, Shift_JIS on a Japanese one, Windows-1252 nearly everywhere else — and 1.16.1 still reads it that way. Remastered writes UTF-8 and, reading, tries UTF-8 first and falls back to the client's legacy code page when the bytes are not valid UTF-8. The file itself carries no note of which was used, so a table is guessed on open (detectTextEncoding) and the guess is a setting the user can correct (Scenario ▸ Map Revision).

Decoding is the platform's (TextDecoder knows every label here). Encoding is not — TextEncoder is UTF-8 only — so each legacy encoding's table is built once, lazily, by decoding every byte and every lead/trail byte pair it has and remembering what came back (reverseTable). A character the encoding cannot hold is written as ?, the way StarEdit's own dialogs did, and unencodable lists them so Check Map and the dialog can say so before the file is written.

StringTableinterface

interface StringTable

STR/STRx string table.

Index 0 means "no string" and is never stored. Indices are referenced from TRIG, MRGN, SPRP and friends — several of which we round-trip as raw bytes — so the table must keep its index space stable across a save. Entries are therefore addressed by position, never renumbered.

The bytes carry no note of their encoding (see text/encoding.ts): decodeStrings guesses one from the whole table's bytes unless told, and encodeStrings writes the table's, so a file opened and saved keeps its bytes and a Korean file edited on a Korean game stays readable there.

strings: (string | null)[]

strings[i] is string index i; slot 0 is always null.

extended: boolean

True when the source section was STRx (Remastered, 32-bit count and offsets).

encoding: TextEncoding

How the text is written to bytes; guessed on open, a setting afterwards.

UnitRecordinterface

interface UnitRecord
serial: number
x: number
y: number
unitId: number
relationType: number
validProperties: number

Bit set of which "special properties" fields below are meaningful.

validStates: number
owner: number
hitPointsPercent: number
shieldPercent: number
energyPercent: number
resourceAmount: number
hangarUnits: number
stateFlags: number
unused: number
relatedSerial: number

SpriteRecordinterface

interface SpriteRecord
spriteId: number

sprites.dat id for a pure sprite, units.dat id for a unit sprite (see SpriteFlag.PureSprite).

x: number
y: number
owner: number
unused: number
flags: number

SpriteFlag bits. StarEdit writes a doodad's overlay sprite with the doodad's whole CV5 flag word here, so real maps carry the terrain bits (0x80, 0x100, …) too.

DoodadRecordinterface

interface DoodadRecord

One placed doodad, as StarEdit records it (the game never reads this section: it sees only the doodad's tiles in MTXM and its overlay in THG2). doodadId is the index into the tileset's dddata.bin, not a CV5 group; x/y are the pixel centre of the footprint, so the top-left tile is x / 32 - width / 2.

doodadId: number
x: number
y: number
owner: number
disabled: number

0 = enabled (every doodad in Blizzard's maps), 1 = disabled.

LocationRecordinterface

interface LocationRecord
left: number
top: number
right: number
bottom: number
nameIndex: number
elevationFlags: number

Bit 0 low ground, 1 medium, 2 high, 3 low air, 4 medium air, 5 high air.

Forcesinterface

interface Forces
playerForce: number[]

Force index (0-3) each of the 8 playable slots belongs to.

nameIndex: number[]

String index of each force's name.

flags: number[]

Bit 0 random start, 1 allied, 2 allied victory, 3 shared vision.

PlayerRgbinterface

interface PlayerRgb
rgb: [ number, number, number ][]

[r, g, b] for each of the 8 playable slots; only read when mode is Custom.

mode: number[]

A ColorMode per slot.

UnitSettingsinterface

interface UnitSettings
useDefault: Uint8Array

1 = the game uses units.dat / weapons.dat for this type and ignores the columns below.

hitPoints: Uint32Array

Fixed point: hit points × 256, like units.dat.

shields: Uint16Array
armor: Uint8Array
buildTime: Uint16Array

Game frames (15 per second at Fastest).

mineralCost: Uint16Array
gasCost: Uint16Array
nameIndex: Uint16Array

String index of the custom name, 0 for the default one.

weaponDamage: Uint16Array

Per weapons.dat id, always WEAPONS_BW long; UNIS only stores the first 100.

weaponBonus: Uint16Array

UnitAvailabilityinterface

interface UnitAvailability

Which players may build which unit types. Three tables, player-major (puniIndex): a per-player answer, the global default, and whether each player defers to it.

playerAvailable: Uint8Array

1 = the player can build the type; read only where playerUsesDefault is 0.

defaultAvailable: Uint8Array

1 = the type is available to every player that uses the default.

playerUsesDefault: Uint8Array

1 = the player takes defaultAvailable for the type.

UpgradeSettingsinterface

interface UpgradeSettings

Research cost per upgrade: a base and a per-level factor for minerals, gas and time. Struct of arrays over 61 upgrades; the original sections only store the first 46.

useDefault: Uint8Array

1 = the game uses upgrades.dat for this upgrade and ignores the columns below.

mineralCost: Uint16Array
mineralFactor: Uint16Array
gasCost: Uint16Array
gasFactor: Uint16Array
timeCost: Uint16Array

Game frames.

timeFactor: Uint16Array

UpgradeRestrictionsinterface

interface UpgradeRestrictions

How far each player may research each upgrade and where they start. Player-major tables (upgradeIndex), a global default pair, and a per-player "use the default" flag.

playerMax: Uint8Array
playerStart: Uint8Array
defaultMax: Uint8Array
defaultStart: Uint8Array
playerUsesDefault: Uint8Array

TechSettingsinterface

interface TechSettings
useDefault: Uint8Array

1 = the game uses techdata.dat for this ability.

mineralCost: Uint16Array
gasCost: Uint16Array
researchTime: Uint16Array

Game frames.

energyCost: Uint16Array

TechRestrictionsinterface

interface TechRestrictions

Whether each player may research each ability and whether they start with it. Same shape as UpgradeRestrictions.

playerAvailable: Uint8Array
playerResearched: Uint8Array
defaultAvailable: Uint8Array
defaultResearched: Uint8Array
playerUsesDefault: Uint8Array

CuwpSlotinterface

interface CuwpSlot
validProperties: number

CuwpValid bits.

validFields: number

CuwpField bits.

owner: number

Unused by the game; StarEdit writes 0.

hitPointsPercent: number
shieldsPercent: number
energyPercent: number
resources: number
hangar: number
stateFlags: number

CuwpState bits.

unused: number

The record's last four bytes, kept for fidelity.

ConditionRecordinterface

interface ConditionRecord
location: number

1-based location number, 0 = none.

player: number

PlayerGroup.

amount: number
unitId: number
comparison: number

Comparison for numeric conditions; SwitchState for Switch.

type: number

ConditionType.

resource: number

ResourceType / ScoreType / switch number, per type.

flags: number

ConditionFlag bits.

mask: number

EUD mask word; 0 in ordinary maps.

ActionRecordinterface

interface ActionRecord
location: number

1-based source location, 0 = none.

text: number

String index for text / comment / leaderboard label, 0 = none.

wav: number

String index of the WAV file name, 0 = none.

time: number

Milliseconds for Wait / Transmission / Talking Portrait; WAV duration for Play WAV.

player: number

PlayerGroup (first).

target: number

Second player / destination location / amount / AI script code, per type.

unitId: number

Unit id / ScoreType / ResourceType / AllianceStatus, per type.

type: number

ActionType (or BriefingActionType in MBRF).

modifier: number

Unit count (0 = all) / SetModifier / SwitchAction / Order / UnitState, per type.

flags: number

ActionFlag bits.

padding: number
mask: number

EUD mask word; 0 in ordinary maps.

TriggerRecordinterface

interface TriggerRecord
conditions: ConditionRecord[]
actions: ActionRecord[]
flags: number

TriggerFlag bits.

players: number[]

27 bytes, one per PlayerGroup; non-zero = the trigger runs for that group.

currentAction: number

The game's bookkeeping byte (offset 2399); StarEdit writes 0.

ReadonlyTriggerinterface

interface ReadonlyTrigger

A trigger that is only read: nothing on it, its conditions or its actions may be written.

readonly conditions: readonly Readonly<ConditionRecord>[]
readonly actions: readonly Readonly<ActionRecord>[]
readonly flags: number
readonly players: readonly number[]
readonly currentAction: number

ResourceTypeconst

const ResourceType: {
	readonly Ore: 0;
	readonly Gas: 1;
	readonly OreAndGas: 2;
}

ScoreTypeconst

const ScoreType: {
	readonly Total: 0;
	readonly Units: 1;
	readonly Buildings: 2;
	readonly UnitsAndBuildings: 3;
	readonly Kills: 4;
	readonly Razings: 5;
	readonly KillsAndRazings: 6;
	readonly Custom: 7;
}

Scenariointerface

interface Scenario

A parsed scenario.

chk holds every original section in file order and is the fidelity anchor: sections we do not model are re-emitted byte for byte, so opening and saving a map we only partly understand does not destroy the parts we don't. Only names listed in dirty are re-encoded on save.

chk: ChkFile
dirty: Set<string>
warnings: string[]
type: string

TYPE, e.g. "RAWB" for Brood War.

fileVersion: number

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

width: number
height: number
era: number

ERA value as stored; the meaningful tileset is tilesetId.

strings: StringTable
nameIndex: number
descriptionIndex: number
playerTypes: number[]
editorPlayerTypes: number[] | null

IOWN: StarEdit's own copy of the player types — what its Player Settings dialog shows, where the game reads OWNR. The editor keeps the two in step; a file where they differ (another tool wrote one and not the other) is flagged by Check Map. Null when the file has no section.

playerRaces: number[]
playerColors: number[]
playerRgb: PlayerRgb | null

CRGB, Remastered's per-slot colour choice; null when the file has none (every client then reads COLR).

forces: Forces
unitSettings: UnitSettings | null

UNIx if the file has one, else UNIS; null when it has neither (every type on its dat defaults).

unitAvailability: UnitAvailability | null

PUNI; null when the file has none (everything buildable by everyone).

upgradeSettings: UpgradeSettings | null

UPGx if the file has one, else UPGS; null when it has neither (every upgrade on its dat costs).

upgradeRestrictions: UpgradeRestrictions | null

PUPx else UPGR; null when absent (every player on the dat level caps, starting at 0).

techSettings: TechSettings | null

TECx else TECS; null when absent.

techRestrictions: TechRestrictions | null

PTEx else PTEC; null when absent (everything researchable, nothing researched).

wavs: number[] | null

WAV: 512 string indices of the map's sound paths; null when the file has no section.

cuwp: CuwpSlot[] | null

UPRP: the 64 Create Unit with Properties slots (the action names one 1-based); null when the file has no section.

cuwpUsed: boolean[] | null

UPUS: StarEdit's "slot in use" byte per CUWP slot; null when the file has no section.

tiles: Uint16Array

MTXM: what the game draws — terrain with the doodads stamped over it.

editorTiles: Uint16Array

TILE: StarEdit's copy of the terrain without doodads (a doodad's cells hold the ground it was placed on). Terrain brushes write both arrays; placing a doodad writes only tiles, and removing one restores its cells from here. A file without TILE starts with a copy of MTXM.

isom: Uint16Array | null
mask: Uint8Array | null
units: UnitRecord[]
sprites: SpriteRecord[]
doodads: DoodadRecord[]
locations: LocationRecord[]
triggers: TriggerRecord[]

TRIG, in execution order.

briefing: TriggerRecord[]

MBRF: mission briefings, same record layout with briefing action types.

switchNames: number[] | null

SWNM: string index per switch (0 = unnamed); null when the file has no section.

MapVersiontype

type MapVersion = "original" | "hybrid" | "broodwar" | "remastered";

TilesetIdtype

type TilesetId = "badlands" | "platform" | "install" | "ashworld" | "jungle" | "desert" | "ice" | "twilight";

StarCraft tileset reference data.

TerrainNameinterface

interface TerrainName

One ISOM terrain type: its id is the CV5 index of the flat left/right group pair that draws it, and the value the ISOM section stores for it.

id: number
name: string

TileChangeinterface

interface TileChange
at: number

Flat index into scenario.tiles.

before: number
after: number
under?: number

What scenario.editorTiles (TILE) held before a terrain change, when that differs from before (the cell was under a doodad). Filled in by applyChanges the first time a change is applied, so undo can put the ground back rather than the doodad tile.

Rectinterface

interface Rect
x0: number
y0: number
x1: number

Exclusive.

y1: number

UnitChangeinterface

interface UnitChange

Unit edits as invertible change lists, in the same spirit as terrain's TileChange. before/after are whole records: null before is an insertion at index, null after a removal, both set a replacement. Removals are listed highest index first so that applying them in order keeps the remaining indices valid; undo walks the list backwards and so re-inserts lowest first.

index: number
before: UnitRecord | null
after: UnitRecord | null

SpriteChangeinterface

interface SpriteChange
index: number
before: SpriteRecord | null
after: SpriteRecord | null

SpriteKindtype

type SpriteKind = "pure" | "unit";

DoodadChangeinterface

interface DoodadChange
index: number
before: DoodadRecord | null
after: DoodadRecord | null

LocationStringChangeinterface

interface LocationStringChange
index: number
before: string | null
after: string | null

LocationChangeinterface

interface LocationChange
index: number
before: LocationRecord
after: LocationRecord
string?: LocationStringChange

A string slot the edit adds (a name no existing string matched); removed again on undo.

SYNC_FIELDSconst

const SYNC_FIELDS: readonly [
	"type",
	"fileVersion",
	"nameIndex",
	"descriptionIndex",
	"playerTypes",
	"editorPlayerTypes",
	"playerRaces",
	"playerColors",
	"playerRgb",
	"forces",
	"unitSettings",
	"unitAvailability",
	"upgradeSettings",
	"upgradeRestrictions",
	"techSettings",
	"techRestrictions",
	"wavs",
	"cuwp",
	"cuwpUsed",
	"triggers",
	"briefing",
	"switchNames"
]

SyncFieldtype

type SyncField = (typeof SYNC_FIELDS)[number];

ListFieldtype

type ListField = "triggers" | "briefing";

ValueFieldtype

type ValueField = Exclude<SyncField, ListField>;

StringsFormatinterface

interface StringsFormat
extended: boolean
encoding: TextEncoding

Changeinterface

interface Change
before: T
after: T

TablesEditinterface

interface TablesEdit

What one dialog commit changed, each part with both of its sides.

values?: Partial<Record<ValueField, Change<string>>>

The changed tables as JSON text (packed).

lists?: Partial<Record<ListField, Change<TriggerRecord[]>>>
strings?: [ number, string | null, string | null ][]

String slots that changed: [index, before, after].

stringsLength?: Change<number>
stringsFormat?: Change<StringsFormat>
extras?: Change<Map<string, Uint8Array>>

The archive's files, when the commit changed them too (the Sound Editor).

HistoryEditinterface

interface HistoryEdit

The change lists of one edit; HistoryEntry adds the label.

changes: TileChange[]
isom?: TileChange[]

The isometric brush's changes to scenario.isom, undone together with the tiles.

createdIsom?: Uint16Array

Set when the edit gave a map an ISOM section it did not have (Rebuild ISOM). Undo removes the section again rather than leaving an all-zero one behind.

rebuiltIsom?: boolean

Set when the edit rebuilt an existing lattice from the tiles, which is the one edit to isom the ISOM health is re-measured after: a brush stroke keeps the two in step by construction and is deliberately not measured (useIsomStatus), and measuring costs a second rebuild.

units?: UnitChange[]

Unit placements, moves and deletions (see editor/units.ts).

doodadTiles?: TileChange[]

Doodad tiles stamped into or lifted off MTXM alone — TILE keeps the ground beneath (see editor/doodads.ts). Applied after changes, so a terrain stroke that removes the doodads it painted over restores their remaining cells on top of its own edit.

doodads?: DoodadChange[]

DD2 record insertions, removals and replacements.

sprites?: SpriteChange[]

THG2 record changes: the Sprites layer's edits, and a doodad's overlay sprite coming and going with it.

locations?: LocationChange[]

MRGN slot replacements — create, move, resize, rename, delete (see editor/locations.ts); a rename may carry a string.

fog?: TileChange[]

Fog of war edits to scenario.mask (see editor/fog.ts); at indexes the MASK byte.

createdMask?: Uint8Array

Set when the edit gave a map a MASK section it did not have (the first fog stroke on such a map). Undo removes the section again.

tables?: TablesEdit

What a dialog wrote — settings, triggers, the briefing, strings (editor/tableHistory.ts). An entry with this part has no other: applyEntry leaves it alone, and the undo and redo atoms apply it with applyTables.

Diamondinterface

interface Diamond
x: number
y: number

IsomCheckinterface

interface IsomCheck
rects: number

Rects that have tiles under them.

mismatched: number

Rects whose tiles are not what their ISOM resolves to (doodad tiles are excused).

FogModetype

type FogMode = "fog" | "clear";

EditorLayertype

type EditorLayer = "terrain" | "doodads" | "units" | "sprites" | "locations" | "fog" | "clipboard";

The classic SCMDraft layer combo; "clipboard" is Cut / Copy / Paste.

TerrainModetype

type TerrainMode = "isom" | "rect" | "tile" | "blend";

DialogIdtype

type DialogId = "newMap" | "openMap" | "saveAs" | "exportImage" | "mapProperties" | "resizeMap" | "mapRevision" | "playerSettings" | "forceSettings" | "playerColors" | "unitSettings" | "upgradeSettings" | "techSettings" | "stringEditor" | "soundEditor" | "switches" | "locationList" | "unitProperties" | "locationProperties" | "spriteProperties" | "triggerEditor" | "missionBriefing" | "cuwpEditor" | "replaceTerrain" | "autoStarts" | "testMap" | "symmetry" | "gridSettings" | "preferences" | "shortcuts" | "validateMap" | "statistics" | "importTriggers" | "exportTriggers" | "importStrings" | "exportStrings" | "find" | "about" | "confirmClose" | "recovery" | "previousVersions" | "plugins" | "confirmPlugin" | "pluginDialog" | "gameData" | "update" | "whatsNew";

Every built-in dialog, by the id openDialogAtom takes; DialogHost maps each to its component.

MapImageOptionsinterface

interface MapImageOptions
pixelsPerTile: number

Output pixels per map tile. 32 matches the game's art 1:1; 1 is a minimap.

units: boolean
sprites: boolean
locations: boolean
locationNames: boolean
startLocations: boolean
fog: boolean
fogPlayer: number

Whose fog is drawn (0-based player), when fog is on.

grid: number

Grid spacing in map pixels (32 = one tile); 0 for no grid.

rect?: Rect | null

The part of the map to draw, in tiles (exclusive x1 / y1). The whole map when absent. Everything is drawn in map coordinates and the canvas is translated, so a region looks exactly like that part of the full picture — a unit half outside the region still leans in.

PlayerSlotViewinterface

interface PlayerSlotView
slot: number

0-based; the chrome shows it as slot + 1.

type: number
typeName: string
race: number
raceName: string
color: number | null

COLR index; null for the four unplayable slots.

colorHex: string | null

The colour the chrome shows for the slot (CRGB-aware).

rgb: [ number, number, number ] | null

The CRGB custom triple when one is in effect.

force: number | null

0-based force; null for the unplayable slots.

forceName: string | null

ForceViewinterface

interface ForceView
force: number

0-based.

name: string
flags: number
allied: boolean
alliedVictory: boolean
sharedVision: boolean
randomStart: boolean
players: number[]

0-based playable slots in the force.

WeaponViewinterface

interface WeaponView
id: number
name: string
damage: number
bonus: number

UnitTypeViewinterface

interface UnitTypeView
id: number
name: string

The game's name (or the custom one when the map sets it).

customName: string

The custom name the map sets, "" for the default.

useDefault: boolean
hitPoints: number

Whole hit points.

shields: number
armor: number
buildTime: number

Game frames.

mineralCost: number
gasCost: number
weapons: WeaponView[]

The type's ground and air weapons (a turreted vehicle's are its turret's), with the effective damage.

defaults: { hitPoints: number; shields: number; armor: number; buildTime: number; mineralCost: number; gasCost: number; weapons: WeaponView[]; } | null

units.dat / weapons.dat, null without the game data.

availability: { defaultAvailable: boolean; players: (boolean | "default")[]; }

PUNI: whether the type can be built by default, and per player ("default" where the player follows the default).

UpgradeLevelsViewinterface

interface UpgradeLevelsView
start: number
max: number
usesDefault: boolean

UpgradeViewinterface

interface UpgradeView
id: number
name: string
useDefault: boolean
mineralCost: number
mineralFactor: number
gasCost: number
gasFactor: number
timeCost: number

Game frames.

timeFactor: number
defaults: { mineralCost: number; mineralFactor: number; gasCost: number; gasFactor: number; timeCost: number; timeFactor: number; maxLevel: number; } | null

upgrades.dat, null without the game data.

levels: { defaultStart: number; defaultMax: number; players: UpgradeLevelsView[]; }

UPGR / PUPx: the default start and cap, and each of the 12 players' (effective, with usesDefault).

TechStateViewinterface

interface TechStateView
available: boolean
researched: boolean
usesDefault: boolean

TechViewinterface

interface TechView
id: number
name: string
useDefault: boolean
mineralCost: number
gasCost: number
researchTime: number

Game frames.

energyCost: number
defaults: { mineralCost: number; gasCost: number; researchTime: number; energyCost: number; } | null
state: { defaultAvailable: boolean; defaultResearched: boolean; players: TechStateView[]; }

PTEC / PTEx: the default column and each of the 12 players' effective state.

SoundRowinterface

interface SoundRow
slot: number
stringIndex: number
path: string

The path as the string table has it.

present: boolean

Whether the archive carries a member at that path.

size: number

Bytes in the archive, 0 when absent.

member: string | null

The archive member's name as stored (case may differ from the path).

usedBy: string[]

CuwpSlotViewinterface

interface CuwpSlotView

The slot as a patch-shaped view: null where the unit's default applies.

index: number
used: boolean
references: number

How many Create Unit with Properties actions name the slot.

hitPointsPercent: number | null
shieldsPercent: number | null
energyPercent: number | null
resources: number | null
hangar: number | null
cloaked: boolean | null
burrowed: boolean | null
inTransit: boolean | null
hallucinated: boolean | null
invincible: boolean | null
summary: string

ArchiveCompressiontype

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

How the members of a map archive are compressed.

Sidetype

type Side = "left" | "top" | "right" | "bottom";

ClipParttype

type ClipPart = "terrain" | "doodads" | "units" | "sprites" | "locations" | "fog";

ClipPartstype

type ClipParts = Record<ClipPart, boolean>;

PasteModetype

type PasteMode = "merge" | "replace";

Whether a paste adds to what is in the target area or clears its objects first.

ClipLocationinterface

interface ClipLocation
left: number

Bounds in map pixels relative to the clip's origin (an inverted box keeps its inversion).

top: number
right: number
bottom: number
elevationFlags: number
name: string

Clipinterface

interface Clip
width: number

Size in tiles.

height: number
era: number

ERA of the source map: tile ids mean nothing on another tileset.

tiles: Uint16Array | null

MTXM ids, row-major, or null when terrain was not included.

ground: Uint16Array | null

TILE ids (the ground under the doodads), alongside tiles.

doodads: DoodadRecord[]

Records with positions relative to the origin in map pixels.

units: UnitRecord[]
sprites: SpriteRecord[]
locations: ClipLocation[]
fog: Uint8Array | null

MASK bytes, row-major, or null when fog was not included.

PasteCountsinterface

interface PasteCounts
tiles: number
doodads: number
units: number
sprites: number
locations: number
fog: number
removed: number

Objects the paste cleared out of the way (replace mode) or that a new tile stranded.

PasteResultinterface

interface PasteResult
edit: HistoryEdit
counts: PasteCounts
notes: string[]

Things that could not be pasted, in words.

PLUGIN_API_VERSIONconst

const PLUGIN_API_VERSION = 1

The version a host provides; a manifest that asks for a newer one is refused. It stays at 1 while the API is only used by the plugins in the scm-js organisation and grows with them — the first incompatible change after outside plugins exist bumps it.

Disposableinterface

interface Disposable
dispose(): void

PluginManifestinterface

interface PluginManifest

plugin.json, next to the entry file. Only name is required.

name: string
id?: string

Stable identifier (storage prefix, log prefix); derived from the name when absent.

version?: string
description?: string
author?: string
homepage?: string
entry?: string

Entry file relative to the manifest; plugin.ts by default, then plugin.js.

build?: string

A built, self-contained JavaScript bundle of the plugin, relative to the manifest ("dist/plugin.js"). When there is one the editor loads it and never entry: one fetch, no TypeScript compiler, no import graph to walk — and the plugin may use npm dependencies, which the source path cannot (bundleModule refuses a bare specifier because it has no resolver).

entry stays the source of truth and stays in the manifest: it is what a person reads, what npm run typecheck checks, and what loads when there is no build. A repository that publishes one builds it in CI at the tag it is loaded from — see docs/plugins.md.

icon?: string

The plugin's face in Manage Plugins and on its own dialogs: an emoji ("🗺️"), a data:image/… URI, an https://… image, or an image file beside the manifest ("icon.svg"). Anything else is ignored — see resolveIcon in loader.ts.

api?: number

The PLUGIN_API_VERSION the plugin was written against.

requires?: string[]

Plugins this one needs running, as the specs Manage Plugins takes ("github:owner/repo", "github:owner/repo@v1.2.0", a URL to a plugin.json, "builtin:name"). Adding this plugin installs them first, enabling it enables them, and the editor starts them before it; a required plugin cannot be turned off or removed while something enabled needs it.

Which version of the required plugin is enough is not said here. The two plugins meet through api.services: the required one provides a service with a version (ServiceOptions), and this one checks ServiceInfo.version in its watch and says so in its own words when it is too old. A version range in the manifest would have the editor arbitrate a contract it never reads.

Deactivatetype

type Deactivate = void | (() => void) | Disposable;

What activate may hand back: nothing, a cleanup function, or a Disposable.

PluginActivatetype

type PluginActivate = (api: PluginApi) => Deactivate | Promise<Deactivate>;

PluginModuleinterface

interface PluginModule

The shape of the entry module: export default function activate(api) {…}, or export default { activate }, or export function activate(api) {…}.

activate: PluginActivate

PluginIcontype

type PluginIcon = {
	kind: "text";
	text: string;
} | {
	kind: "image";
	url: string;
};

A manifest icon after resolution: a glyph to print, or an image to show.

PluginScopeinterface

interface PluginScope

A child API that can be taken back as a whole (PluginApi.scope).

readonly api: PluginApi
readonly disposed: boolean

True once dispose has run, or once the plugin that made the scope was turned off.

PasteOptionsSpecinterface

interface PasteOptionsSpec
parts?: Partial<ClipParts>

Over what clipboard.parts() says.

mode?: PasteMode

Over clipboard.mode().

WidgetOptionsinterface

interface WidgetOptions
className?: string
title?: string
disabled?: boolean

pluginIdOffunction

function pluginIdOf(manifest: {
	id?: string;
	name: string;
}): string;

A slug for storage keys and log prefixes.

scmJS 0.7.3 + main@e2d8ba5 · Generated from the repository. The source is under the MIT license, which does not cover what ATTRIBUTION.md lists. StarCraft and Brood War are trademarks of Blizzard Entertainment; this project ships none of their data.