Async Loading Screens and Transition Levels | Unreal Fest Europe 2019 | Unreal Engine

Just another WordPress site

Async Loading Screens and Transition Levels | Unreal Fest Europe 2019 | Unreal Engine

>>Axel Riffard: Welcome to this session My name is Axel, and actually this morning, my throat and voice decided to give up on me, so sorry if I crack up But it is actually pretty cool, because you can make things like [distorted voice] I’m Batman Okay, so we will be talking today about how to make smooth transitions inside of Unreal Engine 4 We will cover different approaches for both solo player games and multiplayer games I am French, but actually, I have been living in Japan for more than six years now I work at Epic Games Japan Before joining Epic, I shipped a couple of Unreal Engine games I have worked on series, including Naruto or No More Heroes, so if you have played some of them, thank you My work at Epic Games is a Support Engineer What that means is, basically when one of our licensees has a problem using Unreal, beta feature, a bug, or just wanting to get the most out of our tools, and doing things for profiling and optimizing, we help them It can be made online using UDN, as I am sure many of you guys use Or, we can actually go to your site and help them right at their studio That is something we can do in Japan, because pretty much every game company is located in Tokyo, so it is very easy to move In my spare time, I have been learning Assembly, because I was not listening in school I was playing Monster Hunter on my PSP, so I kind of regret it now But, yeah Actually, if you are very serious about how you are fetching instructions to your CPU, I would highly recommend Assembly, at least to understand it It will really help you to debug things on a very low level In my spare time, I am also playing Kingdom Hearts III, which has actually been made using Unreal Engine 4 in Japan by Square Enix, it is an amazing game Actually, I think it is probably the best example of how I can really scale Unreal Engine to AAA, or as in this case, credible A games It is a pretty cool game, you should definitely give it a try Let us get started What you will learn in this session: Well, first of all, we will be talking about something I really love about the Unreal Engine, which are modules Everybody should use modules We will also be talking a lot about threads, about multi-thread, about how it is being handled inside of UE4, and how you can leverage them to make beautiful and smooth loading screens Also, we will have a quick overview of one of my favorite functions and features inside of Unreal Engine, but it is not so well known It is called Seamless Travel, and it is really a life saver when you want to do some smooth transitions inside of a multiplayer game But at the same time, what this session is not: It is definitely not a deep dive into how threads work inside of UE4 — 45 minutes would never be enough to do so It is also definitely not a full tutorial on how to build a loading screen inside of multiplayer games Basically, I have made these slides not for you, but for me, for me two years ago when I was working on a game and my manager told me, okay, you are going to be making the loading screens for No More Heroes I was, like, okay, sure I will Google some documentation, and I am sure Epic will have some cool docs, right? It turns out it was pretty scarce Actually, this is exactly the kind of starter guide I wish I had two years ago, when trying to tackling this problem I hope it will help some of you guys First of all, we have been talking about the solo player approach, so asynchronous loading screens We will be talking about many concepts, but first of all we should have a quick introduction about what is multithreading, and how is it implemented itself in Unreal Engine? To keep things very, very simple, it is obviously not this simple really — multithreading — it is basically just the ability to make multiple calculations on the same processing unit, but depending on hardware, so on the type of CPU But also on the OS layer of the system, multithreading can really mean a very different thing When you are making a multiplatform game, you really have to understand how multithreading is being handled by every platform, otherwise you will get beaten very hard Always test very fully every asynchronous code, and for every platform that you are shipping on But inside of UE4 — so multithreading, actually even if you have never used it,

you are actually using it because Unreal Engine is using threads very heavily It can have, channel even 15 threads running at the same time I think the best example of it is when you are using the common stats unit, and when you get your top right corner of your screen you have there, with the frame, game and draw, but you basically get all of the performance of your frame rates for your game Actually, Game and Draw mean Game thread and Draw thread You can obviously add as many threads as you want For more regular and basic asynchronous task in the Engine, I will recommend using and searching for FAsyncTask inside of your source code Definitely put a few break points inside of how it is being implemented inside of the Engine It is very useful Now, about loading screens — well, what is a good loading screen? First, I would say it is short, but not too short, though I do not know about you, but when in a game, there are hints displayed in a sentence, and actually cannot even read through the end of a sentence, but the loading screen is already gone — it pisses me off You should have a timer in a good loading screen logic, right, to be able to manage at least the number of seconds the loading screen has to be displayed A good loading screen would also have good performance and be smooth By this, for example, if we have a spinning animation, so like this, let us say it is running at 20 or 30 FPS, this is decent, this is probably enough for a loading screen But on many games, what you see is actually that, right, running at maybe 4, 5 FPS You might say that is not really relevant for just a spinning animation But I personally think that loading screens are a good opportunity for your artists to shine, and to maybe show cool, concept arts about the World of your game, or about showing a video in this case Well, good performance is actually very relevant, so you should have good frame rate inside of your loading screens Now, about how it is implemented inside of UE4 First thing you have to know is that all of the Level Load operations that can only be made in the main thread is kind of counter-intuitive, but what you have to do is actually create a new thread to display the UI of a newly-created thread, to make it a loading screen, and do all of the Level Load operation on the main thread But do this in background When it is done, you can bring back the main thread to a full round, and do all of the Assets loading using FAsync Task This is what it looks like This is for ActionRPG, which we are going to talk a lot more about in the next slides On your title screen, you press Start Game What will happen then is, it will actually create a new thread, displaying the loading screen, and you will push this newly-created thread in the foreground Well, you do not display the main thread anymore In the main thread, you will do all of the Level Load operations When it is done, you get a notification kicking back in and saying, okay, I am ready Then you can stop displaying the newly-created thread and go back to the main thread, and to your new Level Yeah, we will be talking about ActionRPG It is actually a very great example for this kind of threading logic But not only for that, it is actually the Epic way of making games We obviously cannot share with you guys the source code of Fortnite, but still, we wanted to share how we are making games at Epic We are using exactly the same design choices for ActionRPG that we are actually using in Fortnite You should definitely check it out, and really studying the source code, and how we are handling everything in ActionRPG It is free for download in the Epic Games Launcher, but just make sure to go to the Marketplace tab and not the Learn tab, otherwise you will not find it This is what it looks like You press the Start Game button, and you can see on the bottom right corner the animation is actually very smooth You get good frame rate, so it is doing all the Level Loads in background in the main thread When it is over, you could go back, and then, boom You get the Levels from it again You are on your new Level This is what is happening As you can see here, what is important is that first, never, one single call from the game module directly to the Engine It is using an interface This interface is inside of a module that you are going to create from now on This is, I think, the best way to have as less side effects as possible

Basically, your designers will only be calling it in the Blueprint, or maybe C++, and then the programmer who will be in charge of loading module can really talk to the Engine, and nobody else does Now, how to use it? It is pretty simple In the case of ActionRPG, for example, in the GameInstance Blueprint, you all know the open Level function, right? Before that, from now on, you would only have this fade in and show loading screen function call, which is actually only one call to a Blueprint callable C++ function, which is called Play Loading Screen, which is the one we are going to make It is very easy; it is just basically one call to make before you open Level, so nobody can miss that, right? Just one tip — actually, on purpose, I have put as the Level Name arguments of upper Level, just do a Level to load string — this is very bad Never do that You always want to use the absolute path for the Level Main Assets, otherwise it will loop in all of your Level Assets, and is very bad for full performance Always put the full path of Level Asset I have seen this many times, and it is like something that could be fixed in a few seconds Sorry for all non-programmers people here — now I will start the programmer’s talk We will be talking about modules first Modules, you have to understand that it is really a fundamental building block of Unreal Engine Actually, everything in Unreal Engine is a building block Everything in Unreal Engine is a module, including the game, the game itself is a module You can add as many and you can edit as many module as you want, and this is what we are going to do Modules, they have a few merits First of all, you can split the logic between the game and loading, in our case, for loading screen module What this means is, when you get your engineering working on the Level part and the other one working on the loading part, when there is a new bug in the game, there is very less chance that it will have an impact on the loading This is also true the other way around It is also very easy to manage, and by that I mean that especially source code-wise, when you have just one person working on the feature, you will have less conflicts when submitting your code It is a lot of time that can be gained It is also very portable Most of the time it is overlooked but shouldn’t be I mean, how cool can it be for you making your game with Unreal — You are shipping, it is selling well, you have a party, everybody’s happy But at some point in time, you will have to make a new game How cool could it be if you could just pretty much copy-paste everything you have made as logic for your past game, and just change the Assets and be able to use it in your new game? That would be pretty kick-ass in my opinion It is actually a lot of time that you can gain Also, it is something that I was taking care of, and I know how tedious of a task it can be, is about updating and merging Engine releases First you think, okay, it is going to take me two or three days, and after two weeks, you go back to your manager, and you are, like, facepalming and say, oh man, I am never going to — it is just a mess Yes, it is Probably never be an easy task, but there are ways that you can make this easier, is by actually editing the Engine as little as possible If you are explaining all the logic you can inside of modules, it will actually make things a lot easier, in my opinion Last one, I think that using modules is actually very black box Actually, when I was having the rehearsal of this talk back at Epic in Japan, my colleagues told me, and they were right — oh, man, you should not use black box We are all about giving our developers the source code and always be very open — this is a very negative world, and I fully agree Black box is negative But it turns out when you are actually making a game, not everybody wants to know what is happening I personally think that actually, it is not the Engine and the programmer are actually not making the game, they are just giving the technological and technical support to the people making the game, and we are the artists and the game designers Actually, on a day-to-day basis,

you just want things to work You do not want to always know how everything is working, but at the same time, you need to be able to understand when needed I think this is why modules are really great It is just like a black box, but you can actually dive in when needed To that extent, I think black box is actually a very good thing We will cover the implementation now About the folders — nothing fancy It is just that you have got your Project folder, and after you get your source In the case of ActionRPG, you get the Private with implementation files, and the Public with the headers You will just be adding a new folder for every new module, with some C Sharp files for Unreal build too If you want to check the implementation, you can just download ActionRPG; it is very straight-forward One thing though, it is about how modules are being loaded inside of the Engine Because we are making a loading module, it has to be initialized before the game, because you cannot possibly have loading kicking in even before the game starts This has to be defined This is actually defined by an enum inside of the Unreal Engine, called ELoadingPhase:: Type Just look for it and see all the options you have I think for loading screen, the one called PreLoadingScreen, which is the one right before default, which is the game one, is actually the best How to do that, you just open the UProject file with your favorite text edit tool, mine is Notepad++, obviously You just change default to pre-loading screen, and you are good to go Yeah, nothing fancy Now we will be talking about the code itself The interface is pretty straight-forward, nothing fancy, only for functions, Get, a Start and a Stop You cannot really make things easier than that, right? Boom, done The implementation now — so the implementation of the interface child — I will not look at the three functions, we actually will be doing that later But just see that we are only really fitting some arguments, which is something called, on the last line, the MoviePlayer This is the important line inside of this function Otherwise, it is just very basic initialization The big part, actually, is the UI The UI, we are going to be using Slate Who has ever used Slate here? Cool Yeah, actually half, or something. Cool Slate is a custom UI programming framework designed by Epic Games for Unreal Engine, and actually, the Editor itself is made using Slate Nowadays on the recent releases, we are pushing lots of fancy stuff You can use Python, you can use Blueprint, you can use UMG But I personally think that low-level stuff, C++ is actually very efficient, and should definitely be used for this kind of system-related functions This is what the widget will look like for Slate It can look actually quite old, it is like some CSS styling weird thing But when you look closely, for example, what is happening in the ChildSlot or even the +SOverlay::Slot, this kind of thing, you only see that a lot in C++ — but when you really look at it closely, you can see that it is perfectly correct, C++ For example, the plus is only an operator overload If you are used to using styling languages such as CSS, actually in a couple of days you can really be a master of Slate For once, we actually have very good documentation about this feature Some are made by Epic, some are actually made by some other folks, maybe some of you guys You can also shows on YouTube and everything; my personal favorite is actually on the Unreal Engine Wiki, it is called Slate Hello, so check it out Now back to the implementation of a module logic You can see a Start, Stop, and a Create Once again, nothing fancy The only real important lines here are the GetMoviePlayer Yeah, that is pretty much it Actually, now you may be starting to think, okay, man, you show me this as an asynchronous thing, but you are actually not doing — you have nothing asynchronous there But it turns out that we are The reason is that

Slate is actually running on a separate thread For people interested, it is actually using RHI To get an idea of where it is actually being threaded, it is MoviePlayer It is running on the Slate thread If you do not believe me, you can look for yourself inside of a MoviePlayerThreading.cpp file, and I personally think that it is a great example of how you should create and add threads to a threads Array inside of the Engine We will just have a look at the initialize As you can see, we are actually creating a new thread, pushing it on the threads Array This will be a runnable thread, right? Boom, there you go Smooth loading screen, maybe you can do this Okay, let us call it five days of work, and you are done for all of the projects of your company I think really, there is no excuse of not making good loading screens that is for a solo player Yeah, definitely check out the ActionRPG Now we will be talking something actually very different It is called Seamless Traveling I have worked on several multiplayer games, and I was not really aware of this feature until very late in production, but it is a real life saver when you know how to use it What is it? Well, it is a way to move from one Level to another in a server-client relationship-based game You are coordinating needed data from the server What is important is that it is non-blocking What is happening is that when you are actually loading the new Level on the client, you are in a Transition Map where it can do things It is like a regular map, but only you can use it as a loading screen, it is pretty cool Actually, you have another very good benefit using it, is that you can determine by yourself which Actors you want to keep and which ones you want to let go and be garbage collected This is what a typical server-client relationship looks like A server wants to move to the new map, so it will send signal to every client, saying okay guys, time to move Client will still be on the old map, and when the loading is done — boom You get a notification back to a server saying, okay guy, okay man, I am ready to move When all the clients async the single, you are moving to a new map This is how we are handling things in Unreal Engine, pretty straight-forward But what would happen in a non-seamless travel, which is the regular way, is that every time, you are moving to a new map You have a full disconnect and reconnect to a server This is really non-efficient That has some merits, which are that you have a clean slate every time — pretty cool for your data But you can, actually, you should know how to handle your data and Assets You can really do way better than this performance-wise This is what Seamless Travel is It is like this in-between state You actually have a Transition Map, and you have no disconnection from the server, so you are always connected to it Just everybody is moving along, it is pretty cool When to use it? I would say actually as a rule, you have to be the other way around — when not to use it You should find a reason not to use it, and not a reason to use it, because it is so easy But still you have got some limitations inside of Unreal about when you actually cannot use it by design — well, when you have your first load inside of your game, so when you are going to the first match of your multiplayer session, well, you cannot use Seamless Travel The reason why is that you do not have a server, so, yeah It is also true that when, for some reason, you actually have a disconnection from your current server and you are switching servers You cannot use it for these two times, and otherwise use it as much as possible Now let us have a quick overview of how it works To activate it, nothing can be more simple It is just you have Integer, it is called bUseSeamlessTravel, and just by 1, and you are good to go You will also need a Transition Map First, what is a Transition Map? It is, as I said, a Level between the old and the new Levels It is basically made because there is a design limitation inside of UE4, is that to keep Actors, you actually need the World The easiest way to have a World is to have a Level

This is why Transition Levels exist But actually, it is a great opportunity to make, I do not know, things such as a mini-game, or just having maybe in a very simple map the ability for your player to move, or something You know, if you have to wait for 20 seconds for every client to move to the new map, you should at least be able to wait almost 20 seconds in a funny way But definitely keep this Transition Map as light as possible, otherwise it would kind of defeat the purpose Personally, I would not use sub-levels, but let us say by designing your game, you are using sub-levels to split, I do not know, something like Blueprint and lightning and geometry, for example I think this is a very good idea But still, for Transition Map, what you would want to do in that case is, in the persistent level, load all of your sub-levels by default at start of a Level, and not doing it in Blueprint or C++ Actually, many games using non-Seamless Travel are using a simplest Transition Map possible, which is like this It is blank, there is nothing This is also a very good Transition Map The whole point of a Transmission Map is actually to keep your data alive, so if you do not intend on creating a mini-game or something — I think you should — but if you do not want to, is cool, too Why should you define it? It is in the Project Settings, in Map and Mode You see in default maps, the last one is called Transition Map, so you set your Transition Map here, and you are good to go Now, what the whole data flow will look like, using Transition Map? First, you are going to mark what Actors you are to get Then you are going to move to a Transition Map; this will be handled by the Engine, actually, you do not have to do anything Then, when you are on your Transition Map, I would definitely check that all your Actors are alive and well When it is done, and when everybody has a new Transition, well, then you can move to a new map I am talking a lot about keeping Actors alive But so you know, by default, using Seamless Travel on the server side, you have GameMode, you have GameState, and all the controllers with a PlayerState, what are, by default, being kept alive You also have every local player controller for both clients and the server But actually, you can really add as many as you want, it is pretty fun On the server side, it is in the GameMode base, and you get the Get Seamless Travel Actor’s function As you can see in the bToTransition, if we have the Actor list and we are adding stuff there You can add as many stuff as you want here, it is what it is made for On the client side, it’s defined inside the Player Controller You get the same, it gets Seamless Travel Actor List, and then you get your Actor, as you can see where it is just an Array of Actors Everything you put inside of it will be kept for the new map But please, please, please — do not edit the Engine for that You want to override You want to inherit and do this locally on your game There is no reason why you should edit the Engine for this You just override it Do not forget, you called it Super, and then you can edit the actual list as much as you want There is no real drawback to Seamless Travel I think that, as once written in a great comic book, you just have — great power comes with great responsibility Let us say that you have really bigger power over the life cycle of your data, well, then, you have to be careful about using it It is just about always searching, always checking, life and death; making sure that [inaudible] that could happen to me Yeah, just always be very careful about checking the life of your data, and you will not have any problem Also, that is actually not really related to Seamless Travel, but it is more about working in general — it cannot be debugged inside of a PIE It is kind of a mess, but it is how it is Personally, when I was working on multiplayer games, what I would do is, on my PC, I would have three or four instances of Visual Studio running I would have pre-cooked all the Assets of a game I would actually run the game in debug, or whatever, using the game arguments on the same machine

Then you can use all the break points and everything inside of your Visual Studio When you are used to it, it can be — actually it takes some time to set up — every time you have to debug something But it is actually quite efficient, and you are closer to real game performance than PIE, so it actually has merits A few final thoughts — well, in a multiplayer game, you still have single player loadings, co you can definitely apply the things we have looked at in the first part of the talk Also, I personally think that good loading screens will make your players more forgiving about slow server connections or slow performance, or even if you have got big Textures or big Assets to load If you are loading screens are traditionally that good, your players will probably be happy with that Okay, thank you! [Applause] ♫ Unreal logo music ♫