Untitled

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

Guides Overview

Enklu comes with the ability to create realtime multiplayer experiences, as well as support for running devices as servers, or “hosts” as we refer to them.

There are a couple concepts to wrap your head around, but Enklu makes it straightforward to set up multiplayer AR experiences that any number of people can enjoy together.

Requirements

To successfully run multiplayer, you will need at least two HoloLens devices.

You will also need a wifi connection, and both devices must be connected to the same network.

Setting up a Simple Multiplayer Experience

Let’s set up a very simple multiplayer experience. We’ll make a multiplayer experience where all players can collectively watch a frog dart back and forth in a room. As the frog darts around the room, players should see that frog in the same forward/back position.

First, create an element, and then add a child that will represent the frog. Drop in one of the frog Public assets (it doesn’t matter what you use).

image.png

This experience requires that the frog’s position is synchronized between all players.

To accomplish this, mark this element as “Networked” in its Advanced tab. When checked on, this property enables an element to synchronize its visibility, position, rotation and scale for all players if multiplayer is running.

Untitled

Now let’s make the frog move back and forth in the room. Apply a public Move_Complex script to make it scoot back and forth.

You should start to see the Frog move back and forth.

image.png

Lastly, let’s modify Move_Complex enter function as shown below.

function enter() {
	// If there is a trigger message,
  if (TRIGGER_MSG) {
    // listen for the trigger message to start the move tween.
    messages.on(TRIGGER_MSG, startTweenPosition);
  }
  
  // Create position tween
  setTweenPosition();
  setLoopTweenPosition();
  
	if (!multiplayer.isServer()) {
    log.info("only the host should spin the frog, and players who join the game will get the position of the frog from the server.")
    return;
  }
  
  // If the Test Move checkbox is checked,
  if (TEST_TWEEN) {
    // start the move tween.
    startTweenPosition();
  } else {
    // Otherwise reset the element to its original position
    resetPosition();
  }
}

Great, we’ve done these two things:

At this point, the main feature of this experience is ready to go for multiplayer. But you won’t be able to see it in action unless you start up a multiplayer session!

First, let’s understand how Enklu does multiplayer.

How it Works

Here’s how Enklu makes multiplayer happen:

Using technical language: Enklu multiplayer is server-authoritative, in that servers running the experience are responsible for running the experience and are a central source of truth for everything going on. Players simply receive the server’s game state when they join it.

Setup

To get Multiplayer running, we will first need to set up a device to run as the Host.

A few functions can be called to make this happen. First, let’s create a simple interface to enable these actions. Create two Button Elements and designate one as the button for Joining a multiplayer game, and the other for running a device as the Host.

image.png

Setup Running as Host

Next, create a script named Host Game and paste in the following contents:

// -- Requires --
const messages = require('messages');

// -- Constants --
const self = this;

// -- Fields --
const MSG_HOST_GAME = '{[Host Game Message:string]}';

// -- Constructor --
function enter() {
  messages.on(MSG_HOST_GAME, hostGame);
}

// -- hostGame --
function hostGame() {
  // for this example, we will be not discoverable on internet (first parameter) but discoverable on the local network (second parameter)
  multiplayer.hostMode(false, true);
  multiplayer.networkHierarchy(self);
}

// -- Destructor --
function exit() {
  messages.off(MSG_HOST_GAME, hostGame);
}

module.exports = {
  enter: enter,
  exit: exit
};
    

Add it to the Frog Root element.

image.png

Next, fill in the Host Game Message field with a message that is dispatched by the Host Game button on press. See Button Elements for a sample script that will make the button do that. Make sure Host Game listens for the same message dispatched by the button.

image.png

image.png

In addition, fill in this message into the Frog’s Move_Complex script for Move Trigger Message.

image.png

If you’ve set this up correctly, when you press the Host Game button, the Frog should restart its movement.

The multiplayer code will not do anything yet, as you can only see its effects in an actual multiplayer game. However, the Web Editor is running locked in the Host configuration, so the Web Editor is always a simulation of what you will be seeing on the Hosting side of a multiplayer game (what will be synchronized to all clients)

Setup Joining a Game

Now, create a new script named Join Game and fill it with the following code:

// -- Requires --
const messages = require('messages');

// -- Constants --
const self = this;

// -- Fields --
const MSG_JOIN_GAME = '{[Join Game Message:string]}';
const IP = '{[IP:string]}';

// -- Constructor --
function enter() {
  messages.on(MSG_JOIN_GAME, joinGame);
}

// -- joinGame --
function joinGame() {
  multiplayer.useIPOnly(true);
  multiplayer.joinServerWithIP(IP);
}

// -- Destructor --
function exit() {
  messages.off(MSG_JOIN_GAME, joinGame);
}

module.exports = {
  enter: enter,
  exit: exit
};
    

Add it to the Join Game button element (or some other element in the scene).

image.png

You’ll notice that we need to pass in an IP address to one of the functions. This is one of the means by which you can connect to another device running a multiplayer game: connect directly to it via their exact network address.

Choose one of the two HoloLenses to run as a Host.

First, ensure it’s connected to the internet, and that both devices are on the same internet.

<aside> 💡 If the network changes, the IP address will also change, so keep that in mind.

</aside>

Say the voice command: “What is my IP address?” A popup will appear on screen that will show that device’s IP address.

Then, fill in the IP field with that address.

image.png

Lastly, connect Join Game to the Join Game button via a message.

image.png

image.png

Try Playing!

Do the following steps in order:

  1. Make sure both devices are connected to the same WiFi network!
  2. Load both devices into this experience. Make sure it’s the same!
  3. On the device you designate as Host (the one that you got the IP address on), press the Run as Host button. Your device is now running as a Host and is awaiting connections.
    1. at this time, the Frog should start moving on the Host device.
  4. On the device that is not the host, and will act as a joining player, you will not see the frog move initially. Press the Join Game button. Your device will try to join the server with the provided IP.

If all goes well, the following should happen:

If you compare whether or not the Frog has moved forwards or has moved backwards, it will be the same on both devices.

The Frog will not be in the same spatial location - however, if you apply a Space Scan to the experience, both HoloLenses will now see the frog in the exact same place in the room at the exact same time.

Congratulations - you are now running a synchronized multiplayer game!

Current Limitations

Explanations

Earlier, we asked you to add a few lines to the Move_Complex script:

if (!multiplayer.isServer()) {
  log.info("only the host should spin the frog, and players who join the game will get the position of the frog from the server.")
  return;
}

This code was run on the Hosting device when we press the Host Game button:

multiplayer.hostMode(false, true);
multiplayer.networkHierarchy(self);

This code was run on the player / Joining device:

multiplayer.useIPOnly(true);
multiplayer.joinServerWithIP(IP);

Expanding Your Multiplayer Experience

You have learned how to create and run a simple multiplayer experience. The following sections will go over additional tools at your disposal.

Disconnecting

If you want to exit the multiplayer game, call this function on a player:

multiplayer.disconnectFromServer();

If you want to shut down the Host, call this function. It will kick out all players that are currently in the game.

multiplayer.stopHost();

If the server shuts down, players will attempt to reconnect to the last server address they connected to. You’ll find that if you Start Host again, the players will automatically rejoin!

Controlling the Host via Networked Buttons

In a typical multiplayer game, the player can perform actions that will modify game state. But if the game is running entirely in the Host, how can the player ever make any impact?

The idea is that you want to command the Host to run certain code. A simple way to provide this is through Button Elements.


Untitled