{"id":69614,"date":"2019-08-21T04:16:04","date_gmt":"2019-08-21T11:16:04","guid":{"rendered":"http:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/"},"modified":"2019-08-21T04:16:04","modified_gmt":"2019-08-21T11:16:04","slug":"how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1","status":"publish","type":"post","link":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/","title":{"rendered":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)"},"content":{"rendered":"<link rel=\"canonical\" href=\"https:\/\/www.smashingmagazine.com\/2019\/08\/real-time-multiplayer-virtual-reality-game-part-1\/\"><title>How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)<\/title><\/p>\n<article>\n<header>\n<h1>How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)<\/h1>\n<address>Alvin Wan<\/address>\n<p>                  <time datetime=\"2019-08-20T15:30:59+02:00\">2019-08-20T15:30:59+02:00<\/time><time datetime=\"2019-08-21T11:06:30+00:00\">2019-08-21T11:06:30+00:00<\/time><\/header>\n<p>In this tutorial series, we will build a web-based multiplayer <a href=\"linkhttps:\/\/www.smashingmagazine.com\/category\/virtual-reality\">virtual reality<\/a> game in which players will need to collaborate to solve a puzzle. We will use <a href=\"https:\/\/aframe.io\/\">A-Frame<\/a> for VR modeling, <a href=\"https:\/\/github.com\/alvinwan\/mirrorvr\">MirrorVR<\/a> for cross-device real-time synchronization, and <a href=\"https:\/\/github.com\/alvinwan\/aframe-low-poly\">A-Frame Low Poly<\/a> for low-poly aesthetics. At the end of this tutorial, you will have a fully functioning demo online that anyone can play.<\/p>\n<p>Each pair of players is given a ring of orbs. The goal is to \u201cturn on\u201d all orbs, where an orb is \u201con\u201d if it\u2019s elevated and bright. An orb is \u201coff\u201d if it\u2019s lower and dim. However, certain \u201cdominant\u201d orbs affect their neighbors: if it switches state, its neighbors also switch state. Only player 2 can control the dominant orbs while only player 1 can control non-dominant orbs. This forces both players to collaborate to solve the puzzle. In this first part of the tutorial, we will build the environment and add the design elements for our VR game.<\/p>\n<p>The seven steps in this tutorial are grouped into three sections:<\/p>\n<ol>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/articles\/#setting-up-the-scene\">Setting Up The Scene<\/a> (Steps 1\u20132)<\/li>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/articles\/#creating-the-orbs\">Creating The Orbs<\/a> (Steps 3\u20135)<\/li>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/articles\/#making-the-orbs-interactive\">Making The Orbs Interactive<\/a> (Steps 6\u20137)<\/li>\n<\/ol>\n<div data-component=\"FeaturePanel\" data-audience=\"non-subscriber\" data-remove=\"true\"><\/div>\n<p>This first part will conclude with a clickable orb that turns on and off (as pictured below). You will use A-Frame VR and several A-Frame extensions.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/1-clickable-orb.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/1-clickable-orb.gif?w=900\"   alt=\"\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/1-clickable-orb.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<h3>Setting Up The Scene<\/h3>\n<h4>1. Let\u2019s Go With A Basic Scene<\/h4>\n<p>To get started, let\u2019s take a look at how we can set up a simple scene with a ground:<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/eee1d9f5-09f5-4326-8565-9e3441598439\/2-simple-scene.png?ssl=1\"><\/p>\n<p>    <img data-recalc-dims=\"1\" decoding=\"async\" srcset=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/2-simple-scene.png 400w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_800\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/eee1d9f5-09f5-4326-8565-9e3441598439\/2-simple-scene.png 800w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1200\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/eee1d9f5-09f5-4326-8565-9e3441598439\/2-simple-scene.png 1200w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1600\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/eee1d9f5-09f5-4326-8565-9e3441598439\/2-simple-scene.png 1600w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_2000\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/eee1d9f5-09f5-4326-8565-9e3441598439\/2-simple-scene.png 2000w\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/2-simple-scene.png?w=900\" sizes=\"100vw\" alt=\"Creating a simple scene\"><\/a><figcaption>\n      Creating a simple scene (<a href=\"https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/eee1d9f5-09f5-4326-8565-9e3441598439\/2-simple-scene.png\">Large preview<\/a>)<br \/>\n    <\/figcaption><\/figure>\n<p>The first three instructions below are excerpted from my <a href=\"https:\/\/www.smashingmagazine.com\/2019\/03\/virtual-reality-endless-runner-game-vr-part-1\/#step-1-setting-up-a-basic-scene\">previous article<\/a>. You will start by setting up a website with a single static HTML page. This allows you to code from your desktop and automatically deploy to the web. The deployed website can then be loaded on your mobile phone and placed inside a VR headset. Alternatively, the deployed website can be loaded by a standalone VR headset.<\/p>\n<p>Get started by navigating to <a href=\"https:\/\/glitch.com\/\">glitch.com<\/a>. Then, do the following:<\/p>\n<ol>\n<li>Click on \u201cNew Project\u201d in the top right,<\/li>\n<li>Click on \u201chello-webpage\u201d in the drop-down,<\/li>\n<li>Next, click on <em>index.html<\/em> in the left sidebar. We will refer to this as your \u201ceditor\u201d.<\/li>\n<\/ol>\n<p>You should now see the following Glitch screen with a default HTML file.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/915368ce-0656-4593-a43e-5d11990470fe\/3-glitch-project-index-html-file.png?ssl=1\"><\/p>\n<p>    <img data-recalc-dims=\"1\" decoding=\"async\" srcset=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/3-glitch-project-index-html-file.png 400w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_800\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/915368ce-0656-4593-a43e-5d11990470fe\/3-glitch-project-index-html-file.png 800w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1200\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/915368ce-0656-4593-a43e-5d11990470fe\/3-glitch-project-index-html-file.png 1200w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1600\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/915368ce-0656-4593-a43e-5d11990470fe\/3-glitch-project-index-html-file.png 1600w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_2000\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/915368ce-0656-4593-a43e-5d11990470fe\/3-glitch-project-index-html-file.png 2000w\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/3-glitch-project-index-html-file.png?w=900\" sizes=\"100vw\" alt=\"Glitch project: the index.html file\"><\/a><figcaption>\n      Glitch project: the index.html file (<a href=\"https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/915368ce-0656-4593-a43e-5d11990470fe\/3-glitch-project-index-html-file.png\">Large preview<\/a>)<br \/>\n    <\/figcaption><\/figure>\n<p>As with the linked tutorial above, start by deleting all existing code in the current <em>index.html<\/em> file. Then, type in the following for a basic webVR project, using A-Frame VR. This creates an empty scene by using A-Frame\u2019s default lighting and camera.<\/p>\n<div>\n<pre><code><!DOCTYPE html>\n<html>\n  <head>\n    <title>Lightful<\/title>\n    <script src=\"https:\/\/aframe.io\/releases\/0.8.0\/aframe.min.js\"><\/script>\n  <\/head>\n  <body>\n    <a-scene>\n    <\/a-scene>\n  <\/body>\n<\/html>\n<\/code><\/pre>\n<\/div>\n<p>Raise the camera to standing height. Per A-Frame VR recommendations (<a href=\"https:\/\/github.com\/aframevr\/aframe\/issues\/3351\">Github issue<\/a>), wrap the camera with a new entity and move the parent entity instead of the camera directly. Between your <code>a-scene<\/code> tags on lines 8 and 9, add the following.<\/p>\n<pre><code><!-- Camera! -->\n<a-entity id=\"rig\" position=\"0 3 0\">\n  <a-camera wasd-controls look-controls><\/a-camera>\n<\/a-entity>\n<\/code><\/pre>\n<p>Next, add a large box to denote the ground, using <code>a-box<\/code>. Place this directly beneath your camera from the previous instruction.<\/p>\n<div>\n<pre><code><!-- Action! -->\n<a-box shadow width=\"75\" height=\"0.1\" depth=\"75\" position=\"0 -1 0\" color=\"#222\"><\/a-box>\n<\/code><\/pre>\n<\/div>\n<p>Your <em>index.html<\/em> file should now match the following exactly. You can find the full source code <a href=\"https:\/\/github.com\/alvinwan\/lightful\/tutorial\/step01.html\">here, on Github<\/a>.<\/p>\n<div>\n<pre><code><html>\n  <head>\n    <title>Lightful<\/title>\n    <script src=\"https:\/\/aframe.io\/releases\/0.8.0\/aframe.min.js\"><\/script>\n  <\/head>\n  <body>\n    <a-scene>\n      <!-- Camera! -->\n      <a-entity id=\"rig\" position=\"0 3 0\">\n        <a-camera wasd-controls look-controls><\/a-camera>\n      <\/a-entity>\n\n      <!-- Action! -->\n      <a-box shadow width=\"75\" height=\"0.1\" depth=\"75\" position=\"0 -1 0\" color=\"#222\"><\/a-box>\n    <\/a-scene>\n  <\/body>\n<\/html>\n<\/code><\/pre>\n<\/div>\n<p>This concludes setup. Next, we will customize lighting for a more mysterious atmosphere.<\/p>\n<h4>2. Add Atmosphere<\/h4>\n<p>In this step, we will set up the fog and custom lighting.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/e9584a2b-9b23-488e-ad6d-f97380353789\/4-preview-simple-scene-dark-mood.png?ssl=1\"><\/p>\n<p>    <img data-recalc-dims=\"1\" decoding=\"async\" srcset=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/4-preview-simple-scene-dark-mood.png 400w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_800\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/e9584a2b-9b23-488e-ad6d-f97380353789\/4-preview-simple-scene-dark-mood.png 800w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1200\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/e9584a2b-9b23-488e-ad6d-f97380353789\/4-preview-simple-scene-dark-mood.png 1200w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1600\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/e9584a2b-9b23-488e-ad6d-f97380353789\/4-preview-simple-scene-dark-mood.png 1600w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_2000\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/e9584a2b-9b23-488e-ad6d-f97380353789\/4-preview-simple-scene-dark-mood.png 2000w\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/4-preview-simple-scene-dark-mood.png?w=900\" sizes=\"100vw\" alt=\"A preview of a simple scene with a dark mood\"><\/a><figcaption>\n      A preview of a simple scene with a dark mood (<a href=\"https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/e9584a2b-9b23-488e-ad6d-f97380353789\/4-preview-simple-scene-dark-mood.png\">Large preview<\/a>)<br \/>\n    <\/figcaption><\/figure>\n<p>Add a fog, which will obscure objects far away for us. Modify the <code>a-scene<\/code> tag on line 8. Here, we will add a dark fog that quickly obscures the edges of the ground, giving the effect of a distant horizon.<\/p>\n<div>\n<pre><code><a-scene fog=\"type: linear; color: #111; near:10; far:15\"><\/a-scene>\n<\/code><\/pre>\n<\/div>\n<p>The dark gray <code>#111<\/code> fades in linearly from a distance of 10 to a distance of 15. All objects more than 15 units away are completely obscured, and all objects fewer than 10 units away are completely visible. Any object in between is partially obscured.<\/p>\n<p>Add one ambient light to lighten in-game objects and one-directional light to accentuate reflective surfaces you will add later. Place this directly after the <code>a-scene<\/code> tag you modified in the previous instruction.<\/p>\n<div>\n<pre><code><!-- Lights! -->\n<a-light type=\"directional\" castshadow=\"true\" intensity=\"0.5\" color=\"#FFF\" position=\"2 5 0\"><\/a-light>\n<a-light intensity=\"0.1\" type=\"ambient\" position=\"1 1 1\" color=\"#FFF\"><\/a-light>\n<\/code><\/pre>\n<\/div>\n<p>Directly beneath the lights in the previous instruction, add a dark sky. Notice the dark gray <code>#111<\/code> matches that of the distant fog.<\/p>\n<pre><code><a-sky color=\"#111\"><\/a-sky>\n<\/code><\/pre>\n<p>This concludes basic modifications to the mood and more broadly, scene setup. Check that your code matches the <a href=\"https:\/\/github.com\/alvinwan\/lightful\/blob\/master\/tutorial\/step02.html\">source code for Step 2<\/a> on Github, exactly. Next, we will add a low-poly orb and begin customizing the orb\u2019s aesthetics.<\/p>\n<div><\/div>\n<h3>Creating The Orbs<\/h3>\n<h4>3. Create A Low-Poly Orb<\/h4>\n<p>In this step, we will create a rotating, reflective orb as pictured below. The orb is composed of two stylized low-poly spheres with a few tricks to suggest reflective material.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/5-rotating-rreflective-orb.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/5-rotating-rreflective-orb.gif?w=900\"   alt=\"Rotating, reflective orb\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/5-rotating-rreflective-orb.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>Start by importing the low-poly library in your <code>head<\/code> tag. Insert the following between lines 4 and 5.<\/p>\n<div>\n<pre><code><script src=\"https:\/\/cdn.jsdelivr.net\/gh\/alvinwan\/aframe-low-poly@0.0.5\/dist\/aframe-low-poly.min.js\"><\/script>\n<\/code><\/pre>\n<\/div>\n<p>Create a carousel, wrapper, and orb container. The <code>carousel<\/code> will contain multiple orbs, the <code>wrapper<\/code> will allow us to rotate all orbs around a center axis without rotating each orb individually, and the <code>container<\/code> will \u2014 as the name suggests \u2014 contain all orb components.<\/p>\n<div>\n<pre><code><a-entity id=\"carousel\">\n  <a-entity rotation=\"0 90 0\" id=\"template\" class=\"wrapper\" position=\"0 0 0\">\n    <a-entity id=\"container-orb0\" class=\"container\" position=\"8 3 0\" scale=\"1 1 1\">\n      <!-- place orb here -->\n    <\/a-entity>\n  <\/a-entity>\n<\/a-entity>\n<\/code><\/pre>\n<\/div>\n<p>Inside the orb container, add the orb itself: one sphere is slightly translucent and offset, and the other is completely solid. The two combined mimic reflective surfaces.<\/p>\n<div>\n<pre><code><a-entity class=\"orb\" id=\"orb0\" data-id=\"0\">\n  <lp-sphere seed=\"0\" shadow max-amplitude=\"1 1 1\" position=\"-0.5 0 -0.5\"><\/lp-sphere>\n  <lp-sphere seed=\"0\" shadow max-amplitude=\"1 1 1\" rotation=\"0 45 45\" opacity=\"0.5\" position=\"-0.5 0 -0.5\"><\/lp-sphere>\n<\/a-entity>\n<\/code><\/pre>\n<\/div>\n<p>Finally, rotate the sphere indefinitely by adding the following <code>a-animation<\/code> tag immediately after the <code>lp-sphere<\/code> inside the <code>.orb<\/code> entity in the last instruction.<\/p>\n<div>\n<pre><code><a-animation attribute=\"rotation\" repeat=\"indefinite\" from=\"0 0 0\" to=\"0 360 0\" dur=\"5000\"><\/a-animation>\n<\/code><\/pre>\n<\/div>\n<p>Your source code for the orb wrappers and the orb itself should match the following exactly.<\/p>\n<div>\n<pre><code><a-entity id=\"carousel\">\n  <a-entity rotation=\"0 90 0\" id=\"template\" class=\"wrapper\" position=\"0 0 0\">\n    <a-entity id=\"container-orb0\" class=\"container\" position=\"8 3 0\" scale=\"1 1 1\">\n      <a-entity class=\"orb\" id=\"orb0\" data-id=\"0\">\n        <lp-sphere seed=\"0\" shadow max-amplitude=\"1 1 1\" position=\"-0.5 0 -0.5\"><\/lp-sphere>\n        <lp-sphere seed=\"0\" shadow max-amplitude=\"1 1 1\" rotation=\"0 45 45\" opacity=\"0.5\" position=\"-0.5 0 -0.5\"><\/lp-sphere>\n        <a-animation attribute=\"rotation\" repeat=\"indefinite\" from=\"0 0 0\" to=\"0 360 0\" dur=\"5000\"><\/a-animation>\n      <\/a-entity>\n    <\/a-entity>\n  <\/a-entity>\n<\/a-entity>\n<\/code><\/pre>\n<\/div>\n<p>Check that your source code matches the full <a href=\"https:\/\/github.com\/alvinwan\/lightful\/blob\/master\/tutorial\/step03.html\">source code for step 3<\/a> on Github. Your preview should now match the following.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/6-rotating-reflective-orb.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/6-rotating-reflective-orb.gif?w=900\"   alt=\"Rotating, reflective orb\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/6-rotating-reflective-orb.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>Next, we will add more lighting to the orb for a golden hue.<\/p>\n<h4>4. Light Up The Orb<\/h4>\n<p>In this step, we will add two lights, one colored and one white. This produces the following effect.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/7-orb-lit-point-lights.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/7-orb-lit-point-lights.gif?w=900\"   alt=\"Orb lit with point lights\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/7-orb-lit-point-lights.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>Start by adding the white light to illuminate the object from below. We will use a point light. Directly before <code>#orb0<\/code> but within <code>#container-orb0<\/code>, add the following offset point light.<\/p>\n<div>\n<pre><code><a-entity position=\"-2 -1 0\">\n    <a-light distance=\"8\" type=\"point\" color=\"#FFF\" intensity=\"0.8\"><\/a-light>\n<\/a-entity>\n<\/code><\/pre>\n<\/div>\n<p>In your preview, you will see the following.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/5-rotating-rreflective-orb.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/5-rotating-rreflective-orb.gif?w=900\"   alt=\"Orb lit with white point light\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/5-rotating-rreflective-orb.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>By default, lights do not decay with distance. By adding <code>distance=\"8\"<\/code>, we ensure that the light fully decays with a distance of 8 units, to prevent the point light from illuminating the entire scene. Next, add the golden light. Add the following directly above the last light.<\/p>\n<div>\n<pre><code><a-light class=\"light-orb\" id=\"light-orb0\" distance=\"8\" type=\"point\" color=\"#f90\" intensity=\"1\"><\/a-light>\n<\/code><\/pre>\n<\/div>\n<p>Check that your code matches the <a href=\"https:\/\/github.com\/alvinwan\/lightful\/blob\/master\/tutorial\/step04.html\">source code for step 4<\/a> exactly. Your preview will now match the following.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/7-orb-lit-point-lights.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/7-orb-lit-point-lights.gif?w=900\"   alt=\"Orb lit with point lights\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/7-orb-lit-point-lights.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>Next, you will make your final aesthetic modification to the orb and add rotating rings.<\/p>\n<h4>5. Add Rings<\/h4>\n<p>In this step, you will produce the final orb, as pictured below.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/9-golden-orb-with-multiple-rings.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/9-golden-orb-with-multiple-rings.gif?w=900\"   alt=\"Golden orb with multiple rings\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/9-golden-orb-with-multiple-rings.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>Add a ring in <code>#container-orb0<\/code> directly before <code>#orb0<\/code>.<\/p>\n<div>\n<pre><code><a-ring color=\"#fff\" material=\"side:double\" position=\"0 0.5 0\" radius-inner=\"1.9\" radius-outer=\"2\" opacity=\"0.25\"><\/a-ring>\n<\/code><\/pre>\n<\/div>\n<p>Notice the ring itself does not contain color, as the color will be imbued by the point light in the previous step. Furthermore, the <code>material=\"side:double\"<\/code> is important as, without it, the ring\u2019s backside would not be rendered; this means the ring would disappear for half of its rotation.<\/p>\n<p>However, the preview with only the above code will not look any different. This is because the ring is currently perpendicular to the screen. Thus, only the ring\u2019s \u201cside\u201d (which has 0 thickness) is visible. Place the following animation in between the <code>a-ring<\/code> tags in the previous instruction.<\/p>\n<div>\n<pre><code><a-animation attribute=\"rotation\" easing=\"linear\" repeat=\"indefinite\" from=\"0 0 0\" to=\"0 360 0\" dur=\"8000\"><\/a-animation>\n<\/code><\/pre>\n<\/div>\n<p>Your preview should now match the following:<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/8-golden-orb-with-ring.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/8-golden-orb-with-ring.gif?w=900\"   alt=\"Golden orb with ring\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/8-golden-orb-with-ring.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>Create a variable number of rings with different rotation axes, speeds, and sizes. You can use the following example rings. Any new rings should be placed underneath the last <code>a-ring<\/code>.<\/p>\n<div>\n<pre><code><a-ring color=\"#fff\" material=\"side:double\" position=\"0 0.5 0\" radius-inner=\"2.4\" radius-outer=\"2.5\" opacity=\"0.25\">\n  <a-animation attribute=\"rotation\" easing=\"linear\" repeat=\"indefinite\" from=\"0 45 0\" to=\"360 45 0\" dur=\"8000\"><\/a-animation>\n<\/a-ring>\n<a-ring color=\"#fff\" material=\"side:double\" position=\"0 0.5 0\" radius-inner=\"1.4\" radius-outer=\"1.5\" opacity=\"0.25\">\n  <a-animation attribute=\"rotation\" easing=\"linear\" repeat=\"indefinite\" from=\"0 -60 0\" to=\"-360 -60 0\" dur=\"3000\"><\/a-animation>\n<\/a-ring>\n<\/code><\/pre>\n<\/div>\n<p>Your preview will now match the following.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/9-golden-orb-with-multiple-rings.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/9-golden-orb-with-multiple-rings.gif?w=900\"   alt=\"Golden orb with multiple rings\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/9-golden-orb-with-multiple-rings.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>Check that your code matches the <a href=\"https:\/\/github.com\/alvinwan\/lightful\/blob\/master\/tutorial\/step05.html\">source code for step 5<\/a> on Github. This concludes decor for the orb. With the orb finished, we will next add interactivity to the orb. In the next step, we will specifically add a visible cursor with a clicking animation when pointed at clickable objects.<\/p>\n<div><\/div>\n<h3>Making The Orbs Interactive<\/h3>\n<h4>6. Add A Cursor<\/h4>\n<p>In this step, we will add a white cursor that can trigger clickable objects. The cursor is pictured below.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/10-clicking-on-orb.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/10-clicking-on-orb.gif?w=900\"   alt=\"clicking on orb\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/10-clicking-on-orb.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>In your <code>a-camera<\/code> tag, add the following entity. The <code>fuse<\/code> attribute allows this entity the ability to trigger click events. The <code>raycaster<\/code> attribute determines how often and how far to check for clickable objects. The <code>objects<\/code> attribute accepts a selector to determine which entities are clickable. In this case, all objects of class <code>clickable<\/code> are clickable.<\/p>\n<div>\n<pre><code><a-entity cursor=\"fuse: true; fuseTimeout: 250\"\n      position=\"0 0 -1\"\n      geometry=\"primitive: ring; radiusInner: 0.03; radiusOuter: 0.04\"\n      material=\"color: white; shader: flat; opacity: 0.5\"\n      scale=\"0.5 0.5 0.5\"\n      raycaster=\"far: 20; interval: 1000; objects: .clickable\">\n    <!-- Place cursor animation here -->\n<\/a-entity>\n<\/code><\/pre>\n<\/div>\n<p>Next, add cursor animation and an extra ring for aesthetics. Place the following inside the entity cursor object above. This adds animation to the cursor object so that clicks are visible.<\/p>\n<div>\n<pre><code><a-circle radius=\"0.01\" color=\"#FFF\" opacity=\"0.5\" material=\"shader: flat\"><\/a-circle>\n<a-animation begin=\"fusing\" easing=\"ease-in\" attribute=\"scale\"\n   fill=\"backwards\" from=\"1 1 1\" to=\"0.2 0.2 0.2\" dur=\"250\"><\/a-animation>\n<\/code><\/pre>\n<\/div>\n<p>Next, add the <code>clickable<\/code> class to the <code>#orb0<\/code> to match the following.<\/p>\n<pre><code><a-entity class=\"orb clickable\" id=\"orb0\" data-id=\"0\">\n<\/code><\/pre>\n<p>Check that your code matches the <a href=\"https:\/\/github.com\/alvinwan\/lightful\/blob\/master\/tutorial\/step06.html\">source code for Step 6<\/a> on Github. In your preview, drag your cursor off of them onto the orb to see the click animation in action. This is pictured below.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/10-clicking-on-orb.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/10-clicking-on-orb.gif?w=900\"   alt=\"clicking on orb\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/10-clicking-on-orb.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>Note the clickable attribute was added to the orb itself and not the orb container. This is to prevent the rings from becoming clickable objects. This way, the user must click on the spheres that make up the orb itself.<\/p>\n<p>In our final step for this part, you will add animation to control the on and off states for the orb.<\/p>\n<h4>7. Add Orb States<\/h4>\n<p>In this step, you will animate the orb in and out of an off state on click. This is pictured below.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/11-interactive-orb-responding-clicks.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/11-interactive-orb-responding-clicks.gif?w=900\"   alt=\"Interactive orb responding to clicks\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/11-interactive-orb-responding-clicks.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>To start, you will shrink and lower the orb to the ground. Add <code>a-animation<\/code> tags to the <code>#container-orb0<\/code> right after <code>#orb0<\/code>. Both animations are triggered by a click and share the same easing function <code>ease-elastic<\/code> for a slight bounce.<\/p>\n<div>\n<pre><code><a-animation class=\"animation-scale\" easing=\"ease-elastic\" begin=\"click\" attribute=\"scale\" from=\"0.5 0.5 0.5\" to=\"1 1 1\" direction=\"alternate\" dur=\"2000\"><\/a-animation>\n<a-animation class=\"animation-position\" easing=\"ease-elastic\" begin=\"click\" attribute=\"position\" from=\"8 0.5 0\" to=\"8 3 0\" direction=\"alternate\" dur=\"2000\"><\/a-animation>\n<\/code><\/pre>\n<\/div>\n<p>To further emphasize the off state, we will remove the golden point light when the orb is off. However, the orb\u2019s lights are placed outside of the orb object. Thus, the click event is not passed to the lights when the orb is clicked. To circumvent this issue, we will use some light Javascript to pass the click event to the light. Place the following animation tag in <code>#light-orb0<\/code>. The light is triggered by a custom <code>switch<\/code> event.<\/p>\n<div>\n<pre><code><a-animation class=\"animation-intensity\" begin=\"switch\" attribute=\"intensity\" from=\"0\" to=\"1\" direction=\"alternate\"><\/a-animation>\n<\/code><\/pre>\n<\/div>\n<p>Next, add the following click event listener to the <code>#container-orb0<\/code>. This will relay the clicks to the orb lights.<\/p>\n<div>\n<pre><code><a-entity id=\"container-orb0\" ... onclick=\"document.querySelector('#light-orb0').emit('switch');\">\n<\/code><\/pre>\n<\/div>\n<p>Check that your code matches the <a href=\"https:\/\/github.com\/alvinwan\/lightful\/blob\/master\/tutorial\/step07.html\">source code for Step 7<\/a> on Github. Finally, pull up your preview, and move the cursor on and off the orb to toggle between off and on states. This is pictured below.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/11-interactive-orb-responding-clicks.gif\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/11-interactive-orb-responding-clicks.gif?w=900\"   alt=\"Interactive orb responding to clicks\"><\/a><figcaption>(<a href=\"http:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/11-interactive-orb-responding-clicks.gif\">Large preview<\/a>)<\/figcaption><\/figure>\n<p>This concludes the orb\u2019s interactivity. The player can now turn orbs on and off at will, with self-explanatory on and off states.<\/p>\n<h3>Conclusion<\/h3>\n<p>In this tutorial, you built a simple orb with on and off states, which can be toggled by a VR-headset-friendly cursor click. With a number of different lighting techniques and animations, you were able to distinguish between the two states. This concludes the virtual reality design elements for the orbs. In the next part of the tutorial, we will populate the orbs dynamically, add game mechanics, and set up a communication protocol between a pair of players.<\/p>\n<div>\n  <img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/logo-red-15.png?w=900\" alt=\"Smashing Editorial\"><span>(rb, dm, il)<\/span>\n<\/div>\n<\/article>\n<p class=\"wpematico_credit\"><small>Powered by <a href=\"http:\/\/www.wpematico.com\" target=\"_blank\">WPeMatico<\/a><\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) Alvin Wan 2019-08-20T15:30:59+02:002019-08-21T11:06:30+00:00 In this tutorial series, we will build a web-based multiplayer virtual reality game in which players will need to collaborate to solve a puzzle. We will use A-Frame for VR&#8230;<a class=\"moretag\" href=\"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/\"> Read the full article&#8230;<\/a><\/p>\n","protected":false},"author":4,"featured_media":69615,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[371],"tags":[],"class_list":["post-69614","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-user-experience"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) Alvin Wan 2019-08-20T15:30:59+02:002019-08-21T11:06:30+00:00In this tutorial series, we will build a web-based multiplayer virtual reality game in which players will need to collaborate to solve a puzzle. We will use A-Frame for VR modeling, MirrorVR\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Guest Contribution\"\/>\n\t<meta name=\"keywords\" content=\"user experience\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Design for Immersive Technologies | User Experience for Games, Virtual Reality (VR) and Augmented\/Mixed Reality (AR\/MR)\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) | Design for Immersive Technologies\" \/>\n\t\t<meta property=\"og:description\" content=\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) Alvin Wan 2019-08-20T15:30:59+02:002019-08-21T11:06:30+00:00In this tutorial series, we will build a web-based multiplayer virtual reality game in which players will need to collaborate to solve a puzzle. We will use A-Frame for VR modeling, MirrorVR\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-08-21T11:16:04+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-08-21T11:16:04+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) | Design for Immersive Technologies\" \/>\n\t\t<meta name=\"twitter:description\" content=\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) Alvin Wan 2019-08-20T15:30:59+02:002019-08-21T11:06:30+00:00In this tutorial series, we will build a web-based multiplayer virtual reality game in which players will need to collaborate to solve a puzzle. We will use A-Frame for VR modeling, MirrorVR\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#article\",\"name\":\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) | Design for Immersive Technologies\",\"headline\":\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)\",\"author\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/www.taterboy.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/1-clickable-orb.gif?fit=1425%2C684&ssl=1\",\"width\":1425,\"height\":684},\"datePublished\":\"2019-08-21T04:16:04-07:00\",\"dateModified\":\"2019-08-21T04:16:04-07:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#webpage\"},\"articleSection\":\"User Experience\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.taterboy.com\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/category\\\/user-experience\\\/#listItem\",\"name\":\"User Experience\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/category\\\/user-experience\\\/#listItem\",\"position\":2,\"name\":\"User Experience\",\"item\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/category\\\/user-experience\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#listItem\",\"name\":\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#listItem\",\"position\":3,\"name\":\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/category\\\/user-experience\\\/#listItem\",\"name\":\"User Experience\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#organization\",\"name\":\"Design for Immersive Technologies\",\"description\":\"User Experience for Games, Virtual Reality (VR) and Augmented\\\/Mixed Reality (AR\\\/MR)\",\"url\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/#author\",\"url\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/\",\"name\":\"Guest Contribution\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d2aad73eb0f48c67b141e9fc978a0e498969791ed623346e361d02d19775b0bb?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Guest Contribution\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#webpage\",\"url\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/\",\"name\":\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) | Design for Immersive Technologies\",\"description\":\"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) Alvin Wan 2019-08-20T15:30:59+02:002019-08-21T11:06:30+00:00In this tutorial series, we will build a web-based multiplayer virtual reality game in which players will need to collaborate to solve a puzzle. We will use A-Frame for VR modeling, MirrorVR\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/www.taterboy.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/1-clickable-orb.gif?fit=1425%2C684&ssl=1\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#mainImage\",\"width\":1425,\"height\":684},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/08\\\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\\\/#mainImage\"},\"datePublished\":\"2019-08-21T04:16:04-07:00\",\"dateModified\":\"2019-08-21T04:16:04-07:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/\",\"name\":\"Design for Immersive Technologies\",\"description\":\"User Experience for Games, Virtual Reality (VR) and Augmented\\\/Mixed Reality (AR\\\/MR)\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) | Design for Immersive Technologies","description":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) Alvin Wan 2019-08-20T15:30:59+02:002019-08-21T11:06:30+00:00In this tutorial series, we will build a web-based multiplayer virtual reality game in which players will need to collaborate to solve a puzzle. We will use A-Frame for VR modeling, MirrorVR","canonical_url":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/","robots":"max-image-preview:large","keywords":"user experience","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#article","name":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) | Design for Immersive Technologies","headline":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)","author":{"@id":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/#author"},"publisher":{"@id":"https:\/\/www.taterboy.com\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/1-clickable-orb.gif?fit=1425%2C684&ssl=1","width":1425,"height":684},"datePublished":"2019-08-21T04:16:04-07:00","dateModified":"2019-08-21T04:16:04-07:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#webpage"},"isPartOf":{"@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#webpage"},"articleSection":"User Experience"},{"@type":"BreadcrumbList","@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.taterboy.com\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/#listItem","name":"User Experience"}},{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/#listItem","position":2,"name":"User Experience","item":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#listItem","name":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#listItem","position":3,"name":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)","previousItem":{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/#listItem","name":"User Experience"}}]},{"@type":"Organization","@id":"https:\/\/www.taterboy.com\/blog\/#organization","name":"Design for Immersive Technologies","description":"User Experience for Games, Virtual Reality (VR) and Augmented\/Mixed Reality (AR\/MR)","url":"https:\/\/www.taterboy.com\/blog\/"},{"@type":"Person","@id":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/#author","url":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/","name":"Guest Contribution","image":{"@type":"ImageObject","@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/d2aad73eb0f48c67b141e9fc978a0e498969791ed623346e361d02d19775b0bb?s=96&d=mm&r=g","width":96,"height":96,"caption":"Guest Contribution"}},{"@type":"WebPage","@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#webpage","url":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/","name":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) | Design for Immersive Technologies","description":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) Alvin Wan 2019-08-20T15:30:59+02:002019-08-21T11:06:30+00:00In this tutorial series, we will build a web-based multiplayer virtual reality game in which players will need to collaborate to solve a puzzle. We will use A-Frame for VR modeling, MirrorVR","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.taterboy.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#breadcrumblist"},"author":{"@id":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/#author"},"creator":{"@id":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/1-clickable-orb.gif?fit=1425%2C684&ssl=1","@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#mainImage","width":1425,"height":684},"primaryImageOfPage":{"@id":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/#mainImage"},"datePublished":"2019-08-21T04:16:04-07:00","dateModified":"2019-08-21T04:16:04-07:00"},{"@type":"WebSite","@id":"https:\/\/www.taterboy.com\/blog\/#website","url":"https:\/\/www.taterboy.com\/blog\/","name":"Design for Immersive Technologies","description":"User Experience for Games, Virtual Reality (VR) and Augmented\/Mixed Reality (AR\/MR)","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.taterboy.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Design for Immersive Technologies | User Experience for Games, Virtual Reality (VR) and Augmented\/Mixed Reality (AR\/MR)","og:type":"article","og:title":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) | Design for Immersive Technologies","og:description":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) Alvin Wan 2019-08-20T15:30:59+02:002019-08-21T11:06:30+00:00In this tutorial series, we will build a web-based multiplayer virtual reality game in which players will need to collaborate to solve a puzzle. We will use A-Frame for VR modeling, MirrorVR","og:url":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/","article:published_time":"2019-08-21T11:16:04+00:00","article:modified_time":"2019-08-21T11:16:04+00:00","twitter:card":"summary","twitter:title":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) | Design for Immersive Technologies","twitter:description":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1) Alvin Wan 2019-08-20T15:30:59+02:002019-08-21T11:06:30+00:00In this tutorial series, we will build a web-based multiplayer virtual reality game in which players will need to collaborate to solve a puzzle. We will use A-Frame for VR modeling, MirrorVR"},"aioseo_meta_data":{"post_id":"69614","title":null,"description":null,"keywords":null,"keyphrases":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_custom_url":null,"og_image_custom_fields":null,"og_custom_image_width":null,"og_custom_image_height":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"created":"2021-02-07 18:13:12","updated":"2026-09-01 21:55:58","focus_keyword":null,"additional_keywords":null,"truseo_locale":null,"primary_term":null,"og_image_url":null,"og_image_width":null,"og_image_height":null,"twitter_image_url":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"limit_modified_date":false,"ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.taterboy.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/\" title=\"User Experience\">User Experience<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tHow To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.taterboy.com\/blog"},{"label":"User Experience","link":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/"},{"label":"How To Build A Real-Time Multiplayer Virtual Reality Game (Part 1)","link":"https:\/\/www.taterboy.com\/blog\/2019\/08\/how-to-build-a-real-time-multiplayer-virtual-reality-game-part-1\/"}],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8wzr5-i6O","jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/08\/1-clickable-orb.gif?fit=1425%2C684&ssl=1","_links":{"self":[{"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/posts\/69614","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/comments?post=69614"}],"version-history":[{"count":0,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/posts\/69614\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/media\/69615"}],"wp:attachment":[{"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/media?parent=69614"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/categories?post=69614"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/tags?post=69614"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}