Scripting

Script the Commonwealth

Fallout MP servers run TypeScript and JavaScript resources. The complete server API reference, generated from the server itself, with samples that compile against it.

02Scripting

If you can script it, the server can run it

Resources are plain TypeScript or JavaScript, loaded by the server and hot-reloaded while players stay connected. The API below is the one the mod itself is built on.

A command, in twenty lines

Drop a folder in the server’s resources, export a server entry point, and it loads on startup. Greet players as they arrive in the world and hand them a starter kit on request.

serverresources/welcome/src/server/index.ts
// Form IDs come from Fallout4.esm. Look yours up in the Creation Kit or xEdit.
const kStimpak = "0x00023736";

// playerConnect fires before the player has a position. Wait for playerReady to touch the world.
Events.on("playerReady", (player: Player) => {
  Chat.sendToPlayer(player, `Welcome to the Commonwealth, ${player.nickname}. Try /kit.`);
});

Events.on("playerCommand", (player: Player, command: string, args: string[]) => {
  if (command !== "kit") return;

  // Entity state is replicated and survives nothing but the session, which is all a kit flag needs
  if (player.state.get("kitTaken")) {
    Chat.sendToPlayer(player, "You have already taken a kit.");
    return;
  }

  const count = Math.min(Number(args[0] ?? 3) || 3, 10);
  player.giveItem(kStimpak, count);
  player.state.set("kitTaken", true);

  Chat.sendToPlayer(player, `${count} stimpaks. Do not spend them all in Concord.`);
});

02Reference

The whole server API

Generated from the running server, so this page and the mod cannot disagree. Every global, class, member and event the server exposes. Client resources have an API of their own, including the Web views that draw interfaces over the game.

28 globals and classes · 289 members · 19 native events

Events

Registered with Events.on(name, handler). The signature shown is the handler's argument list.

playerConnect(player: Player)
Dispatched once a connecting player's entity exists. It has no position yet; wait for `playerReady` to place them.
playerReady(player: Player)
Dispatched once the player's world is synced and they stand in it: the moment to spawn, dress and equip them. Their inventory record follows shortly after, with their first report.
playerDisconnect(player: Player)
Dispatched while a player is leaving, before their entity is destroyed, so the handle still reads. Anything keyed on the player is cleaned up here.
playerDeath(player: Player, killer: Player | null)
Dispatched once when a player dies. `killer` is the last player who hit them, or null. Nothing brings them back on its own: call `player.respawn`.
playerShoot(player: Player)
Dispatched when a player fires, before the shot is shown to the players around them.
playerHit(attacker: Player, victim: Player, damage: number)
Dispatched when a player's game lands a hit on another player, before the victim takes it. Return `false` to drop the hit. `damage` is the attacker's game's own.
playerChat(player: Player, text: string)
Dispatched for a chat line, before anyone sees it. Return `false` to swallow it.
playerCommand(player: Player, command: string, args: string[])
Dispatched for a `/command arg...` line; `command` has no slash.
doorChange(player: Player, ref: number, open: boolean)
Dispatched when a player opens or closes a door. Return `false` to refuse: their door swings back.
lockChange(player: Player, ref: number, locked: boolean)
Dispatched when a player picks, unlocks or locks a lock. Return `false` to refuse: their lock goes back.
containerOpen(player: Player, ref: number)
Dispatched when a player opens a container nobody else holds. Return `false` to keep it shut.
itemDrop(player: Player, item: Item)
Dispatched when a player drops an item. Return `false` to refuse: the item leaves the world and goes back into their inventory.
itemPickUp(player: Player, item: Item | null, ref: number | null)
Dispatched when a player picks up a loose item, before they get it: a dropped or spawned `item`, or a placed reference by its form ID as `ref`. Return `false` to refuse; the item stays where it is.
inventoryChange(player: Player, changes: InventoryDelta[])
Dispatched after the server accepted a change a player's game reported: looting, buying, crafting, using an item. Changes a script made itself do not raise it.
resourceStart(resourceName: string)
Dispatched after a resource entry point has run and immediately before the resource becomes running.
resourceStop(resourceName: string)
Dispatched while a resource is stopping, before its stop callback, timers, exports and event handlers are cleaned up.
entityStateChange(entity: Entity, key: string, value: any, previous: any)
Dispatched when one key of an entity's state changes: on the server when a script writes it, on a client when the write arrives. `value` is undefined when the key was removed and `previous` is undefined when it held nothing before, so a stored null stays distinguishable from an absent key. The entity is whatever the game's WrapScriptEntity answers, and the base Entity handle by default.
consoleCommand(command: string, args: string[])
Dispatched for a line typed into the server console that no built-in command (help, ensure, refresh, ...) claimed. `args` is the rest of the line, split on whitespace. The console is the operator's, so this is the place for commands no player may run.
playerConnecting(connection: PendingConnection)
Dispatched when a player asks to join, before the connection exists: they hold no player slot, are not counted as online, and are sent nothing -- no resource list, no download, no body. The request waits until every handler has returned and every Promise a handler returned has settled, then it is let in if a player slot is free (otherwise it is refused as full). `connection.reject()` turns it away instead, and so does a handler that throws or rejects, or handlers that have not settled within the server's admission timeout (30 seconds by default, restarted by every `connection.update()`). With no handler at all, every request is let in at once.

Globals

Always in scope, in every resource. No imports.

Events

global

Asynchronous resource event bus.

Methods
on(eventName: string, handler: EventHandler): Unsubscribe

Registers a persistent handler in the shared event namespace.

eventName
Case-sensitive event name.
handler
Resource-owned callback invoked with the emitted arguments.

Returns Function that removes this exact subscription.

once(eventName: string, handler: EventHandler)

Registers a handler that is removed before its first invocation.

eventName
Case-sensitive event name.
handler
Resource-owned callback invoked with the emitted arguments.
off(eventName: string, handler: EventHandler)

Removes a matching handler owned by the calling resource.

eventName
Case-sensitive event name.
handler
Resource-owned callback invoked with the emitted arguments.
emit(eventName: string, ...args: unknown[]): Promise<void>

Invokes every shared handler and waits for all synchronous and asynchronous results.

eventName
Shared event name.
args
Arguments delivered to every matching handler.

Returns Promise rejected with an AggregateError when one or more handlers fail.

emitTo(resourceName: string, eventName: string, ...args: unknown[]): Promise<void>

Invokes matching handlers belonging only to one resource.

resourceName
Destination running resource.
eventName
Shared event name.
args
Arguments delivered to matching handlers owned by the destination.

Returns Promise rejected when one or more destination handlers fail.

onLocal(eventName: string, handler: EventHandler)

Registers a handler in the calling resource's private local-event namespace.

eventName
Case-sensitive event name.
handler
Resource-owned callback invoked with the emitted arguments.
emitLocal(eventName: string, ...args: unknown[]): Promise<void>

Emits an event only within the calling resource.

eventName
Private local event name.
args
Arguments delivered only to handlers owned by the calling resource.

Returns Promise rejected when one or more local handlers fail.

listenerCount(eventName: string): number

Counts persistent and one-shot shared handlers across resources.

eventName
Shared event name to inspect.

Returns Number of matching handlers.

emitAllClients(eventName: string, payload?: unknown)

Broadcasts a named event to every connected client's shared Events handlers.

eventName
Client shared-event name.
payload
Optional string payload sent verbatim; other values are JSON-serialized.
onClient(eventName: string, handler: EventHandler): Unsubscribe

Registers a persistent server handler for events originating from clients; this namespace is isolated from native events.

eventName
Case-sensitive event name.
handler
Resource-owned callback invoked with the emitted arguments.

Returns Function that removes this exact subscription.

onceClient(eventName: string, handler: EventHandler)

Registers a one-shot server handler for a client-originated event.

eventName
Case-sensitive event name.
handler
Resource-owned callback invoked with the emitted arguments.
offClient(eventName: string, handler: EventHandler)

Removes a matching client-originated event handler owned by the calling resource.

eventName
Case-sensitive event name.
handler
Resource-owned callback invoked with the emitted arguments.

Chat

global

Server-side delivery of structured chat messages to connected clients.

Methods
sendToAll(text: string, options?: { author?: string; color?: number | Color })

Broadcasts a structured chat message to all clients.

text
Message body broadcast to every connected client.
options
Optional author label and color: a Color or a packed 0xRRGGBBAA integer.
sendToPlayer(player: Entity, text: string, options?: { author?: string; color?: number | Color })

Sends a structured chat message to one player's owning connection.

player
Player-owned entity identifying the destination connection.
text
Message body sent to the player.
options
Optional author label and color: a Color or a packed 0xRRGGBBAA integer.

World

global

The server's clock and weather, which every client follows.

Properties
hour: numberread-only

The hour of the day, from 0 up to but not including 24, with the minutes as the fraction: 13.5 is half past one.

timeScale: numberread-only

Game minutes per real minute. 20 is the game's own pace; 0 holds the clock.

weather: numberread-only

The TESWeather form ID every client shows.

weatherForced: booleanread-only

Whether the weather was swapped in at once rather than transitioned to.

Methods
setHour(hour: number)

Sets the clock. Every client jumps to it.

hour
The hour, wrapped into 0-24; 13.5 is half past one.
setTimeScale(scale: number)

Sets how fast the clock runs.

scale
Game minutes per real minute, 0 or more; 0 holds the clock.
setWeather(weather: number | string | null, force?: boolean)

Sets the weather every client shows. Only a client's data files can tell whether the form is a weather, so a wrong one leaves the sky as it is.

weather
A TESWeather form ID, as a number or hex string; null for the server's default, CommonwealthClear.
force
Swap it in at once rather than transition to it.

Objects

global

Doors, locks and containers, by the form ID of their placed reference. The server knows only what changed this session; the rest is as the data files place it, which only a client loads.

Methods
isDoorOpen(ref: number | string): boolean | null

Whether a door stands open.

ref
The placed reference's form ID.

Returns Null when nobody moved it this session.

isLocked(ref: number | string): boolean | null

Whether a door or container is locked.

ref
The placed reference's form ID.

Returns Null when nobody changed its lock this session.

setDoorOpen(ref: number | string, open: boolean)

Opens or closes a door for everyone, players who join later included.

ref
The placed reference's form ID.
open
Open or closed.
setLocked(ref: number | string, locked: boolean)

Locks or unlocks a door or container for everyone.

ref
The placed reference's form ID.
locked
Locked or not.
getContainer(ref: number | string): InventoryItem[] | null

What a container holds.

ref
The placed reference's form ID.

Returns Null until a player or a script set its contents this session; before that, each client rolls its own.

setContainer(ref: number | string, items: { form: number | string; count: number }[]): boolean

Fills a container for everyone.

ref
The placed reference's form ID.
items
Exactly what it should hold.

Returns False past 1024 kinds of item.

getContainerHolder(ref: number | string): Player | null

The player whose menu has a container open; nobody else can take from it meanwhile.

ref
The placed reference's form ID.

Returns Null when nobody holds it.

Voice

global

Server-side proximity voice rules: how far voice carries, and who may talk to or hear whom.

Methods
setRange(range: number)

Sets how far voice carries for talkers with no override of their own. Connected clients are told, so their playback fades out at the same distance.

range
Audibility radius in world units; values <= 0 restore the default of 25.
getRange(): number

Reads the server-wide proximity range.

Returns Radius in world units.

setPlayerRange(player: Entity, range: number)

Overrides how far one player's voice carries, whichever voice tier they chose.

player
Player whose voice carries the given distance.
range
Audibility radius in world units; values <= 0 return them to the radius of their voice tier.
getPlayerRange(player: Entity): number

Reads how far a player's voice carries, with the server-wide default already resolved.

player
Player to query.

Returns Radius in world units.

setTierRange(tier: number, range: number)

Sets how far a voice tier carries. Players switch tier themselves; whisper starts at 3, shout at 25, and normal carries the server-wide range. Set a tier to 0 to make it carry the server-wide range, which takes it away. Connected clients are told.

tier
Voice tier: 0 whisper, 1 normal, 2 shout.
range
Audibility radius in world units; values <= 0 make the tier carry the server-wide range.
getTierRange(tier: number): number

Reads how far a voice tier carries, with the server-wide range already resolved.

tier
Voice tier: 0 whisper, 1 normal, 2 shout.

Returns Radius in world units.

setPlayerTier(player: Entity, tier: number)

Puts a player on a voice tier, as if they had switched to it. Their own indicator follows, and the playerVoiceTierChange event is not raised.

player
Player to move.
tier
Voice tier: 0 whisper, 1 normal, 2 shout.
getPlayerTier(player: Entity): number

Reads the voice tier a player is on. A player switching tier raises the playerVoiceTierChange event with the player and the new tier.

player
Player to query.

Returns 0 whisper, 1 normal, 2 shout.

setPlayerMuted(player: Entity, muted: boolean)

Server-wide mute: a muted player's voice reaches nobody.

player
Player to mute or unmute.
muted
True to stop their voice reaching anyone.
isPlayerMuted(player: Entity): boolean

Checks the server-wide mute flag.

player
Player to query.

Returns True when the player's voice reaches nobody.

setPlayerDeaf(player: Entity, deaf: boolean)

Server-wide deafen: a deaf player receives nobody.

player
Player to deafen or undeafen.
deaf
True to stop them receiving anyone's voice.
isPlayerDeaf(player: Entity): boolean

Checks the server-wide deafen flag.

player
Player to query.

Returns True when the player receives nobody's voice.

setLocalMute(listener: Entity, target: Entity, muted: boolean)

One-way mute between two players, enforced by the server rather than the client.

listener
Player who stops hearing the target.
target
Player the listener stops hearing.
muted
True to mute, false to restore.
isLocallyMuted(listener: Entity, target: Entity): boolean

Checks a one-way mute.

listener
Player doing the muting.
target
Player being muted.

Returns True when the listener does not receive the target.

isPlayerVoiceEnabled(player: Entity): boolean

Checks whether a player left voice chat enabled in their own client settings. A preference, not a permission: use setPlayerMuted or setPlayerDeaf to enforce anything.

player
Player to query.

Returns True unless the player turned voice chat off.

isPlayerTalking(player: Entity): boolean

Checks whether a player is speaking right now. Tracks speech rather than the push-to-talk key: silence is dropped before it reaches the server, and the state clears shortly after the last frame. The same signal raises the playerVoiceStart and playerVoiceStop events.

player
Player to query.

Returns True while the player's voice is reaching the server.

Messages

global

Typed request and notification channel between local resources through the global Messages object.

Methods
handle(messageType: string, handler: MessageHandler)

Registers or replaces a message handler owned by the calling resource.

messageType
Message type unique within the receiving resource.
handler
Handler invoked with the payload and a reply callback; the reply is ignored for notifications.
request(resourceName: string, messageType: string, payload?: unknown): Promise<unknown>

Sends a request to another local resource and waits for its handler to call reply.

resourceName
Destination running resource.
messageType
Handler type registered by the destination.
payload
Optional payload delivered to the handler.

Returns Promise resolved with the reply value or rejected when delivery or handling fails.

send(resourceName: string, messageType: string, payload?: unknown)

Sends a fire-and-forget notification to another local resource.

resourceName
Destination running resource.
messageType
Handler type registered by the destination.
payload
Optional payload delivered to the handler.

Imports

global

Bulk access to values exported by another running resource through the global Imports object.

Methods
get(resourceName: string): Record<string, unknown>

Builds an object containing every currently registered export from another resource; undeclared dependencies produce a warning.

resourceName
Name of the running resource whose exports should be read.

Returns Object keyed by export name, or an empty object when the resource has no exports.

Exports

global

Registration and lookup of cross-resource values through the global Exports object.

Methods
register(name: string, value: unknown): boolean

Registers a value from the calling resource for use by dependent resources.

name
Export name, preferably declared in the current resource manifest.
value
JavaScript value or function retained by the current resource.

Returns True when the value was registered.

get(resourceName: string, exportName: string): unknown

Reads one registered export from another running resource; undeclared dependencies produce a warning.

resourceName
Name of the running resource that owns the export.
exportName
Registered export name.

Returns The exported value.

console

global

Resource-aware console that routes output through the Framework logger.

Methods
log(...values: unknown[])

Writes an informational log entry prefixed with the current resource name.

values
Values formatted and joined with spaces.
info(...values: unknown[])

Alias of console.log for informational output.

values
Values formatted and joined with spaces.
warn(...values: unknown[])

Writes a warning log entry prefixed with the current resource name.

values
Values formatted and joined with spaces.
error(...values: unknown[])

Writes an error log entry prefixed with the current resource name.

values
Values formatted and joined with spaces.
debug(...values: unknown[])

Writes a debug log entry prefixed with the current resource name.

values
Values formatted and joined with spaces.

ExecutionEnvironment

global

Runtime-side flags exposed as the global ExecutionEnvironment.

Properties
isClient: booleanread-only

True in the sandboxed client scripting runtime.

isServer: booleanread-only

True in the authoritative server scripting runtime.

frameworkVersion: stringread-only

Local Framework release version.

modVersion: stringread-only

Local mod version from InstanceOptions.modVersion; empty when unset.

Players and entities

What the server hands your event handlers.

Player

classextends BasePlayer

A connected player and the character they control. Their own game decides their body: what a getter reads is their last report, and a setter is a request their game carries out, then reports back.

Constructor
new Player(id: number)

Wraps an already connected player with this ID; it neither connects nor spawns anyone.

id
Network entity identifier.
Properties
nickname: stringread-only

The name the player connected with. Empty once they are gone.

health: numberread-only

Current health, as the player's game last reported it.

maxHealth: numberread-only

Health at full.

armor: numberread-only

Damage resistance from the armor the player wears.

isDead: booleanread-only

Whether the player is dead. A dead player stays down until `respawn`.

isFemale: booleanread-only

Whether the character is female.

heading: numberread-only

Facing, in radians around Z.

aimPitch: numberread-only

Aim pitch, in radians.

velocity: Vector3read-only

Velocity, in game units per second.

isSneaking: booleanread-only

Whether the player sneaks.

isJumping: booleanread-only

Whether the player is in the air from a jump.

isSprinting: booleanread-only

Whether the player sprints.

isRunning: booleanread-only

Whether the player runs rather than walks.

isWeaponDrawn: booleanread-only

Whether the player's weapon is out.

isAiming: booleanread-only

Whether the player aims down the sights of a drawn gun.

isPipBoyOpen: booleanread-only

Whether the player's Pip-Boy is up.

Methods
kill(): boolean

Kills the player through their game's own hit path; `playerDeath` follows with a null killer.

Returns True when sent; false when the player is gone or already dead.

openLookEditor(): boolean

Opens the character look editor on the player's screen.

Returns True when sent; false when the player is gone.

toString(): string

Formats this handle for logging.

Returns The player's network ID and nickname.

teleport(position: Vector3, heading?: number): boolean

Moves the player within their current worldspace.

position
Where to, in the worldspace the player is in.
heading
Facing in radians; the current one when left out.

Returns True when sent; false when the player is gone. Throws for a position that is not a finite Vector3.

respawn(position?: Vector3, heading?: number): boolean

Brings a dead player back at full health. Nothing respawns a player on its own: call this from `playerDeath`, at once or later.

position
Where to come back; where the player fell when left out.
heading
Facing in radians; the one they died with when left out.

Returns True when sent; false when the player is gone or alive.

fire(shots?: number): boolean

Has the player's game fire its drawn weapon.

shots
How many times, 1 to 255; once when left out.

Returns True when sent; false when the player is gone.

getSpace(): PlayerSpace | null

Where the player is.

Returns The worldspace or interior cell, or null when the player is gone.

getWeapon(): PlayerWeapon | null

The weapon in the player's hands.

Returns The weapon, or null when they have none or are gone.

getOutfit(): OutfitPiece[]

What the player wears.

Returns One entry per armor piece; empty when the player is gone.

setOutfit(pieces: (number | string | { form: number | string; mods?: (number | string)[] })[], mode?: "replace" | "add" | "remove"): boolean

Dresses the player. Pieces the player's game cannot wear are skipped there.

pieces
Armor form IDs, or objects naming the mods to attach. Up to 32 pieces of 8 mods.
mode
`replace`, the default, wears exactly these and takes every other piece off; `add` puts them on over what is worn; `remove` takes them off.

Returns True when sent; false when the player is gone.

randomizeOutfit(seed?: number): boolean

Dresses the player in a random playable outfit, mods included.

seed
Rolls the same outfit for the same seed; a fresh one when left out.

Returns True when sent; false when the player is gone.

setLook(look: { female?: boolean; skinTone?: { r: number; g: number; b: number }; hair?: number | string }): boolean

Changes the character's look; the player's game rebuilds them and everyone sees it.

look
What to change: the sex, the skin tone in 0-255 channels, a hair BGSHeadPart. What is left out stays.

Returns True when sent; false when the player is gone.

randomizeLook(seed?: number, morphsOnly?: boolean): boolean

Rolls the character a new look from their race's character generation data.

seed
Rolls the same look for the same seed; a fresh one when left out.
morphsOnly
Only the face sliders and regions, keeping sex, hair and colours.

Returns True when sent; false when the player is gone.

getInventory(): InventoryItem[]

What the player carries, from the server's record.

Returns One entry per stack; empty before the player's first report, shortly after they join, and once they are gone.

getItemCount(form: number | string): number

How many of an item the player carries.

form
The base object.

Returns The count; 0 when they carry none or are gone.

giveItem(form: number | string, count?: number): boolean

Puts items in the player's inventory. It does not equip them: see `equipItem`.

form
The base object.
count
How many, 1 to 1000000; one when left out.

Returns True when the record changed; false before the player's first report or once they are gone.

removeItem(form: number | string, count?: number): boolean

Takes items out of the player's inventory.

form
The base object.
count
How many, 1 to 1000000; one when left out. More than they carry takes them all.

Returns True when the record changed; false before the player's first report or once they are gone.

setItemCount(form: number | string, count: number): boolean

Sets how many of an item the player carries.

form
The base object.
count
How many the player should carry, 0 to 1000000.

Returns True when the record changed; false before the player's first report or once they are gone.

equipItem(form: number | string): boolean

Has the player draw a weapon or wear an armor piece they carry. Right after `giveItem` it lands too: the inventory reaches their game first.

form
A weapon or armor piece the player carries.

Returns True when sent; false when the server's record has none of it or the player is gone.

static all(): Player[]

Every connected player.

Returns One handle per player, in no particular order.

static getById(id: number): Player | null

Looks a player up by network ID.

id
Network entity identifier.

Returns The handle, or null when no connected player has that ID.

BasePlayer

classextends Entity

Framework-owned base handle for a connected player, extended by each game or mod.

Constructor
new BasePlayer(id: number)

Creates a wrapper for an existing connected player with this ID; it does not connect or spawn a player.

id
Network entity identifier.
Properties
steamId: stringread-only

Authenticated Steam identifier, or an empty string when unavailable.

epicId: stringread-only

Epic Games account identifier the client reported, not verified by the server, or an empty string when unavailable.

discordId: stringread-only

Authenticated Discord identifier, or an empty string when unavailable.

hardwareId: stringread-only

Framework hardware identifier, or an empty string when unavailable.

ping: numberread-only

Current round-trip latency in milliseconds, or -1 when unavailable.

ip: stringread-only

Current remote network address, or an empty string when unavailable.

Methods
toString(): string

Formats this player handle for logging and debugging.

Returns Text containing the player's network entity ID.

isNametagVisible(): boolean

Checks whether this player's nametag is shown to other players.

Returns True unless the nametag was hidden; false also when this game has no nametags.

isNametagHealthVisible(): boolean

Checks whether the health bar under this player's nametag is shown.

Returns True unless the health bar was hidden; false also when this game has no nametags.

getNametagText(): string

Reads this player's nametag text override.

Returns The override, or an empty string when the player's own name is drawn.

getNametagColor(): number

Reads this player's nametag color.

Returns Packed 0xAARRGGBB color; opaque white when untinted.

kick(reason?: string)

Disconnects this player from the server.

reason
Optional reason shown to the disconnected player; omitting it uses the generic kicked reason.
emit(eventName: string, payloadJson?: string)

Emits a named script event to this player's client connection.

eventName
Client event name.
payloadJson
Optional JSON payload forwarded verbatim to the owning client.
getIP(): string

Returns this player's current remote network address.

Returns Address string, or an empty string when the player or peer is unavailable.

setNametagVisible(visible: boolean)

Shows or hides the name over this player's head for every other player. The health bar has its own switch, and each player can still hide all nametags locally.

visible
True to show this player's nametag to everyone, false to hide it.
setNametagHealthVisible(visible: boolean)

Shows or hides the health bar under this player's nametag, leaving the name itself alone.

visible
True to show the health bar under this player's name, false to hide it.
setNametagText(text?: string)

Overrides the text drawn on this player's nametag.

text
Text to show instead of the player's name, cut to 64 bytes; empty or omitted restores the name.
setNametagColor(color: number)

Tints the text on this player's nametag.

color
Packed 0xAARRGGBB color.

Entity

class

Base handle for a live replicated network entity.

Constructor
new Entity(id: number)

Creates a script wrapper for an existing entity with this ID; it does not spawn an entity.

id
Network entity identifier.
Properties
id: numberread-only

Immutable network entity identifier.

virtualWorld: numberread-only

Current virtual-world identifier.

position: Vector3

Authoritative world-space position; assignment forces replicated state.

rotation: Quaternion | Vector3

Authoritative rotation; reads return a quaternion and assignments accept a quaternion or Euler angles in degrees.

state: StateBagread-only

Arbitrary key/value state carried by this entity. The server writes it and every client that can see the entity receives it; see StateBag.

Methods
toString(): string

Formats this entity handle for logging and debugging.

Returns Text containing the network entity ID.

setVirtualWorld(world: number)

Moves this entity into another virtual world.

world
Virtual-world identifier used to partition replication and visibility.
setVisibleTo(player: Entity | null)

Restricts replication of this entity to one owning connection while preserving normal range and visibility checks.

player
Player-owned entity whose connection should exclusively receive this entity, or null to clear the restriction.

Item

classextends Entity

A loose item in the world: one a player dropped or a script spawned. Picking it up destroys it, after which the handle reads nothing. Setting `position` moves it for everyone.

Constructor
new Item(id: number)

Wraps an existing item with this ID; it spawns nothing. See `Item.spawn`.

id
Network entity identifier.
Properties
form: numberread-only

The base object's form ID; 0 once it is gone.

count: numberread-only

How many the stack holds; 0 once it is gone.

Methods
destroy(): boolean

Takes the item out of the world for everyone.

Returns True when it was there to take.

toString(): string

Formats this handle for logging.

Returns The item's network ID, form and count.

getSpace(): PlayerSpace | null

Where the item lies.

Returns The worldspace or interior cell, or null once it is gone.

static spawn(form: number | string, count: number, position: Vector3, space: { worldSpace?: number | string; interiorCell?: number | string }, angle?: Vector3): Item | null

Puts a loose item in the world, which any player can pick up. It does not fall: it stays where it is put.

form
The base object.
count
How many, 1 to 1000000.
position
Where it lies.
space
The worldspace, or the interior cell: exactly one of the two.
angle
Its rotation, radians.

Returns The item, or null when it could not be created.

static all(): Item[]

Every loose item in the world.

Returns One handle per item.

StateBag

class

Arbitrary key/value state attached to one replicated entity, reached as `entity.state`. Keys set on the server replicate to every client that can currently see the entity.

Methods
get(key: string): any

Reads one key from this entity's state.

key
Key to read.

Returns The stored value, or undefined when the key is not set.

has(key: string): boolean

Checks whether this entity's state holds a key.

key
Key to test.

Returns True when the key is set.

keys(): string[]

Lists the keys this entity's state holds, sorted.

Returns Every key currently set, in ascending order.

toObject(): Record<string, any>

Copies this entity's whole state into a plain object.

Returns Every key and value currently set. The copy does not track later changes.

onChange(key: string | null, handler: Function): Function

Watches this entity's state. The filter is applied before the handler runs, so a listener watching one key of one entity is not woken by unrelated changes. The subscription is dropped when the registering resource stops.

key
Only report this key, or null to report every key of this entity.
handler
Called as (key: string, value: any, previous: any) with the changed key, its new value and the value before it. `value` is undefined when the key was removed and `previous` is undefined when it held nothing.

Returns A zero-argument function that cancels this subscription.

set(key: string, value: any, options?: { scope?: 'broadcast' | 'owner' | 'server' }): boolean

Writes one key of this entity's state and replicates it to whoever the scope names. Throws when a limit is reached.

key
Key to write; at most 64 UTF-8 bytes.
value
Value to store. Booleans, numbers and strings travel as themselves; anything else is serialized as JSON. At most 4096 bytes.
options
Who the key reaches: every client that can see the entity (the default), only its owning client, or nobody -- server-side storage that never goes on the wire.

Returns True when the value changed, false when it was already stored.

remove(key: string): boolean

Removes one key from this entity's state, telling every client that held it.

key
Key to drop.

Returns True when the key was set and has been removed.

PendingConnection

type

A player asking to join, handed to `playerConnecting`. Every identifier is reported by the player's own client and is not verified by the server.

Properties
nickname: stringread-only

The name the player asked to join under.

steamId: stringread-only

Steam identifier the client reported, or an empty string when it had none.

epicId: stringread-only

Epic Games account identifier the client reported, or an empty string when it had none.

discordId: stringread-only

Discord identifier the client reported, or an empty string when it had none.

hardwareId: stringread-only

Framework hardware identifier the client reported, or an empty string when it had none.

ticket: stringread-only

The string the client was launched with, as the `ticket` of its launch link, or an empty string. The framework passes it through untouched; checking it -- against a one-time join ticket your own launcher or website issued, typically -- is the script's job.

ip: stringread-only

The remote address the connection comes from, without its port.

Methods
reject(reason?: string)

Turns the player away before they receive anything. Takes effect on the next server tick, whatever other handlers are still doing. Does nothing once the connection is decided or the player has left.

reason
Shown to the player as written, up to 512 bytes. Omitted, they read that the server refused the connection.
update(message: string)

Shows the waiting player a line of status and restarts the admission timeout, so a queue that keeps updating its players is never timed out. Does nothing once the connection is decided or the player has left.

message
One line for the player's connecting screen, up to 256 bytes: 'Checking the whitelist', 'You are 4th in the queue'.
isPending(): boolean

Checks whether this connection is still waiting on a decision.

Returns False once it was let in or turned away, or the player gave up and left; a queue drops such entries.

Maths and colour

Positions, rotations and colours, with the operators you expect.

Vector2

class

Mutable two-dimensional vector.

Constructor
new Vector2(x: number, y: number)

Creates a vector from two numeric components.

x
Initial X component.
y
Initial Y component.
Properties
x: number

Mutable X component.

y: number

Mutable Y component.

length: numberread-only

Read-only Euclidean magnitude of this vector.

lengthSquared: numberread-only

Read-only squared magnitude, avoiding a square-root calculation.

Methods
add(other: Vector2): this

Adds another vector to this vector in place.

other
Vector to add component-wise.

Returns This mutated vector for chaining.

sub(other: Vector2): this

Subtracts another vector from this vector in place.

other
Vector to subtract component-wise.

Returns This mutated vector for chaining.

mul(scalar: number): this

Multiplies this vector by a scalar in place.

scalar
Multiplier applied to both components.

Returns This mutated vector for chaining.

div(scalar: number): this

Divides this vector by a scalar in place.

scalar
Divisor applied to both components; must be non-zero.

Returns This mutated vector for chaining.

dot(other: Vector2): number

Computes the dot product without changing either vector.

other
Vector used for the dot product.

Returns Scalar dot product.

normalize(): this

Normalizes this vector in place; a zero vector remains unchanged.

Returns This mutated vector for chaining.

lerp(target: Vector2, t: number): this

Linearly interpolates this vector toward a target in place.

target
Destination vector.
t
Interpolation factor; 0 keeps the current value and 1 reaches target.

Returns This mutated vector for chaining.

set(x: number, y: number): this

Replaces both components in place.

x
Replacement X component.
y
Replacement Y component.

Returns This mutated vector for chaining.

distance(other: Vector2): number

Computes Euclidean distance to another vector.

other
Vector to measure from this vector.

Returns Distance between the two vectors.

clone(): Vector2

Creates an independent copy of this vector.

Returns New vector with the same components.

toString(): string

Formats this vector for logging and debugging.

Returns Text in Vector2(x, y) form.

toJSON(): { x: number; y: number }

Converts this vector to a plain object for JSON.stringify.

Returns Object containing the current components.

static zero(): Vector2

Creates a vector whose components are zero.

Returns New Vector2(0, 0).

static one(): Vector2

Creates a vector whose components are one.

Returns New Vector2(1, 1).

Vector3

class

Mutable three-dimensional vector for positions, directions, and Euler angles.

Constructor
new Vector3(x: number, y: number, z: number)

Creates a vector from three numeric components.

x
Initial X component.
y
Initial Y component.
z
Initial Z component.
Properties
x: number

Mutable X component.

y: number

Mutable Y component.

z: number

Mutable Z component.

length: numberread-only

Read-only Euclidean magnitude of this vector.

lengthSquared: numberread-only

Read-only squared magnitude, avoiding a square-root calculation.

Methods
add(other: Vector3): this

Adds another vector to this vector in place.

other
Vector to add component-wise.

Returns This mutated vector for chaining.

sub(other: Vector3): this

Subtracts another vector from this vector in place.

other
Vector to subtract component-wise.

Returns This mutated vector for chaining.

mul(scalar: number): this

Multiplies this vector by a scalar in place.

scalar
Multiplier applied to every component.

Returns This mutated vector for chaining.

div(scalar: number): this

Divides this vector by a scalar in place.

scalar
Divisor applied to every component; must be non-zero.

Returns This mutated vector for chaining.

dot(other: Vector3): number

Computes the dot product without changing either vector.

other
Vector used for the dot product.

Returns Scalar dot product.

cross(other: Vector3): this

Replaces this vector with its cross product against another vector.

other
Second vector in the cross product.

Returns This mutated perpendicular vector for chaining.

normalize(): this

Normalizes this vector in place; a zero vector remains unchanged.

Returns This mutated vector for chaining.

lerp(target: Vector3, t: number): this

Linearly interpolates this vector toward a target in place.

target
Destination vector.
t
Interpolation factor; 0 keeps the current value and 1 reaches target.

Returns This mutated vector for chaining.

set(x: number, y: number, z: number): this

Replaces all components in place.

x
Replacement X component.
y
Replacement Y component.
z
Replacement Z component.

Returns This mutated vector for chaining.

distance(other: Vector3): number

Computes Euclidean distance to another vector.

other
Vector to measure from this vector.

Returns Distance between the two vectors.

clone(): Vector3

Creates an independent copy of this vector.

Returns New vector with the same components.

toString(): string

Formats this vector for logging and debugging.

Returns Text in Vector3(x, y, z) form.

toJSON(): { x: number; y: number; z: number }

Converts this vector to a plain object for JSON.stringify.

Returns Object containing the current components.

static zero(): Vector3

Creates a zero vector.

Returns New Vector3(0, 0, 0).

static one(): Vector3

Creates a vector whose components are one.

Returns New Vector3(1, 1, 1).

static up(): Vector3

Creates the framework's positive-Y unit direction.

Returns New Vector3(0, 1, 0).

static forward(): Vector3

Creates the framework's positive-Z unit direction.

Returns New Vector3(0, 0, 1).

static right(): Vector3

Creates the framework's positive-X unit direction.

Returns New Vector3(1, 0, 0).

Vector4

class

Mutable four-dimensional vector.

Constructor
new Vector4(x: number, y: number, z: number, w: number)

Creates a vector from four numeric components.

x
Initial X component.
y
Initial Y component.
z
Initial Z component.
w
Initial W component.
Properties
x: number

Mutable X component.

y: number

Mutable Y component.

z: number

Mutable Z component.

w: number

Mutable W component.

length: numberread-only

Read-only Euclidean magnitude of this vector.

lengthSquared: numberread-only

Read-only squared magnitude, avoiding a square-root calculation.

Methods
add(other: Vector4): this

Adds another vector to this vector in place.

other
Vector to add component-wise.

Returns This mutated vector for chaining.

sub(other: Vector4): this

Subtracts another vector from this vector in place.

other
Vector to subtract component-wise.

Returns This mutated vector for chaining.

mul(scalar: number): this

Multiplies this vector by a scalar in place.

scalar
Multiplier applied to every component.

Returns This mutated vector for chaining.

div(scalar: number): this

Divides this vector by a scalar in place.

scalar
Divisor applied to every component; must be non-zero.

Returns This mutated vector for chaining.

dot(other: Vector4): number

Computes the dot product without changing either vector.

other
Vector used for the dot product.

Returns Scalar dot product.

distance(other: Vector4): number

Computes Euclidean distance to another vector.

other
Vector to measure from this vector.

Returns Distance between the two vectors.

normalize(): this

Normalizes this vector in place; a zero vector remains unchanged.

Returns This mutated vector for chaining.

lerp(target: Vector4, t: number): this

Linearly interpolates this vector toward a target in place.

target
Destination vector.
t
Interpolation factor; 0 keeps the current value and 1 reaches target.

Returns This mutated vector for chaining.

set(x: number, y: number, z: number, w: number): this

Replaces all components in place.

x
Replacement X component.
y
Replacement Y component.
z
Replacement Z component.
w
Replacement W component.

Returns This mutated vector for chaining.

clone(): Vector4

Creates an independent copy of this vector.

Returns New vector with the same components.

toString(): string

Formats this vector for logging and debugging.

Returns Text in Vector4(x, y, z, w) form.

toJSON(): { x: number; y: number; z: number; w: number }

Converts this vector to a plain object for JSON.stringify.

Returns Object containing the current components.

static zero(): Vector4

Creates a zero vector.

Returns New Vector4(0, 0, 0, 0).

static one(): Vector4

Creates a vector whose components are one.

Returns New Vector4(1, 1, 1, 1).

Quaternion

class

Mutable quaternion for three-dimensional rotations. Components are scalar-first (w, x, y, z), matching GLM — not the x, y, z, w order some libraries use.

Constructor
new Quaternion(w: number, x: number, y: number, z: number)

Creates a quaternion in scalar-first w, x, y, z component order. Watch the trap: the scalar w is the first argument, unlike the x, y, z, w order used by some other libraries.

w
Initial scalar component (comes first — this is not x, y, z, w order).
x
Initial X imaginary component.
y
Initial Y imaginary component.
z
Initial Z imaginary component.
Properties
w: number

Mutable scalar component.

x: number

Mutable X imaginary component.

y: number

Mutable Y imaginary component.

z: number

Mutable Z imaginary component.

length: numberread-only

Read-only magnitude (norm) of this quaternion; 1 for a unit rotation.

lengthSquared: numberread-only

Read-only squared magnitude, avoiding a square-root calculation.

Methods
mul(other: Quaternion): this

Composes this rotation with another quaternion in place.

other
Rotation composed after this quaternion.

Returns This mutated quaternion for chaining.

normalize(): this

Normalizes this quaternion in place; a zero quaternion becomes the identity rotation instead of NaN.

Returns This unit quaternion for chaining.

conjugate(): Quaternion

Computes the conjugate without changing this quaternion.

Returns New conjugated quaternion.

inverse(): Quaternion

Computes the inverse rotation without changing this quaternion.

Returns New inverse quaternion.

slerp(target: Quaternion, t: number): this

Spherically interpolates this quaternion toward a target in place.

target
Destination rotation.
t
Interpolation factor; 0 keeps the current rotation and 1 reaches target.

Returns This mutated quaternion for chaining.

dot(other: Quaternion): number

Computes the quaternion dot product.

other
Quaternion used for the dot product.

Returns Scalar dot product.

rotateVector(vector: Vector3): Vector3

Applies this rotation to a vector without mutating either value.

vector
Vector to rotate.

Returns New rotated vector.

toEuler(): Vector3

Converts this rotation to Euler angles in radians.

Returns Pitch, yaw, and roll as a Vector3.

set(w: number, x: number, y: number, z: number): this

Replaces all quaternion components in place.

w
Replacement scalar component.
x
Replacement X imaginary component.
y
Replacement Y imaginary component.
z
Replacement Z imaginary component.

Returns This mutated quaternion for chaining.

clone(): Quaternion

Creates an independent copy of this quaternion.

Returns New quaternion with the same components.

toString(): string

Formats this quaternion for logging and debugging.

Returns Text in Quaternion(w, x, y, z) form.

toJSON(): { w: number; x: number; y: number; z: number }

Converts this quaternion to a plain object for JSON.stringify.

Returns Object containing the current components.

static identity(): Quaternion

Creates the identity rotation.

Returns New Quaternion(1, 0, 0, 0).

static fromEuler(pitch: number, yaw: number, roll: number): Quaternion

Creates a rotation from Euler angles.

pitch
Pitch angle in radians.
yaw
Yaw angle in radians.
roll
Roll angle in radians.

Returns New rotation quaternion.

static fromAxisAngle(axis: Vector3, angle: number): Quaternion

Creates a rotation around an axis.

axis
Rotation axis; it is normalized internally.
angle
Rotation angle in radians.

Returns New axis-angle rotation quaternion.

Color

class

Mutable RGBA color, with components stored from 0 to 1.

Constructor
new Color(r: number, g: number, b: number, a?: number)

Creates a color from normalized RGBA components.

r
Initial red component from 0 to 1.
g
Initial green component from 0 to 1.
b
Initial blue component from 0 to 1.
a
Optional alpha component from 0 to 1; defaults to 1.
Properties
r: number

Mutable normalized red component.

g: number

Mutable normalized green component.

b: number

Mutable normalized blue component.

a: number

Mutable normalized alpha component.

Methods
lerp(target: Color, t: number): this

Linearly interpolates every component toward a target in place.

target
Destination color.
t
Interpolation factor; 0 keeps this color and 1 reaches target.

Returns This mutated color for chaining.

set(r: number, g: number, b: number, a?: number): this

Replaces this color's normalized components in place.

r
Replacement red component from 0 to 1.
g
Replacement green component from 0 to 1.
b
Replacement blue component from 0 to 1.
a
Optional replacement alpha; defaults to 1 when omitted.

Returns This mutated color for chaining.

clone(): Color

Creates an independent copy of this color.

Returns New color with the same components.

toHex(includeAlpha?: boolean): string

Converts normalized components to a hexadecimal CSS-style string.

includeAlpha
Whether to append the alpha byte; defaults to false.

Returns Lowercase #rrggbb or #rrggbbaa string.

toString(): string

Formats this color for logging and debugging.

Returns Text in Color(r, g, b, a) form.

toJSON(): { r: number; g: number; b: number; a: number }

Converts this color to a plain object for JSON.stringify.

Returns Object containing the current normalized components.

static fromHex(hex: string): Color

Parses a hexadecimal color string.

hex
Hexadecimal color in #RRGGBB or #RRGGBBAA form; the leading # is optional. Three- and four-digit shorthands are not supported.

Returns Parsed color, or opaque white when the input is invalid.

static fromRGB(r: number, g: number, b: number, a?: number): Color

Creates a normalized color from byte components.

r
Red byte from 0 to 255.
g
Green byte from 0 to 255.
b
Blue byte from 0 to 255.
a
Optional alpha byte from 0 to 255; defaults to 255.

Returns New normalized color.

static white(): Color

Creates opaque white.

Returns New Color(1, 1, 1, 1).

static black(): Color

Creates opaque black.

Returns New Color(0, 0, 0, 1).

static red(): Color

Creates opaque red.

Returns New Color(1, 0, 0, 1).

static green(): Color

Creates opaque green.

Returns New Color(0, 1, 0, 1).

static blue(): Color

Creates opaque blue.

Returns New Color(0, 0, 1, 1).

static yellow(): Color

Creates opaque yellow.

Returns New Color(1, 1, 0, 1).

static cyan(): Color

Creates opaque cyan.

Returns New Color(0, 1, 1, 1).

static magenta(): Color

Creates opaque magenta.

Returns New Color(1, 0, 1, 1).

static transparent(): Color

Creates fully transparent black.

Returns New Color(0, 0, 0, 0).

Other types

The structural types the API passes around.

PlayerSpace

type

Where a player is: the worldspace it stands in, or the interior cell, which has none.

Properties
worldSpace: number

The TESWorldSpace form ID; 0 inside an interior.

interiorCell: number

The interior TESObjectCELL form ID; 0 outside.

PlayerWeapon

type

The weapon in a player's hands, drawn or holstered.

Properties
form: number

The TESObjectWEAP form ID.

ammo: number

The ammo form ID it loads; 0 for none.

mods: number[]

The OMOD form IDs attached to it.

OutfitPiece

type

One armor piece a player wears, with the mods attached to it.

Properties
form: number

The TESObjectARMO form ID.

mods: number[]

The OMOD form IDs attached to it.

InventoryItem

type

A stack in a player's inventory, as the server's record holds it.

Properties
form: number

The base object's form ID.

count: number

How many the player carries.

InventoryDelta

type

How many of one item a player's inventory gained or lost.

Properties
form: number

The base object's form ID.

delta: number

Gained when positive, lost when negative.

from: number | null

The reference on the other side, such as a container; null for none the game named.

Timeout

type

Node.js timer handle returned by setTimeout and setInterval.

Methods
ref(): Timeout

Keeps the event loop alive while this timer is pending.

Returns This timer.

unref(): Timeout

Lets the event loop exit while this timer is still pending.

Returns This timer.

hasRef(): boolean

Whether this timer keeps the event loop alive.

refresh(): Timeout

Restarts this timer's countdown from now, with its original delay.

Returns This timer.

Timers

Free functions, the same shape as the browser and Node ones.

Timers

global
Methods
setTimeout(handler: (...args: any[]) => void, milliseconds?: number, ...args: unknown[]): Timeout

Calls a function once after a delay.

handler
Function to call.
milliseconds
Delay before the call.
args
Arguments passed to the handler.

Returns Handle to pass to the matching clear function.

setInterval(handler: (...args: any[]) => void, milliseconds?: number, ...args: unknown[]): Timeout

Calls a function repeatedly, waiting the delay between calls.

handler
Function to call.
milliseconds
Delay before the call.
args
Arguments passed to the handler.

Returns Handle to pass to the matching clear function.

clearTimeout(handle?: Timeout)

Cancels a pending setTimeout.

handle
Handle returned when the timer was scheduled; anything else is ignored.
clearInterval(handle?: Timeout)

Cancels a setInterval.

handle
Handle returned when the timer was scheduled; anything else is ignored.
queueMicrotask(callback: () => void)

Queues a function on the microtask queue.

callback
Function to run once the current task completes.

The vault door is open

Builds are released in the Discord. Join it to get the current one, follow development, and help work out what the wasteland should feel like with other people in it.

Join the Discord