Events and RPC
Varion has four separate channels:
varion.on(...)for built-in server/client lifecycle and local client events;varion.onClient(...)for custom client -> server events;varion.onServer(...)for custom server -> client events;varion.onRpc(...)/varion.callServer(...)for client -> server request/response.
Built-in server events
This is the current Node-host contract. Names are case-sensitive.
| Event | Arguments |
|---|---|
resourceStart | () for the resource being started |
resourceStop | () before resource teardown |
anyResourceStart | (resourceName) |
anyResourceStop | (resourceName) |
anyResourceError | (resourceName) for all loaded observer resources |
resourceError | (error, file, line, stackTrace) before failed-resource cleanup |
serverStarted | () after all configured resources finish their initial start |
playerConnect | (player, name) after transport authentication |
playerReady | (player) after the client resource manifest is loaded |
playerDisconnect | (player, reason) before the Player proxy is removed |
playerSpawn | (player) after a validated spawn packet is queued for delivery |
playerHeal | (player, oldHealth, newHealth, oldArmour, newArmour) after an authoritative increase |
playerDimensionChange | (player, oldDimension, newDimension) on an actual dimension change |
playerWeaponChange | (player, oldWeapon, newWeapon) from a validated client sync packet |
playerAnimationChange | (player, oldAnimDict, newAnimDict, oldAnimName, newAnimName) from animation sync-node hashes |
netOwnerChange | (entity, ownerOrNull, oldOwnerOrNull) when entity ownership migrates |
syncedMetaChange | (entity, key, value, oldValue) after all-client entity metadata changes |
streamSyncedMetaChange | (baseObject, key, value, oldValue) after streamed entity metadata changes |
globalMetaChange | (key, value, oldValue) for server-local global metadata |
globalSyncedMetaChange | (key, value, oldValue) for global metadata replicated to clients |
metaChange | (target, key, value, oldValue) after local Player/Entity metadata changes |
baseObjectCreate | (baseObject) after authoritative Player/Entity creation |
baseObjectRemove | (baseObject) before a Player/Entity proxy becomes invalid |
removeEntity | (entity) before a network entity is removed |
vehicleDestroy | (vehicle) before a Vehicle is removed |
vehicleSiren | (vehicle, state) on an authoritative siren-state edge from the net owner |
weaponDamage | (source, target, weaponHash, damage, offset, bodyPart) |
playerDamage | (victim, attacker, healthDamage, armourDamage, weaponHash) |
playerDeath | (player, killerOrNull, weaponHash) |
playerEnterVehicle | (player, vehicleId, seat) |
playerLeaveVehicle | (player, vehicleId, seat) |
playerChangeVehicleSeat | (player, vehicleId, oldSeat, newSeat) |
playerEnteredVehicle | (player, vehicle, seat); driver seat = 1 |
playerLeftVehicle | (player, vehicle, seat); driver seat = 1 |
playerChangedVehicleSeat | (player, vehicle, oldSeat, newSeat) |
playerEnterColshape | (player, colshapeId) |
playerLeaveColshape | (player, colshapeId) |
entityEnterColshape | (colshape, entity) — colshape first; current server proximity tracks Player entities |
entityLeaveColshape | (colshape, entity) — colshape first; current server proximity tracks Player entities |
playerEnterCheckpoint | (player, checkpointId) |
playerLeaveCheckpoint | (player, checkpointId) |
weaponDamage runs synchronously before authoritative health changes:
varion.on('weaponDamage', (source, target, weaponHash, damage) => {
if (weaponHash === varion.hash('WEAPON_RPG')) return false;
if (weaponHash === varion.hash('WEAPON_STUNGUN')) return 1;
return undefined;
});Return false to cancel, a number to replace damage, or undefined to accept the original value. A Promise is not allowed for this event; other handlers may be async.
Gameplay resources own spawning:
varion.on('playerReady', (player) => {
player.spawn({ x: 215.76, y: -810.12, z: 30.73 }, 157, 0x705E61F2);
});setMeta is server-local. setSyncedMeta reaches every client, while setStreamSyncedMeta reaches only clients currently streaming the entity. Setting, replacing, and deleting a value fires the matching event with exact new and old values. The legacy setGlobalMeta methods are aliases for global synced metadata.
Built-in client events
Subscribe with varion.on(name, callback). The verified core surface is:
| Category | Events |
|---|---|
| Connection | connection:state, connection:complete, connectionComplete, connection:queue, disconnect |
| Resources | resourceStart, resourceStop, anyResourceStart, anyResourceStop, anyResourceError, everyTick |
| Spawn/combat | playerSpawn, spawn:success, spawned, playerDeath, incomingDamage, playerWeaponChange, playerWeaponShoot |
| Entities | entityStreamIn, entityStreamOut, worldObjectStreamIn, worldObjectStreamOut, gameEntityCreate, gameEntityDestroy, baseObjectCreate, baseObjectRemove, netOwnerChange |
| Virtual/position | virtualEntityStreamIn, virtualEntityStreamOut, virtualEntityPositionChange, worldObjectPositionChange |
| Player state | playerDimensionChange, playerInteriorChange, playerAnimationChange |
| Vehicle | enteredVehicle, leftVehicle, changedVehicleSeat |
| Areas | playerEnterColShape, playerExitColShape, entityEnterColshape, entityLeaveColshape, playerEnterCheckpoint, playerExitCheckpoint |
| Metadata | metaChange, syncedMetaChange, streamSyncedMetaChange, localMetaChange, globalMetaChange, globalSyncedMetaChange, localDimension |
| Input/window | keydown, keyup, gamepadConnected, gamepadDisconnected, gamepadButtonDown, gamepadButtonUp, windowFocusChange, windowResolutionChange |
| Voice | playerStartTalking, playerStopTalking, voice:playerStartTalking, voice:playerStopTalking, voice:channelChange, voice:channelCreate, voice:channelDestroy, voice:pushToTalk |
| Assets | stream:ready, stream:updated, stream:mounted |
| World visuals | blipCreate, blipDestroy, markerCreate, markerDestroy, checkpointCreate, checkpointDestroy, colshapeCreate, colshapeDestroy, textLabelCreate, textLabelDestroy |
| Services | locale:change, discord:ready, discord:activityUpdate, discord:activityCleared, rml:show, rml:hide, webViewDestroyed, headshotBase64 |
Exact callback signatures are declared by VarionClientEventMap in @varion/client.
varion.on('connection:state', (phase, message) => {});
varion.on('playerDeath', (player, killer, weaponHash) => {});
varion.on('enteredVehicle', (vehicle, seat) => {});
varion.on('netOwnerChange', (entity, owner, previousOwner) => {});
varion.on('voice:pushToTalk', (active) => {});Server-side names use Colshape with a lowercase s and Enter/Leave. The historical client contract uses ColShape and Enter/Exit. Do not mix these names.
Custom events
// client/main.js
varion.emitServer('inventory:use', 12);
// server/main.js: the first argument is always a Player
varion.onClient('inventory:use', (player, itemId) => {
player.emit('inventory:used', itemId);
});
// client/main.js
varion.onServer('inventory:used', (itemId) => {});For frequent non-critical messages, use varion.emitServerUnreliable(...) and varion.onServerUnreliable(...).
RPC
// server/main.js
varion.onRpc('inventory:get', async (player) => ({ owner: player.id, slots: 40 }));
// client/main.js
const inventory = await varion.callServer('inventory:get');Thrown errors and rejected Promises return to the client as RPC errors. The handler is removed automatically when its owning resource stops or restarts.
Current MVP boundary
The full event set is not finalized yet. Server events such as explosion, startProjectile, generic entityEnterColshape, consoleCommand, vehicleDamage, and playerEnteringVehicle are not part of the public contract today. Do not build gameplay around unverified names — rely only on the list above.