Skip to content

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.

EventArguments
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:

js
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:

js
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:

CategoryEvents
Connectionconnection:state, connection:complete, connectionComplete, connection:queue, disconnect
ResourcesresourceStart, resourceStop, anyResourceStart, anyResourceStop, anyResourceError, everyTick
Spawn/combatplayerSpawn, spawn:success, spawned, playerDeath, incomingDamage, playerWeaponChange, playerWeaponShoot
EntitiesentityStreamIn, entityStreamOut, worldObjectStreamIn, worldObjectStreamOut, gameEntityCreate, gameEntityDestroy, baseObjectCreate, baseObjectRemove, netOwnerChange
Virtual/positionvirtualEntityStreamIn, virtualEntityStreamOut, virtualEntityPositionChange, worldObjectPositionChange
Player stateplayerDimensionChange, playerInteriorChange, playerAnimationChange
VehicleenteredVehicle, leftVehicle, changedVehicleSeat
AreasplayerEnterColShape, playerExitColShape, entityEnterColshape, entityLeaveColshape, playerEnterCheckpoint, playerExitCheckpoint
MetadatametaChange, syncedMetaChange, streamSyncedMetaChange, localMetaChange, globalMetaChange, globalSyncedMetaChange, localDimension
Input/windowkeydown, keyup, gamepadConnected, gamepadDisconnected, gamepadButtonDown, gamepadButtonUp, windowFocusChange, windowResolutionChange
VoiceplayerStartTalking, playerStopTalking, voice:playerStartTalking, voice:playerStopTalking, voice:channelChange, voice:channelCreate, voice:channelDestroy, voice:pushToTalk
Assetsstream:ready, stream:updated, stream:mounted
World visualsblipCreate, blipDestroy, markerCreate, markerDestroy, checkpointCreate, checkpointDestroy, colshapeCreate, colshapeDestroy, textLabelCreate, textLabelDestroy
Serviceslocale:change, discord:ready, discord:activityUpdate, discord:activityCleared, rml:show, rml:hide, webViewDestroyed, headshotBase64

Exact callback signatures are declared by VarionClientEventMap in @varion/client.

js
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

js
// 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

js
// 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.

Varion Multiplayer Platform