Entities
An entity reference is EntityRef = { index, id } — a raw pointer never crosses to JavaScript. index is the slot in the game entity system; id is a host-minted liveness id (the engine serial never leaves Rust).
Every field access re-validates the ref against the host’s liveness books, then slot-matches the entity identity. A stashed ref whose entity was destroyed reads null / false, never garbage. The framework mints every EntityRef; plugin code never constructs one.
import { plugin } from '@s2script/sdk/plugin';
import { Player } from '@s2script/cs2';
export default plugin((ctx) => {
ctx.entities.onSpawn('weapon_ak47', (entity) => {
// entity: EntityRef | null
});
for (const p of Player.allConnected()) {
const hp = p.pawn?.health; // number | null
}
}); CS2 Pawn / Player are EntityRef-backed with generated schema accessors (health, origin, …). Handle fields return live refs; writes call notifyStateChanged automatically.
Accessors exist for 367 entity classes, including embedded structs (collision, glow) and enum fields. An entity you create yourself starts bare — wrapEntity applies a class’s accessors to any ref. See Schema fields.
Create/spawn/teleport/remove, entity I/O, and ray casts live on @s2script/sdk/entity; entity lifecycle listeners are on ctx.entities. See the entity module.