Reverse Engineering for Procedural Generation at No Man's Sky

Original author: gregkwaste
  • Transfer


No Man's Sky is a space exploration game that uses technology to procedurally generate the game environment and resources (textures, models, terrain, etc.). I was delighted when they announced its development in 2013, not only because of the game itself, but mainly because of the opportunity to study game files and find out how it works. After the release, the game received the most controversial reviews, but I still wonder what is going on inside it.

If you install the game, you will see that it is very small in volume, and it really is. The main reason for this is that the game works with a very limited set of resources and with the help of procedural generation creates literally hundreds of options on their basis. I will focus on content related to 3D models of the game, because for me they are always the most interesting. The article will be divided into three main categories: geometry, textures and animations.

Geometry


So, in the game, geometry files (vertices, index buffers, etc.) are stored in files with the extension ".GEOMETRY.MBIN". Already with the help of these files you can create fairly simple parsers that convert geometry to work in 3D-modeling software. But this file is not enough on its own. Such a geometry file is used as a container for pure geometric data.

The game loads resources like scenes. This means that all model resources are defined as files of individual scenes with their own hierarchies of objects, several parts of grids, several types of objects (hinges, light sources, interaction points, collisions, other scene files), etc. This type of information is stored in the ".SCENE.MBIN" files. They are real descriptors of a particular scene, and usually such files refer to one geometry container, from which all parts of the grids in the scene receive the corresponding geometry information.

So far this is nothing new. The same situation in many different games. No Man's Sky differs from other games (at least I have never encountered one before) in that this scene file is not just one ready-made creature that can be spawned in the game under certain conditions, procedural generation comes into play here.

I will briefly explain how this looks by attaching a few images from the NMS Model Viewer I created.


Triceratops model

As you can see, at first glance the scene is complete chaos, you can’t even say exactly what we see. Of course, such a model cannot be spawned in the scene.

The most important thing in this data is the actual names of the objects. You can clearly see that there is a certain connection between them and the way the game learns about how to combine these parts and eliminate unnecessary ones when creating the model.

Noticing this, I started looking for other files that could control the organization of the scene, and it turned out that these were ".DESCRIPTOR.MBIN" files. Not all models have such files. It turned out that only procedurally generated models have them, but static models (such as the astronaut model or materials created for the trailer) do not have them.

I started the reverse engineering of the NMS file format by parsing these descriptor files. But at that moment they seemed to me some kind of porridge, I could not understand what they were doing. After parsing the scenes, I already realized what to look for, and returned to these descriptor files. They are very similar to scene files. They use the same method for defining parts and everything else, but they can only refer to other parts of grids or entire scene files. These files work as follows:


             ......;
          
            ......;
          
            ......;
          
            ......;
          
            .....;
          

The procedure is this: there is a main part that decides what it will be, in our example it is _HEAD_. Usually, parts whose names begin with underscores mean that they belong to the group of descriptors and only one of them will be selected for the final model. As you can see, this part is defined in the TkResourceDescriptorList list. Its elements contain the Descriptors property, whose child elements are candidates for selection. Next you just need to select one of the Descriptors property children. So, for example, a head model is selected. After choosing this particular head model, there is another “Descriptors” property that has its own list of possible options, and again you need to select one from it. Etc.

After performing these operations for all elements in the descriptor.mbin file, we will end up with a set of selected parts from which a unique complete model is created.


Example SHARKRIG


Fighter exported from No Man's Model Viewer


Sentinels

The entire procedure is actually a traversal of the tree tops. The root node is a scene with all parts, and in the end we get a unique tree branch, which is a complete model with the necessary parts.

The most important in this procedure is the method of selecting the part. If you look closely at the XML code presented above, you can see that each part has the “Chance” property, but for many parts its value is 0. I think that the real probabilities of choosing parts are either determined by the engine when the game is executed, or set to other game parameter files. In my model viewer, I randomized the selection. All parts have the same probability of choice and this leads to the appearance of quite different models.


Random generation of creatures based on the Triceratops model


Procedural generation of fighters (cubes are undecided decals)


Procedural generation of landing boats


Procedural generation of SHARKRIG

I spent about 70 hours in the game, and during all this time I neverdid not meet a diplodocus-like creature. This means that either the engine contains an error and these parts are not selected (which I doubt), or the probability of choosing these parts is so small that they rarely appear in the game. A lot of discussions (mostly angry) touched upon the missing content in the game and content that is present only in game trailers, as well as related topics. I can not judge the operation of the game or the gameplay capabilities, but judging by the number of creature models I studied, there are a LOT of content in the game that, due to the decisions of the engine (?), Doesn’t appear in the game very often (or doesn’t appear at all). In my opinion, procedurally generated diplodocus models are 10 times better than static ones, and if the developers wanted, they could force the engine to load static models (and, of course,


Diplodocus model from the trailer on E3

Here's how the bulk of procedural model generation works. This is a very elegant and reasonable procedure, because artists can very conveniently add new content for procedural generation. In fact, as each new part is added, the number of combinations increases exponentially (if that part is available on all paths of the tree). As far as I know, two or three artists worked on models for developers. The brain-blowing fact about procedural generation: if they doubled the number of people working only on this part of the work, game content (relating to creatures) would be hundreds of times more. And this fact in itself proves the capabilities and potential of the NMS game engine.

Textures


Textures are another challenging aspect of NMS models. As I mentioned in the Geometry section, all parts of the grids are defined in the SCENE.MBIN files. Elements of these files look something like this:


As you can see, there are several attributes that I will not describe now, and I will only talk about the latter. It defines the material used for the mesh. As you can see, this node refers to the material file that you want to use. Let's look at this material file:


    ...
  
    ...
  

An important part of the material files is the Samplers section. Obviously, this section defines the textures used in part of the model. And here's what is interesting: for static models, all textures are very high-quality textures that can be used directly on models without any problems. But if the grid is used for a procedurally generated model, only the normal texture is correct. The diffuse texture, which contains all the color information about the part, is an empty white texture.

At first, I decided that all the colors and textures are also selected during the game, but in fact this is not so. These texture files are always accompanied by ".TEXTURE.MBIN" files, which, as you might guess, work exactly like model descriptor files. They determine how textures are combined to create the final diffuse texture of the model. The artists of the game not only created various parts of the models, but also painted many different textures for each part. Therefore, going through this file in the same way as using the descriptor file, you can calculate the final diffuse texture of the procedurally generated model. Moreover: even if the two models are the same in terms of geometry, due to the procedural generation of textures, they can have completely different colors, marks, shapes, etc.


Sample texture with spots.

Texture details during procedural generation can vary greatly. It seems that the textures are created in layers. I will show an example of assembling a procedurally generated creature texture. Typically, the base layer is the base texture that adds the primary color and hue of the model (the names of such textures end in .BASE.DDS). The next layer is the underbelly texture (.UNDERBELLY.DDS), which adds detail to the animal’s belly. Then comes another layer, adding more detail to random parts of the model (.UNDERLAYER.X.DDS). Then there are marks (.MARKINGS.X.DDS) defining the most noticeable details of the model's skin. The next layer again contains the skin parts located on top of the marks (.SKIN.DDS), and on the last layer another texture is applied (TOP.X.DDS), which adds parts to separate parts of the model.

It seems that the maximum number of layers in procedural textures is 8 (usually 5 or 6 is used). Obviously, there are many textures that need to be mixed together. Therefore, all textures are accompanied by the corresponding texture of the mask containing the necessary information about the alpha channel, so that the mixing is as accurate as possible. Most often, textures are also accompanied by an appropriate normal map, which creates details on each part.

But all this chaos with textures is not enough, even with all the mixes the final texture does not have the correct coloring. And the developers came up with another ingenious technical trick. They wanted the creatures to have a color that matches the colors of the environment, and implemented this in the game using palettes. I am not 100% sure how they work in the game, but I will describe what they do in my opinion. I applied my implementation method in the viewer, and it seems to be pretty accurate.


FURPALETTE.DDS


PAINTPALETTE.DDS

So, in the process of creating a planet (or creating a star system) certain colors are chosen that will be used for living beings of the entire planet. I’m talking about choosing a color, because game files have specific 8 × 8 color palettes (in the PCBANKS / TEXTURES / PALETTES folder). These palettes probably make up various forms. This means that 64 colors contained in palettes are usually combined in groups of 4 or 8 colors. Therefore, when the game creates the environment of the planet, it selects from these groups that will be used later. These groups are easy to identify by looking at the palettes, because they are actually a gradient of two border colors.

Indexing in the selected group is performed with the information contained in the .texture.mbin file. The description of the texture in such files is as follows:


Again I will not talk about what the rest of the options do. We are only concerned with the description in the Palette property. From the information in this property we can find out what color we need to choose for the part. In our case, we see that the index of the “Fur” palette is required (fur) (which, as we saw earlier, consists of groups of 4 colors), and in the selected group we need the color “Alternative1”. Here's how colors are indexed in palettes. These “ColourAlt” property values ​​can be equal to “Primary”, “Alternative1”, “Alternative2”, “Alternative3”, etc. So, primary will be the first color in the group, alternative1 - the second, etc. Here I am also not 100% sure, but I use palettes like that, and this is logical, based on the principle of color groups in the palette.

So, we have one base color for a specific texture, so what do we do with it? You just need to multiply it by the color of the texture. Typically, game textures default to a bluish color that looks neutral. After multiplying by the color of the palette, the texture gets the desired saturated color.

I repeat, this operation is performed for each individual texture applied to the model. There can be 8 in total, we get them, combine them with suitable palette colors, mix the layers from top to bottom and apply to the model.

Thanks to such texture combinations, diffuse textures can verygeometrically identical models may also have completely different skin. This technique of procedural texture generation together with procedural generation of models is enough to give the generated models a unique look. As I wrote above, if artists only worked on adding layer variations and more detailed color palettes, the resulting world would become richer and more detailed.

Animations



Skeletal animation of a triceratops model


Astronaut Walking Animation Cycle


Animation of a slow walk of a procedurally generated Spiderrig model

Honestly, I have not explored animations in as much detail as geometry and textures. All I did (and it was not as simple as it seems: P) was to perform parsing of animations and successfully play them in my model viewer. In this category, there are also many interesting and unique details.

First, model skeletons are defined in the SCENE.MBIN files. They represent a hierarchical system of hinges, to which parts of the models are attached using vertex skinning. There is nothing surprising. The interesting thing is that, as I mentioned in the Geometry section, there are many parts of grids in the SCENE.MBIN file. Therefore, to control the animation and movement of all these parts, the designated hinge system affects allparts of the scene.

Animations work in exactly the same way, they animate the entire skeleton, even if not all the joints are used for the final generated model. At first glance, this seems like a waste of resources. In fact, the only waste here is parsing the entire animation file. When playing the game, the MBIN SCENE and GEOMETRY files provide enough information to load only the data needed for each specific part of the model into the GPU.

When playing the game, I understand that there is a final generation procedure that processes the articulated skeleton. Somehow the engine can change the skeleton. Lower the center of gravity of the model, make the legs longer or shorter, resize the head, etc. I have not researched it long enough to find out how this is controlled, but I know that this is happening and it adds a whole new dimension to the procedural generation of creatures, because this is a way to change the final form of the model. In fact, the final form can be changed to such an extent that it will not be like a basic model. In addition, the necessary inverse kinematic calculations that must be performed to apply old animations to the new articulated skeleton lead to a change in the animations. Such a change can make creatures look completely different.

conclusions


I tried to explain how the game works, as I understand it after three weeks of work. I focused on generating creatures, but the same principles apply to other aspects (ships, NPCs, buildings, plants). When I started working with files, everyone was delighted with the game, looking for novelty and variety. Weeks passed, and the game began to be considered monotonous. The question is: was procedural usage generation worthwhile in NMS?

There is no definite answer to this question.

As a software developer and a reverse video game developer, I answer: yes, it was definitely worth it. From a technical point of view, I have never seen game mechanics similar to NMS mechanics, and I doubt that I will see new games using procedural generation technology. Because no one will try to create fictional worlds with this level of randomness. Technically, No Man's Sky has become a real treasure., and everyone who tries to deny this, simply lies to himself, or does not know how the game works (or is not interested in it). The game engine has very great potential, and I constantly think about what the game could have become if the engine were in the hands of a large game studio. Even taking into account the limited resources, I still like the variety of creatures that I see in the game (and I believe that with more fine-tuning, we can squeeze even more out of available resources).

My feelings as a player are contradictory. Although this is not my style of play, from the very pre-order of No Man's Sky I knew that this would be a game in which I could just relax. Explore the environment, plants and animals. At first, they all seem the same, but looking closer, we will see differences in most of them. Maybe only the textures differ, but they are different: it can be a small horn on the creature’s head, or different spots, or a different part of the ship. There is content in the game (even gameplay that developers could spawn if they wanted to), it cannot be said that it is not. All we get is the result of an extremely good generation procedure. In fact, the content created by the NMS engine for a system of 2-3 planets is muchsuperior to resources that can be seen, for example in ARK. Of course, no creatures will be completely perfect, like dinosaurs in ARK, but that’s their beauty. It is the engine that can create luxurious and magnificent creatures, and at the same time - the most obscure animals that were in computer games. That's why I bought this game, and why I love it. I live for those moments when, after exploring various tedious nonsense, I suddenly land on the most beautiful planet I have ever seen. Again, I am not comparing RPG elements or gameplay capabilities. I am only talking about procedural content. This does not mean that the game could not be better. I believe that I could, and I expect that the developers will improve it.

On the other hand, if you are not inclined to relax, be patient and pay attention to details, the game is not worth the purchase, and all the procedural generation will be a waste of resources for you. This is not a shooter where you are constantly hunted and you are constantly in suspense. The developers make this clear. For those who choose this style of play, everything will look the same. Even if the content from the trailer was created in the game, and on every second planet there was lush vegetation, dinosaurs and sandworms, the game would still bore you. After the third star system, everything would seem the same to you, because you would not look closely. You cannot blame the game or the developers for not doing research in the research game. Moreover, procedural generation has never been and never will be a way to create decent content from scratch. At least not in the near future. You can’t just write a mathematical expression and create a new animal. This will work for terrain, plants, stones or ships (while texturing will still be a big question), but for living moving objects, such as creatures or NPCs, everything becomes so complicated that it is almost impossible. (Of course, if it were possible, the developers had no reason not to do this, because they already did the same with the rest of the objects.) Therefore, if you expect to see a new alien every five steps, then I'm sorry, this is the problem of your expectations, not developers. If there is a way to create such content, then this is exactly the way the NMS engine. not in the near future. You can’t just write a mathematical expression and create a new animal. This will work for terrain, plants, stones or ships (while texturing will still be a big question), but for living moving objects, such as creatures or NPCs, everything becomes so complicated that it is almost impossible. (Of course, if it were possible, the developers had no reason not to do this, because they already did the same with the rest of the objects.) Therefore, if you expect to see a new alien every five steps, then I'm sorry, this is the problem of your expectations, not developers. If there is a way to create such content, then this is exactly the way the NMS engine. not in the near future. You can’t just write a mathematical expression and create a new animal. This will work for terrain, plants, stones or ships (while texturing will still be a big question), but for living moving objects, such as creatures or NPCs, everything becomes so complicated that it is almost impossible. (Of course, if it were possible, the developers had no reason not to do this, because they already did the same with the rest of the objects.) Therefore, if you expect to see a new alien every five steps, then I'm sorry, this is the problem of your expectations, not developers. If there is a way to create such content, then this is exactly the way the NMS engine. stones or ships (while texturing will still be a big question), but for living moving objects such as creatures or NPCs, everything becomes so complicated that it is almost impossible. (Of course, if it were possible, the developers had no reason not to do this, because they already did the same with the rest of the objects.) Therefore, if you expect to see a new alien every five steps, then I'm sorry, this is the problem of your expectations, not developers. If there is a way to create such content, then this is exactly the way the NMS engine. stones or ships (while texturing will still be a big question), but for living moving objects such as creatures or NPCs, everything becomes so complicated that it is almost impossible. (Of course, if it were possible, the developers had no reason not to do this, because they already did the same with the rest of the objects.) Therefore, if you expect to see a new alien every five steps, then I'm sorry, this is the problem of your expectations, not developers. If there is a way to create such content, then this is exactly the way the NMS engine. because they already did the same with the rest of the objects.) Therefore, if you expect every five steps to see a new alien, then I'm sorry, this is the problem of your expectations, not the developers. If there is a way to create such content, then this is exactly the way the NMS engine. because they already did the same with the rest of the objects.) Therefore, if you expect every five steps to see a new alien, then I'm sorry, this is the problem of your expectations, not the developers. If there is a way to create such content, then this is exactly the way the NMS engine.

After all, after all my research, I know that the game has enough content to at least create everything in a new way on every planet, so I can’t blame the game or the engine. I can blame setting up and configuring the engine. I can also blame the damned multi-platform releases and publisher. I'm 100,000,000,000,000,000,000% sure that the developers were forced to rush when releasing the game. The game that we got is far from complete, and does not even come close to 80% of the capabilities provided by the engine. After studying the files, this is absolutely clear to me. It is closer to the technical demo, not to the game. An attempt to cram the same content onto PC and PS4 simply tore the game, and the desire to get it to work on weak machines further reduced the quality. Personally, I am waiting for updates, and there should be a lot of them . I can forgive a lot of Hello Games errors when releasing the game, overpriced, lack of communication with consumers, even the lack of many features (for example, a multiplayer mode, which, frankly, I do not care). But even taking into account the confusion and tension before the release, I can not forgive the fact that they could not fully show what the engine with the correct configuration is capable of. Modders are now plunging into the jungle of files and trying to find ways to create the same enginericher and more diverse content. And most often they do it because the engine can provide a much better game. All these options should be available to any player, not just modders. Obviously, the developers decided not to give the players such an opportunity that they all were in the same universe and could have common points on the route, creatures and the planet. But they should have left such an opportunity. Focus on the single player game and show all players what the engine is capable of.

For some reason, it seems to me that sooner or later HG will do so. They can't just forget over four years of work on an engine that is really great. And to all lovers of conspiracy theories about Hello Games, I can say that the developers had a thousand ways to get your money, and if they had such a desire, this could happen much earlier.

Even before the game engine becomes so beautiful ...

Also popular now: