Untitled

📰Getting Started | ⭐**Updates |** 📝 Guides | 🔢 API | ❓FAQ

Guides Overview

The Players API lets you customize a number of things about how players behave in a multiplayer experience.

Player Object

When you join a multiplayer server, by default, each player will have a Player Object that hovers over their head and follows them around. This object includes a button and name tag.

This object can be customized to simply be a name display, or orchestrate interactions between players using the button, which will be explained in the Player Interactions section.

Each player will be assigned a random name on join, but this can be customized as shown in the Player Name section.

<aside> ⚠️ The Player Object will only line up accurately with the player’s head if the experience has a space scan and all players are properly anchored. Not recommended for free floating experiences.

</aside>

Untitled

Testing in the Web Editor

In the Web Editor, if you turn on Debug Mode, you will see a dummy player object a few units behind the world origin that you can use to test the appearance and interactivity of your Player Object.

Untitled

This simulates the following scenario:

With the following limitations:

Visibility

First, you can set the visibility of both the name tag and button like so. If you do not want this object to have any part in the experience, you can simply hide it.

Currently, the visibility setting will apply to all Player Objects.

// show name tag and button of all player objects
multiplayer.players.nameTagVisible = true;
multiplayer.players.buttonVisible = true;

// hide name tag and button of all player objects
multiplayer.players.nameTagVisible = false;
multiplayer.players.buttonVisible = false;

Appearance

You can use any of the VineML icons, fonts and colors to customize the name tag and button’s appearance.

Currently, your appearance settings will apply to all Player Objects.

// configure look of the player object
multiplayer.players.nameTagColor = "Secondary";
multiplayer.players.nameTagFontSize = 100;
multiplayer.players.nameTagFont = "OpenSans-Bold";
multiplayer.players.nameTagPosition = vec3(0.0, 0.6, 0.0); // position relative to a player's head

multiplayer.players.buttonColor = "Secondary";
multiplayer.players.buttonPosition = vec3(0.0, 0.4, 0.0); // position relative to a player's head
multiplayer.players.buttonScale = vec3(2, 2, 2);
multiplayer.players.buttonIcon = "exclamation";

Player Name

At any time, you can set the name tag on your device’s Player Object.

If set before you join a server, it will be applied when you join. If set while in a server, it will be updated in real time.

multiplayer.players.changeLocalPlayerName("UltimateEnklunaught5000");

At any time, you can also get your current player name.

multiplayer.players.getLocalPlayerName();

If you want to get another player’s name, they will need to give it to you through a Player Interaction.

Player GUID

Each player is assigned a unique GUID on join, which can be used for identification. At any time, you can get your own GUID like this.

multiplayer.players.getLocalPlayerGUID();

If you want to get another player’s GUID, they will need to give it to you through a Player Interaction.

Player Interactions

The button on the Player Object can be used to initiate Player Interactions, where players can communicate with one another and exchange data. They can even cause one another to invoke custom JS code.

The example below will demonstrate how to set up a basic interaction.

Example

As an example, we will create a Player Interaction where two players can challenge one another to a hypothetical battle.

First, we will need to define a starting point for the interaction.

multiplayer.players.defaultInteractionType = "startBattleChallenge";
multiplayer.players.defaultInteractionParameter = "I want to battle!";

Next, let’s define what happens when we send this interaction to another player. This code will be invoked on my player’s device when I send an interaction to someone else, which can be used to display feedback, i.e. confirmation that my interaction was sent.

Note the parameters that are made available to this callback.

// register this callback as a function that is invoked when you send another player an interaction.
multiplayer.players.onSendPlayerInteraction(onSendInteraction);

// -- onSendInteraction --
// These are invoked on your device when you send an interaction to another player.
// type: string
// param: string
// targetPlayerName: string
// targetPlayer: player identity
function onSendInteraction(type, param, targetPlayerName, targetPlayer) {
  log.info("Sent interaction of type {0} to {1}", type, targetPlayerName);
  
  if (type === "startBattleChallenge")
  {
    log.info("Sent interaction to {0} with the following message: {1}", targetPlayerName, param);
  }
}

Then, we should define what happens when a player receives an interaction. This code will be invoked on the player’s device that is the recipient of the interaction.

// register this callback as a function that is invoked when you receive an interaction from another player.
multiplayer.players.onReceivePlayerInteraction(onReceiveInteraction);

// -- onReceiveInteraction --
// These are invoked on your device when you receive an interaction from another player.
// type: string
// param: string
// targetPlayerName: string
// targetPlayer: player identity
function onReceiveInteraction(type, param, sendingPlayerName, sendingPlayer) {
  log.info("Received interaction of type {0} from {1}", type, sendingPlayerName);
  
  if (type === "startBattleChallenge")
  {
    log.info("Received startBattleChallenge from {0}", sendingPlayerName);
    log.info("They sent this message: {0}", param);
  }
}

Now, if you run these scripts and click on the button on the dummy player object, you should see these messages in the Logs.

Untitled

In the Web Editor, the player names may be a bit confusing because both your camera and the dummy player are on the same device. But we can see the following flow occurred:

  1. I pressed another player’s button
  2. I sent the other player an interaction with a “Hello World!” message
  3. I invoked my onSendInteraction callback
  4. The other player received my interaction
  5. They invoked their onReceiveInteraction callback
  6. They received my “Hello World!” message

Great! We have sent and received some basic information between Players. Now, let’s make it more complex.

For our battle challenging UX, we’d like it to be a “conversation” of sorts, where one player can request another player to battle, and the other can accept or reject it. This will require the interaction to have more than one part, and also necessitates going back and forth between a specific player.

Inside the onSendInteraction and onReceiveInteraction callbacks, there is a parameter targetPlayer and sendingPlayer. This is an object that stores identifying information about the player the interaction is being sent to, or the player who sent it, respectively.

You can’t do too much with this object by itself, but if you pass it into the function interactWithSpecificPlayer, that function will be able to send an interaction to the specific player it refers to without having to press their button.

var player; // at some point we need to fill this variable with player identification

let param = "Information about my Player";

let type = "initiateChallenge";

// player - player identification
// type - interaction type
// param - interaction parameter
multiplayer.players.interactWithSpecificPlayer(player, type, param);

Since we get player identification information via the aforementioned parameters, let’s add this function to our onReceiveInteraction callback.

// register this callback as a function that is invoked when you receive an interaction from another player.
multiplayer.players.onReceivePlayerInteraction(onReceiveInteraction);

// -- onReceiveInteraction --
// These are invoked on your device when you receive an interaction from another player.
// type: string
// param: string
// targetPlayerName: string
// targetPlayer: player identity
function onReceiveInteraction(type, param, sendingPlayerName, sendingPlayer) {
  log.info("Received interaction of type {0} from {1}", type, sendingPlayerName);
  
  var player = sendingPlayer; // get identifying information
  
  if (type === "startBattleChallenge")
  {
    log.info("Received startBattleChallenge from {0}", sendingPlayerName);
    log.info("They sent this message: {0}", param);

		let info = "Information about me";
		multiplayer.players.interactWithSpecificPlayer(player, "confirmBattleChallenge", info);
  }
}

This function will send an interaction to a specific player. We entered a new type, "confirmBattleChallenge", so let’s add handling for when we receive that.

// register this callback as a function that is invoked when you receive an interaction from another player.
multiplayer.players.onReceivePlayerInteraction(onReceiveInteraction);

// -- onReceiveInteraction --
// These are invoked on your device when you receive an interaction from another player.
// type: string
// param: string
// targetPlayerName: string
// targetPlayer: player identity
function onReceiveInteraction(type, param, sendingPlayerName, sendingPlayer) {
  log.info("Received interaction of type {0} from {1}", type, sendingPlayerName);
  
  var player = sendingPlayer; ****// get identifying information
  
  if (type === "startBattleChallenge")
  {
	  log.info("Received startBattleChallenge from {0}", sendingPlayerName);
    log.info("They sent this message: {0}", param);
  
		let info = "Information about me";
		multiplayer.players.interactWithSpecificPlayer(player, "confirmBattleChallenge", info);
  }
  else if (type === "confirmBattleChallenge")
  {
	  log.info("Do you want to accept this challenge from {0}?", sendingPlayerName);
	 }
}

Now, every time this player receives an interaction, it will save information about the specific player who sent it. Then, we can use that information to send an interaction back and prolong the conversation.

Now, my interaction has gotten longer…

Untitled

You can chain together these calls to make a player interaction as long as you want. The main rules:

If you want to unregister your send / receive callbacks, use these:

multiplayer.players.clearOnReceivePlayerInteraction();
multiplayer.players.clearOnSendPlayerInteraction();

Next: Physics

Sidebar Table of Contents


Untitled