Skip to content

Server JavaScript API

Complete reference for the global varion object available in the server-side main.js of every JS resource. Every method and signature here is verified against the @varion/server typings contract (VarionServerApi) and the Node host.

A resource with type = "js" and a main entry is started by the platform automatically — no extra modules are required. See Server Scripting and resource.toml.

Resource Model

  • varion is the single global entry point. There are no imports; it is available directly at module scope.
  • Handler registration (on, onClient, onRpc), timer creation, new VoiceChannel, blip/marker/checkpoint/colshape and entity factories must be called within a resource context — that is, during module load or inside a callback owned by the same resource. Calling outside a context throws.
  • Everything a resource creates (handlers, timers, world handles, entities, voice channels) is owned by it and released automatically on stop/restart. No manual teardown on unload is required.
javascript
varion.log('resource loaded');

varion.on('playerReady', (player) => {
  player.spawn({ x: 215.76, y: -810.12, z: 30.73 }, 157, 0x705E61F2);
});

Events (Local and Lifecycle)

MethodSignaturePurpose
varion.onon(name, handler)Subscribe to a built-in or local event. Multiple handlers per name are allowed
varion.offoff(name, handler?)Unsubscribe. Without handler, removes this resource's handlers for that event
varion.emitemit(name, ...args)Emit a local in-process event. Delivered to on handlers on the same server, but not to clients

The full list of 41 built-in server events with exact arguments is in Events & RPC — it is not duplicated here.

weaponDamage runs synchronously before authoritative health changes; its handler must be synchronous (false cancels the hit, a number replaces the damage, undefined accepts the original). All other events may be async.

javascript
varion.on('playerDeath', (player, killer, weaponHash) => {
  varion.log(player.name, 'killed by', killer ? killer.name : 'world');
});

Client Events and RPC

MethodSignaturePurpose
varion.onClientonClient(name, (player, ...args) => void | Promise)client -> server event. The first argument is a Player proxy, not a numeric id. Multiple handlers are allowed
varion.offClientoffClient(name, handler?)Unsubscribe from a client event
varion.onRpconRpc(name, (player, ...args) => result | Promise)client -> server RPC. Exactly one handler per name (re-registering replaces the previous). Client-initiated only. Async is supported
varion.offRpcoffRpc(name, handler?)Remove an RPC handler

The first argument to onClient and onRpc is always a Player. An RPC return value (or resolved Promise) is sent to the client as the result; a thrown exception or rejected Promise reaches the client as an RPC error.

javascript
varion.onClient('chat:message', (player, message) => {
  varion.emitAllClients('chat:addMessage', player.name, String(message));
});

varion.onRpc('inventory:get', async (player) => ({ owner: player.id, slots: 40 }));

Emitting Events to Clients

MethodSignaturePurpose
varion.emitClientemitClient(playerId, name, ...args)Event to one player. The first argument is a numeric player id
varion.emitAllClientsemitAllClients(name, ...args)Event to all connected players
player.emitplayer.emit(name, ...args)The same per-player emit through a Player proxy

emitClient expects a numeric id. When you hold a Player object, use player.emit(...) or varion.emitClient(player.id, ...).

javascript
varion.emitClient(player.id, 'hud:show', true);
varion.emitAllClients('announce', 'server restarting');

Logging

varion.log(...parts), varion.logWarning(...parts), varion.logError(...parts) — arguments are stringified, space-joined, and tagged with the resource name in the server output.

Players

MethodReturnsPurpose
varion.getPlayer(id)PlayerPlayer proxy by id. Always returns an object
varion.getPlayers()Player[]All connected players
varion.getPlayerCount()numberNumber of connected players

The Player object: read-only id, type, valid, name, ip, ping; readable and writable health, armour, model, dimension, pos (a write is applied to the player immediately); methods spawn(pos, heading?, model?), kick(reason?), giveWeapon(weaponHash, ammo?), removeAllWeapons(), emit(name, ...args), and the metadata family (below). See Entities.

World: Time and Weather

  • varion.setTime(hour, minute) — set in-game time.
  • varion.setWeather(weatherId) — set weather by id.

World Visuals

Every factory returns a { id, type, valid, destroy() } handle owned by the resource. Options objects carry the visual's fields (position, color, etc.).

MethodSignature
varion.createBlipcreateBlip(options)
varion.createRadiusBlipcreateRadiusBlip(x, y, z, radius, color?, dimension?)
varion.createAreaBlipcreateAreaBlip(x, y, z, width, height, color?, dimension?)
varion.createMarkercreateMarker(options)
varion.createCheckpointcreateCheckpoint(options)
varion.createTextLabelcreateTextLabel(options)
javascript
const blip = varion.createRadiusBlip(215, -810, 30, 50, 5);
// ...later
blip.destroy();

Colshapes

Seven factories; each returns a Colshape ({ id, type: 'colshape', valid, destroy() }). Enter/leave raise the entityEnterColshape / entityLeaveColshape events (and player variants) — see Events & RPC.

MethodSignature
varion.createColshapecreateColshape(options)
varion.createColshapeSpherecreateColshapeSphere(x, y, z, radius, dimension?)
varion.createColshapeBoxcreateColshapeBox(x, y, z, halfX, halfY, halfZ, dimension?)
varion.createColshapeCylindercreateColshapeCylinder(x, y, z, radius, height, dimension?)
varion.createColshapeCirclecreateColshapeCircle(x, y, radius, dimension?)
varion.createColshapeRectanglecreateColshapeRectangle(x, y, halfX, halfY, dimension?)
varion.createColshapePolygoncreateColshapePolygon(points, minZ, maxZ, dimension?)

points for a polygon is a flat number array [x0, y0, x1, y1, ...].

Entities (async)

MethodReturns
varion.createVehicle(model, pos, rot?)Promise<Vehicle>
varion.createPed(model, pos, rot?)Promise<Ped>
varion.createObject(model, pos, rot?)Promise<ObjectEntity>

All three are asynchronous: the server allocates the network id, so await the Promise to get the entity proxy. The proxy exposes id, type, valid, netOwner, destroy(), and the metadata family.

javascript
const car = await varion.createVehicle(varion.hash('adder'),
  { x: 220, y: -805, z: 30 }, { x: 0, y: 0, z: 0 });
car.setStreamSyncedMeta('plate', 'VARION');

Voice Channels

varion.createVoiceChannel(spatial, maxDistance?) returns a VoiceChannel (equivalent to new varion.VoiceChannel(spatial, maxDistance)).

A VoiceChannel instance:

  • Properties: id, type, valid, isSpatial, maxDistance, players, playerCount (read-only); priority, filter (read/write).
  • Methods: addPlayer(player), removePlayer(player), hasPlayer(player), isPlayerInChannel(player), isPlayerMuted(player), mutePlayer(player, muted?) (defaults to true), unmutePlayer(player), setFilter(filterHash), destroy().
  • Static: VoiceChannel.all (all valid channels), VoiceChannel.getByID(id).

The player argument accepts a Player proxy or a numeric id.

javascript
const channel = varion.createVoiceChannel(true, 20);
channel.addPlayer(player);
channel.mutePlayer(player.id);

Metadata

There are two storage levels.

Entity/player level (methods on a Player or Entity proxy):

MethodReplication scopeEvent
setMeta(key, value) / setMeta(obj)Server only, not replicatedmetaChange
setSyncedMeta(...)All clientssyncedMetaChange
setStreamSyncedMeta(...)Clients currently streaming the entitystreamSyncedMetaChange

Each set has paired get*, has*, delete*, and get*Keys.

Global level (methods on varion):

MethodReplication scopeEvent
varion.setMeta(...)Server only, not replicatedglobalMetaChange
varion.setSyncedMeta(...)All clientsglobalSyncedMetaChange
varion.setGlobalMeta(...)All clientsglobalSyncedMetaChange

varion.setSyncedMeta and varion.setGlobalMeta write to the same replicated store and both raise globalSyncedMetaChange — they are aliases. Only varion.setMeta uses a separate, server-only store that is not replicated. Paired get*/has*/delete*/get*Keys exist for all three families (...Meta, ...SyncedMeta, ...GlobalMeta). See Metadata.

Utilities

  • varion.getNetTime()Promise<number>, milliseconds since server start (an async request to the platform).
  • varion.hash(value)number, JOAAT hash of a string (input is lowercased). Convenient for model and weapon hashes.
javascript
const now = await varion.getNetTime();
const model = varion.hash('adder');

Resource Management

MethodReturnsPurpose
varion.getResourceConfig(name?)objectThe [config] table from resource.toml. Synchronous. Without name, the current resource (or the sole one)
varion.hasResource(name)booleanWhether the resource is known
varion.getAllResources()ResourceInfo[]All resources: { name, path, valid, started, config }
varion.startResource(name)voidQueue a start (fire-and-forget)
varion.stopResource(name)voidQueue a stop
varion.restartResource(name)voidQueue a restart
varion.Resource.currentResourceInfo | nullThe current resource
varion.Resource.get(name)ResourceInfo | nullA resource by name
varion.Resource.allResourceInfo[]All resources

getResourceConfig is synchronous — do not await it.

javascript
const cfg = varion.getResourceConfig();
if (cfg.debug) varion.log('debug mode');

Timers

Timers are bound to the resource and cleared automatically on its stop/restart. The global setTimeout/setInterval/setImmediate in the host are also wrapped and behave the same way.

MethodPurpose
varion.setTimeout(callback, delay?, ...args)One-shot timer, returns a handle
varion.setInterval(callback, delay?, ...args)Repeating timer, returns a handle
varion.clearTimeout(handle)Cancel a timer
varion.clearInterval(handle)Cancel an interval
varion.nextTick(callback, ...args)Run on the next tick (setImmediate)
varion.everyTick(callback)Run every tick (~16 ms)
varion.clearEveryTick(handle)Stop an everyTick

Classes

  • varion.Vector3new Vector3(x?, y?, z?) or new Vector3(vectorLike); a length property; a distanceTo(other) method.
  • varion.RGBAnew RGBA(r = 255, g = 255, b = 255, a = 255).
  • varion.VoiceChannel — constructor new VoiceChannel(isSpatial, maxDistance?); see the "Voice Channels" section.
javascript
const a = new varion.Vector3(0, 0, 72);
const b = new varion.Vector3({ x: 10, y: 0, z: 72 });
const d = a.distanceTo(b);
const red = new varion.RGBA(255, 0, 0, 255);

Source Backing

This page is verified against sdk/Varion.Server/npm/@varion/server/index.d.ts (the VarionServerApi interface) and the Node host runtime server/host/varion-host.cjs. The list of built-in events is in Events & RPC.

Varion Multiplayer Platform