### Executing Functions Remotely Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Examples of how to execute registered functions on other clients using the socket object obtained after module registration. ```APIDOC ## Executing Functions Remotely ### Description These functions allow you to execute registered functions on other connected clients. You can wait for the return value using `await`. ### Usage ```javascript // Execute a function for all other connected users socket.executeForEveryone("hello", game.user.name); socket.executeForEveryone(showHelloMessage, game.user.name); // Execute a function on a GM client and retrieve the result const result = await socket.executeAsGM("add", 5, 3); console.log(`The GM client calculated: ${result}`); ``` ### Functions - **`socket.executeForEveryone(functionNameOrFunction, ...args)`**: Executes the specified function on all other connected clients. - **`socket.executeAsGM(functionNameOrFunction, ...args)`**: Executes the specified function on one of the connected GM clients. If multiple GMs are connected, only one will execute the function. Returns the result of the function execution. - **`socket.executeForUser(userId, functionNameOrFunction, ...args)`**: Executes the specified function on the client of the user with the given `userId`. Returns the result of the function execution. - **`socket.executeForGroup(groupIdentifier, functionNameOrFunction, ...args)`**: Executes the specified function for a group of users. The `groupIdentifier` can be a specific user ID or an array of user IDs. Returns the result of the function execution. - **`socket.executeForAllGMs(functionNameOrFunction, ...args)`**: Executes the specified function on all connected GM clients. Returns an object where keys are GM user IDs and values are the results of the function execution. ``` -------------------------------- ### Module Manifest: Declaring socketlib Dependency Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt To ensure socketlib is installed before your module loads, declare it as a required relationship in your module's manifest (`module.json`). Also set `"socket": true` to enable socket usage. ```json { "id": "my-module", "title": "My Module", "socket": true, "relationships": { "requires": [ { "id": "socketlib", "type": "module", "manifest": "https://github.com/farling42/foundryvtt-socketlib/releases/latest/download/module.json" } ] } } ``` -------------------------------- ### Register System with SocketLib Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Call `registerSystem` to enable SocketLib to listen for sockets from your game system. This should be the first function your system calls. It returns a socket instance for further interactions. ```javascript registerSystem(systemId); ``` -------------------------------- ### Register Module and Execute Functions with SocketLib Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Register your module with SocketLib and demonstrate executing functions for all users and as the GM. Ensure functions are registered before calling them remotely. The `socketlib.ready` hook fires when SocketLib is initialized. ```javascript let socket; Hooks.once("socketlib.ready", () => { socket = socketlib.registerModule("my-module"); socket.register("hello", showHelloMessage); socket.register("add", add); }); Hooks.once("ready", async () => { // Let's send a greeting to all other connected users. // Functions can either be called by their given name... socket.executeForEveryone("hello", game.user.name); // ...or by passing in the function that you'd like to call. socket.executeForEveryone(showHelloMessage, game.user.name); // The following function will be executed on a GM client. // The return value will be sent back to us. const result = await socket.executeAsGM("add", 5, 3); console.log(`The GM client calculated: ${result}`); }); function showHelloMessage(userName) { console.log(`User ${userName} says hello!`); } function add(a, b) { console.log("The addition is performed on a GM client."); return a + b; } ``` -------------------------------- ### Register Game System with socketlib Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Register your game system with socketlib, similar to `registerModule`. The `systemId` must match the active system's ID, and the system manifest needs `"socket": true`. ```javascript let systemSocket; Hooks.once("socketlib.ready", () => { systemSocket = socketlib.registerSystem("my-game-system"); systemSocket.register("rollDice", handleDiceRoll); systemSocket.register("updateActor", handleActorUpdate); }); ``` -------------------------------- ### socketlib.registerSystem Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Registers your game system with SocketLib, enabling it to send and receive socket messages. This should be the first SocketLib function your game system calls. ```APIDOC ## socketlib.registerSystem ### Description Call `registerSystem` to make socketlib listen for sockets that come in for your game system. This is the first function in socketlib that your game system should call. ### Parameters #### Path Parameters - **systemId** (string) - Required - The id of your game system as specified in your game system's manifest. ### Return value A socket instance is returned, that is used for all further interactions with socketlib. ``` -------------------------------- ### Registering a Module and Functions Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md This snippet shows how to register your module with SocketLib and register functions that can be called remotely. The `socketlib.ready` hook is fired once SocketLib is initialized. ```APIDOC ## Registering Module and Functions ### Description Registers your module with SocketLib and makes functions available for remote execution. This should be done after the `socketlib.ready` hook. ### Usage ```javascript let socket; Hooks.once("socketlib.ready", () => { socket = socketlib.registerModule("my-module"); ssocket.register("hello", showHelloMessage); ssocket.register("add", add); }); ``` ### Functions - **`socketlib.registerModule(moduleName)`**: Registers the module with SocketLib and returns a socket object for further interactions. Returns a `Socket` object. - **`socket.register(functionName, functionToRegister)`**: Registers a function to be callable via SocketLib. Both the calling and executing clients must have the function registered. ``` -------------------------------- ### socketlib.registerSystem Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Registers a game system with socketlib. Similar to `registerModule`, this requires the system manifest to have `"socket": true` and the `systemId` to match the active system. It returns a `SocketlibSocket` instance. ```APIDOC ## socketlib.registerSystem — Register a game system with socketlib ### Description Same as `registerModule` but for Foundry VTT game systems. The `systemId` must match the active system's id and the system manifest must have `"socket": true`. Returns a `SocketlibSocket` instance. ### Usage ```javascript let systemSocket; Hooks.once("socketlib.ready", () => { systemSocket = socketlib.registerSystem("my-game-system"); systemSocket.register("rollDice", handleDiceRoll); systemSocket.register("updateActor", handleActorUpdate); }); ``` ``` -------------------------------- ### Register Module with SocketLib Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Call `registerModule` to enable SocketLib to listen for sockets from your module. This should be the first function your module calls. It returns a socket instance for further interactions. ```javascript socketlib.registerModule(moduleName); ``` -------------------------------- ### Register Module with socketlib Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Register your module with socketlib to enable socket communication. This must be called within the `socketlib.ready` hook. Ensure your module's manifest has `"socket": true`. ```javascript let socket; Hooks.once("socketlib.ready", () => { // "my-module" must match the id in your module's manifest socket = socketlib.registerModule("my-module"); // Register all handlers immediately after obtaining the socket socket.register("createItem", createItemAsGM); socket.register("notify", showNotification); socket.register("syncData", syncDataToUser); }); ``` -------------------------------- ### Include Socketlib as a module dependency Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md To ensure Socketlib is available for your module, include the following 'relationships' configuration in your module's manifest.json file. ```json "relationships": { "requires": [ { "id": "socketlib", "type": "module", "manifest": "https://github.com/farling42/foundryvtt-socketlib/releases/latest/download/module.json" } ] } ``` -------------------------------- ### socket.executeForEveryone Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Broadcasts a fire-and-forget command to every connected client. The function also runs locally on the calling client. Does not await remote completion or return values. Ideal for UI updates or visual effects that all players should see. ```APIDOC ## socket.executeForEveryone — Execute on all clients including self ### Description Broadcasts a fire-and-forget command to every connected client. The function also runs locally on the calling client. Does not await remote completion or return values. Ideal for UI updates or visual effects that all players should see. ### Method `socket.executeForEveryone(handlerName: string, ...args: any[]): Promise ### Parameters #### Path Parameters - **handlerName** (string) - Required - The name of the registered handler to execute. - **args** (any[]) - Optional - Arguments to pass to the handler function. ### Request Example ```javascript Hooks.once("socketlib.ready", () => { socket = socketlib.registerModule("my-module"); socket.register("showExplosionEffect", showExplosionEffect); socket.register("playAmbientSound", playAmbientSound); }); Hooks.once("ready", async () => { const tokenPosition = { x: 450, y: 300 }; // Trigger a visual effect on every client's canvas, including your own await socket.executeForEveryone("showExplosionEffect", tokenPosition, { radius: 60 }); // Play an ambient sound for all players await socket.executeForEveryone("playAmbientSound", "sounds/explosion.ogg", 0.8); }); function showExplosionEffect(position, options) { canvas.interface.createScrollingText(position, "💥 BOOM!", { duration: 2000 }); } function playAmbientSound(src, volume) { AudioHelper.play({ src, volume, autoplay: true, loop: false }); } ``` ``` -------------------------------- ### Register Function with SocketLib Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Registers a function to be called later via SocketLib. Ensure registration happens on all connected clients before calling. Recommended to do this during the `socketlib.ready` hook immediately after `socketlib.registerModule`. ```javascript socket.register(name, func); ``` -------------------------------- ### Execute Function on Specific User Client with Return Value Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Use `executeAsUser` to run a function on a specific user's client and await its return value. Throws errors if the user is invalid or disconnected. ```javascript Hooks.once("ready", async () => { // Send data to a specific player and get their confirmation back const targetPlayer = game.users.find(u => u.name === "Alice"); if (!targetPlayer) return; try { const confirmed = await socket.executeAsUser( "syncData", targetPlayer.id, { mapRegion: "dungeon-level-2", fogData: canvas.fog.data } ); console.log(`Alice confirmed sync: ${confirmed}`); // Output: "Alice confirmed sync: true" } catch (err) { if (err instanceof socketlib.errors.SocketlibInvalidUserError) { ui.notifications.warn("Target user is not connected."); } else if (err instanceof socketlib.errors.SocketlibRemoteException) { console.error("An error occurred on the remote client:", err.message); } } }); ``` -------------------------------- ### Broadcast Function to Other GM Clients (Excluding Self) Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Use `executeForOtherGMs` to send commands to all GM clients except the caller. If the caller is not a GM, it behaves identically to `executeForAllGMs`. ```javascript // A GM wants to relay an update to all *other* GM clients only Hooks.once("ready", () => { socket.register("syncGMState", receiveGMState); }); async function broadcastGMStateToOthers(stateSnapshot) { // Won't execute locally, only on other connected GMs await socket.executeForOtherGMs("syncGMState", stateSnapshot); } function receiveGMState(state) { console.log("Received GM state from another GM:", state); } ``` -------------------------------- ### socket.executeForOthers Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Broadcasts a fire-and-forget command to every connected client except the calling client. Useful when you handle the local case separately or want to avoid duplicate execution. ```APIDOC ## socket.executeForOthers — Execute on all clients except self ### Description Broadcasts a fire-and-forget command to every connected client except the calling client. Useful when you handle the local case separately or want to avoid duplicate execution. ### Method `socket.executeForOthers(handlerName: string, ...args: any[]): Promise ### Parameters #### Path Parameters - **handlerName** (string) - Required - The name of the registered handler to execute. - **args** (any[]) - Optional - Arguments to pass to the handler function. ### Request Example ```javascript // Handle local state immediately, then sync to all other clients async function updateTokenPositionLocally(tokenId, newPos) { // Apply locally first for instant feedback const token = canvas.tokens.get(tokenId); await token.document.update({ x: newPos.x, y: newPos.y }); // Then sync to everyone else (they should not re-run our local update) await socket.executeForOthers("syncTokenPosition", tokenId, newPos); } socket.register("syncTokenPosition", (tokenId, newPos) => { const token = canvas.tokens.get(tokenId); token?.document.update({ x: newPos.x, y: newPos.y }); }); ``` ``` -------------------------------- ### socket.executeForAllGMs Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on the clients of all connected GMs. If the current user is a GM, the function will be executed locally as well. ```APIDOC ## socket.executeForAllGMs ### Description Executes a function on the clients of all connected GMs. If the current user is a GM the function will be executed locally as well. The function must have been registered using `socket.register` before it can be invoked via this function. ### Parameters #### Path Parameters - **handler** (function | string) - Required - The function to execute or its registered name. - **parameters...** - Optional - Parameters to pass to the called function. ### Return value The promise returned by this function will resolve as soon as the request for execution has been sent to the connected GM clients and *will not* wait until those clients have finished processing that function. The promise will not yield any return value. ``` -------------------------------- ### socketlib.registerModule Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Registers a Foundry VTT module with socketlib. This function must be called within the `socketlib.ready` hook. The module's manifest must include `"socket": true`. It returns a `SocketlibSocket` instance for subsequent operations. ```APIDOC ## socketlib.registerModule — Register a module with socketlib ### Description Registers a Foundry VTT module with socketlib so it can send and receive socket messages. Must be called inside the `socketlib.ready` hook. The module's manifest must have `"socket": true` set. Returns a `SocketlibSocket` instance used for all further calls. ### Usage ```javascript let socket; Hooks.once("socketlib.ready", () => { // "my-module" must match the id in your module's manifest socket = socketlib.registerModule("my-module"); // Register all handlers immediately after obtaining the socket socket.register("createItem", createItemAsGM); socket.register("notify", showNotification); socket.register("syncData", syncDataToUser); }); ``` ``` -------------------------------- ### socket.executeForOtherGMs Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Same as `executeForAllGMs` but explicitly skips local execution even if the caller is a GM. If the caller is not a GM, behavior is identical to `executeForAllGMs`. ```APIDOC ## socket.executeForOtherGMs — Broadcast to all GM clients (excluding self) ### Description Same as `executeForAllGMs` but explicitly skips local execution even if the caller is a GM. If the caller is not a GM, behavior is identical to `executeForAllGMs`. ### Method `socket.executeForOtherGMs(handlerName: string, ...args: any[]): Promise ### Parameters #### Path Parameters - **handlerName** (string) - Required - The name of the registered handler to execute. - **args** (any[]) - Optional - Arguments to pass to the handler function. ### Request Example ```javascript // A GM wants to relay an update to all *other* GM clients only Hooks.once("ready", () => { socket.register("syncGMState", receiveGMState); }); async function broadcastGMStateToOthers(stateSnapshot) { // Won't execute locally, only on other connected GMs await socket.executeForOtherGMs("syncGMState", stateSnapshot); } function receiveGMState(state) { console.log("Received GM state from another GM:", state); } ``` ``` -------------------------------- ### Broadcast Function to All GM Clients Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Utilize `executeForAllGMs` for fire-and-forget commands to all connected GM clients. The function also runs locally if the caller is a GM. No return value is expected from remote clients. ```javascript // A player triggers an alert that all GMs should see async function alertGMs(alertMessage) { await socket.executeForAllGMs("notify", alertMessage); // All GM clients (including local if GM) will call notify(alertMessage) } // Registered handler function notify(message) { ui.notifications.info(`[GM Alert] ${message}`); } // Usage alertGMs("A player has triggered a trap in Room 4!"); ``` -------------------------------- ### Execute for Specific Users with socket.executeForUsers Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Sends a fire-and-forget command to a specified array of user ids. If the current user's id is included in the list, the function also runs locally. Does not await remote completion or return values. ```javascript Hooks.once("socketlib.ready", () => { socket = socketlib.registerModule("my-module"); socket.register("receivePartyAlert", receivePartyAlert); }); async function sendAlertToParty(partyMemberIds, alertText) { // partyMemberIds is an array of Foundry user id strings // e.g., ["userId1", "userId2", "userId3"] await socket.executeForUsers("receivePartyAlert", partyMemberIds, alertText); // Only the listed users (and self if included) will execute receivePartyAlert } function receivePartyAlert(message) { ui.notifications.warn(`⚔️ Party Alert: ${message}`); ChatMessage.create({ content: `Alert: ${message}` }); } // Trigger from a macro or hook: const partyIds = game.users .filter(u => u.active && !u.isGM) .map(u => u.id); sendAlertToParty(partyIds, "Prepare for combat — initiative begins now!"); ``` -------------------------------- ### socket.executeForAllGMs Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Sends a fire-and-forget command to all connected GM clients. If the caller is a GM, the function also runs locally on their client. Does not return a value from the remote clients. Useful for notifying all GMs of an event. ```APIDOC ## socket.executeForAllGMs — Broadcast to all GM clients (including self if GM) ### Description Sends a fire-and-forget command to all connected GM clients. If the caller is a GM, the function also runs locally on their client. Does not return a value from the remote clients. Useful for notifying all GMs of an event. ### Method `socket.executeForAllGMs(handlerName: string, ...args: any[]): Promise ### Parameters #### Path Parameters - **handlerName** (string) - Required - The name of the registered handler to execute. - **args** (any[]) - Optional - Arguments to pass to the handler function. ### Request Example ```javascript async function alertGMs(alertMessage) { await socket.executeForAllGMs("notify", alertMessage); } // Registered handler function notify(message) { ui.notifications.info(`[GM Alert] ${message}`); } // Usage alertGMs("A player has triggered a trap in Room 4!"); ``` ``` -------------------------------- ### socket.executeForUsers Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Sends a fire-and-forget command to a specified array of user ids. If the current user's id is included in the list, the function also runs locally. Does not await remote completion or return values. ```APIDOC ## socket.executeForUsers ### Description Sends a fire-and-forget command to a specified array of user ids. If the current user's id is included in the list, the function also runs locally. Does not await remote completion or return values. ### Method `socket.executeForUsers(handlerName, userIds, ...args)` ### Parameters - **handlerName** (string) - The name of the registered handler function to execute on remote clients. - **userIds** (Array) - An array of user IDs to send the command to. - **...args** - Any additional arguments to pass to the handler function. ``` -------------------------------- ### socketlib.registerModule Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Registers your module with SocketLib, enabling it to send and receive socket messages. This should be the first SocketLib function your module calls. ```APIDOC ## socketlib.registerModule ### Description Call `registerModule` to make socketlib listen for sockets that come in for your module. This is the first function in socketlib that your module should call. ### Parameters #### Path Parameters - **moduleName** (string) - Required - The name of your module as specified in your module's manifest. ### Return value A socket instance is returned, that is used for all further interactions with socketlib. ``` -------------------------------- ### Execute Function as GM Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on exactly one connected GM's client. Fails if no GM is connected. The function must be registered beforehand. Returns a promise that resolves with the function's return value. ```javascript async socket.executeAsGM(handler, parameters...); ``` -------------------------------- ### socket.executeForOtherGMs Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on the clients of all connected Game Masters (GMs), excluding the current user. If the current user is not a GM, it behaves like `socket.executeForAllGMs`. The function must be registered prior to invocation. ```APIDOC ## socket.executeForOtherGMs ### Description Executes a function on the clients of all connected GMs, except for the current user. If the current user is not a GM this function has the same behavior as `socket.executeForAllGMs`. The function must have been registered using `socket.register` before it can be invoked via this function. ### Parameters - **handler** (Function | String) - The function to execute or its registered name. - **parameters...** (Any) - Parameters to pass to the called function. ### Return value Resolves when the execution request is sent, does not wait for client processing. No return value. ``` -------------------------------- ### Execute Function on All Clients Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Employ `executeForEveryone` to broadcast a fire-and-forget command to every connected client, including the caller. This method does not await remote completion or return values, making it suitable for UI updates. ```javascript Hooks.once("socketlib.ready", () => { socket = socketlib.registerModule("my-module"); socket.register("showExplosionEffect", showExplosionEffect); socket.register("playAmbientSound", playAmbientSound); }); Hooks.once("ready", async () => { const tokenPosition = { x: 450, y: 300 }; // Trigger a visual effect on every client's canvas, including your own await socket.executeForEveryone("showExplosionEffect", tokenPosition, { radius: 60 }); // Play an ambient sound for all players await socket.executeForEveryone("playAmbientSound", "sounds/explosion.ogg", 0.8); }); function showExplosionEffect(position, options) { canvas.interface.createScrollingText(position, "💥 BOOM!", { duration: 2000 }); } function playAmbientSound(src, volume) { AudioHelper.play({ src, volume, autoplay: true, loop: false }); } ``` -------------------------------- ### Execute Function as Specific User Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on the client of a specified user. Fails if the user is not connected. The function must be registered beforehand. Returns a promise that resolves with the function's return value. ```javascript async socket.executeAsUser(handler, userId, parameters...); ``` -------------------------------- ### socket.executeForUsers Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on the clients of a specified list of users. The function must be registered prior to invocation. ```APIDOC ## socket.executeForUsers ### Description Executes a function on the clients of a specified list of players. The function must have been registered using `socket.register` before it can be invoked via this function. ### Parameters - **handler** (Function | String) - The function to execute or its registered name. - **recipients** (Array) - An array of user IDs that should execute the function. - **args...** (Any) - Parameters to pass to the called function. ### Return value Resolves when the execution request is sent, does not wait for client processing. No return value. ``` -------------------------------- ### socket.executeAsGM Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on the client of exactly one connected GM. Fails if no GM is connected. ```APIDOC ## socket.executeAsGM ### Description Executes a function on the client of exactly one GM. If multiple GMs are connected, one of the GMs will be selected to execute the function. This function will fail if there is no GM connected. The function must have been registered using `socket.register` before it can be invoked via this function. ### Parameters #### Path Parameters - **handler** (function | string) - Required - The function to execute or its registered name. - **parameters...** - Optional - Parameters to pass to the called function. ### Return value The promise that this function returns will resolve once the GM has finished the execution of the invoked function and will yield the return value of that function. If the execution on the GM client fails for some reason, this function will fail with an appropriate Error as well. ``` -------------------------------- ### Execute Function for All GMs Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on all connected GMs' clients. If the current user is a GM, the function executes locally as well. The function must be registered beforehand. Returns a promise that resolves once the execution request is sent, without waiting for completion. ```javascript async socket.executeForAllGMs(handler, parameters...); ``` -------------------------------- ### socket.executeForEveryone Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on all connected clients, including the local client. The function must be registered prior to invocation. ```APIDOC ## socket.executeForEveryone ### Description Executes a function on all connected clients, including on the local client. The function must have been registered using `socket.register` before it can be invoked via this function. ### Parameters - **handler** (Function | String) - The function to execute or its registered name. - **args...** (Any) - Parameters to pass to the called function. ### Return value Resolves when the execution request is sent, does not wait for client processing. No return value. ``` -------------------------------- ### socket.register Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Registers a function to be callable via SocketLib. It's recommended to register functions during the `socketlib.ready` hook immediately after `socketlib.registerModule`. ```APIDOC ## socket.register ### Description Registers a function that can subsequently be called using socketlib. It's important that the registration of a function is done on all connected clients before the function is being called via socketlib. Otherwise the call won't succeed. For this reason it's recommended to register all relevant functions during the `socketlib.ready` hook, immediately after `socketlib.registerModule` has been called. ### Parameters #### Path Parameters - **name** (string) - Required - A unique name used to identify the function within socketlib. - **func** (function) - Required - The function that's being registered within socketlib. ### Return value This function has no return value. ``` -------------------------------- ### Execute Function on GM Client Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Execute a registered handler on a single GM client and receive its return value. If the caller is a GM, the function runs locally. Throws `SocketlibNoGMConnectedError` if no GM is online. ```javascript Hooks.once("ready", async () => { // Players can trigger GM-privileged operations and get results back try { const newItem = await socket.executeAsGM("createJournalEntry", "Session Notes", "

Tonight's adventure summary...

" ); console.log(`Journal entry created with id: ${newItem.id}`); // Output: "Journal entry created with id: abc123xyz" } catch (err) { if (err instanceof socketlib.errors.SocketlibNoGMConnectedError) { ui.notifications.warn("No GM is currently connected."); } else { console.error("Remote execution failed:", err); } } }); ``` -------------------------------- ### socket.executeForOthers Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on all connected clients, excluding the local client. The function must be registered prior to invocation. ```APIDOC ## socket.executeForOthers ### Description Executes a function on all connected clients, but not locally. The function must have been registered using `socket.register` before it can be invoked via this function. ### Parameters - **handler** (Function | String) - The function to execute or its registered name. - **args...** (Any) - Parameters to pass to the called function. ### Return value Resolves when the execution request is sent, does not wait for client processing. No return value. ``` -------------------------------- ### socket.executeAsUser Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Executes a registered function on the client of a specified user. Fails if the user is not connected. ```APIDOC ## socket.executeAsUser ### Description Executes a function on the client of the specified user. This function will fail if the specified user is not connected. The function must have been registered using `socket.register` before it can be invoked via this function. ### Parameters #### Path Parameters - **handler** (function | string) - Required - The function to execute or its registered name. - **userId** (string) - Required - The id of the user that should execute this function. - **parameters...** - Optional - Parameters to pass to the called function. ### Return value The promise that this function returns will resolve once the user has finished the execution of the invoked function and will yield the return value of that function. If the execution on other user's client fails for some reason, this function will fail with an appropriate Error as well. ``` -------------------------------- ### Execute function on other GMs' clients Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Use socket.executeForOtherGMs to run a registered function on all connected GM clients, excluding the current user. If the current user is not a GM, it behaves like executeForAllGMs. The handler can be a function reference or its registered name. Parameters are passed directly. The promise resolves once the execution request is sent, not upon completion. ```javascript async socket.executeForOtherGMs(handler, parameters...); ``` -------------------------------- ### socket.executeAsUser Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Executes a registered handler on the client of a specific user identified by their Foundry user id. Awaiting resolves with the remote return value. Throws `SocketlibInvalidUserError` if the user does not exist or is not connected. ```APIDOC ## socket.executeAsUser — Execute a function on a specific user's client (with return value) ### Description Executes a registered handler on the client of a specific user identified by their Foundry user id. If the target is the calling user, runs locally. Awaiting resolves with the remote return value. Throws `SocketlibInvalidUserError` if the user does not exist or is not connected. ### Method `socket.executeAsUser(handlerName: string, userId: string, ...args: any[]): Promise ### Parameters #### Path Parameters - **handlerName** (string) - Required - The name of the registered handler to execute. - **userId** (string) - Required - The ID of the target user's client. - **args** (any[]) - Optional - Arguments to pass to the handler function. ### Request Example ```javascript const targetPlayer = game.users.find(u => u.name === "Alice"); if (!targetPlayer) return; try { const confirmed = await socket.executeAsUser( "syncData", targetPlayer.id, { mapRegion: "dungeon-level-2", fogData: canvas.fog.data } ); console.log(`Alice confirmed sync: ${confirmed}`); } catch (err) { if (err instanceof socketlib.errors.SocketlibInvalidUserError) { ui.notifications.warn("Target user is not connected."); } else if (err instanceof socketlib.errors.SocketlibRemoteException) { console.error("An error occurred on the remote client:", err.message); } } ``` ### Response #### Success Response - **returnValue** (any) - The return value from the executed handler on the remote client. #### Error Response - **SocketlibInvalidUserError**: If the target user does not exist or is not connected. - **SocketlibRemoteException**: If an error occurs during the execution of the remote handler. ``` -------------------------------- ### socket.executeAsGM Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Executes a registered handler function on a single connected GM client. If the caller is already a GM, the function executes locally. This method returns a promise that resolves with the remote function's return value. It throws `SocketlibNoGMConnectedError` if no GM is online. ```APIDOC ## socket.executeAsGM — Execute a function on one GM client (with return value) ### Description Executes a registered handler on exactly one connected GM client. If the calling user is already a GM, the function runs locally. Awaiting this call will resolve with the remote function's return value. Throws `SocketlibNoGMConnectedError` if no GM is online. ### Usage ```javascript Hooks.once("ready", async () => { // Players can trigger GM-privileged operations and get results back try { const newItem = await socket.executeAsGM("createJournalEntry", "Session Notes", "

Tonight's adventure summary...

" ); console.log(`Journal entry created with id: ${newItem.id}`); // Output: "Journal entry created with id: abc123xyz" } catch (err) { if (err instanceof socketlib.errors.SocketlibNoGMConnectedError) { ui.notifications.warn("No GM is currently connected."); } else { console.error("Remote execution failed:", err); } } }); ``` ``` -------------------------------- ### Execute Function on All Clients Except Self Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Use `executeForOthers` to broadcast a fire-and-forget command to all connected clients, excluding the caller. This is useful when the local case is handled separately to avoid duplicate execution. ```javascript // Handle local state immediately, then sync to all other clients async function updateTokenPositionLocally(tokenId, newPos) { // Apply locally first for instant feedback const token = canvas.tokens.get(tokenId); await token.document.update({ x: newPos.x, y: newPos.y }); // Then sync to everyone else (they should not re-run our local update) await socket.executeForOthers("syncTokenPosition", tokenId, newPos); } socket.register("syncTokenPosition", (tokenId, newPos) => { const token = canvas.tokens.get(tokenId); token?.document.update({ x: newPos.x, y: newPos.y }); }); ``` -------------------------------- ### Execute function on all connected clients Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md socket.executeForEveryone runs a registered function on all connected clients, including the local one. The handler can be a function reference or its registered name. Parameters are passed directly. The promise resolves once the execution request is sent, not upon completion. ```javascript async socket.executeForEveryone(handler, ...args); ``` -------------------------------- ### Execute function for specific users Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md socket.executeForUsers allows executing a registered function on the clients of a specified list of players. The handler can be a function reference or its registered name. The recipients parameter is an array of user IDs. Parameters are passed directly. The promise resolves once the execution request is sent, not upon completion. ```javascript async executeForUsers(handler, recipients, ...args); ``` -------------------------------- ### Execute function on all clients except local Source: https://github.com/farling42/foundryvtt-socketlib/blob/develop/README.md Use socket.executeForOthers to execute a registered function on all connected clients, excluding the local client. The handler can be a function reference or its registered name. Parameters are passed directly. The promise resolves once the execution request is sent, not upon completion. ```javascript async socket.executeForOthers(handler, ...args); ``` -------------------------------- ### Typed Error Handling with socketlib.errors Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Socketlib exposes a hierarchy of error classes accessible via `socketlib.errors` for typed error handling in `try/catch` blocks around `executeAsGM` and `executeAsUser` calls. All error classes extend `SocketlibError` → `Error`. ```javascript // All error classes extend SocketlibError → Error // Available via socketlib.errors.* async function safeBroadcastAsGM(data) { try { const result = await socket.executeAsGM("processData", data); return result; } catch (err) { if (err instanceof socketlib.errors.SocketlibNoGMConnectedError) { // No GM is online to handle the request ui.notifications.warn("Action requires a GM to be connected."); } else if (err instanceof socketlib.errors.SocketlibInvalidUserError) { // Target user doesn't exist or disconnected before completion ui.notifications.error("Target user is unavailable."); } else if (err instanceof socketlib.errors.SocketlibRemoteException) { // The remote function threw an exception — details in their console console.error("Remote handler failed:", err.message); } else if (err instanceof socketlib.errors.SocketlibUnregisteredHandlerError) { // Handler not registered on the remote client console.error("Handler not registered on remote client:", err.message); } else if (err instanceof socketlib.errors.SocketlibInternalError) { // Unexpected internal socketlib error — please file a bug report console.error("Internal socketlib error:", err.message); } else { throw err; // Re-throw unrecognized errors } } } ``` -------------------------------- ### socket.register Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Registers a handler function on a `SocketlibSocket` instance under a unique name. This allows the function to be invoked remotely by other clients. All clients should register handlers within the `socketlib.ready` hook. The `this.socketdata.userId` property within the handler provides the ID of the user who initiated the call. ```APIDOC ## socket.register — Register a handler function ### Description Registers a function under a unique name so it can be invoked by socketlib on any client. All clients must register the same handlers (ideally in the `socketlib.ready` hook) before any cross-client calls are made. The registered function is called with `this.socketdata.userId` set to the id of the user who triggered the execution. ### Usage ```javascript Hooks.once("socketlib.ready", () => { socket = socketlib.registerModule("my-module"); // Register with a name that will be used when calling across clients socket.register("createJournalEntry", createJournalEntry); socket.register("deleteToken", deleteToken); // Inside the handler, `this.socketdata.userId` is the sender's user id function createJournalEntry(title, content) { const senderId = this.socketdata.userId; console.log(`Request from user: ${senderId}`); return JournalEntry.create({ name: title, content }); } function deleteToken(tokenId) { const token = canvas.tokens.get(tokenId); if (token) token.document.delete(); } }); ``` ``` -------------------------------- ### Error Classes Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt socketlib exposes a hierarchy of error classes accessible via `socketlib.errors` for typed error handling in `try/catch` blocks around `executeAsGM` and `executeAsUser` calls. ```APIDOC ## Error Classes — `socketlib.errors` ### Description Provides a hierarchy of error classes for robust error handling when using socketlib's execution methods. ### Available Error Classes - `SocketlibError` (Base class, extends `Error`) - `SocketlibNoGMConnectedError`: Thrown when no GM is online to handle the request. - `SocketlibInvalidUserError`: Thrown when the target user doesn't exist or disconnected before completion. - `SocketlibRemoteException`: Thrown when the remote function threw an exception. - `SocketlibUnregisteredHandlerError`: Thrown when the handler is not registered on the remote client. - `SocketlibInternalError`: Thrown for unexpected internal socketlib errors. ``` -------------------------------- ### Register Handler Function Source: https://context7.com/farling42/foundryvtt-socketlib/llms.txt Register a function to be invoked remotely by its name. All clients should register the same handlers. The sender's user ID is available as `this.socketdata.userId` within the handler. ```javascript Hooks.once("socketlib.ready", () => { socket = socketlib.registerModule("my-module"); // Register with a name that will be used when calling across clients socket.register("createJournalEntry", createJournalEntry); socket.register("deleteToken", deleteToken); // Inside the handler, `this.socketdata.userId` is the sender's user id function createJournalEntry(title, content) { const senderId = this.socketdata.userId; console.log(`Request from user: ${senderId}`); return JournalEntry.create({ name: title, content }); } function deleteToken(tokenId) { const token = canvas.tokens.get(tokenId); if (token) token.document.delete(); } }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.