 Okay, thank you. So yeah, as we said, I'm going to be talking about what goes into making games for VR. And I think all of you must have played somehow with VR. Some of you may have used a headset, some of you may have played some games. Some of you may have used Pokemon Go, the AR game, or some other form of AR, at least even if it was just to check what the hype is about. So all these seem to be very different things, but they have a lot in common. And at Mozilla, we call it the mixed reality. And it's a spectrum from virtual reality to augmented reality, and there are some variations in the middle. So now is a great time for developers to jump into this field, mixed reality. And A-Frame is a tool that I'm going to be using today, which is something open source community tool, web framework, actually, which helps you build VR scenes with just web technologies. Very simple, primarily HTML. And you can actually ignore the boilerplate code that you have to do, the basic setup, et cetera. You can just not worry about how to make this into a VR thing, how to do the basic setup. You can concentrate on actual logic of your game. First of all, I'd like to talk about a very useful tool called Spoke, which is SPOKE Spoke. It's very useful, easy to use. It's a complete studio, runs on your browser. It lets you quickly take all the amazing 3D content from across the web, Sketchfab, Google Poly. You may have searched these sites if you ever looked for 3D models. They are amazing. So you can use them. You can create your own custom scene and your own personal experience. And you can also, first of all, it can be published immediately on hubs, which is a web-based social experience. It also runs right on your browser. Or you can just export the complete scene and import it literally anywhere else. So you can set up the trees, mountains, you can basically position them, drag and drop, et cetera. And you can directly import it as one 3D model and use it anywhere else in your other game also. So I really use screenshots here for some reason. My laptop isn't working quite right. So if you want a bunch of trees for your game, so I've used here one tree from Sketchfab, I can just copy paste the URL on this. Here, if I click on this plus, there is something to import your 3D model. You can basically copy paste the URL and use models directly. And they'll be imported. You can duplicate, you can position them, drag them around. You can add more things. You can do everything without writing anything, any code. And you can export it. All you have to do is just file export as gltf. But anyway, before getting into all this, I'll be talking about how to get started with building A-Frame games. Now, I thought there was a session before mine, which was to talk about the basics of A-Frame. So I didn't really put a lot of basics. But I will mention whatever is needed, wherever it's needed, if the code gets. So anything in A-Frame comes inside. So all you need to do is import the library, like script SRC. That's all. No build steps or anything complex like you do in Unity. Anything in A-Frame comes inside. A-Scene is like a global object in A-Frame. It does all of the setup for you, lights, camera, all the boilerplate code, the setup for VR. It does it for you. Stats is basically just to see some stats. Here, if you see, I've added A-Cursor inside the camera. What it's doing is you see a circular cursor for the headsets that don't have controllers. So most headsets have controllers. You can point things around. But for those who don't have, you'll primarily be using gaze-based interactions. So where you look, there should be a cursor, something to know where you're looking at. I'll just show you in a second. OK, where is my cursor? We'll be building something like this. There'll be an imp coming out of it. Your aim is to use a stick or a staff to hit the imp. And if not, first of all, it'll be coming out. And with the effect of gravity, it will fall down. And your aim is to hit it before it falls down. This is all actually created by Josh Marinacci from Mozilla. Getting back to the presentation. Showing it. OK, so our game, as I said, will have that object. And so before doing all that, we'll be building a basic prototype. We'll not get directly into 3D models. So we want to prove that our concept will work. So we'll basically start off with a simple scene. I think this is done. We'll be using this one. We'll have a stick. If the player misses, the object should fall on the ground, as you already saw. Since I said we'll be building a basic prototype first, we'll have the object as a sphere. And we'll have a plane. And we'll have a box for the paddle to hit, just to know if the game is working. And in A frame, you basically have stuff like A sphere, A cylinder, A dash plane, for building a sphere, a cylinder, a plane. So basic primitives have direct tags. Entity is basically, everything in A frame is an entity. So it's like a generic way to build things, build objects. So this is a sphere built by the standard syntax, because we'll basically be replacing it with a 3D model later on. That's the imp. That's the object we'll be hitting. The plane is just going to be a plane, so we'll just use the shorter syntax. So basically, we have an object to hit. Now we just created a sphere, which we'll be hitting. To hit it with, we'll use a box. So we just use A box. Color equals to blue. We're just using blue color for now. We are placing it inside the camera. Inside the camera, if you see, here it's not visible. We'll be placing it inside the camera. So basically, what it means is it's kind of on your head. Wherever you look, it will be there. It's kind of here, stuck to the camera. So z equals to 3, as I've mentioned, depth equals to 3, because we want it to be a bit far away. You won't be able to see if anything. When you build a game, and you have to specify x, y, and z axis of everything. When you build any object. So x is this way, y is this way, z goes into the screen. So if you reload the screen, it will be something like this has been built. You just created a sphere. You just created a box. And since the box is stuck to the camera, so something like this, you have A cursor. Now we have the geometry we needed. We can move your head and the paddle moves with it. So trying to hit the ball with the paddle won't do anything yet, because we just have the geometry now. The computer knows how the objects will look, but not how they will behave. So for that, we need physics, the laws of physics. So physics engines can generally be very complicated. So the beauty of A frame is that there's a lot of components. So built-in components, the community has built some components. So physics components are basically one of the components that's built by the community. Don McCurdy's A frame dash extras component specifically is the one you need to import right now. And then you can start playing with physics. And you can add this to the head of the HTML page. And we can simply turn on the physics by adding physics equals to debug true to the ACM. But adding physics won't just do anything. We still have to tell. So the physics laws are in the environment, but we have to tell which objects in the scene should be affected by gravity and other forces. So our game has a lot of things. So the imp will be suddenly coming out, and it will have a certain velocity, and then it will be affected by gravity. So there will be a lot of things involved. So here, we have dynamic and static bodies. A dynamic body basically, it has full physics. It can experience all forces, even the forces of gravity, and affect other bodies. A static body, it cannot do that, but it can transfer forces when other bodies come in touch with it. So you will generally use static bodies for things that don't move, like a wall or a ground. And dynamic will be something like a ball that we have. So if you reload the page now, so if you see we've added a static body and dynamic body, ball has a dynamic body, static body is a ground. If you reload the page, the ball will suddenly fall to the ground due to the force of gravity. It will just fall to the ground. But the ground will stop it. So now we need to make the paddle of the box able to hit the ball. So if you think of it, you might think that since it's moving, it might be a dynamic body. But it's actually, we don't really want the physics to work on that. We want our code to be able to hit it and exert the force. So we will use a static body for it, and we can use the camera to swing the paddle and hit the ball. So if you reload the page now, if you see we've just mentioned static body here, so it will work. So you can kind of like this. You've not really created the score thing yet, but you will be able to hit the ball and stuff like that. Coming back to the presentation, so you might ask why not turn on physics for everything. First of all, physics is computationally expensive. So if more objects have associated physics, more CPU resources will be used. Secondly, for many objects in the scene, we don't really want physics to be turned on. So for example, if a tree is 1 millimeter above the ground, we don't really want it to fall back to the ground. Or the moon, we don't really want to fall back to the ground. So only turn on physics for the objects that's necessary. Now moving the ball by hitting is OK. But for a real game, we need to track when the paddle hits the ball to increase the score. That's the whole point of a game. So we need a score to increase when the collision occurs. So we use collisions to do this. The physics engine emits a collide event. Every time the object hits another object. So we can listen to this event, and we can find out when something has been hit, what it is, and we can manipulate it. So here, if you see, we've just created some utility function for accessing the DOM elements. So talking about the functions that we will be needing. So this is a point where we just can't get away with just HTML. We need to write some functions, logic, and JavaScript. We will need to, first of all, reset the ball after the player has hit it. Or if they've missed, and a certain number of seconds have passed by. And resetting means moving the ball back to the center, setting the forces to 0, and initializing a timeout. So as you can see, we've done the reset ball function to do this. And we're using a selector to find the ball. And then we have a body property added by the physics engine. And we have all the attributes of physics. We can reset the position, velocity, angular velocity. That's what the code is doing. It might look longer, but it's actually basically just repetitions and accessing the. So velocity, if you see, we've not really set it back to 0. It's 0, 5, 0. So basically, when the imp comes out, it will be with a velocity of 5 in the y direction. y is this direction. And then, of course, afterwards, the gravity will start acting. It will fall down. But initially, it will come out with 5. So now we need to know when the collision actually happens. So we can increment the score and trigger the reset. So we'll do this by colliding event on the weapon entities. So this will go after a scene. And we are just making sure that the player didn't already hit the ball. Otherwise, they could hit the ball over and over again before we reset it. So it's actually comparing the body IDs, if you say. And yeah, so if the ball was hit, then set hit to true. And clear the reset timeout. Schedule a new one for two seconds in the future. So after that, we'll be able to launch the ball over and over and keep track of the score. But a score isn't very useful if you can't see it. So we'll just add a text. In A-frame, text is just added by A-text. And it's kind of like a heads-up display. Again, you add it inside a camera. So wherever you look, the score is visible. And we need to update the score text whenever the score changes. So we just add this at the end of the colliding event handler. So now if you reload, it will be like this. The one that I showed you before, the score will be displayed. And so now that we have a basic game running, we have proven the concept. We can now replace it with 3D models. So we have a lot of 3D models to import. So we will be using assets. So assets are basically large chunks of data when they actually preload. And they are cached automatically. That's the A-frame asset management system. And so we can just use A-asset item to import one by one. And we can put it at the top of the scene and access them by their IDs later on. And so now what we have to do is we can swap the sphere with the imp that we will be hitting and parallel the box for the staff, the stick. So that's what I've done here, weapon and ball elements. So sometimes it may happen when you're building such a game. While importing the models, you may not be able to see some models after positioning them appropriately. So most of the times when you import models from the internet, you pick up them from the internet. If this happens, what it means is the center of the model is away from the coordinate system. You're here, here, sorry. So you just need to reposition it. That's all that's needed. So now there's still a problem. The staff, the stick we have, it's not a geometric shape. It's a full 3D model. And the physics engine can't really directly work with a full mesh. So instead, it needs to know which primitive object to use. So what we will do is a workaround we could use a sphere, which is centered at the end of the staff. And that part, the player will actually be using to hit. And also we need to move the static body definition to the outer entity, so it's not affected by the model offset. So if you see here, we've just added a static body and the shape sphere. So now if you reload it, we have a core mechanics working correctly with the new models. And now it's time to add the decorations. What we can do is two things here. What we have already created on Spoke, the complete environment, we can import directly. Or we could just import one by one 3D models and test their positions and move around them. So if you do the second option, we have a lot of 3D models here, as you can see. I've used here a 3D model for a pot, a cauldron, which has bubbles, animating bubbles. So animations won't really directly work unless you enable them. To enable them, you need to add a component animation dash mixer. So that's, again, a component. You don't really need to do a lot of work, just add in a component. So if you reload it, everything will be there. All the 3D models are here. So you can add more things like, for example, if you want some rocks scattered around the field, we don't really want to manually position them at 50 different locations. So you can use components for that. And components in A frame have some input properties and they execute code when the init function is called and maybe some other functions. So in this case, we want to accept the source of a model, some variables controlling how to distribute the model, and then have a function which will create n copies of the model. So I'll share the whole code, the link to it if it's not visible. It's basically the things that I just said. So if you do all that, this will be the final result. There will be rocks scattered. But since we want this to be a very interesting and realistic scene, because that's the whole point of VR, we'll do some polishing. Maybe we'll start with changing the color of the ground to something more ground-like, like a dark green. We added a dark violet color to the sky. And for the moonlight, we'll be using a directional light. So there are types of light. Directional light is basically something like maybe this is a bad example, but we've studied optics and lenses at some point in our lives where you see infinitely parallel rays coming and then focusing and converging or diverging, whatever. So this is those kind of light, that kind of light, coming from infinitely far away. But it's equal at all objects, equal intensity, et cetera. So it hits all the surfaces equally. For something like the moon, that's what we want. And what it looks like is like this. So we're getting there, but this is not exactly right. The moonlight is reflecting nicely of the tops. But the bottom of the rocks and the trees, I don't know if you can see it, but they're completely black and not a very realistic scene. So a common movie trick is shooting a night scene. For shooting a night scene is to have colored light shining up from the below of objects. And without making the scene look like day, it's just a light intensity. So it's a hemispherical light, and that's what we'll be using. A hemispherical light, it gives one color above and one color below. We use the white for the upper one and purplish dark blue for the lower one. And we've used the intensity 0.4. You can use different settings. So now just one more thing is left. The fire under the cauldron should be emitting a red glow. And the nearby object should be reflecting this glow. And this is a point light. So that means this is not coming from infinitely far away. This is coming from a point. It will be at a specific position and will decay with distance. So you can set the decay to 2 or intensity to 1 point. So if this is all experimental, you can try different settings. You can also appropriately mention the distance until which the light will be seen. So after you do that, there will be a red light coming from the fire. So there's just one more piece of lighting and we need to add some shadows. So shadows are expensive, computationally speaking. But we want to turn on them, turn on the shadows only for objects whose shadows we really want care about. So first we must enable casting shadows from the light source that will be causing the shadows. So we use the cast shadow true on the moonlight because that's what we will be using for casting shadows. And we'll use shadow equals to receive true to the ground. So all of the objects now start casting shadows automatically to the ground. So that's what it looks like. Now it kind of feels like a real place. But some things more are needed, like some audio, lived in places aren't really silent. So we have a summer night kind of a background for the. These are some audios that are taken from the internet. And here again, we have types of sounds. So the background music, the background sounds, the summers, the crickets, or maybe anything else that you want for the background music, background sound. That shouldn't be positional. That is heard by the person, by any player. Everywhere they go, equal intensity. So that will be, we should loop over and over. And we put the sound on the scene itself for that. But for the bubbles that are there in the pot, it will need to loop, of course. But it's attached to that particular entity. So the sound will come from that particular entity itself. So positional audio is what we want. It will be from that particular cauldron. And as the person goes closer to the thing, it will grow in intensity. So it feels realistic. And we also need a sound on an imp, like a shouting sound or something whenever it's hit with the stick. But we don't want it to autoplay or loop. We want the code to handle that. So we just went to the Collide Event Handler here and added this line to play the sound on every collision. So this is the basic game that we created. That's the 90% of building a game. But polishing the experience is also very important. So this would get very boring, very fast. So the only thing the person is doing is hitting something and waiting until the next one. Next imp is arriving. So it will be more interesting if the person comes across something he shouldn't hit. So for that, we just added a dragon's egg. Inside the ball entity, we have a model for the imp, as you can see. So next to it, we added another entity called egg model. We're using a slight distorted sphere. And to make it look more magical, we've given it a purple colored material with flash shading and also set the emissive color to red. So normally a material only reflects light that comes from a light source. But emissive colors as the material produce its own light and even in the dark. So it kind of glows. So now we need to update the recent ball event handler with Boolean indicating if we should show the imp or the dragon egg. And we need to make the collide event handler, collide handler, play the correct sound and decrement the score by 10 if you accidentally hit the line. So everywhere we just add conditions for imp or egg. That's all, that's all I think. That's the game that we have. That's the basic game with 3D models imported. And for final details, we have changed the color of the score for too white and we've turned off the physics debugging and we removed the cursor inside the camera that we talked about before because now we have the stick to hit with. So we can see the stuff or stick or whatever we call it. So that's all, that's the game. We can do more polishing like we can automatically detect whether the person is using a headset with controllers and if they're using the controllers, they should be able to use the controllers, not just gaze-based interactions. They should be able to walk around and also use the controllers to use the stuff. So that's all for this game. Due to time constraints, we won't really talk about more details, but I am available apart from the offline. I can, you can ask me any doubts that you have tomorrow or the day after tomorrow or after the talk. So the whole point of this game is to know what goes into making these games. So basically, this is not about how wonderful games you can create. It's for, in a VR system, the necessity is to create it more immersive, to make it more immersive and realistic. It should feel, it's not just a 2D or 3D game, it should feel like you're really in it. It's really happening around you. So the types of lights, the types of sounds, that's all that we need to really concentrate about these small things. So thank you for having me here. That's all for today. If you have any more doubts, I'll be around. So thank you.