Skip to main content

Events

The WorkAdventure scripting API runs in the browser of each player. If you want to exchange data between users of a same map, you have 2 options:

Variables are a good way to store data on the map, or attached to a player. You can also track the changes to a variable, so variables can be used for real-time communication.

If you don't need to store data, but just want to send real-time short-lived messages between players, you can use events.

Broadcast vs targeted events

An event can be sent:

  • to all players in a room (broadcast)
  • to a specific player (targeted)

Broadcasting an event

To broadcast an event, use the WA.event.broadcast method:

WA.event.broadcast("my-event", "my payload");

An event has a name (my-event in the example above), and a payload (my payload in the example above).

The payload can be any JSON-serializable value (including objects, arrays, strings, numbers, booleans, undefined, etc.).

Targeting a player

If you are tracking users using the players API, you can target a specific player using the RemotePlayer.sendEvent method:

Example: let's send an event only to players that have the admin tag:

await WA.players.configureTracking();
const players = WA.players.list();
for (const player of players) {
if (player.tags.includes("admin")) {
player.sendEvent("my-event", "my payload");
}
}

Listening to events

All events (whether they are broadcast or targeted) can be listened to using WA.event.on.

WA.event.on("my-event").subscribe((event) => {
console.log("Event received", event.data);
});

The on method returns an RxJS Observable. You can use the subscribe method to listen to events. The subscribe method takes a callback function that will be called each time an event is received. The callback function takes a single argument: the event object that contain the following fields:

  • data (type: unknown): the payload of the event
  • name (type: string): the name of the event
  • senderId (type: number): the ID of the player that sent the event (or undefined if the event was sent by the system)

The subscribe method returns a Subscription object. You can use the unsubscribe method of this object to stop listening to events.

const subscription = WA.event.on("my-event").subscribe((event) => {
console.log("Event received", event.data);
});

// ...

subscription.unsubscribe();

A note about the data field

If you are using Typescript, the data field of the event object is of type unknown. This is because the type of the payload is not known in advance. You can use a type assertion to tell Typescript what is the type of the payload:

WA.event.on("my-event").subscribe((event) => {
const payload = event.data as string;
console.log("Event received", payload);
});

Please note that using a type assertion is not a type-safe operation. If you assert the wrong type, you will get a runtime error. Furthermore, events are sent by other players, so you should not trust the type of the payload. If your code is to be used publicly, you should always validate the type of the payload before using it.

Pro tip

Use Zod to validate the type of the payload.

The example below validates the type of the payload of the event and ensures it is an object containing a myField field of type string:

import {z} from "zod";

const myEventSchema = z.object({
myField: z.string()
});

WA.event.on("some-event").subscribe((event) => {
const result = myEventSchema.safeParse(event.data);
if (!result.success) {
console.error("Invalid event payload", result.error);
return;
}
const payload = result.data;

console.log("Event received", payload.myField);
});