Unreal Engine 4.21 came out of Preview recently. As usual I dive into the release notes and see which parts most interest me. This time I figured I would share some of my thoughts on this release and provide additional notes and results from my initial experiments. I only developer on PC/Console so I am skipping any mobile specific changes (4.21 specifically has a lot of Mobile improvements due to Fortnite’s mobile launches) So Let’s dive in!

Game Packaging Performance

Cooker Performance has been greatly improved (up to 60% faster which sounds pretty incredible) which is entirely transparent and you don’t need to enable any settings for this to kick in. I ran a quick comparison with ShooterGame for 4.20 and 4.21 which is about 1.3GB in cooked size and contains about 1.000 files in the Content folder. The cook was about 30-45% faster in 4.21 running on my laptop. (Don’t take these as hard numbers as the tests were done under non-ideal circumstances and your mileage may very)

There are multiple mentions of Cooking performance improvements in the 4.21 release notes which is great and doesn’t require anything from us to take advantage. Small projects will likely see little to no difference in performance overall.

Gauntlet Automation Framework

Another big feature is new Gauntlet Automation Framework which entered early access. While it has been instrumental in optimizing Fortnite, Epic has stated it’s not quite production ready. At the time of writing there is very little to no information about this new Automation Tool unfortunately. This means we’ll have to do some digging of our own.

The release includes two tiny files which give some insight in how to use this new framework

(UE4.21/Engine/Source/Programs/AutomationTool/Gauntlet/Unreal/Game/Samples/ElementalDemoTest.cs and ./FortGPUTestbedPerfTest.cs)

Keep in mind that it’s more than just a performance measuring framework and can be used to unit test many other things like gameplay logic, running automatic multiplayer tests and checking API return values (aka Unit Tests).

One very interesting feature of this framework is the concept of “Nodes” which lets you run multiple clients and servers easily. This is quite important test multiplayer performance and functionality without requiring many people or machines to manually connect and test.

I’ve tried to run the new framework with the Elemental Demo, but unfortunately at this time it does not work. I ran this demo specifically as it has the Test file as you can see above (ElementalDemoTest.cs) and it even includes some Blueprint nodes as you can see in the image below.

The nodes basically work as follows, you start the profiling. You take several snapshots at an interval or at key positions of a session and finally you end the snapshot to collect the data. This data is then available to check the “health” of the project.

Example of Elemental Demo Performance Report

Physics Interface Changes

The Physics Interface update deprecates the “Async Scene” (which according to Epic was only supposed to be used for APEX Destruction) and introduces a new Physics Interface rather than direct PhysX calls. This mainly affects C++ users that deal with physics directly. Read up on the Technical Notes for the physics changes if you want to know more.

New: Added DDoS detection/mitigation, for non-NetConnection UDP packets

DDoS Detection and Mitigation is listed as a new way to detect and mitigate your game servers from being flooded with packets from unverified sources. There is no mention in the release notes on how to use this new feature unfortunately, but a quick search for “ddos” in the source does provide some clues. See DDoSDetection.cpp for more commented details.

This is not a full solution against DDoS as a heavy attack against the server can still bring down the hardware itself. It’s an application level measurement only. (Again, the comments in .\Engine\Source\Runtime\PacketHandlers\PacketHandler\Private\DDoSDetection.cpp help a lot in explaining the system)

The new system is disabled by default and can be enabled via the config files in your project’s DefaultEngine.ini. The defaults in BaseEngine.ini are:

[DDoSDetection] bDDoSDetection=false bDDoSAnalytics=false DDoSLogSpamLimit=64 HitchTimeQuotaMS=500 HitchFrameTolerance=3

I have not had a chance to test this out myself, but this may very well be an important feature for most multiplayer games. If someone has an easy way to self-DDoS for testing purposes please let me know in the comments!

PSO Shader Caching

The cache system should allow us to reduce load hitches by letting the engine gain a better understanding of how materials/shaders are used in your game. This is a manual process where you package the game, play through the levels and then use the gathered PSO data to inject this into the next package.

The tooltips of the Packaging settings do indicate that it will reduce deployment sizes but might increase load times. I don’t know if these tooltips are not outdated (as I know these have existed for a while) but it’s something to keep in mind.

There is a step-by-step guide available on how to generate and inject the PSO shader data on the Unreal Docs Pages. Unfortunately I have not been able to successfully gather PSO data as it crashes on the gathering step with a packaged build.

Update: Turns out this feature is not intended to run on DX11, but should work on Vulkan on Windows.

AI: Made UActorComponent.bCanEverAffectNavigation configurable via ini files so that it can be change perf component class project wide.

“Useful if you want only deliberately picked components to affect navigation. This also allowed for some optimizations in SceneComponent resulting in never calling PostUpdateNavigationData for components that are never nav-relevant.”

A small improvement, but good nonetheless. I often find myself running into objects that shouldn’t affect navigation meshes but do so by default (eg. weapons in the player’s hand) to which I then need to per-instance disable them depending on the setup.

New: Reduction is now allowed on Static Mesh LOD 0.

Epic’s implementation of poly reduction produces incredibly impressive results. It’s great to have this now available on LOD 0 as you don’t always get the most optimal meshes imported into your game, especially when dealing with Marketplace assets. The function is available under “Reduction Settings” in LOD0 of the Static Mesh Editor properties panel. Try it, and you’ll be amazed and the results with little to no visual loss in quality.

New: AutomationTool now accepts values for its -client and -server parameters, letting you have multiple Client and Server targets per-project.

“So if you have ClientA.Target.cs and ClientB.Target.cs, run UAT with -client=ClientB to make a build of that variant. If there is only one target of a particular type (true for all projects up to this point) UAT will detect and use it. If more than one target is found, you must specify which one to use.”

This ties in with the new Gauntlet automation framework and is most likely a result of Fortnite’s mass scale multiplayer testing. As I haven’t been able to properly run Gauntlet I don’t know how well this works either, but letting us run automatic multiplayer tests is pretty neat and a good one to keep in your pocket for when Gauntlet is more stable.

New: Added a new Blueprint node that can be used in Editor to export the landscape heightmap to a render target.

The node is called “Landscape Export Heightmap to RenderTarget”. There is also a variation for Weightmap export which takes the LayerName to bake out. I don’t do much with Landscapes at the moment, but this sounds like it could some in helpful in the future.

New: Added new “net pktlossburst=x” debug console command. It will drop incoming and outgoing packets for the next x milliseconds.

“…and is particularly useful with the “setbind” command to debug issues that only occur under packet loss.”

For the duration of the burst it will drop 100% of the packets. Keep in mind that the X parameter is the duration of the loss, not the amount of loss as with the “net pktloss=” command. This command doesn’t show up in the autocomplete when testing in ShooterGame and 4.21.0 which makes it an obscure feature until fixed.

New: Total packets sent/received, total number of bytes sent/received, and total packets lost both in and out are now kept track in the net driver.

In 4.20 there are already stats available for packet loss per second etc. This adds the session total for loss and total sent which can be helpful in tracking overall health and load of your networked game. Inspired by this change I have built a widget and debug graph to track packet loss etc. I’m sure regular readers of my blog will see this appear at some point in the future.

New: Steam can now query various different types of friends list, bringing support in parity with other platforms.

Haven’t been able to try this out yet but found a new enum related to this to access different Friend lists in 4.21.

namespace EFriendsLists { enum Type { /** default friends list */ Default, /** online players friends list */ OnlinePlayers, /** list of players running the same title/game */ InGamePlayers, /** list of players running the same title/game and in a session that has started */ InGameAndSessionPlayers, };

New: UE4 now defaults to symmetric mouse horizontal and vertical sensitivity. (Previously, pitch was 70% less than yaw.)

This one of those hidden changes that could have a big impact on your game’s feel. It affects the configurable variables InputPitchScale and InputYawScale inside PlayerController.

[/Script/Engine.PlayerController] // New 4.21 Values (BaseGame.INI) InputYawScale=2.5 InputPitchScale=-2.5 [/Script/Engine.PlayerController] // Old 4.20 Values (BaseGame.INI) InputYawScale=2.5 InputPitchScale=-1.75

New: Extended VisLog’s functionality with a way to log arrows and to mass-log boxes.

Visual logger is an often overlooked tool (with little documentation to be fair) that can be incredibly helpful in debugging the decision making over time for AI or any other kind of gameplay execution. It logs data in 3D on a timeline that can be scrubbed and log both text events and draw a bunch of primitives to visualize your gameplay logic.

New: APlayerState now maintains a reference to the Pawn it controls. APawn::PlayerState is now private and setting it will update APlayerState’s bi-directional Pawn reference.

“Use GetPlayerState and SetPlayerState to access / manipulate.”

This change is useful as prior to this it was a bit more obscure how to fetch the Pawn reference in the PlayerState. You could grab it via GetOwner() which was a PlayerController and call PlayerController->GetControlledPawn. Having a more clear path is a small but good change.

Networking for large-scale games

Replication Graph is a feature for big scale multiplayer games and is primarily a CPU optimization on the server side. The system allows you to cache which replicated actors should and should not be replicated currently based on the locations and state of the clients, this allows for re-use of the computed data instead of re-calculating for each client connection.

As with many advanced features, Epic’s ShooterGame sample project has an implementation example available which is worth checking out. The code is available in ShooterReplicationGraph.cpp and contains some pretty deep documentation to show how the system can be used.

Particle Editor Improvements (Niagara)

Niagara has seen further improvements, the most notable being it’s now easier to create new emitters and systems via Templates. This should make it easier to start experimenting with the feature. In 4.21 Niagara is only available in a Plugin, follow this link to enable it and get started. (It’s not available in the Editor/Project settings at this time)

I’m hoping to see more interesting community tutorials and examples soon, most so far are mainly focusing on “Spawning 1 million particles” which isn’t what makes Niagara so great. It’s the new UX and amount of exposed data and incredibly deep customization over the current Cascade that will make this tool truly next-gen. Senior Technical Artist Jonathan Lindquist occasionally posts new demos for Niagara on his twitter and I recommend checking those out.

Unreal’s Cascade is really showing its age and I am therefor excited for Niagara’s future. The extensibility and emitter re-use alone is something to be very excited about.

C++ Transition Guide

As with every new version that comes out for Unreal, Rama started a C++ Transition Guide on the Forums to discuss C++ API changes and help you upgrade your project.

Closing

And that’s all for Unreal Engine’s 4.21 release! If you feel like I skimmed over a particular feature, let me know in the comments! I know there are a LOT more changes that are useful but some are simply transparent and nice to haves while others change how we use the engine and are worth highlighting. Follow me on Twitter for more Unreal Engine 4 and Game Development related stuff. And subscribe below to receive new blog posts as they are released.

References