[Twitch] Fortnite Developers Discussion - Apr. 17, 2014

Engine Questions

My experience with networking has been really positive. UE4 and Fortnite both have driven optimizations and quality-of-life improvements in the networking space that have been great to work with. In UE3, if you had a struct you were networking and any part of it changed at all, the entire struct had to be replicated. In UE4, only the differences have to come across. UE4 also adds fast TArray replication, better support for multicast RPCs, etc. I think the engine does a really good job of letting gameplay developers setup their code and content in a way that works properly in a networked environment without having to worry about the low, low level of network/socket programming.

Specifically re: blueprints, I’ve been blown away by how the engine team was able to expose networking functionality directly to blueprints in a way that is fast and usable once you know the concepts. I actually just did a 6-part tutorial on doing networking in blueprints that you can check out here: https://forums.unrealengine/showthread.php?2956-New-Blueprint-Networking-Tutorial-Videos-Posted As mentioned in the stream, definitely want feedback on these, ways to improve, etc.

For Fortnite in particular, because we have so many actors at once that are potentially relevant from a networked standpoint (enemies, players, tons and tons of building pieces), we actually are also using a new network optimization called network dormancy, that effectively lets us manually put various actors to “sleep” and wake them up for updates in our game. That one is definitely more of an advanced feature and something that I would expect the vast majority of games to never need to even worry about, but it is another new thing in the networking space.

The documentation and engine team are hard at work at putting together the C++ documentation for all of these networking topics, so they should be coming soon. Once they’re out, if there are still questions or concerns re: C++ networking, hopefully we can follow-up and get some specific tutorials in that space too.

We effectively use a “vanilla” version. The relationship the engine and our game teams have is very symbiotic and one of my favorite parts of working at Epic. Ultimately having a game in active development in the engine is probably the best way to test out the engine and identify which areas are working really well, which need improvement, features that we need, etc. When the engine team adds a new feature or update, they immediately get it battle-tested by a full game team in-house. They can observe how our developers use (or mis-use :p) things, areas the workflow isn’t as fast as it should be, and so on. Fortnite’s development has yielded numerous feature requests/improvements that wouldn’t be obviously needed until a game team was using the tools directly.

From the game side, we benefit tremendously from being able to work directly with the engine team. They can help us optimize things, figure out the best ways we should be doing things, answer questions, add new engine features that would help our (and others’!) game development, etc. It’s very neat to be able to be like, “Hmm, I have a question about how engine feature X works…I’ll just go ask the person who wrote it!”

On Fortnite, any time we add a new large gameplay feature, we always try to view it through the lens of “is all of this feature specific to our game?” If not, we try to intentionally split stuff out that would be useful for other developers and work to get that put right back into the main engine. Fortnite has been pushing RPG-style mechanics more than past Epic titles, so as our systems develop and mature for that, we’ve been moving or requesting pieces to the engine (example: the CSV/spreadsheet importing stuff mentioned in the stream). We tend to integrate the main branch and Fortnite branch at least once a week, so anytime any Fortnite developer modifies something in the engine, it comes back to the main branch within a week or two.

We do not use archetypes and I’m pretty sure that system is gone (I admittedly haven’t gone looking for it, so I don’t want to say that with 100% confidence right this second). Blueprints have basically entirely replaced that workflow for us in an amazing way. Virtually every spawned actor in Fortnite is a blueprint based off of some native C++ classes we wrote. All of our building pieces, characters, containers, etc. are all blueprints. We basically try to not directly hard-reference content in C++ and instead set all of those properties up in the blueprints. If we need scripting associated with an actor, we can just add it in the blueprint event graph. If we change a property in the blueprint content, it propagates to instances out in the level. Because blueprints are effectively generating classes under the hood, we also benefit tremendously from blueprint inheritance, where we can base one blueprint off of another, just like you could with C++ classes.

This one is probably better answered by the engine team, but the basic gist behind it is better support for multiple worlds existing at once, which allows for a lot of flexibility and neat tools in the editor (like each asset sub-editor in the editor could have its own world). In UE3, there was a global GWorld pointer in code that tried to juggle the currently executing world, but that becomes error-prone and messy as more and more worlds exist. The engine team has actively been working to eliminate usages of that for its removal and GetWorld() is a way to access an actor’s associated world without using it. For any actor that is part of your game session, GetWorld() should be returning your game world, but there are multiple worlds active in the editor, so not every call to that function you see will explicitly be the game world. I’ll see if I can get someone else to come in and explain this better if I massacred it :).

I’m definitely not the best person to answer this one. I’ll see if I can summon the AI team to get you a reply, but I do know Fortnite is making heavy use of dynamic updates to the navmesh as players place building pieces and destroy tons of actors across the world.

This is another one out of my wheelhouse. Again will attempt to summon a more knowledgeable source instead of ruining this question answering it myself. Sorry!

Hmm, this one is a little tricky to answer, partially because I’m not quite sure what kind of details you’re asking for. Do you mean starting from scratch, how do you go about making a game? Or do you mean what is our workflow in regards to like importing art assets, setting them up, etc.?

The generic answer here is we tend to brainstorm/design up some ideas we want to try and then go about prototyping them. When it’s early and we don’t know if something is going to be successful or not, we just piece things together with the bare-minimum prototype assets necessary to convey the idea and get people testing it, so we can iterate on feedback. It doesn’t need to look good, it just needs to work enough that we can tell if we think it’s fun or not. If you’re starting at the very, very beginning, it’s really important that you test and iterate on whatever the core mechanic of your game is going to be and make sure it is solid/fun, because that’s the foundation everything else is built off of. There’s definitely a temptation to start adding tons of features, mechanics, shiny art, etc., but if the core mechanic can’t hold up, you’re going to run into problems down the road.

The really important part of making a game that people tend to ignore or don’t want to face is that you need to be willing to work really hard on a feature and throw it away when it’s not working. This is why we try to do prototypes without committing full art, effects, etc. when we can avoid it. The more resources devoted to something that gets thrown away, the more expensive it was to make. Sometimes you iterate on something a lot, try everything you can think of, but when you sit back and look at it, the feature just doesn’t work in the game for whatever reason. Maybe it’s just not fun, it’s too confusing, it doesn’t fit in with the rest of the game, etc. You need to be willing to toss it in the dumpster for the good of the game, which is something that takes getting used to, especially when you’re really invested in a particular feature.

When we have something we’re pretty sure is fun and want to move forward on, that’s usually when we start involving the art team. Depending on what it is, a concept artist might draw up what things should look like, send it off to a modeler to actually make in 3d, etc. We’ll hook the art up, make the code or script more solid and shippable, etc., and move on to the next thing.

If you’re meaning specifically how to start the framework of a game in UE4, that’s probably dependent on your team composition and size. For Fortnite, we have a good mix of artists, designers, programmers, etc., so we tend to split things up where it makes the most sense for us. Our engineers start making custom C++ classes based off of the engine framework ones (game mode, etc.), designers/artists might prototype out some things we might want to try in blueprints, etc. A smaller team w/o programmers might just opt to start things in blueprints. It really depends.

If you can clarify your question a bit, maybe I can give you a better answer instead of this rambling mess of answer :).

Performance/Optimization Questions

I don’t think we’ve worked out the specifics on this just yet, other than “PC.” We know we want the game to be playable for as many people as possible, so we’ll probably be targeting mid-range PCs and up. The trick there is we want to be scalable, so the beefy machines can play all of the shiny extras we might want to add, whereas the older machines aren’t missing out on anything important to gameplay.

We basically approach things from the “don’t do things that are obviously so bad for performance this game can’t ship,” but we’re not down into doing tons of targeted, specific optimizations just yet. We keep tabs on performance trends of builds of the game over time so we know if we’re veering off course, but as we’re still pre-alpha, we’re very much still in “make this game as fun as possible” phase. In the future, we’ll definitely be doing perf./optimization passes specifically if we spot problem points. So far, working with UE4 for a PC game has been fantastic overall.

I’m not one well-qualified to speak to any rendering/art components of this question, but as mentioned in the earlier answer re: networking, we are using a network dormancy optimization to handle the sheer number of networked actors in a big scene in Fortnite. We also try to make smart choices when making our content, like avoiding making lots and lots of our code or blueprint actors have logic that executes in all of their tick functions every frame. Especially if an actor is ticking to only update visual things, we tend to shut ticking off on that actor when the visuals are finished, etc.

I’ll see if I can summon or Ori from the engine team in on this one. Fortnite doesn’t use tons and tons of physics objects as part of its gameplay. When our walls are destroyed (and the pieces fly off), that’s actually being done in a shader! Pretty convinced our tech artists are wizards sometimes.

Tutorial/Demo Questions

We’re a little too early to know on some of these things, but the short answer I can give is that I’m pretty sure a lot of the team is excited to share things when we can and time allows. I know I’ve already heard a few team members being excited about writing blog posts, etc. about how we’ve done some things. As I mentioned on the stream, we love giving as many tools/tips/etc. as we can for everyone to use, because it just results in more cool games/projects for everyone to play and see. So I guess stay tuned is the best answer on these ones.

Fortnite Questions

I’m not sure I know the exact breakdown off the top of my head. What I do know is that we’re still hiring people to help us make Fortnite as awesome as it can be. ://epicgames/careers/ Get those applications in!

Right now we’re focused entirely on PC and making that as good as we possibly can. We’re always listening to requests, feedback, etc. though and haven’t closed the door on anything in the future yet.

Right now we don’t have split-screen support for PC, but I imagine if we went to other platforms, we’d probably consider something like that again.

Misc. Questions from the Stream as I Remember Them

The cop-out answer here is that I think it’s easiest to learn through doing. Get your hands dirty, try some simple programs, make mistakes, and learn from them. When you first start, you’re going to mess things up, but that’s ok. I shudder to think of my first C++ projects when I was first learning programming. They were probably awful and full of problems, but were a valuable step towards learning! Hopefully the community can chime in with some good intro tutorials, books, resources, etc. to get you started on the way also.

One thing I would say is that if you want to be serious about programming in general, it pays to learn a lot of the basic concepts of computer science and programming paradigms, entirely agnostic of a particular language. Once you have a solid foundation, I’ve found it becomes much easier to pick up any one particular language, because then you roughly know what you’re trying to accomplish, you just need to learn the syntax/idiosyncrasies/way of doing things in that language. I like to say an experienced programmer can probably swap to a new language and produce a working program pretty quickly, but it still takes some time to learn a language in a way that you can appreciate everything it has to offer and how to program specifically in that language. Personal example: I knew C++ well before I was exposed to C#. I was able to make a C# program that ran and did what I wanted within a day, but it was still very much from a C++ programmer’s mindset. If you already know another language, there are often lots of online resources you can search for like, “C++ programming for ____ programmers,” where you’d sub in the language you know.

For context, my personal learning path with all this stuff was me fiddling around with programming in high school on my own, taking some courses in high school (I think in PASCAL?!), and then studying computer science in undergrad, before going on to grad school. In undergrad, we did a lot of C and Java, with only a little C++. I mostly self-taught myself C++ from reading various websites and books in undergrad and then learned a lot more/had knowledge reinforced in grad school by excellent professors. In terms of language references, I learned C from the K&R book, which is super concise and considered the book about C: ://en.wikipedia.org/wiki/The_C_Programming_Language , and I learned a lot of C++ from the Stroustrup book (://en.wikipedia.org/wiki/The_C%2B%2B_Programming_Language), but as mentioned on the stream, it is very thick and can be quite dry at times, so I’m not sure it’s the best intro book. If you want a super technical manual all about C++ though, it’s a great source.

One final point I’d make here, if you’re learning C++ or programming for the first time, don’t set yourself up for frustration by jumping right into making a massive AAA-game right from the start. It’s important to learn the basics of programming, how things work, etc., and it’s easier to do that with a simple project first. Once you have the foundations under your belt, the rest will come. Again, from my personal experience, my first ever “game” was tic-tac-toe :p. I worked my way up to pong, simple maze games, etc.

Ok, thx for the info :smiley:

Ok, whew, I tried to go through and answer most of the original round of questions to the best of my ability. The answers overflowed the amount of space a post allows, so I had to split things up. Thanks again for everyone who participated!

Ah, so many other replies in the meanwhile too! You all are fast! Thank you for all the nice comments everyone, we really enjoyed ourselves. Ever since you encouraged him, Matthew has just been practicing even more dad jokes, and he, Cameron, and I all share an office, so thanks a lot for that…:stuck_out_tongue: Cameron has also been fulfilling his promise of providing no updates on his newly formed twitter, so I admire his dedication to his cause.

Evenios, I’m sorry the format wasn’t your cup of tea, but I will pass along the feedback that some people might prefer some visual aspects too. We’re not always going to be able to make everyone happy, but we’re always open to suggestions for how the livestreams would work better for the community.

, thanks a lot for taking the time to write such detailed answers and for answering my questions. The livestream was very informative and enjoyable. You all seem to have a great time at Epic. Working at such a cool place sounds definitely enticing. I still have to finish up my masters though :slight_smile:

Currently there’s no built in system to do saving at the level you need for a game like fortnite. Fortnite built a custom solution, on top of some features in the engine that can be used. We’re going to work on a comprehensive example of how to build a save/load system, but it isn’t ready yet. I’ll make sure to let people know when that information is available. There is a Simple Save Game system that works really well for simpler games, there are some questions on AnswerHub that go into detail for that system such as this one.

For fortnite, we assigned each of our objects that we wanted to save a custom GUID, but other UE4 developers have used a similar system using just the object’s full path, as that should stay the same. So, you have a system to identify an actor uniquely. Then, we’re using a system built on the SaveGame property flag to actually serialize the actors. If you set the ArIsSaveGame archive flag on an archiver, it will only serialize properties that have that flag set on them. Some of the basic properties are set this way in the engine, and you can then tag your game specific properties.

So, you need to set up a savegame archive. For fortnite, we’re using a proxy wrapper based on the Objects-as-strings proxy wrapper:


struct FFortniteSaveGameArchive : public FObjectAndNameAsStringProxyArchive
{
    FFortniteSaveGameArchive(FArchive& InInnerArchive)
       : FObjectAndNameAsStringProxyArchive(InInnerArchive)
    { 
       ArIsSaveGame = true;
    }
};

Then, you can use that proxy archive to serialize a record for an actor or object you wish to. Here’s our save code, that writes to a simple struct that has the actor’s class, transform, and a TArray storing the bytestream:


ActorRecord->ActorClass = Actor->GetClass();
ActorRecord->ActorTransform = Actor->GetTransform();
 
FMemoryWriter MemoryWriter(ActorRecord->ActorData, true);
 
// use a wrapper archive that converts FNames and UObject*'s to strings that can be read back in
FFortniteSaveGameArchive Ar(MemoryWriter);
 
// serialize the object
Actor->Serialize(Ar);

And here’s our code that restores that actor:


AFooActor *NewActor = GetWorld()->SpawnActor<AFooActor>(ActorRecord->ActorClass, TempVector, TempRotator, SpawnInfo );
 
FMemoryReader MemoryReader(ActorRecord->ActorData, true);
FFortniteSaveGameArchive Ar(MemoryReader);
NewActor->Serialize(Ar);

This works well for actors that are self contained, if you have references between actors you can fix those up inside the archive handler, and if you maintain the object’s full path before and after they should hook up automatically, if you do a two step process where you create every actor, then in a second run serialize the records on top.

Hey everyone, glad you enjoyed the stream. I’m Ben, and I’m one of the tech leads on Fortnite. I thought I’d chime in with a bit of extra detail on a few of the questions answered, I think he did he a pretty good job eh? :slight_smile:

Fortnite scenes have a LOT of actors, but we don’t really use Physics in the sense of doing proper Physics simulation. In this random scene I just opened up we have around 7000 building piece actors. As mentioned most of our physical effects are done in shaders for optimization, and we use things like Projectiles (Shootergame has some good examples) for other things. We need to keep the state on the client and server tightly in sync, so we avoided using proper physics simulation.

Each of the building pieces (a wall, a floor, etc) is one actor, with one static mesh component so they stay really cheap. We use network dormancy to keep them cheap for replication, if you run the command SetNetDormancy you can put an actor to sleep for the networking system, and if you use SetActorTickEnabled you can put it to sleep for the tick system. Then, whenever the player interacts with a building piece we “wake them up” and spawn various additional components on demand. This keeps things cheap in the default case, but lets us make the entire game world interactive.

Hi Kain,

You can mark pieces of navmesh as “areas”, either with volumes or by having navigation relevant actors supply appropriate data. Areas have flags and cost associated with them. Regarding cost you can override default navigation query filter to supply alternative area entering and traversal costs.

When supporting multiple agents types you can also consider using multiple navmesh instances.

We do have a concept of “navigation link” which describes discrete traversable connections on navmesh (like jump-down location). Special subclass of these links, called “smart navigation links” (wink-wink) can be toggled on and off at runtime…

But that’s not what you’re asking :slight_smile: Rotating bridges or elevators could be supported by simply rebuilding navmesh at runtime. Of course done when the bridge or elevator stops moving. Navigation on platforms at move is not supported at the moment, but I imagine the low hanging fruit solution would be similar to what we did in Bulletstorm where we simply had a separate navmesh instance hard-attached to the platform. No worries, super cheap memory-wise :slight_smile:

Like mentioned it’s one of the things that’s happening all the time in Fortnite. At the heart of our navmesh generation lies modified Recast library. Recast, for those that don’t know (shame on you! :wink: ) is a fast-navmesh-generation open source lib. Our modifications made it even faster to the point where runtime building of big navmesh chunks is not a CPU killer, and Fortnite takes a full advantage of it.

Navigation system in UE4 has been created from scratch, to utilize new technologies and gain both speed and flexibility.

You can but not out of the box. You’d need to recompile Recast lib with navigation filter’s cost function marked as virtual… But you probably don’t really need that! :slight_smile:

We have a sophisticated, data driven system for spatial reasoning. Go ahead and look up Environment Tactical Querying in UE4 sources. It has lots of advantages over using goal evaluators and path constraints like UE3 did. Performance, flexibility and readability are the main ones.

None, to my knowledge. Which is not necessarily a bad thing :wink:

Cheers,
–mieszko

Thanks for all the awesome Q&A-ing guys. It’s really nice that you aren’t just leaving us to figure the engine out for ourselves, getting these tips straight from the devs is great. Looking forward to the next stream! :smiley:

Personally I found it all rather entertaining and the only thing that could have made it better would be

  1. Women.
  2. Zak after consuming vast amounts of alcohol

P.S. Women of course just to get the female perspective on gaming in general.

,
Thanks for the fireside chat last week! I just wanted to pass on to you that I have been doing some work with the folks over at Mixamo and they were very happy to hear Matthew’s comments on their animation website. Simply put, it made their day! I can tell you that they are very interested in putting together animations or an anim set that works with the Unreal engine. If you or Matthew is interested I can give you a contact at Mixamo to help make this happen. Just send me a private message.

Hey Demolition Man,
Thanks for the info. Yeah, I’ve already been working with the Mixamo crew. Exciting stuff coming down the pipe!

Hey Ben,
Sorry this is a bit of a thread resurrection. I’ve been using the two step save/load mechanism that you describe and it has been working great the last few month. I noticed after the jump to 4.8 that when I serialize the records over top of my created actors as the final step that my dangling pointers no longer hook up correctly. Were there any changes that you guys had to make based on the thread safe Serialize effort that came with 4.8?