Skip to content

Client globals clientside ​

Everything available to clientside weapons (*.client.ts), client classes and clientside NPC code (weapons/globals.client.d.ts).

Source

Generated from templates/server/data/scripts/weapons/globals.client.d.ts. To change this page, edit the JSDoc in that file.

Overview ​

Ambient declarations for host functions injected by the CLIENT's ClearScript V8 runtime (see GClient's WeaponRuntime). These are available to every weapon's clientside script (*.client.ts) without needing an import. The server-side globals (scripts/globals.d.ts) do not exist here.

Fire-and-forget host calls (echo, disabledefmovement, ...) are batched: they queue JS-side and apply at the next flush point — the end of the current onUpdate dispatch at the latest, i.e. still within the same frame. Ordering between batched calls is preserved, but their arguments must be JSON-serializable and they cannot return values. Calls that return values (keydown, player reads) reach the host directly.

Writing player.x / player.y / player.dir is batched too: any number of writes in a flush window fold into ONE host command that applies at flush. Reads see your pending writes immediately (player.x += 2 twice moves by 4), but the clamp to level bounds only happens when the write applies.

Declarations ​

echo function ​

ts
declare function echo(msg: string): void

Prints a message to the client console. Batched: applied at the next flush point (end of the current onUpdate dispatch at the latest).

sleep function ​

ts
declare function sleep(seconds: number): Promise<void>

Cooperatively pauses the calling (async) script for the given number of seconds. Other weapon scripts keep running while this one is suspended. Resolution is tied to frames, so resume timing is rounded up to the next frame.

setTimeout function ​

ts
declare function setTimeout(handler: (...args: any[]) => void, ms?: number, ...args: any[]): number

Runs handler once after ms milliseconds (rounded up to the next frame). Returns an id usable with clearTimeout. Extra args are forwarded to the handler.

clearTimeout function ​

ts
declare function clearTimeout(id: number): void

Cancels a pending setTimeout by id.

setInterval function ​

ts
declare function setInterval(handler: (...args: any[]) => void, ms?: number, ...args: any[]): number

Runs handler repeatedly every ms milliseconds (fires at most once per frame). Returns an id usable with clearInterval. Extra args are forwarded to the handler.

clearInterval function ​

ts
declare function clearInterval(id: number): void

Cancels a running setInterval by id.

keydown function ​

ts
declare function keydown(key: string): boolean

Whether a key is held this frame. Accepts "up", "down", "left", "right", letters ("a".."z"), digits ("0".."9"), and named keys like "space" or "leftshift". Always false while the game window is inactive or while the player is typing in the chat bar or a text field. Direct call: reads live input, safe to use for movement.

mousex function ​

ts
declare function mousex(): number

Mouse position in window (screen) pixels. The world scrolls under the camera, so convert to world pixels before touching tiles: the hovered tile is floor((mousex() + camerax()) / 16), floor((mousey() + cameray()) / 16). Frozen while the game window is inactive. Direct call: reads live input.

mousey function ​

ts
declare function mousey(): number

Mouse position in window (screen) pixels. The world scrolls under the camera, so convert to world pixels before touching tiles: the hovered tile is floor((mousex() + camerax()) / 16), floor((mousey() + cameray()) / 16). Frozen while the game window is inactive. Direct call: reads live input.

camerax function ​

ts
declare function camerax(): number

World pixels of the screen's top-left corner (the camera offset): worldPx = screenPx + camerax()/cameray(). Direct call: reads live data.

cameray function ​

ts
declare function cameray(): number

World pixels of the screen's top-left corner (the camera offset): worldPx = screenPx + camerax()/cameray(). Direct call: reads live data.

ScreenWidth global ​

ts
declare const ScreenWidth: number

Current client viewport size in pixels. Live values (they track window resizes), handy for centering screen-space findimg images: img.x = ScreenWidth / 2 with style 'c' centers text on screen.

ScreenHeight global ​

ts
declare const ScreenHeight: number

Current client viewport size in pixels. Live values (they track window resizes), handy for centering screen-space findimg images: img.x = ScreenWidth / 2 with style 'c' centers text on screen.

TextMeasurement interface ​

ts
interface TextMeasurement

Result of measuretext().

TextMeasurement.width ​

ts
width: number

Width of the widest line, in pixels.

TextMeasurement.height ​

ts
height: number

Total height of all lines, in pixels (lines.length * lineheight).

TextMeasurement.lineheight ​

ts
lineheight: number

Height of one line in pixels for that font/fontsize/style.

TextMeasurement.lines ​

ts
lines: string[]

The text as rendered lines: explicit newlines, plus word-wrapping when width was given. Join a slice with '\n' to show part of a long text.

measuretext function ​

ts
declare function measuretext(
    text: string,
    opts?: { font?: string, fontsize?: number, style?: string, width?: number }
): TextMeasurement

Measures text the way a GuiTextCtrl renders it. font/fontsize/style are the label props (omit for the label defaults); width > 0 word-wraps like a label with that width set, so lines is exactly what such a label would draw. Direct call: returns a value.

setfocus function ​

ts
declare function setfocus(x: number, y: number): void

Pins the camera so tile (x, y) sits at the center of the screen, instead of following the player. Stays pinned until resetfocus(), or until any weapon is removed from the player (the client resets focus, ambient light and default movement whenever a weapon is taken away). Batched.

resetfocus function ​

ts
declare function resetfocus(): void

Returns the camera to following the player. Batched.

setambient function ​

ts
declare function setambient(r: number, g: number, b: number): void

Sets the ambient light level, 0-255 per channel. Below 255,255,255 the world darkens and NPC lights (drawaslight) become visible; lights with lightmode = 1 are visible at any ambient level. Persists across level changes for the session like setfocus, and resets when any weapon is removed from the player. Default 255,255,255 (lighting off). Batched.

resetambient function ​

ts
declare function resetambient(): void

Restores full ambient light (disables the lighting pass). Batched.

mousedown function ​

ts
declare function mousedown(button: 'left' | 'right' | 'middle'): boolean

Whether a mouse button is held this frame. Always false while the game window is inactive. Direct call: reads live input.

mouseonui function ​

ts
declare function mouseonui(): boolean

Whether the mouse cursor is over any GUI control (windows, buttons, the chat bar...). Use it to keep world clicks from firing through UI. Chat bubbles are not interactive and don't count. Direct call.

updatelevel function ​

ts
declare function updatelevel(): void

Asks the server to re-save the current level's .glvl file, persisting every tile painted since the last save ("update level"). Batched.

(There is deliberately no client-side tile-painting function: painting is server-authoritative. Send the edit to a serverside script via triggerServer — it calls setleveltile, and the change comes back to every client in the level as a tile update. See the tileeditor weapon.)

gettile function ​

ts
declare function gettile(layer: number, x: number, y: number): number

Reads a tile of the current level: the row-major tileset index at (x,y) on layer, 65535 for empty, or -1 when out of range / no level is loaded. Direct call: reads live data.

onwall function ​

ts
declare function onwall(x: number, y: number, w?: number, h?: number): boolean

True when a blocking collision tile intersects [x, x+w) × [y, y+h), in tile units (fractions allowed). Omit w/h to test the single tile containing (x, y). Tiles outside the level count as blocked, as does having no level loaded. Blocking NPCs count too (see NpcThis.dontblock). The player's walking footprint is the lower body: onwall(player.x, player.y + 1, 2, 1). Direct call: reads live data.

tiletype function ​

ts
declare function tiletype(x: number, y: number): number

Collision type of the tile containing (x, y): 1 walkable, 22 blocking, etc. -1 when out of range or no level is loaded. Direct call: reads live data.

gmaptolevel function ​

ts
declare function gmaptolevel(gmapName: string, gx: number, gy: number): { level: string; x: number; y: number } | null

On a gmap, converts gmap-global tile coordinates to the member level under them and its member-local coordinates. The client only knows its CURRENT gmap: pass '' (or the current gmap's name) for gmapName; anything else — or not being on a gmap — returns null. While on a gmap, player.x/y and all tile/collision functions are gmap-global. Direct call: reads live data.

leveltogmap function ​

ts
declare function leveltogmap(levelName: string, x: number, y: number): { gmap: string; x: number; y: number } | null

On a gmap, converts member-level-local tile coordinates to gmap-global. Resolves only members of the CURRENT gmap (the client doesn't know other gmaps); anything else returns null. Direct call: reads live data.

ScriptImage interface ​

ts
interface ScriptImage

A client-only image object (never seen by the server or other players). Property writes are validated at the assignment site, readable back immediately, and coalesced into one batched host command per image per flush window. Draw order is controlled by layer, coordinate space by screen; all images draw below the GUI.

ScriptImage.id ​

ts
readonly id: number

The id this image was created with.

ScriptImage.image ​

ts
image: string

Server asset name, e.g. "images/pics1.png". '' (default) draws a solid width x height rectangle of the tint color. Ignored while polygon is set.

ScriptImage.imagerect ​

ts
imagerect: string

"left,top,width,height" px source region; '' shows the whole image.

ScriptImage.polygon ​

ts
polygon: number[]

Solid filled polygon drawn INSTEAD of the image/rectangle: a flat list of x,y pairs, vertices in order, at least 3 pairs (even length, finite numbers). [1,1, 3,1, 3,3, 1,3] is a 2x2-tile square from (1,1) to (3,3). Vertex units follow screen (tiles, or screen px); x/y offset every vertex and zoom scales them about that anchor, so with the defaults (0,0,1) the coordinates are absolute. Even-odd fill, so concave and self-intersecting outlines work. Respects layer, screen, visible, alpha and tint/red/green/blue; image, imagerect, width and height are ignored while set, and text still takes precedence. [] (default) clears it. Reads return a frozen copy of the last write.

ScriptImage.text ​

ts
text: string

Non-empty text renders INSTEAD of the image/rectangle. Text respects x/y, layer, screen, zoom (scale), tint/red/green/blue (color) and alpha; width/height and imagerect are ignored for text.

ScriptImage.style ​

ts
style: string

Any combination of 'b' (bold), 'i' (italic), 'c' (centered on x), in any order — "bci", "ib", "b", '' (default, plain left-aligned).

ScriptImage.font ​

ts
font: string

Font family for text; '' (default) is the built-in font. Unknown names fall back to the default.

ScriptImage.fontsize ​

ts
fontsize: number

Text size (default 16), in points at 96 DPI (the em is fontsize * 4/3 px), clamped to 256. Each size is rasterized exactly on first use, so any size stays crisp. Composes with zoom.

ScriptImage.textshadow ​

ts
textshadow: boolean

true draws a drop shadow behind the text (see shadowoffset/shadowcolor).

ScriptImage.shadowoffset ​

ts
shadowoffset: string

Shadow offset "x,y" in px (default "1,1"), scaled with zoom.

ScriptImage.shadowcolor ​

ts
shadowcolor: string

Shadow color "r,g,b" (0-255), default "0,0,0".

ScriptImage.x ​

ts
x: number

Position. World mode (screen=false): TILE coordinates like player.x — tile t sits at pixel t*16, and the image scrolls with the camera. Screen mode (screen=true): screen pixels from the top-left of the window.

ScriptImage.y ​

ts
y: number

Position. World mode (screen=false): TILE coordinates like player.x — tile t sits at pixel t*16, and the image scrolls with the camera. Screen mode (screen=true): screen pixels from the top-left of the window.

ScriptImage.layer ​

ts
layer: number

Draw order (default 4). World mode: 0-3 draw under NPCs and players (0 lowest, each layer over the previous); 4+ draw above players and projectiles. Screen mode: pure z-order among screen images, 0 lowest. Negative values clamp to 0; fractions truncate. Equal layers draw in (script, id) order.

ScriptImage.screen ​

ts
screen: boolean

false (default): x/y are world tile coordinates. true: x/y are screen pixels — the image ignores the camera and draws above the whole world and chat bubbles, but below GUI controls.

ScriptImage.zoom ​

ts
zoom: number

Scale factor (1 = natural size).

ScriptImage.alpha ​

ts
alpha: number

0 (invisible) .. 1 (opaque).

ScriptImage.red ​

ts
red: number

Color multiplier channels, 0..1 each (default 1 = unchanged). Applies to the image, rectangle or text — never to the text shadow (shadowcolor). red = 0; blue = 0 leaves only green. Same color as tint, viewed per channel: writing one updates the other.

ScriptImage.green ​

ts
green: number

Color multiplier channels, 0..1 each (default 1 = unchanged). Applies to the image, rectangle or text — never to the text shadow (shadowcolor). red = 0; blue = 0 leaves only green. Same color as tint, viewed per channel: writing one updates the other.

ScriptImage.blue ​

ts
blue: number

Color multiplier channels, 0..1 each (default 1 = unchanged). Applies to the image, rectangle or text — never to the text shadow (shadowcolor). red = 0; blue = 0 leaves only green. Same color as tint, viewed per channel: writing one updates the other.

ScriptImage.tint ​

ts
tint: string

"r,g,b" (0-255) color multiplier; "255,255,255" is unchanged. Same color as red/green/blue.

ScriptImage.width ​

ts
width: number

Explicit size in px, stretching the source region; -1 (default) = natural size.

ScriptImage.height ​

ts
height: number

Explicit size in px, stretching the source region; -1 (default) = natural size.

ScriptImage.visible ​

ts
visible: boolean

Explicit size in px, stretching the source region; -1 (default) = natural size.

ScriptImage.emitter ​

ts
readonly emitter: ParticleEmitter

The image's particle emitter (Graal particle engine). Created lazily on first access; does nothing until configured. Destroyed with the image (see emitter.continueafterdestroy). The emitter's origin reads the image's x/y as a WORLD position, so emitters on screen-mode images stay world-anchored (they do not follow the screen position).

ScriptImage.show ​

ts
show(): void

The image's particle emitter (Graal particle engine). Created lazily on first access; does nothing until configured. Destroyed with the image (see emitter.continueafterdestroy). The emitter's origin reads the image's x/y as a WORLD position, so emitters on screen-mode images stay world-anchored (they do not follow the screen position).

ScriptImage.hide ​

ts
hide(): void

The image's particle emitter (Graal particle engine). Created lazily on first access; does nothing until configured. Destroyed with the image (see emitter.continueafterdestroy). The emitter's origin reads the image's x/y as a WORLD position, so emitters on screen-mode images stay world-anchored (they do not follow the screen position).

ScriptImage.destroy ​

ts
destroy(): void

Removes the image for good; the id can be reused with findimg.

ParticleTemplate interface ​

ts
interface ParticleTemplate

Default attributes for the next emitted particles (emitter.particle). Writes are validated at the assignment site and batched like image props. Distances are in TILES, speeds in tiles/second.

ParticleTemplate.x ​

ts
x: number

Spawn offset from the emitter, tiles.

ParticleTemplate.y ​

ts
y: number

Spawn offset from the emitter, tiles.

ParticleTemplate.movex ​

ts
movex: number

Extra velocity on top of angle/speed, tiles/s.

ParticleTemplate.movey ​

ts
movey: number

Extra velocity on top of angle/speed, tiles/s.

ParticleTemplate.angle ​

ts
angle: number

Movement direction in radians; pi/2 moves up the screen.

ParticleTemplate.zangle ​

ts
zangle: number

Accepted for Graal compatibility; there is no 3D axis (ignored).

ParticleTemplate.speed ​

ts
speed: number

Movement speed, tiles/s.

ParticleTemplate.spin ​

ts
spin: number

Rotation rate of the image, rad/s.

ParticleTemplate.lifetime ​

ts
lifetime: number

Seconds until the particle disappears (max 60).

ParticleTemplate.alpha ​

ts
alpha: number

0 (invisible) .. 1 (opaque).

ParticleTemplate.rotation ​

ts
rotation: number

Image facing angle in radians (independent of movement).

ParticleTemplate.zoom ​

ts
zoom: number

Scale factor.

ParticleTemplate.stretchx ​

ts
stretchx: number

Scale factor.

ParticleTemplate.stretchy ​

ts
stretchy: number

Scale factor.

ParticleTemplate.red ​

ts
red: number

Color multipliers, 0..1 each.

ParticleTemplate.green ​

ts
green: number

Color multipliers, 0..1 each.

ParticleTemplate.blue ​

ts
blue: number

Color multipliers, 0..1 each.

ParticleTemplate.mode ​

ts
mode: number

Blend mode: 0 = additive, 1 = normal (default), 2 = subtractive.

ParticleTemplate.image ​

ts
image: string

Server asset name; '' (default) draws a solid 16x16 square.

ParticleModifierHandle interface ​

ts
interface ParticleModifierHandle

Handle returned by the addXmodifier functions; chains extra (variable, modtype, valuemin, valuemax) modifications onto the same schedule.

ParticleModifierHandle.addmod ​

ts
addmod(variable: string, modtype: 'replace' | 'add' | 'multiply',
        valuemin: number, valuemax: number): ParticleModifierHandle

ParticleEmitter interface ​

ts
interface ParticleEmitter

A particle emitter attached to a script image (Graal particle engine). Configuration writes batch like image props; emit()/modifier calls keep program order with them. The emitter sits at its image's position (plus emissionoffset) and spawns particles that fly on their own.

Modifier schedules — all three functions share the signature (type, rangemin, rangemax, variable, modtype, valuemin, valuemax):

  • 'once': fires when the clock passes rangemin, applying a random value
ts
in [valuemin, valuemax].
  • 'impulse': refires at random intervals in [rangemin, rangemax] seconds.
  • 'range': over clock window [rangemin, rangemax]; 'replace' sets the
ts
interpolated valuemin->valuemax value, 'add' treats the interpolated
value as a RATE PER SECOND ('multiply' is not allowed).

The clock is the particle's age for addlocalmodifier and the emitter's age for addglobalmodifier (all live particles at once) and addemitmodifier (mutates emitter.particle instead). Modifiable variables: x, y, movex, movey, angle, speed, rotation, spin, stretchx, stretchy, red, green, blue, alpha, zoom (x/y in tiles).

ParticleEmitter.delaymin ​

ts
delaymin: number

Min/max seconds between automatic bursts (min 0.05). Default 0.5.

ParticleEmitter.delaymax ​

ts
delaymax: number

Min/max seconds between automatic bursts (min 0.05). Default 0.5.

ParticleEmitter.nrofparticles ​

ts
nrofparticles: number

Particles per burst (max 100). Default 1.

ParticleEmitter.maxparticles ​

ts
maxparticles: number

Concurrent particle cap for this emitter (max 1000). Default 100.

ParticleEmitter.emitautomatically ​

ts
emitautomatically: boolean

false stops the automatic bursts; emit() still works. Default true.

ParticleEmitter.isfrozen ​

ts
isfrozen: boolean

true pauses the emitter and all its particles (still drawn).

ParticleEmitter.continueafterdestroy ​

ts
continueafterdestroy: boolean

true lets live particles finish when the image is destroyed.

ParticleEmitter.attachposition ​

ts
attachposition: boolean

true keeps particles relative to the emitter as it moves.

ParticleEmitter.firstinfront ​

ts
firstinfront: boolean

First-emitted particle draws in front (default true).

ParticleEmitter.autorotation ​

ts
autorotation: boolean

true points each particle's rotation along its movement.

ParticleEmitter.emissionoffset ​

ts
emissionoffset: { xd: number; yd: number; zd?: number }

Emission position relative to the image, TILES (zd ignored).

ParticleEmitter.clippingbox ​

ts
clippingbox: { xd1: number; yd1: number; xd2: number; yd2: number; zd1?: number; zd2?: number }

Particles outside this emitter-relative box (tiles) are destroyed.

ParticleEmitter.cliptoscreen ​

ts
cliptoscreen: boolean

true clips to the visible screen instead of clippingbox.

ParticleEmitter.wraptoclippingbox ​

ts
wraptoclippingbox: boolean

true wraps clipped particles to the other side instead of destroying.

ParticleEmitter.particle ​

ts
readonly particle: ParticleTemplate

Default attributes for the next emission.

ParticleEmitter.dropemitter ​

ts
readonly dropemitter: ParticleEmitter

Sub-emitter bursting where this emitter's particles expire (one level deep).

ParticleEmitter.currentparticlecount ​

ts
readonly currentparticlecount: number

Live particle count (direct read).

ParticleEmitter.emittedparticles ​

ts
readonly emittedparticles: number

Total particles ever emitted (direct read).

ParticleEmitter.emit ​

ts
emit(): void

One manual burst of nrofparticles.

ParticleEmitter.removeparticles ​

ts
removeparticles(): void

Destroys all live particles.

ParticleEmitter.removemodifiers ​

ts
removemodifiers(): void

Removes all modifiers.

ParticleEmitter.addlocalmodifier ​

ts
addlocalmodifier(type: 'once' | 'impulse' | 'range', rangemin: number, rangemax: number,
        variable: string, modtype: 'replace' | 'add' | 'multiply',
        valuemin: number, valuemax: number): ParticleModifierHandle

Removes all modifiers.

ParticleEmitter.addglobalmodifier ​

ts
addglobalmodifier(type: 'once' | 'impulse' | 'range', rangemin: number, rangemax: number,
        variable: string, modtype: 'replace' | 'add' | 'multiply',
        valuemin: number, valuemax: number): ParticleModifierHandle

Removes all modifiers.

ParticleEmitter.addemitmodifier ​

ts
addemitmodifier(type: 'once' | 'impulse' | 'range', rangemin: number, rangemax: number,
        variable: string, modtype: 'replace' | 'add' | 'multiply',
        valuemin: number, valuemax: number): ParticleModifierHandle

Removes all modifiers.

findimg function ​

ts
declare function findimg(id: number): ScriptImage

Returns this script's image object with the given id, creating it on first use (visible=true, image=''). An image with no image, text or polygon draws as a solid 16x16 rectangle in its tint (white by default), so set visible = false on images used only as emitter anchors. Ids are PER SCRIPT — another weapon's findimg(1) is a different image. Usable in handlers, onCreated and timer callbacks (timers stay attributed to the script that set them). Images are swept automatically when the weapon unloads.

hideimg function ​

ts
declare function hideimg(id: number): void

Destroys this script's image with the given id (Graal convention).

disabledefmovement function ​

ts
declare function disabledefmovement(): void

Turns off the built-in arrow-key movement so this weapon can drive the player itself (by assigning player.x / player.y). Position sync to the server keeps running either way. Default movement comes back on whenever any weapon is removed from the player. Batched.

enabledefmovement function ​

ts
declare function enabledefmovement(): void

Re-enables the built-in arrow-key movement. Batched.

setAni function ​

ts
declare function setAni(name: string): void

Plays a .gan animation on the local player; the server relays it to everyone else in the level. Pass the animation name without the extension, e.g. setAni('sword'). Re-setting the current animation restarts it unless the animation is CONTINUOUS (like the default walk). When a non-looping animation finishes, its SETBACKTO chain (usually back to idle) resumes the built-in idle/walk switching. Batched.

replaceAni function ​

ts
declare function replaceAni(from: string, to: string): void

Replaces a default animation for the local player: wherever from would play — setAni(from), the built-in walk/idle switching, SETBACKTO chains, a server-set animation — to plays instead, and everyone else in the level sees to. If the player is in the old animation right now, it switches on the next frame. replaceAni(from, from) removes the replacement. One level only: replacements don't chain. Replacements last until clearAnis() (or the session ends) — removing the weapon that set them does NOT undo them. Direct (player.replacedAnis reflects it immediately). @example replaceAni('idle', 'handgun-idle'); replaceAni('walk', 'handgun-walk')

clearAnis function ​

ts
declare function clearAnis(...names: string[]): void

Restores replaced animations to their defaults: clearAnis('walk', 'idle') resets those two, clearAnis() resets every replacement. Direct.

triggerServer function ​

ts
declare function triggerServer(scriptType: 'weapon' | 'script', scriptName: string, ...params: any[]): void

Asks the server to invoke onActionServerSide on a serverside script, injecting params after the triggering player. Batched; params must be JSON-serializable.

scriptType "weapon" targets the serverside half of one of YOUR weapons (scripts/weapons/<scriptName>.ts — the server rejects weapons you don't have); "script" targets a plain server script (scripts/<scriptName>.ts). scriptName carries no extension — pass this.name to reach your own serverside half:

ts
triggerServer('weapon', this.name, 'dothing', 'hello')
// server: onActionServerSide(player, 'dothing', 'hello')

WeaponThis interface ​

ts
interface WeaponThis

Every handler in a weapon script runs with this bound to the weapon's own object: this.name is the weapon's name (file name without .client.ts), and scripts may stash extra state on this between calls. Only function declarations see it — arrow functions ignore this.

export is optional: every top-level function is exported by the build (so function onCreated() is a handler), and the weapon's own functions and joined class exports are callable on this too. Inside a top-level function this is always the weapon: a bare helper(...) call from a handler falls back to the running script's self instead of JS's undefined.

this types as any in handlers (noImplicitThis is off in tsconfig.json); annotate a handler with this: WeaponThis if you want it typed:

ts
export function onCreated(this: WeaponThis) { ... }

WeaponThis.name ​

ts
name: string

The weapon's name, e.g. "test" for test.client.ts.

WeaponThis.join ​

ts
join(name: string): boolean

Joins this script to a class's clientside half (scripts/classes/<name>.client.ts): the class's exported handlers fire after this script's own, its exported helpers become callable on this, and its onCreated runs now with this script as this. Serverside joins replicate here automatically. Returns false when the class has no clientside half.

WeaponThis.leave ​

ts
leave(name: string): boolean

Removes a joined class's handlers from this script.

WeaponThis.joinedclasses ​

ts
readonly joinedclasses: readonly string[]

Currently joined class names, in join order.

WeaponThis.[key] ​

ts
[key: string]: any

Scripts may keep arbitrary state on this.

player global ​

ts
declare const player: { … }

The local player. Reads are live; writes to x / y / dir / chat / head / body / colors are validated at the assignment site, readable back immediately, and coalesced into batched host commands per flush (position clamped to level bounds when it applies). Assigning anything else throws.

player.id ​

ts
readonly id: number

Server-assigned player id.

player.name ​

ts
readonly name: string

Account name.

player.account ​

ts
readonly account: string

Account name (same as name).

player.level ​

ts
readonly level: string

Current level (or gmap) name.

player.nick ​

ts
readonly nick: string

Display name rendered under the player. Read-only here — players change it with the setnick chat command, or a server script assigns player.nick. Your own tag is hidden; the showname chat command (and setnick) reveals it for 5 seconds. Other players' tags are always visible.

player.x ​

ts
x: number

Position in tiles. Writable; clamped to level bounds at flush.

player.y ​

ts
y: number

Position in tiles. Writable; clamped to level bounds at flush.

player.dir ​

ts
dir: "up" | "down" | "left" | "right"

Facing direction. Writable.

player.chat ​

ts
chat: string

Chat bubble above the player's head. Assigning shows it locally AND sends it to the server for everyone in the level ('' clears it); it fades 5s after the player moves. Text is trimmed to 200 chars and control characters become spaces. Batched like x/y/dir.

player.ani ​

ts
readonly ani: string

The player's current .gan animation name (without extension), including SETBACKTO chain results. Reports the gani actually played, so with idle replaced by 'handgun-idle' this reads 'handgun-idle' — compare against player.replacedAnis.idle ?? 'idle'. Read-only — play animations with setAni().

player.replacedAnis ​

ts
readonly replacedAnis: Record<string, string>

Current replaceAni() replacements, logical name → played gani, e.g. { idle: 'handgun-idle', walk: 'handgun-walk' }. A fresh snapshot per read; modifying it changes nothing.

player.head ​

ts
head: string

Head image, e.g. 'head0.png'; '' means the default (head0.png). Assigning is readable back immediately and, at flush, shown locally and sent to the server for everyone in the level (and saved to the account), like the sethead chat command. Invalid names are dropped.

player.body ​

ts
body: string

Body image, e.g. 'body.png'; '' means the default. Assign like head.

player.colors ​

ts
colors: string[]

Body colors as 'r,g,b' strings, recoloring the body's reserved key colors: [0] skin, [1] coat, [2] sleeves, [3] shoes, [4] belt. Always five entries. Assigning an index (player.colors[1] = '255,0,0') is readable back immediately and, at flush, shown locally and sent to the server for everyone in the level (and saved to the account). Invalid indices or values are ignored. Assigning an array sets each slot it provides.

player.hasWeapon ​

ts
hasWeapon(name: string): boolean

Whether the server currently grants you the named weapon (true as soon as the grant arrives, even if its script is still downloading). Grants change server-side only, via player.addWeapon/removeWeapon there.

client global ​

ts
declare const client: Record<string, any>

The local player's read/write script flags (the same set the server sees as player.client.*). Reads come from a local mirror and are readable back immediately after a write; each changed flag is coalesced per flush window and sent to the server (which does not echo it back). Values must be JSON-serializable; flag names are 1-128 characters, values up to 8192 characters of JSON — violations throw at the assignment site. Assigning null or undefined deletes a flag, as does delete client.foo. Persisted in your account on the server.

Values are stored JSON-normalized, and mutating a nested value does NOT sync it — reassign to write:

ts
const inv = client.inventory ?? []; inv.push('sword');
client.inventory = inv;

clientr global ​

ts
declare const clientr: Readonly<Record<string, any>>

Per-player flags the server set with player.clientr.* — read-only here (writes/deletes log a console warning and are ignored). Live-updating: server writes arrive as they happen; the full set arrives at login. Values are deep-frozen (local mutation would never sync anyway).

serverr global ​

ts
declare const serverr: Readonly<Record<string, any>>

Global flags the server set with serverr.* — identical on every client, read-only here (writes/deletes log a console warning and are ignored). Live-updating and deep-frozen like clientr.

CollectionEventMap interface ​

ts
interface CollectionEventMap

Events a client collection mirror fires.

CollectionEventMap.change ​

ts
change: (key: string, record: any) => void

One record changed: (key, record) — record is null on delete.

CollectionEventMap.reset ​

ts
reset: () => void

The whole replica was replaced (login snapshot, revoke).

CollectionQueryRow interface ​

ts
interface CollectionQueryRow

A row from a client-side collection query().

CollectionQueryRow.key ​

ts
key: string

CollectionQueryRow.record ​

ts
record: any

ClientCollection interface ​

ts
interface ClientCollection

Read-only materialized mirror of a server collection replica: built from snapshots (or the disk cache after a CollectionUpToDate), mutated in place by server deltas — reads are O(1) and records are deep-frozen. Which replicas are live is the server's call: eager owner/all arrive at login, level scopes track your level / gmap window (the mirror reads across every live scope), lazy and group replicas appear when a server script subscribes you and empty when it unsubscribes; anything else reads as empty.

ClientCollection.name ​

ts
readonly name: string

ClientCollection.get ​

ts
get(key: string): any

The record's value, or undefined. Frozen — local mutation would never sync.

ClientCollection.keys ​

ts
keys(): string[]

All record keys across the live scopes, sorted.

ClientCollection.forEach ​

ts
forEach(fn: (key: string, record: any) => void): void

All record keys across the live scopes, sorted.

ClientCollection.on ​

ts
on<K extends keyof CollectionEventMap>(event: K, listener: CollectionEventMap[K]): this

Subscribes to mirror changes — rebuild the one slot that changed instead of re-reading everything in onUpdate. Listeners belong to the registering script and are removed when it unloads. Chainable.

ClientCollection.off ​

ts
off<K extends keyof CollectionEventMap>(event: K, listener?: CollectionEventMap[K]): void

Removes a listener (or all listeners for the event when omitted).

ClientCollection.query ​

ts
query(opts?: {
        where?: string
        params?: (number | string | boolean | null)[]
        limit?: number
        offset?: number
        scope?: string
    }): Promise<CollectionQueryRow[]>

Explicit paged fetch straight from the server — THE access path for replicate-'none' collections (auction listings), and a paged view over anything sql-backed you may see. Access is audience-checked server-side: 'all' → the global set, 'owner' → your own scope, 'level' / 'group' → scopes you currently hold (pass scope). where addresses record fields by (dotted) name with ? params, like the serverside query API. Default limit 100, max 200.

ClientCollection.fetch ​

ts
fetch(key: string): Promise<any | null>
fetch(keys: string[]): Promise<(any | null)[]>

Per-record on-demand read — THE access path for replicate-'cache' collections (item catalogs). Resolves from the local mirror when the record is cached; otherwise round-trips to the server, which registers you for pushed updates to exactly the fetched keys (a 'change' fires whenever a fetched record later changes — including a key that was missing being created). Missing records resolve null. Concurrent fetches of one key coalesce onto a single request; max 64 keys per call. Rejects for collections that don't replicate 'cache'.

collection function ​

ts
declare function collection(name: string): ClientCollection

A stateless handle on a collection mirror. Unknown names read as empty.

ChatPlayer interface ​

ts
interface ChatPlayer

Frozen snapshot of a player (yourself or a remote player in the level) handed to event handlers like onPlayerChats.

ChatPlayer.id ​

ts
readonly id: number

Server-assigned player id; compare with player.id to spot yourself.

ChatPlayer.name ​

ts
readonly name: string

Account name.

ChatPlayer.nick ​

ts
readonly nick: string

Display name rendered under the player.

ChatPlayer.x ​

ts
readonly x: number

Position in tiles.

ChatPlayer.y ​

ts
readonly y: number

Position in tiles.

ChatPlayer.dir ​

ts
readonly dir: "up" | "down" | "left" | "right"

Facing direction.

ChatPlayer.chat ​

ts
readonly chat: string

The player's chat at the time of the event.

PMSender interface ​

ts
interface PMSender

Who a PM came from (onPMReceived).

PMSender.account ​

ts
readonly account: string

Sender's account, or the sending server's name for system PMs.

PMSender.server ​

ts
readonly server: string

Name of the GServer the sender is on ('' if unknown).

PMSender.system ​

ts
readonly system: boolean

True for PMs sent by a serverside script (sendPM on a GServer).

Friends, sendPM and reading PM text are NOT available here: they belong to the Login Server's privileged weapons (its global PM system). Game weapons only hear that a PM arrived, and from whom (onPMReceived). Event handlers. A weapon subscribes by exporting a function with the matching name; the client invokes it on every loaded weapon that exports one:

  • export function onCreated(): void
    Fired once when the weapon is loaded on the client (after download or from cache, shortly after login).

  • export function onUpdate(delta: number): void
    Fired every frame; delta is the elapsed time in seconds since the previous frame.

  • export function onKeyPressed(key: string): void
    Fired once when a key goes down; holding it does not repeat — it fires again only after the key is released and pressed again. key is the key name: letters uppercase ("T"), digits "0".."9", others like "Enter", "Space", "Up", "LeftShift", "F1" (keydown() accepts the same names). Silent while the chat bar or a text field has focus, or while the window is inactive. Fires on every weapon, clientside NPC script and joined class, before onUpdate in the same frame.

  • export function onActionClientSide(...params: any[]): void
    Fired when a serverside script calls triggerClient('weapon', <thisWeapon>, ...params) — the params arrive as the handler's arguments (JSON round-tripped).

  • export function onPlayerChats(player: ChatPlayer, chat: string): void
    Fired when any player in the level — yourself included — sets their chat, whether typed in the chat bar, assigned by a script, or set server-side ('' means it was cleared). Only actual changes fire, so setting the same text again is silent and a handler that reacts by writing player.chat can't feed back into itself. NOT fired when a bubble expires (5s after the owner moves) or for chats that already existed when their owner entered the level.

ts
Chat starting with '/' is a COMMAND (e.g. '/te'): it is not shown as a
bubble and never leaves this client, but it IS delivered here — with
the command as `chat` — so weapons can implement chat commands.
  • export function onShotAt(x: number, y: number, data: any): void
    A projectile (a serverside level.shoot) stopped in this level: it hit a blocking tile or its lifetime ran out. (x, y) is where it stopped — level tiles, gmap-global tiles on a gmap; data is the shoot call's payload. Fires on every weapon and clientside NPC script.

  • export function onShot(data: any): void
    A projectile hit THIS client's player. Only the hit player's client fires it; data is the shoot call's payload.

  • export function onPMReceived(sender: PMSender): void
    Someone sent you a private message, from any server — or a serverside script sent a system PM (sender.system is true). A notification only: the text is read by the Login Server's PM system (openPM), never here. Also fires on clientside NPC scripts.

WeaponHandle interface ​

ts
interface WeaponHandle

A handle on another loaded weapon script, from findweapon().

WeaponHandle.name ​

ts
readonly name: string

The weapon's name, e.g. "gun".

WeaponHandle.trigger ​

ts
trigger(event: string, ...params: any[]): boolean

Invokes the named exported handler on that weapon RIGHT NOW (its own export, then any joined classes), with this bound to that weapon and the params passed as live values (no JSON round trip). GUI controls and images the handler creates belong to the TARGET weapon. Returns false when the weapon has since unloaded or its handler threw (the error is logged); true otherwise, including when it exports no such handler.

findweapon function ​

ts
declare function findweapon(name: string): WeaponHandle | null

Finds another weapon script this client currently has LOADED, so one weapon can call into another — the inventory weapon uses it to deliver onWeaponFired / onEquipped / onUnequipped to the equipped item's weapon:

ts
findweapon('gun')?.trigger('onWeaponFired', entry)

null when the weapon is not granted or its script hasn't arrived yet, so re-look it up per call rather than caching the handle.

findWeapon function ​

ts
declare function findWeapon(name: string): WeaponHandle | null

Alias of findweapon.