đ°Getting Started | â**Updates |** đ Guides | đ˘ API | âFAQ
Web Editor Basics
HoloLens
Mobile
Meta Quest
Chapter Series Documentation
Assets
Scripting
Enklu Embedded
API Reference
Release Notes
FAQ
Contact
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.
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.
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).
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.
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.
Move_Complex
script if it cannot be found in the Public library.You should start to see the Frog move back and forth.
Lastly, letâs modify Move_Complex
enter function as shown below.
messages.on
, setTweenPosition()
and setLoopTweenPosition()
calls to the top.multiplayer
function, isServer()
. Weâll go into more detail later why this is needed.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.
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.
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.
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.
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.
In addition, fill in this message into the Frogâs Move_Complex
script for Move Trigger Message.
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)
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).
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.
Lastly, connect Join Game to the Join Game button via a message.
Do the following steps in order:
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!
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);
You have learned how to create and run a simple multiplayer experience. The following sections will go over additional tools at your disposal.
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!
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.