But before I go and talk about performance, which is the main thing we want to discuss on this presentation, first we need to talk about how state management works and how that's different when we are in a game environment.
So when we look at a traditional web application, we can think about it like this. We have your browser, for example, here I have Firefox running the UI and that has its own JavaScript runtime and then we have, let's say, a server on the internet running Node.js and then we have HTTP requests and response coming back. So it's a very kind of like request-response separation and then we have a copy of the state in the browser.
When you go into a game world, what we usually have is just a single process, right? We have the JavaScript engine still running, which will have our React code and our UI code in there, but we have the C++ game engine right there and that's what we call our backend and that's usually the holder of the state. If you want to understand this, it's better to look at an example and a good example is Minecraft.
So if you look at this screen, which is basically what you see if you're playing the game, this is the HUD. We see basically the information about how much health your character has, the fullness because Minecraft is a survival game, so if you don't eat, you start to starve and you can die. We also see the items that you have access to in your hotbar, so this is items that you can quick switch using the gamepad, and which item you have selected. So here you can see we have the first item selected, which is the sword, but a player can also by interacting with the game, can switch to change the selected item to be the Rotten Flesh and that not only affects the game itself, but also needs to be reflected in the UI. And the player can also take damage, right? Let's say a mob comes and a creeper blows up next to the player, and then we need to take some health damage and here the health has dropped to eight. So we can see here that we have kind of like two categories of data, two groups of data. And we call those facets.
So facets a term that we coined internally in the studio because we needed something that didn't exist within the code base. So we couldn't use model, for example. But this is kind of like what it is. It's just a slice of data. But all like that, like facets conceptually, they're very similar to an observable where available over time. So we subscribe to a facet, like let's say the player stats, and then we keep getting updates about new values as they change, as the player plays the game, right? So the bottom there we can see as the time progresses and the player loses health, we have a hypothetical player health component updating with how much health the player has. Conceptually then what we want is that the state shouldn't live in the JavaScript side, but it rather should live on the C++ side, which is our back end, but it's living right there within the same process. We want kind of like a global store and that global store is the C++ side of the game. And we think about global stores, and we look at the JavaScript ecosystem, there are a couple solutions available. Some of the popular ones these days are Recoil or Jotai and they're very kind of like on this fashion where you have a global store. And we took a very similar approach to these solutions, and we got inspired by Recoil's API to build something that feels very familiar so that anyone that would come to the studio would understand what the concepts were trying to imply. But there are some differences of course that we're going to go through in Next.
RackFacet is actually a pack, a collection of packages. We have a lot of packages. The part that deals with the communication between the JavaScript bits and the C++ bits we call RackFacet Remote. And that's the first part I'm going to talk about now. And I guess the first thing that we need to look at is how do we define the facets, right, the state bits that we have that is shared between the C++ side and the JavaScript side.
Comments