Unreal engine 4 games on the engine. Video: Dishonored debut trailer

23.06.2019 Construction

New mobile Lineage 2 on Unreal Engine 4 we decided to compile a small selection of interesting remakes of games on this engine that deserve your attention.

So, the top 5 game remakes on Unreal Engine 4. Let's go!

1.

Announcement of the remake of the legendary Final Fantasy 7 at E3 2015 was the highlight of that year for many people.

Subsequently, at PlayStation Experience 2015, a trailer was shown containing several seconds of gameplay shown for the first time with the participation of Cloud and Barret at the very beginning of the game.

To understand what place it occupies Final Fantasy 7 in the gaming industry, and how much people were waiting for this moment, just look at the reactions to the announcement of this remake.

2.

3.

22-year-old 3D environment artist Kimmo Kaunela from Finland has been working on the project for the past year. The Last Stop, inspired by the studio's creation - the game. Kimmo managed to create an amazing map showing what the game would look like if it were released on Unreal Engine 4.

The guy has an account on Deviant Art And own website, where you can see his latest work. This project, according to the author, taught him how to work with Unreal Engine 4.

4.

Enthusiast Airam Hernandez shared a video earlier this year of an amateur remake of the first part, which he is working on alone.

Hernandez's work uses a modified version of the Unreal Engine 4 graphics engine. According to him, at first he only wanted to recreate the island of Shadow Moses using new technology so that gamers familiar with the original and newcomers could explore its attractions. However, after foreign media drew attention to the technical demo, Hernandez decided to take on a full-fledged remake of the stealth action game.

In his Facebook posts the author of the remade Metal Gear Solid did not specify when to wait final version. The video, as the introductory message suggests, is based on an early prototype of the remake.

5.

Modder with nickname Logithx set out to make a remake of the cult shooter. An enthusiast is working on the embodiment of the dystopian City-17 from HL2 using Unreal Engine 4. The author cannot yet give an approximate completion date for the work - everything is still at an early stage.

Logithx spent a lot of time working on a remake of Half-Life 2 using the previous version of Epic's engine - Unreal Engine 3. However, when the company began distributing the powerful UE4, he decided to start work from scratch - and already on new technology.

6.

“How so, you said Top 5 - where does the 6th point come from?” - you ask.

To hell with the rules! This is on Unreal Engine 4! Just look at these graphics! The author of the project to port this wonderful game to a new engine is Alexander Young.

Pong- the first game to show that games are serious. It's funny, but two rackets and a pixel ball were enough to create the first boom in arcade machines: slot machines with Pong were so popular that its clones soon flooded the market. Atari subsequently released a version of Pong for the Atari 2600 console, proving that home gaming systems have a right to life too. The success of Pong also became a signal for other gaming companies - for example, Konami quickly entered the arcade market with the game Maze.

This guide is designed to help developers improve performance in games made with Unreal Engine 4 (UE4). Here we will talk about tools that can be used both in the engine itself and outside of it, about the best approaches to using the editor, as well as about scripting that helps increase the frame rate and stability of the project.

The overall goal of this guide is to identify what causes performance problems and provide several methods to resolve them.

This guide was written using UE4 version 4.14.

Units

Optimization improvements are measured using frames per second (also called frame rate or fps) and milliseconds per frame (ms).

The graph below shows the relationship between average framerate and milliseconds.

To find out ms at any fps, we simply find out the inverse of fps (i.e. take 1 and divide it by fps), and then multiply it by 1000.

1/FPS x 1000 = MS

Using milliseconds to describe performance improvements allows you to better measure the level of optimization required to achieve your target framerate.

Here are a couple of examples of increasing FPS by 20 frames per second:

  • To increase FPS from 100 to 120, you need to improve the result by 1.66 ms
  • To increase FPS from 10 to 30, you need to improve the result by 66.67 ms

Tools

Before we get started, let's look at three tools to understand what's going on under the hood of the engine. These are UE4 CPU Profiler, UE4 GPU Visualizer and Intel Graphics Performance Analyzers (Intel GPA).

Profiler

UE4 CPU Profiler is a tool that is built into UE4 that allows you to track your in-game performance, whether it's a live game or just a saved snippet.

To find Profiler, in UE4 click on Window > Developer Tools > Session Frontend.

How to get to the Session Frontend window

In Session Frontend, select the Profiler tab.

Profiler in Unreal Engine

Now that you're in the Profiler window, select Play-In-Editor (PIE) and then select Data Preview and Live Preview to see the data being read from the game. To begin capturing data, press Data Capture, and to save the data for later viewing, press Data Capture.

Viewing processes via Profiler

In Profiler, every action and command is reflected in milliseconds. Each area can be examined for how it affects the project's frame rate.

GPU Visualizer

UE4 GPU Visualizer determines how much computing resources are required for rendering passes, and also allows you to view in detail what is happening within a particular frame.

You can open GPU Visualizer through the developer console by entering “ProfileGPU” there.

ProfileGPU console command

After you enter the command, the GPU Visualizer window will appear. It shows how long passes take, as well as the approximate location of those passes in the scene.

View processes using GPU Visualizer

Just like in Profiler, by identifying the areas that take the longest to process, you'll know where to optimize.

Intel GPA

Intel Graphics Performance Analyzers (Intel GPA) are a suite of analysis and optimization tools designed to help developers make their graphics projects perform better.

In this tutorial we will focus on two aspects of this suite: Analyze Application and Frame Analyzer. To get started, download GPA from the Intel Developer Zone. Once installed, compile your project with the Development setting (to select it, click on File > Package Project > Build Configuration > Development).

When the project is compiled, launch Graphics Monitor, click on Analyze Application, select the desired *.exe file in the Command Line field and click on the Run button to run it.

Next, the game will start - the same way it usually starts, however, in the upper left corner there will now be a menu with statistics. To expand it, click Ctrl+F1. If you press Ctrl+F1 once, several windows will appear with indicators measured in real time. If you press Ctrl+F1 again, a list of commands (plus the hotkeys you need to press to execute them) will appear with which you can experiment with the game while it is running.

Intel GPA menu in game

To make a frame for subsequent analysis in Frame Analyzer, you need to go into the game and do two additional actions.

First enable Toggle Draw Events. To do this, enter “ToggleDrawEvents” in the console.

Console command ToggleDrawEvents

When you enable this feature, the rendering commands coming from the engine will be given names. This will allow you to understand what's what when you look at the captured frame in Frame Analyzer.

Finally, save the frame by pressing the hotkeys Ctrl+Shift+C.

After saving the frame, launch Graphics Monitor, click on Graphics Frame Analyzer and select the frame you want to load. After saving is completed, the program will show all the information about the graphics available in the frame.

Example of using Intel GPA

The abundance of data in Intel GPA seems overwhelming at first, so let's start with the largest pieces of information. In the upper right corner of the window, set both axes (X and Y) to GPU Duration - the result will be a graph of which rendering commands in this frame are the most resource-intensive.

In our example, i.e. in the frame with a desert landscape, it is clear that the most resource-intensive was the basic passage. Having selected the largest peak on the graph (that is, essentially the most resource-intensive rendering command), as well as the Highlighted item in the lower left preview window (called Render Target Preview), we see that the cause of the peak was the landscape (it is highlighted in pink ).

Next, going to the Process Tree List window (it is located above the preview window and shows a list of processes) to find the selected rendering command, we see that this landscape consists of 520,200 primitives, and the GPU has to process it (this is the GPU indicator Duration) takes 1.3185 milliseconds (ms).

Finding the most resource-intensive rendering command in a frame

Now that we know what caused the spike, we can start optimizing.

Firstly, the terrain can be rebuilt using the Manage mode of the UE4 terrain creation tool, which allows you to reduce the number of primitives to 129032, and GPU Duration to 0.8605 ms. Thus, the scene is optimized by 5%.

We see a decrease in GPU Duration

To reduce the resource "cost" of the landscape again, let's take a look at materials. Our terrain uses a 13-texture 4096 x 4096 (4K) material, resulting in a total of 212.5 MB of texture streaming.

View rendered textures in Intel GPA

By compressing all landscape textures to 2048 x 2048 (2K), we reduced GPU Duration to 0.801 ms and improved performance by an additional 6%.

As a result, reducing texture streaming for the landscape to 53.1 MB and reducing the number of primitives made the project faster. And all this at the cost of only a very small reduction in the visual quality of the landscape.

We see a reduction in GPU Duration achieved by reducing the texture size

Overall, by simply rebuilding the scene and changing the textures, we were able to achieve the following:

  • Reduced GPU Duration when processing terrain by 40% (from 1.3185 to 0.801 ms)
  • Improved FPS by 18 frames (from 143 to 161)
  • Reduced ms by 0.7 milliseconds

Optimization in the editor

Forward Rendering vs Deferred Rendering

Deferred Rendering is the standard rendering method used in UE4. Using Deferred Rendering usually improves the image, but can also cause performance problems, especially in VR games and on weaker machines. In these cases, it makes more sense to switch to Forward Rendering.

For example, in the Reflection scene from the Epic store, you can see that there are some differences between the Deferred and Forward rendering methods.

Reflection scene rendered using Deferred method

Reflection scene rendered using Forward method

With forward rendering, reflections, lighting, and shadows suffer, but other visual elements do not change. As a result, productivity improves, but whether such sacrifices are necessary is, of course, up to you to decide.

If we take a look at the Intel GPA frame of this Deferred rendered scene, we see that the scene runs at 103.6 ms (9 fps), and a significant portion of this time is spent processing lighting and reflections.

Frame data from a Reflection scene rendered using Deferred on an Intel HD Graphics 530

And if we look at the frame rendered using the Forward method, we see that the “ms” indicator has improved from 103.6 to 44.0 (i.e. by 259%), and most of the time is spent on the base pass and post-processing. which can also be optimized.

Frame data from a Reflection scene rendered using Forward on an Intel HD Graphics 530

Level of detail

Static meshes in UE4 can consist of thousands or even hundreds of thousands of triangles - to show the most the smallest details, with which the 3D artist decorated his work. However, when the player is far from the model, he does not see these details, and the engine still processes these triangles. To solve this problem and thereby optimize the game, we can use so-called “levels of detail” (or simply LOD - from the English “level of detail”), so that these details are shown at a close distance, but not at a far distance.

LOD generation

In a standard pipeline, LODs are created by a 3D modeler during the creation of the model itself. Although this method allows you to control the end result, UE4 has a great tool built into it to automatically generate LODs.

Auto-generation of LODs

To do this, select the desired model, go to the Details tab, and then to the LOD Settings item. There, find the Number of LODs item (i.e., the number of levels of detail) and enter the desired value there.

Automatic generation of levels of detail

Click Apply Changes. This will be a signal for the engine to generate several LODs, and the original model among them will be LOD0. The example below shows that when creating five LODs, the number of triangles in our static mesh decreases from 568 to 28 - this is a significant reduction in the load on the GPU.

Number of triangles and vertices, as well as screen size for each LOD

If we place this model on the stage, we will see how it will change as it moves away from the camera.

Visual demonstration of LODs shown according to screen size

Materials for LODs

Another feature of LODs is that each of them can use their own material. This allows us to further reduce the “cost” of the static mesh.

Materials assigned to each level of detail

For example, normal maps are widely used in the gaming industry. However, a problem that arises in VR games is that normal maps are not perfect because upon closer inspection the player sees that it is just a flat surface.

This problem can be solved using LODs. Because LOD0 is detailed to the point where small details like bolts and screws are visible, when the player looks at the object up close, the player experiences a more immersive experience. Since all these details are modeled, the normal map can be abandoned on the first LOD. When the player moves away from this object, the engine switches to another LOD, which has a normal map that reduces the detail of the model. When the player moves further away, the normal map can be removed, because it will become too small and simply not visible.

Static Instance Meshes

Every time a new object appears on the scene, it requires calling an additional render command on the graphics device. If this static mesh, then each copy of this mesh will require a separate call to the drawing command. One way to optimize this (i.e. the situation where the same static mesh is repeated multiple times in the scene) is to instantiate the static meshes and thereby reduce the number of render commands called.

For example, we have two spheres consisting of 200 octagonal meshes - one green and the other blue.

Sphere of static meshes and instance meshes

The green octahedrons are regular static meshes. This means that a separate set of rendering commands is used to generate each of these models.

Draw commands for 200 static meshes (maximum 569)

The blue octahedrons are instance meshes. This means that only one set of rendering commands was used to generate all these models.

Draw commands for 200 mesh instances (maximum 143)

Looking at both examples through GPU Visualizer, the basic pass for the green (with static meshes) sphere takes 4.30 ms, and for the blue (with instance meshes) it takes 3.11 ms. Thus, we optimize the scene by 27%.

One thing you need to know about instance meshes is that if such a mesh renders some part, it will also be rendered for all other “clones” of this mesh. That is, if one of the “clones” ends up outside the camera, our optimization potential is wasted. Therefore, we recommend making grid specimens in small piles - like a pile of stones, a pile of garbage bags, a mountain of boxes or modular buildings located at a distance.

If most mesh instances are off-screen, they are still rendered

Hierarchical static instance grids

If you are using static grids with LODs, consider hierarchical instance grids.

Sphere of hierarchical instance meshes with LODs

Like standard instance meshes, hierarchical instance meshes reduce the number of drawing commands, but also use LOD information.

A sphere of hierarchical instance meshes with LODs; close view

Occlusion Culling

In the UE4 engine, Occlusion Culling is a system that allows you to make sure that objects that the player cannot see are not rendered. This allows you to reduce system requirements to the game, since the engine no longer has to draw absolutely all objects in absolutely all scenes and absolutely all frames.

Octagons scattered around the stage

To see occluded objects (they will be shown as transparent cubes with green edges), enter "r.VisualizeOccludedPrimitives 1" in the editor console. To disable this setting, enter “0” instead of “1”.

Edges of fenced nets; these edges became visible after using the command r.VisualizeOccludedPrimitives 1

Whether the mesh will be rendered or not depends on the so-called “bounding box”. Thanks to it, some objects may be invisible to the player, but visible to the camera - in this case, the engine decides to render these objects.

Viewing the boundaries of an object in the window for working with the object

If the mesh needs to be rendered before the player sees it - for example, to render idle animation, which is an animation of a character that activates when he stands still and does nothing; this could be head scratching, picking the ground with your foot, etc.) – then the size of the boundary cube can be increased. This can be done in the window for working with the object, in the Static Mesh Settings menu. Look for the Positive Bounds Extension and Negative Bounds Extension items there.

Set the scale for the object boundaries

The boundary cube of complex meshes and shapes always extends beyond those meshes, so the more empty space there is in the boundary cube, the more often these meshes will be rendered. Therefore, when working on a scene, it is important to know how the dimensions of the boundary cubes affect its performance.

Let's imagine a thought experiment where we create a 3D model and then export it to UE4. How should we approach creating a Colosseum-style arena?

Let's say a player stands in the center of the arena and looks around the huge Colosseum, trying to intimidate his opponents. When the player rotates the camera, its direction and angle will dictate what the engine needs to render. Since the Colosseum is a very important element of our game, we made it very detailed, but to save on drawing commands, it needs to be made from several objects.

But first, we must abandon the idea that the entire arena should be one big solid object. In this case, the number of triangles that will need to be rendered will correspond to the size of the entire arena - regardless of whether we are looking at its individual parts or not. How can we optimize this model?

Depends on several factors. Firstly, on what pieces the arena will be cut into, and secondly, on how the shape of these pieces will affect the size of the boundary cubes (which is important for Occlusion Culling). To make it easier, let's imagine that the player is using a camera with a 90-degree field of view.

Option one is “sliced ​​pizza”. That is, we create 8 identical sharp pieces, the “noses” of which are directed towards the center of the arena. This method is simple, but it is not very suitable for Occlusion Culling, since in this case there will be a lot of overlap between the boundary cubes. If the player stands in the center and looks around, his camera will capture 3-4 cubes, i.e. most the engine will have to render half of the arena. In the worst case scenario, the player can stand with his back to the wall, look at the arena around him and thereby capture all 8 pieces of “pizza” in the frame. No optimization.

Option two is “tic-tac-toe”. Here we create 9 pieces. This is not the most traditional method, but it has the advantage that there is no overlap between the boundary cubes. As in the case of “pizza,” if the player stands in the center of the arena, he will capture 3-4 pieces in the frame. However, with his back to the wall, he will capture 6 out of 9 pieces in the frame, which, compared to “pizza,” provides some optimization.

The last option is “sliced ​​apple” (1 central piece and 8 side pieces). This is the most common method for this thought experiment, and a very good one - there is overlap between the boundary cubes, but it is small. If the player stands in the center of the arena, he will capture 5-6 pieces in the frame, but unlike the first two options, in the worst case (with his back to the wall) the same 5-6 pieces will be rendered.

A thought experiment showing how a large model could be cut and how this would affect the boundary cubes and the overlaps between them

Cascading shadow maps

Although dynamic shadow cascades add to your game high level details, they can be very “expensive” in terms of performance - to play such a game without losing framerate, you will need a powerful PC.

Luckily, as the feature's name suggests, these shadows are created dynamically on a frame-by-frame basis. That is, we can create several options thanks to which the player can optimize his graphic settings.

“Cost” of dynamic shadow cascades on Intel Graphics 350

The value in dynamic shadow cascades can be controlled dynamically. This can be done in several ways:

  • By changing the shadow quality in Settings > Engine Scalability Settings > Shadows
  • By editing the parameters in the “BaseScalability.ini” file: in the settings Shadow.CSM.MaxCascades (between “0” and “4”) and sg.ShadowQuality (between “0” and “3” - for “low”, “medium”, "high" and "epic")
  • By adding the Execute Console Command node to the game blueprint, where you manually changed the Shadow.CSM.MaxCascades parameter

Optimization through scripting

Disable completely transparent objects

Drawing commands can be called even on completely transparent game objects. To avoid this, you need to configure the engine so that it stops rendering them.

To do this with blueprints, you need to use several different systems in UE4.

Set of parameters for materials

First, we create a set of parameters for materials (or simply MPC - from the English “material parameter collection”). Linear and vector parameters will be stored here, which can be linked to any material in the game. They can be used to modify these materials during the game - to create dynamic effects.

We create an MPC by clicking on the Content Browser tab on Add New > Materials & Textures > Material Parameter Collection.

Creation of MPC

Being in MPC, we can create, name and set default values ​​for linear and vector parameters. In our case, we will need a linear parameter - we will call it Opacity (i.e. “transparency”) and with its help we will control the transparency of our material.

Set a linear parameter called Opacity

Material

Searching for the Collection Parameter node in a material

Having created a node, we connect it with the Opacity parameter on the base material.

Setting up the Collection Parameter in the material

Script in blueprint

Having created the MPC and material, we go to the blueprint and configure it so that we can set and read values ​​​​from the MPC. This is done using the Get/Set Scalar Parameter Value and Get/Set Vector Parameter Value nodes. Next, we go to these nodes, in the Collection item we select the set that we want to use (MPC), and in the Parameter Name item – the name of the parameter from this set.

For this example, we set the linear Opacity value to be a sine at game time - so we can see values ​​ranging from "1" to "-1".

We set and read a linear parameter, and also use its value in a function

To determine whether an object is rendered or not, we create a new function called Set Visible Opacity. Input values it will have an Opacity parameter from MPC and a static mesh, and the output will be a Boolean value indicating whether the object is visible or not.

Next, we run a check to ensure that the value is slightly greater than “0” (in in this case, more than “0.05”). The check for "0" may work, but when getting closer to "0" the player will no longer be able to see the object, so we can simply turn it off before the value becomes "0". In addition, this allows you to create a buffer - in case of floating point errors, due to which the linear parameter will not be able to get an exact "0". For example, if the value is “0.0001”, this system will simply turn it off.

Next, we create a Branch node - if its output is True, then the visibility of the object (the upper Set Visibility node) will be given the value “true”, and if False, then the visibility of the object (the lower Set Visibility node) will be given “false”.

Set Visible Opacity function

Event Tick node, time and render check

If the scene blueprint uses an Event Tick node, these scripts will work even if no objects are visible on the screen. Typically this isn't a big deal, but the fewer blueprints that tick during each frame, the faster the scene will run.

Here are some situations where you can use this type of optimization:

  • Things that don't need to work when the player isn't looking at them
  • Processes that run depending on game time
  • Non-player characters (NPCs) who don't have to do anything when the player isn't around

As the most simple solution You can place the Was Recently Rendered node in front of the Event Tick. Thus, in order for our Event Tick to turn on/off, we do not need to connect special events and detectors to it. In addition, this system can still be independent of other processes occurring in the scene.

Managing an Event Tick Node Using a Render Check

This method can also be used for more complex problems. For example, if we have a process that runs depending on game time (for example, some glowing button that lights up and goes out every second), we can use the graph below:

The Emissive Value in the Material Collection is set in such a way that during rendering it will act as an absolute sine wave of game time

The graph above keeps track of how much game time has passed and then passes that value through an absolute sine plus one, resulting in a sine wave varying between the values ​​"1" and "2".

The advantage of this method is that the button will blink according to the line in the graph above, regardless of whether the player is looking at the button or not (they can either spin in circles or stare at it). And all thanks to the value calculated based on the sine of the game time.

This also works with integer division remainders, but in this case the graph looks different.

You can check for rendering using the Was Recently Rendered node a little later. That is, if the object controlled by the Event Tick node has some tasks that need to be performed every frame, but you can make sure that these tasks are performed before the render check (see the graph below). The fewer nodes that are called with each “tick” of the Event Tick node, the better.

Using a Render Checker to Manage the Visual Fragments of a Blueprint

Another way to reduce the "cost" of a blueprint is to slow it down and allow the Event Tick node to "tick" only once during a certain interval. This interval is set using the Set Actor Tick Interval node.

Switching between intervals

In addition, the interval at which the Event Tick node “ticks” can be set in the Tick Interval item - it is located in the Details tab of the blueprint you are working on. Here the interval is specified in seconds.

Tick ​​Interval item in the Details tab

This is convenient, for example, when you need to make a counter that fires every second.

Create a parallel counter that fires every second

As an example of how this type of optimization can reduce your average ms, let's take a look at the graph below:

Incredibly useful example of what not to do

Here we have a ForLoop node that counts from “0” to “10000”, and an integer Count is specified for it through the SET node. This graph is very resource-intensive and inefficient - so much so that the ms indicator for our scene is a whopping 53.49 ms.

Viewing Stat Unit's "cost" is an incredibly useful example.

Moving into Profiler, we understand why. This simple but extremely ineffective blueprint consumes 43 ms for each tick.

Viewing in Profiler the fragment responsible for triggering the Event Tick in each frame

But if you make this blueprint “tick” every second, then most of the time it will “eat” 0 ms. If we look at the average time (select some fragment of the timeline in the Graph View window) over three ticks, we will see that the average is 0.716 ms.

Viewing in Profiler the fragment responsible for triggering the Event Tick every second

Or let's take a more common case: let's say our blueprint has 1.4 ms, and if the scene runs at 60 fps, then it will take 84 ms to process this blueprint. But if you reduce the time during which the Event Tick node “ticks” on a blueprint, this will also reduce the total time spent on processing this blueprint.

Bulk movement, ForLoop node and multithreading

When multiple models move at the same time, it looks very cool and can make for a very attractive visual style. True, in this case, a large load falls on the CPU, which is why FPS ultimately suffers. However, this can also be optimized by dividing the mass movement into several blueprints - thanks to multithreading and UE4’s ability to manage worker threads.

In this section, we will use a script that will dynamically move 1600 instanced spheres up/down along a modified sine curve.

Below is a simple script that creates a grid. We simply add the Instanced Static Mesh component, in the Details tab, select the mesh we will use, and then add the following nodes:

Script to create a simple grid

Having created the grid, we add this script to the Event Graph tab.

A few words about the Update Instance Transform node. If any of the instances are transformed, this change will not be shown until the Mark Render State Dirty item is marked "true". But this is a resource-intensive operation, because... the check goes through each grid. To save computing resources, especially if this node is launched several times per tick, you can make the grids updated at the end of the blueprint. In the script below, the Mark Render State Dirty item is marked as “true” only if two conditions are met - if ForLoop node costs Last Index and if the value in Index corresponds to Grid Size minus 1.

Dynamic Motion Blueprint for Static Instance Meshes

In addition, using an Actor type blueprint, a grid script and a dynamic motion event, we can create different grid options where 1600 grids will be displayed at the same time.

Multiple grille options with 1600 meshes

Running the scene, we will see lattice elements floating up and down.

Lattice of 1600 static grid instances dynamically moving up and down

However, the type of chunking affects the speed at which the scene runs.

First, if the lattice consists of 1600 individual fragments, then all 1600 blueprints will be processed in 16.86 ms (i.e., an average of 0.0105 ms per blueprint). That is, although the “price” of one blueprint is small, their total number slows down the system. The only thing that can be done here is to reduce the number of blueprints that fire with each tick. Another reason for the high load is the large number of individual meshes, which increases the number of both rendering and mesh transformation commands.

Secondly, if the grid consists of one fragment, which includes 1600 grids, then this option will be very well optimized in terms of drawing commands (because only one drawing command is required for the entire grid), but the “cost” of a blueprint, which is one “tick” will need to process 1600 grids, will be 19.63 ms.

But if you split the grid differently (into 4 fragments of 400 grids, 64 of 25 or 16 of 100), the result is more optimized - thanks to the reduced script processing time and the ability of UE4 to work with multi-threading. Thanks to the latter, UE4 can distribute the blueprint processing load across multiple worker threads, thereby effectively using all CPU cores.

If we look at the processing time of blueprints and how they are distributed among worker threads, we see the following:

Data structures

Using the right data structures is a necessary element of any program, and this applies to game development as much as it applies to other software development. When programming in UE4, blueprints are used, and there are no data structures in the template array, which serves as the main container. They are created manually at a later stage of development - with the addition of functions and nodes found in UE4.

Usage example

As an example of why and how data structure can be used in game development, let's imagine a shootmap game. One of the main mechanics of shootmaps is shooting at enemies, which generates thousands of bullets rushing across the screen. Since bullets eventually reach their targets (or fail to hit objects) and are destroyed, the game engine must clean up this debris, which can impact game performance and even reduce framerate. To deal with this problem, developers should provide in their design a so-called “object pool” - a set of objects (in this case, bullets) placed in an array/list and processed when the game starts - thanks to which developers can enable / disable bullets in any time. As a result, the engine is given only the job of creating bullets.

The most common method of using an object pool is to take the first not yet enabled bullet in the array/list, move it to the starting position, turn it on, and then turn it off when it flies off the screen or hits an enemy. The problem with this method is the time it takes for the script to run, i.e. in big "O". Because you're doing a lot of loops checking objects and looking for which one to turn off, when using 5000 objects it can take a lot of loops to find one object. For this method, the time will be represented as O(n), where “n” is the number of objects in the set.

Although O(n) is far from the worst algorithm. The closer we get to O(1) – i.e. to a fixed “cost”, independent of the size - the more effective the script will be and the faster the game will be. To pull this off with the object pool, we use a data structure called a "queue". Just like a real queue, this data structure takes the first object in the set, uses it, and then deletes it until it has used all the objects in the queue.

Using this "queue" for our object pool, we can take the front piece of the set, include it, then remove it and immediately put it in the back of the set. This will create an efficient loop in the script and reduce the script's running time to O(1). We can also add a check to this loop - if the deleted object was included, then the script takes it and, without creating a new object, places it at the end of the queue, increasing the size of the set, but without increasing the processing time of the script.

Queues

Below are some pictures that demonstrate how to use queues. They add various features to blueprints that make the code cleaner and more reusable.

  • Removal

Implementation of the queue::pop construct in the UE4 blueprint; removes an element from the front of the queue

  • Addition

Implementation of the queue::push construct in Blueprint UE4; inserts a new element at the end of the queue

  • Determining if a queue is empty
  • Determining Queue Size

Implementation of the queue::size construct in Blueprint UE4; reports the queue size

  • Returning a pointer to the first element in the queue

Implementation of the queue::front construct in UE4 Blueprint; returns a pointer to the first element in the queue

  • Returning a pointer to the last element in the queue

Implementation of the queue::back construct in UE4 blueprint; returns a pointer to the last element in the queue

  • Inserting an element at a specific location in the queue

Inserts the specified element into the specified queue location (with position check)

  • Data exchange

Implementation of the queue::swap construct in UE4 blueprint; forces two containers to exchange data (with position verification)

Stacks

Below are some pictures that demonstrate how to use stacks. They add various features to blueprints that make the code cleaner and more reusable.

  • Removal

Implementation of stack::pop construct in UE4 blueprint; removes an element from the front end of the stack

  • Addition

Implementation of stack::push construct in UE4 blueprint; inserts a new element at the end of the stack

  • Determining if the stack is empty

Implementation of stack::empty construct in UE4 blueprint; tells whether the stack is empty

  • Determining Stack Size

Implementation of the stack::size construct in Blueprint UE4; reports the stack size

  • Returning a pointer to the last element on the stack

Returns a pointer to the last element on the stack

  • Inserting an element at a specific location in the stack

Inserts the specified element into the specified stack location (with position check)

The Unreal Engine has its roots back in 1998. Since then, many amazing games have been created. In this article we will talk about the 7 best of them. At the time the engine was created, it was used to create simple games with 2D view. Gradually, more modern 3D action games began to appear. The popularity of the engine was ensured by a unique operating system; it simultaneously has: a graphical and physical core, built-in artificial intelligence, as well as tools for managing file systems and networks. The main attraction was the availability of a ready-made environment for creating games - UnrealEd.

#7 - Batman: Arkham Knight

This game has an action-thriller genre. The plot is based on events that occurred 9 months after the famous war in Arkham City. Since the Joker is dead, Gotham begins to return to its usual rut of life, a safer time begins for its inhabitants, but the balance of power is lost when, one day, the inhabitants of Gotham throw themselves at each other in a cafe for no apparent reason.

After such a performance, Scarecrow appears on stage with the statement that he has only used 100 g of his new toxin and she intends to continue, increasing the dose every day. In this regard, residents are urgently evacuated from the city.


Main character– Batman, who tirelessly fights for the safety of his hometown and eradicates crime. During the game, numerous enemies, beautiful locations, and unique characters will appear. The game is distinguished by a careful approach to gameplay and therefore deserves to take 7th position among the best.

#6 - Street Fighter V

There are games that, without exaggeration, are known all over the world, Street Fighter is one of such games. The modern fifth part will fill the void left by the illogical release of the third and sixth parts. For those few who are not yet familiar with the game, it is a fighting game where the user fights with enemies. The basis of its popularity lies in the possibility of multiplayer, and playing with a friend always brings “live” emotions.


The game has been famous since time immemorial, due to the many characters with unique characteristics and combat abilities. Previously, there were high-class characters and users that were impossible to win against, but gradually the combat strategy and techniques changed and gained more balance.

#5 - We Happy Few

The game focuses on the year 1964, when in a city called Wellington Wells(the name is fictitious) drugs were developed to increase joy, it’s called the “Joy” serum. It is based on clearing memories. The thing is that during the Second World War, residents resorted to using extremely bad things, which provoked a strong suppression of the spirit of the nation. The serum is designed to eliminate these memories and make people happier, and by force. Those residents who refuse to use “Joy” are called “Bores” and they are eradicated.


The main character is Arthur Hastings, an ordinary clerk who is engaged in censoring newspapers of “unfortunate” news from the past. While going through newspaper archives, he discovers his photo and younger brother on the cover. Memories creep into his head and they bring pain. In order to get to know himself, he refuses to drink “Joy”. After the effect ends, his colleagues recognize him as a “Bore” and begin to pursue him. This forces Arthur to flee to the dungeons.

#4 - Gears of War 4

The cult series of games once again inspires the user to immerse themselves in the world of "mess". In terms of gameplay, there are no significant differences from previous parts. The game remains an excellent shooter, where there are numerous enemies and shelters. There are really a lot of weapons, right down to a machine gun with a chainsaw as an under-barrel bayonet. Battles take place both with the Horde, although they are creepy, but alive, and with COG robots. All monsters are trying to devour the hero.


An interesting feature of the game is that a whirlwind of incredible strength may suddenly appear, which provokes a strong shaking of the entire surface of the Sulfur; no one and nothing can resist the force of nature. The player will be able to see houses soaring into the sky; surviving in such conditions will not be easy.

#3 - Mortal Kombat X

Mortal Kombat is in the top three best games on the Unreal Engine. It has a fighting game genre, which was discussed earlier using the example of Street Fighter V. There are many characters here, a countless number of strikes, but making them can be quite difficult, since the combinations are long and must be performed accurately. The popularity of the game is based on its excellent gameplay, spectacular battles and beautiful character models and terrain for fights.


The game even has a plot, although it is more of a formality, because the value of the game does not lie in this component. Fights with friends, which lead to the emergence of a competitive spirit, are the most important feature of the game. To be a winner, you need to memorize and practice combinations for strikes, and then neither your friend nor the computer will be able to resist.

#2 - BioShock Infinite

BioShock is an interesting shooter that fascinates with its atmosphere and has some RPG elements, that is, you can upgrade your character’s abilities. The game takes the user back to 1912, the action takes place in the floating city of Columbia.


The user will play as private practice detective Booker DeWitt, who enters the city to search for Elizabeth. After the discovery of the girl, both heroes become prisoners of the war between the authorities and the rebels, the simple, working class.

Elizabeth's uniqueness is that she can create rifts between parallel worlds that reveal much about the city and the characters' pasts.

#1 - Dishonored

Stealth action is becoming quite a popular genre these days, but it's difficult to compete with Dishonored. Additionally, the game contains elements of the RPG genre.

The game takes you to a city that is completely mired in a plague epidemic - this is Dunwall. It is noticeable that the city is in many ways reminiscent of London in ancient times, approximately the Victorian era. The main character, Corvo Attano, wants to restore justice, because he was blamed for the murder of the empress. The lord escapes from prison and tries to establish a balance between good and evil forces.

Corvo does not neglect any ways to solve the situation, so he “moons” as a hired killer. The main task is to find and eliminate a specific character. Present in the game a large number of various weapons, but that’s not all, because the character has unique abilities.


The game has an interesting plot, it is non-linear. Almost every mission can be completed in many ways, in particular - you can make noise and kill numerous opponents or kill the enemy secretly so that no one notices.



Greetings, Habr! I would like to introduce you to relatively small project, which I made from scratch in about 150 hours (50 runs ~3 hours each) on Unreal Engine 4. I did the project in live only on streams once a week (it took a year in total), answering user questions along the way.

The project itself was not intended to be commercial. My goal was to show in practice the complexity of game development, namely problems such as:

  • Project planning and prototyping
  • Thinking through and implementing the project architecture and its individual components
  • User Interface Implementation
  • Debugging and error correction
  • Working with assets and graphics

At the end of the entire series of streams, we ended up with a playable prototype of a “survival” shooter. Those with a glass half full might even call it pre-alpha without a plot.

If you are interested in the details of the project, stream recordings, sources, etc., read on.

The entire project was implemented on a visual programming system called Blueprints. And of course, many specialists may call it childish; even a relatively large project can be easily developed on it. Moreover, this can be done relatively quickly, as we have already been able to prove.

I want to answer the question right away: " Why Blueprints and not C++?". Well, firstly, when I started the series, I almost didn’t know the pluses. Although I would still make such a single on a power supply. Secondly, power supplies are almost as good as the pluses in our case, but at the same time they provide a number of possibilities: They don’t allow you to do many errors are possible with advantages, you don’t have to be distracted between BP and C++, it’s easier to understand for beginners. And in our case they are not much slower, given the fact that almost all the logic is built on events.

We also managed to work a little on the graphics. Unfortunately, we didn’t have time to make assets, so we left some of them as dummies, some were made directly in the editor from primitives, and some content was borrowed from free Epic Games demos. Nevertheless, we managed to do some things ourselves, for example, a day and night system, post-processing for water and some materials for scene objects.

The plans for my streams also included problems that may arise during development. I specifically solved them live in order to not only show what young developers might encounter, but also how to debug their code, look for bugs and write their code so that the whole thing could be done twice as fast. Of course, I don’t have decades of experience in programming, and this affected the sometimes stupid mistakes I made. And I’m sure that many developers can challenge many points in the process of writing a game.

Naturally, this can hardly be called a full-fledged game, since there is no plot or goal in the game - only pure mechanics. However, I believe that the result is something to be proud of and that it fully reflects what the whole project was intended for.

List of everything we managed to implement in our game

Character

  • Character Control
  • Vital stats system (Hips, armor, stamina, hunger, thirst)
  • Switching view (first person and third person)
  • Model (made in Fuse, animations taken from Mixamo)
  • Customized animations of movement and weapon use
  • Universal interaction with objects

Object Inventory System

  • Inventory component (embed into any object you want)
  • Cage system with support for different size items
  • Inventory size by cells per page and by weight.
  • A class of items that can be put into inventory. Items are stored as objects.
    • Weight, size, information, condition of item
    • Functionality for stacking (when there is a lot of one item in one cell)
    • Ability to add logic for using an item
    • Dropping from inventory
  • Interface for interacting with inventory
  • Interface for exchange between another component and its own.
  • Drag&Drop manipulation of objects between inventories and within one.
  • Context menu for items
  • Hints when pointing at items in the inventory and in the world.
  • List of generated items when creating an object with a component / starting the game.
  • List of starting items when creating an object with a component / starting the game.
  • Trading system between other inventory
    • Trading Interface
    • Money management component (required for trading to work)

Equipment system

  • Equip several types of items: Hats, Top, Pants, Boots, Weapons
  • Skeletal synchronization of the Top, trousers and boots. (Hats and weapons by sockets)
  • Convenient window for equipment with Drag&Drop support
  • Support for modifier logic when dressing
Weapon
  • Ranged weapons
    • Reload
    • Using ammo items from inventory
    • Support for projectile/bullet classes
    • Auto fire/single fire
    • Recoil with spread (own + depending on factors, e.g. running or squatting)
  • Melee weapons (with several types of damage checks to choose from)
  • Weapon condition deteriorates with use
Crafting system
  • Crafting according to a recipe (I chose a recipe, it crafted, ala Fallout)
  • Crafting by items (threw in the necessary items, he crafted them, ala Minecraft)
  • User interface only for the second type of crafting.
Aggressive mobs
  • Melee mobs (if they see them, they will run and start hitting)
  • Mobs of a mixed type (they shoot, but if they are close enough, they will run to hit)
  • Long-range shooters run around obstacles if they cannot shoot.
  • There is a built-in inventory for loot after a kill.
  • Spawn zone
  • List of classes
  • Spawn chance
NPC
  • Town NPCs patrolling their spawn zone
  • Unique NPCs
  • Basic schedule controller for unique NPCs
  • Reaction to damage (run away or use existing weapons)
  • Built-in inventory for loot after killing.
  • Object Dialogue System
    • Dialogue tree
    • Every answer is an object
    • For each answer, you can add any logic or accessibility condition.
    • Dialogue interface
    • Some ready-made classes response (starts trading, takes resources, if any, exits the dialogue)
Construction
  • Class of structures that support placement
  • Using resource items from the inventory when placing.
  • Snapping on some types of structures (e.g. walls, foundations, windows)
  • Menu with designs
  • Highlighting structures that have enough resources
Additionally
  • A small map with a city, forest, bodies of water (you can swim).
  • Day/night system
  • Cars
    • View from the first or third. Common with the Persian
    • Turning headlights on/off.
    • Built-in inventory component (needs to be interacted with at the trunk)
  • Somewhat working vertical stairs.
  • Main menu
  • Pause menu
  • Graphics settings menu

However, we can talk about the project endlessly. And in order not to turn the article into a book, I suggest you familiarize yourself with the game and its capabilities via video. And for those who are really interested, just below you can find recordings of all the streams, links to the sources and build of the game.

Contents in parts

  1. We start and plan the project. We create the character's controls and behavior.
  2. Let's start making an inventory system.
  3. We continue to build the base of the inventory system.
  4. We are preparing a base for equipment and weapons.
  5. Working on weapons and using cartridges.
  6. We do auto-shooting and aiming.
  7. Creating a basic crafting system.
  8. Running, recycling items and wearing them out.
  9. We are implementing reloading for weapons.
  10. Making melee weapons.
  11. We finish the melee and make a ladder that you can climb.
  12. We make interactive objects: Wood, stone, bushes.
  13. We make a HUD and start making an interface for the inventory.
  14. We continue to work on the inventory interface. We generate cells with objects.
  15. We continue to generate cells and search for a place for the item. Adding inventory pages.
  16. We do a little interaction with items in the inventory and a detailed information window.
  17. Made Drag&Drop dragging items across the inventory and into another inventory.
  18. This part is about visualizing crafting.
  19. We create a window with a choice of the number of items from the stack to transfer to another inventory.
  20. We provide support different recipes crafting, and also fix various bugs in the inventory.
  21. We are creating a system for changing day and night, and also creating a new scene for our project.
  22. We are starting to create AI for aggressive bots.
  23. We make an attack on mobs, as well as a reaction to an attack. Plus we implement the collection of loot from dead mobs.
  24. We are making a spawn zone for NPCs. We are also adding the generation of random items in the inventory.
  25. We are updating to 4.13, and also making long-range aggressive NPCs.
  26. Adding different elements to the HUD. Adding manual weapon reloading.
  27. We are finishing the support for skeleton clothes and hats. Adding animation for weapons in first person.
  28. We are making an interface for working with our equipment system.
  29. We are starting to create a trading system and a money management component.
  30. We continue to do trading by creating and customizing the trading component.
  31. We cancel the trade, and also set up the reload animation.
  32. We create a vehicle with our own equipment, headlights and view switching. Let's create a flashlight.
  33. We create construction (or rather, a system for placing objects in front of us).
  34. We make an interface for construction, we make a binding for walls.
  35. We create several more types of structures: Tent, bed, chair, table, lamp, door. chest, fire.
  36. Add a roof and windows. We complete the alignment relative to other structures.
  37. We make a small settlement, and also populate it with NPCs, which we also create in this lesson.
  38. We are starting to create a dialogue system for our residents.
  39. Setting up fog and post-processing. We import the zombie model and customize its animations.
  40. We are finishing the dialogue system.
  41. We make interaction with objects from a third person, as well as modifiers for armor.
  42. We create the main menu, pause menu and graphics settings. We are also putting together the first build of the game.
  43. We are implementing a schedule for unique residents. And also so that city NPCs run away from attacks.
  44. We are adding a context menu to the inventory, and also fixing some bugs in our inventory.
  45. We add recoil, spread, shot animation and the ability to hit for firearms.
  46. We will complete the aggressive and urban NPCs and fix various bugs associated with them.
  47. Setting up animations for the main character. Adding various clothes.
  48. We are fixing various bugs in our game.
  49. We are fixing various crafting, NPC and equipment errors in our game.
  50. We are finalizing the map a little and putting together the latest build.
  • Game development
  • Greetings, Habr! I would like to introduce you to a relatively small project that I made from scratch in about 150 hours (50 runs ~3 hours each) on Unreal Engine 4. I did the project live only on streams once a week (in total it took a year) , answering user questions along the way.

    The project itself was not intended to be commercial. My goal was to show in practice the complexity of game development, namely problems such as:

    • Project planning and prototyping
    • Thinking through and implementing the project architecture and its individual components
    • User Interface Implementation
    • Debugging and error correction
    • Working with assets and graphics

    At the end of the entire series of streams, we ended up with a playable prototype of a “survival” shooter. Those with a glass half full might even call it pre-alpha without a plot.

    If you are interested in the details of the project, stream recordings, sources, etc., read on.

    The entire project was implemented on a visual programming system called Blueprints. And of course, many specialists may call it childish; even a relatively large project can be easily developed on it. Moreover, this can be done relatively quickly, as we have already been able to prove.

    I want to answer the question right away: " Why Blueprints and not C++?". Well, firstly, when I started the series, I almost didn’t know the pluses. Although I would still make such a single on a power supply. Secondly, power supplies are almost as good as the pluses in our case, but at the same time they provide a number of possibilities: They don’t allow you to do many errors are possible with advantages, you don’t have to be distracted between BP and C++, it’s easier to understand for beginners. And in our case they are not much slower, given the fact that almost all the logic is built on events.

    We also managed to work a little on the graphics. Unfortunately, we didn’t have time to make assets, so we left some of them as dummies, some were made directly in the editor from primitives, and some content was borrowed from free Epic Games demos. Nevertheless, we managed to do some things ourselves, for example, a day and night system, post-processing for water and some materials for scene objects.

    The plans for my streams also included problems that may arise during development. I specifically solved them live in order to not only show what young developers might encounter, but also how to debug their code, look for bugs and write their code so that the whole thing could be done twice as fast. Of course, I don’t have decades of experience in programming, and this affected the sometimes stupid mistakes I made. And I’m sure that many developers can challenge many points in the process of writing a game.

    Naturally, this can hardly be called a full-fledged game, since there is no plot or goal in the game - only pure mechanics. However, I believe that the result is something to be proud of and that it fully reflects what the whole project was intended for.

    List of everything we managed to implement in our game

    Character

    • Character Control
    • Vital stats system (Hips, armor, stamina, hunger, thirst)
    • Switching view (first person and third person)
    • Model (made in Fuse, animations taken from Mixamo)
    • Customized animations of movement and weapon use
    • Universal interaction with objects

    Object Inventory System

    • Inventory component (embed into any object you want)
    • Cage system with support for different size items
    • Inventory size by cells per page and by weight.
    • A class of items that can be put into inventory. Items are stored as objects.
      • Weight, size, information, condition of item
      • Functionality for stacking (when there is a lot of one item in one cell)
      • Ability to add logic for using an item
      • Dropping from inventory
    • Interface for interacting with inventory
    • Interface for exchange between another component and its own.
    • Drag&Drop manipulation of objects between inventories and within one.
    • Context menu for items
    • Hints when pointing at items in the inventory and in the world.
    • List of generated items when creating an object with a component / starting the game.
    • List of starting items when creating an object with a component / starting the game.
    • Trading system between other inventory
      • Trading Interface
      • Money management component (required for trading to work)

    Equipment system

    • Equip several types of items: Hats, Top, Pants, Boots, Weapons
    • Skeletal synchronization of the Top, trousers and boots. (Hats and weapons by sockets)
    • Convenient window for equipment with Drag&Drop support
    • Support for modifier logic when dressing
    Weapon
    • Ranged weapons
      • Reload
      • Using ammo items from inventory
      • Support for projectile/bullet classes
      • Auto fire/single fire
      • Recoil with spread (own + depending on factors, e.g. running or squatting)
    • Melee weapons (with several types of damage checks to choose from)
    • Weapon condition deteriorates with use
    Crafting system
    • Crafting according to a recipe (I chose a recipe, it crafted, ala Fallout)
    • Crafting by items (threw in the necessary items, he crafted them, ala Minecraft)
    • User interface only for the second type of crafting.
    Aggressive mobs
    • Melee mobs (if they see them, they will run and start hitting)
    • Mobs of a mixed type (they shoot, but if they are close enough, they will run to hit)
    • Long-range shooters run around obstacles if they cannot shoot.
    • There is a built-in inventory for loot after a kill.
    • Spawn zone
    • List of classes
    • Spawn chance
    NPC
    • Town NPCs patrolling their spawn zone
    • Unique NPCs
    • Basic schedule controller for unique NPCs
    • Reaction to damage (run away or use existing weapons)
    • Built-in inventory for loot after killing.
    • Object Dialogue System
      • Dialogue tree
      • Every answer is an object
      • For each answer, you can add any logic or accessibility condition.
      • Dialogue interface
      • Several ready-made response classes (starts trading, takes resources, if any, exits the dialogue)
    Construction
    • Class of structures that support placement
    • Using resource items from the inventory when placing.
    • Snapping on some types of structures (e.g. walls, foundations, windows)
    • Menu with designs
    • Highlighting structures that have enough resources
    Additionally
    • A small map with a city, forest, bodies of water (you can swim).
    • Day/night system
    • Cars
      • View from the first or third. Common with the Persian
      • Turning headlights on/off.
      • Built-in inventory component (needs to be interacted with at the trunk)
    • Somewhat working vertical stairs.
    • Main menu
    • Pause menu
    • Graphics settings menu

    However, we can talk about the project endlessly. And in order not to turn the article into a book, I suggest you familiarize yourself with the game and its capabilities via video. And for those who are really interested, just below you can find recordings of all the streams, links to the sources and build of the game.

    Contents in parts

    1. We start and plan the project. We create the character's controls and behavior.
    2. Let's start making an inventory system.
    3. We continue to build the base of the inventory system.
    4. We are preparing a base for equipment and weapons.
    5. Working on weapons and using cartridges.
    6. We do auto-shooting and aiming.
    7. Creating a basic crafting system.
    8. Running, recycling items and wearing them out.
    9. We are implementing reloading for weapons.
    10. Making melee weapons.
    11. We finish the melee and make a ladder that you can climb.
    12. We make interactive objects: Wood, stone, bushes.
    13. We make a HUD and start making an interface for the inventory.
    14. We continue to work on the inventory interface. We generate cells with objects.
    15. We continue to generate cells and search for a place for the item. Adding inventory pages.
    16. We do a little interaction with items in the inventory and a detailed information window.
    17. Made Drag&Drop dragging items across the inventory and into another inventory.
    18. This part is about visualizing crafting.
    19. We create a window with a choice of the number of items from the stack to transfer to another inventory.
    20. We are making support for various crafting recipes, as well as fixing various bugs in the inventory.
    21. We are creating a system for changing day and night, and also creating a new scene for our project.
    22. We are starting to create AI for aggressive bots.
    23. We make an attack on mobs, as well as a reaction to an attack. Plus we implement the collection of loot from dead mobs.
    24. We are making a spawn zone for NPCs. We are also adding the generation of random items in the inventory.
    25. We are updating to 4.13, and also making long-range aggressive NPCs.
    26. Adding different elements to the HUD. Adding manual weapon reloading.
    27. We are finishing the support for skeleton clothes and hats. Adding animation for weapons in first person.
    28. We are making an interface for working with our equipment system.
    29. We are starting to create a trading system and a money management component.
    30. We continue to do trading by creating and customizing the trading component.
    31. We cancel the trade, and also set up the reload animation.
    32. We create a vehicle with our own equipment, headlights and view switching. Let's create a flashlight.
    33. We create construction (or rather, a system for placing objects in front of us).
    34. We make an interface for construction, we make a binding for walls.
    35. We create several more types of structures: Tent, bed, chair, table, lamp, door. chest, fire.
    36. Add a roof and windows. We complete the alignment relative to other structures.
    37. We make a small settlement, and also populate it with NPCs, which we also create in this lesson.
    38. We are starting to create a dialogue system for our residents.
    39. Setting up fog and post-processing. We import the zombie model and customize its animations.
    40. We are finishing the dialogue system.
    41. We make interaction with objects from a third person, as well as modifiers for armor.
    42. We create the main menu, pause menu and graphics settings. We are also putting together the first build of the game.
    43. We are implementing a schedule for unique residents. And also so that city NPCs run away from attacks.
    44. We are adding a context menu to the inventory, and also fixing some bugs in our inventory.
    45. We add recoil, spread, shot animation and the ability to hit for firearms.
    46. We will complete the aggressive and urban NPCs and fix various bugs associated with them.
    47. Setting up animations for the main character. Adding various clothes.
    48. We are fixing various bugs in our game.
    49. We are fixing various crafting, NPC and equipment errors in our game.
    50. We are finalizing the map a little and putting together the latest build.