Search docs
Search modules and symbols
API overview

API overview

Author-time types ship in two npm packages; the engine injects the runtime at load:

  • @s2script/sdk — every engine-generic capability. Prefer the root barrel (import { command, hook } from "@s2script/sdk"); subpaths (@s2script/sdk/entity, /events, /chat, …) stay valid. Also carries the s2s build CLI. @s2script/sdk/unsafe stays a deliberate subpath.
  • @s2script/cs2 — CS2 game types (Player, Pawn, schema accessors, the typed event overlay, ChatColors). Player is not on the SDK barrel.

How imports work

import { command, hook, HookResult } from '@s2script/sdk';
import { Player } from '@s2script/cs2';

Add @s2script/sdk (and @s2script/cs2) to your package’s dependencies. The CLI externalizes both by wildcard; the host maps @s2script/sdk/<name> → the injected runtime module. Subpath imports stay valid.

Two flavors of API

  • Load-window APIs — call from OnPluginStart; they throw after settle. command, hook.on / hook.onPre, translations, publish / use / tryUse, previous(), pluginId(), createScope(), onOutput, topmenu. On CS2, ui, gameRules, players, items. These are ledgered and torn down on unload.
  • Named publicsOnPluginStart / OnPluginEnd / OnPluginState, OnMapStart / OnGameFrame / OnClientConnected / OnEntityCreated / OnTakeDamage / … Missing export = not subscribed. Game events are hook.on / hook.onPre, not hook subjects.
  • Stateless helpers are plain named imports — Chat, Player, Admin, config, Translations, Events.fire, delay, fetch. config.onChange is typed on the free config import and is not load-window-gated.

SDKHook is the exception to load-window registration: per-entity, books-gated, callable whenever you hold a live EntityRef. See SDKHooks (OnTakeDamage, SetTransmit, lifecycle virtuals).

import { hook, Chat } from '@s2script/sdk';

export function OnPluginStart(): void {
  hook.on('round_start', () => Chat.toAll('go!')); // game-event catalog → hook
}

export function OnGameFrame(): void {
  // before simulation — SourceMod's public. There is no OnGameFramePre / OnGameFramePost.
}

Post-simulation work is createScope().server.onGameFrame(fn, { phase: 'post' }), not a named public. See lifecycle.

Engine-generic highlights

SubpathRole
@s2script/sdkAuthoring barrel: command, hook, previous, named-public types
@s2script/sdk/pluginhook (game-event catalog), onOutput, createScope, previous, publish / use, Scope
@s2script/sdk/entityEntityRef, create/spawn, I/O
@s2script/sdk/eventsFire events + HookResult
@s2script/sdk/sdkhooksSDKHook / SDKUnhook (OnTakeDamage, SetTransmit, lifecycle virtuals)
@s2script/sdk/timersdelay / nextTick / nextFrame
@s2script/sdk/clientsClient handle
@s2script/sdk/commandscommand / command.admin / command.server
@s2script/sdk/chatChat send
@s2script/sdk/adminAdmin flags + cache
@s2script/sdk/serverServer.command, cvars
@s2script/sdk/dbSQLite / SQL database
@s2script/sdk/http · /ws · /netAsync network
@s2script/sdk/menu · /votesMenus + votes
@s2script/sdk/translationsPhrase files + cmd.replyT
@s2script/sdk/unsafePlugin-declared engine calls and inbound hooks

CS2

@s2script/cs2Player, Pawn, schema accessors, the typed event overlay, ChatColors, pickPlayer, Fade/Shake/HintText, and ui (custom Panorama HUD — prefer components()). Load-window CS2 exports: ui, gameRules, players, items.

Next

s2script — Source 2 plugin framework

GitHub