[Music] Hey so okay when Mike's working great good morning everyone thanks so much for showing up so early and welcome to day one of the main conference if you've been to the summit's over the past couple of days I hope you enjoyed them and welcome to those of us those of you just joining us today before we start I've got a couple of messages to pass on from the CAS so the first thing is that if you can check all your phones or tablets or whatever are set to silent or are turned off the second thing is that about 15 minutes into this session you'll be emailed a link to an assessment form if you can really try and give any feedback on that it is super useful the speaker's get to see it and it's just incredibly appreciated if you could fill that out okay so let's get on with the top I'm in it's Mackendrick and I'm a programmer at a little UK indie game company called hello games I've been there for about five years now and so I joined just
before we released Joe Danger to the movie and then have been working on sci-fi exploration game no man's sky for about four years since then so I started on that project really near the beginning when just four of us went and shot ourselves away in a little room in the office right through to shipping and now we're continuing to work on updates because we're quite a small company and and just because it suits me as well I'm a bit of a generalist as a programmer so I've worked on a number of areas across the project so early on I worked on a bunch of engine related stuff I've touched a whole load of the prop gen content so things to do with foliage placement some texturing some model composition I've also done some work on the visuals for example the atmospherics the water rendering and I've been involved with a whole bunch of gameplay related programming as well so this talk is going to kind of reflect that it's going to cover quite a lot of content across the board of the game so this
talk is about continuous world generation in no man's sky and what I mean by that the technical architecture of the game is the code that lets us generate and simulate this world in real-time as the game is running but what it really means is here's our story through a bunch of the really interesting and exciting problems that we got to solve while working on the game and some of the aspects that make it a bit different to a lot of other games that are out there in terms of the the technical problems we got to work on so to give a brief summary of what I'm going to talk through first I'm going to go over how we structure the world how geometrically we build our planets on spheres and how we transforms about how we work with voxels then I'm going to talk through our generation pipeline I'm going to go through step by step the process of how we create world in real time what's involved in taking an area of terrain and creating that through
from being an empty space to something that we can render and play on the threading the parallelism and ordering issues to do with that and finally I'm going to talk about our simulation itself the special considerations that we have to take because we're working on a game that's generated in real time and occupies a space bigger than we can know a lot of information about I think to understand the reason behind a lot of the technical decisions that we made on the project you have to know a bit of background to it and to the team that I'm working as part of so people probably know no man sky is a sci-fi exploration game but for those of you who aren't super familiar with it it involves the players all starting on planets spread out across a vast galaxy and you can take off from those planets and fly continuously and land on another piece of terrain and the simulation continues throughout that so so much of the tech is focused on
that core design decision hello games itself is a small team as I said we started off with just four of us working on the project the three programmers and an artist and we've we've grown and changed sides a little bit and know we're affected at around 20 people for the time being and that's about 10 programmers code heavy and five artists and on our team that size I mean everything is hard and everything has to cut you know shipping a game shipping a dick disk-based game with 20 people is was a real challenge I think it was a real achievement but I'm super proud of but also it means when it comes to the work our artists are doing the work our coders are doing we have to be really careful about what we take on every asset that the artists produce has to count for so much more than the work they're doing it has to have a real meaning in game and every technical decision that we take on as programmers has to be really pragmatic we can't read of an R&D team to to go off and play with a lot of things for a long time so
we had to be really careful about our progress through the project in terms of our philosophy as a company we're fairly fast and iterative and that's one of the benefits of being a small team I guess is that we can do that and it's a really enjoyable way to work but it meant we could come across problems find our way through them and then see if there were other design approaches and other technical approaches that we could lead off from that so we had fairly flexible design goals as well we'd be really driven by people playing the game rather than by some solid design document laid out for years before the project as I noted we have to make the most of our artists but that doesn't just mean making the most of the content they produce it also means generating content in a way that they have real control over and that's something that is sometimes missing when people talk about prop gen they talk about replacing artists and hopefully through this talk you see that that's not our philosophy at all we want to to be able to enable our artists to produce more rather than
replacing them with an algorithm that doesn't quite do the same job to give a bit more detail on our text so we work on our own engine and that's written in C++ which is kind of inconsequential probably but it's the first question in rumson to ask so I put it on there if we had to make the decision of what engine to use now I think that's a way less clear-cut thing so you have to remember that we made the choice four years ago to work on our own engine at the time when there weren't really major voxel-based projects that has a lot of visibility that we could see in unreal in unity so the sort of taking on an existing engine and having to optimizing that and having to work with walk so thin that when we probably wouldn't have source code access we wouldn't have a lot of support with a really daunting task whereas our own tech we know what's going on there you know we know we have a lightweight renderer we know what we can do to it we know the sort of time might the might be involved in expanding and improving that so I'm not necessarily saying it's the right route for everyone to go down for there it was the right choice for us at
the time for sure we ship simultaneously on PC and ps4 and we just worked simultaneously on both platforms throughout development which again as a small team is a tricky thing to do just getting test coverage on those kind of things is an interesting problem as the focus of the talk implies we use run time generation but that has a number of really interesting consequences for the problem for the game and for tech problem solving within the game so any generation that we do because we're producing this vast amount of content it's more than we can store offline is more than we can load into the game so we're generating at runtime and that gives us performance constraints on all of the generation work that we do that we might not face if we were able to bake out a load of textures rather than generating them as you warp into a system or bake a set of terrain rather than generating it in regions as you move around that's really you know the significant bulk of the work that I'm
going to talk about today the other thing that comes from that is that we have to be able to simulate gameplay with only a small knowledge of the world so if we're generating this whole planet and that's a bigger space than we can really get much information about at all you know we can maybe know a few points of interest but beyond that any kind of data we have about it is too much data for us to keep in memory and for us to argue about all the time so any work that we do have to be able to work just in its own local space without knowledge of whether there's a lake over that mountain whether you're at the highest mountain that the planet or just a mountain and that's a really significant thing to keep in mind I think as I'm talking through this a final note is that our engine is really agnostic to procedural content I think people sometimes talk about Nolan Skye is the procedural game and I'm not sure that's the right way to look at things for us our engine doesn't really care whether we generate the content online or whether we loaded it or where it comes from at all to be honest you know
a texture is a texture and does that's a really significant and useful thing to say and it's a useful thing to say about the game as well the players shouldn't necessarily know whether your texture was generated or whether an artist created it the sheer size of space that we're working with implies we have to generate content but I guess one of the the end goals for a lot of proxy on work at the moment would be that you can generate this massive space that you can create a load of content that would be indistinguishable from something that an artist is also directly so like I said to start with I'm going to talk about structuring our worlds working with our spherical planet so to understand our simulation process you kind of have to know how everything is laid out in this way and also it's just an interesting problem that we work through is one of those things where I say we're dealing with planets in space we want you to be able to take off and land on them and everyone has an opinion about how we should have done this and we have a lot of opinions too but we work through a
number of different things and I think it's probably interesting to talk through the different approaches that did and didn't work for us so our driving design goal is that ability to fly off the planet fly to another planet fly back but it's also that we have distances that have meaning to the player that we're simulating a large enough space for some of those to be significant to them so we need to simulate a space where someone walking around the planet if they want to walk to the other side that should feel like a really weighty and significant thing for them to do or if they want to fly around the planet or ship even that should take a significant amount of time and again that changes the way that we work with things we want our players to explore to feel alone and that that needs those distances to be suitably large so like I said we went through a few iterations and here's the first one so our first driving goals we essentially thought of this problem like you being a sphere which is an annoying problem you know if you've had to UV
spheres then there are a bunch of issues there with poles and things like that but our our first consideration was that we wanted to have a flat plane for the terrain to exist on we wanted to simulate on the next airplane and the way that you typically typically were then again have that flap have the y-axis always be up because that makes things a lot simpler not just for simulation but also for generating our terrain there's no complications about distortion because you're just generating it in a really continuous exed space so what we did was we took this plane while you're on the planet and we let you explore it infinitely so if you walk along in the x-direction forever we'll just keep making terrain over there and in same if you walk in the Zed but the moment that you leave that planet will take whatever space and terrain you have and we'll just wrap it around a sphere and we'll wrap it around with poles that are placed as far away from the player as possible so that the the kind of pinching that you'd expect
to see on the poles when you wrap a flat texture to it would at least be as far away as possible and we handled that in the shader so those spheres in space are all actually entirely implicit but of course there are some problems with that so you can kind of see the pinching as a bottomless screen shot this must be one of the oldest screenshots that we have of the game is pretty early on you can kind of see the pinching at the bottom some distortion there and that's not that bad but the thing that makes that really bad is that you're moving around continuously so you get some swimming coordinates on the sphere and a really the really significant problem for us was that you end up with some impossible places on your flat terrain that you can't possibly map in a useful way to the sphere so if you have these points of interest maybe you want to share them with other players you know because we have some networks aspects that use that then they can't possibly have the same point because the way your sphere looks depends for you takeoff drama or where you come into it also our infinite
generation has precision issues and all you can fix that by wrapping all of your generation functions you know we could have interpolation between noise or come up with a new noise function that handles it that tends to be more expensive than the generation we were already doing and cost was a major factor so I'd consider this a kind naive approach but at the same time it would have been workable I think you could take something like this and probably ship a game using it but it wasn't the right one for us so the next thing we thought about was like well a lot of people have been thinking about mapping terrain to spheres and to flat planes for a really long time so we should look at cartographers and what they're doing so I went through the Wikipedia list of all the good map projections and tried to find the ones with the least distortion because if if you've ever experienced you know the cartography community you've probably heard people complain about market or projection which is fair for you know if you came from Greenland you probably know why that's bad so we tried to look
for ones that would be more appropriate but generally there weren't solutions there that were useful to us a lot of the transforms were either expensive or really expensive to invert so we need to transform from our flat plane to our sphere and back very often for like loads of vertices or loads of points so that wasn't really an option and some other are some other techniques that looks promising are really designed for the planet Earth so that image on your left yep had to check what was left I think is a pure screen conceal projection I don't know how that's pronounced because I've only seen it written done but that really only works if you have oceans in kind of the places that Earth has oceans and becomes pretty useless when you generalize that to arbitrary planets that we were generating so we gave up on this one as well and moved on to the scary approach that we have been trying to avoid and in some ways this is the simplest approach but it's the one with
a wide ranging number of consequences for us so that approach is just to run our simulation on the sphere so other coordinates are nice and consistent within our solar system you can be standing on the planet you can be standing on space and you just have this 3d continuous court coordinate system so that's that's nice in terms of gameplay but on the other hand this complicates all of our gameplay coding because know whenever you stand on the sphere you don't know which way up is you have to do that calculation all the time and if anyone is like a programmer in the room you're probably thinking us and my gravity is always going towards the center of the sphere or if you're a graphics programmer in your shaders you can never simplify anything to be 2d around your world you're always working on this curved plane so it has knock on and just about every area of code that you could think about it makes it more difficult to integrate other people's libraries because they're going to assume that you have an axis that's consistently up I will be really excited to one day work
on a project where I always know what up is and it's the same thing but it is it is workable though because you know it's a simple calculation to do you know calculating your your up vector from your position on a planet is is just considering your position relative to the center so it is cheap and simple but there's a second problem that makes that gets in the way just about all the time when you do things and that is the hairy ball problem so this is a really intuitive theory and that's that if you if you take a sphere and you imagine it's really hairy and you try to comb it you can't have continuous hair around that without having singularities about having little licks you know picture that so you can't have continuous tangents around your sphere so that causes problems with lighting with normal mapping all the time and various other places for you don't really think about the fact that you need to use tangents that are in a continuous space but suddenly when you don't have them then it's really obvious where we can
mostly counter that by using projection onto your sphere from three planes but try planar projection in some places or a long single plane in other places or we can use local mapping where maybe our tangents won't be deterministic but they will be continuous we can just calculate them from the first point we reach the planet and then move them continuously from there so it's definitely workable and it's you know what we stuck with it's just interesting for new people joining the project the thing about the other thing but spheres is they're not a really great way for us to store data generally if we have something like voxels or any other data structure we want to store that in contiguous and cube based system so we do store data on a cube we do a projection from her sphere to a cube so we simulate everything on that sphere when it comes to to store a box or data we're mapping that onto a cube and you can kind of see in the sphere in a diagram how it just about maps to the
face of the cube you can see where the vertices match up there hopefully you'd think that would cause a lot of distortion so if you imagine that we're generating terrain on one of these when we project to the other then we're having some distortion in the size of the the polygons were generating or the space of the voxels take up and but it's generally not a huge problem because if we generate all our terrain and do most of our work in simulation space and then only map it to a coupon restoring it then it's just that the density of voxels or the space that that data is able to take up that's lost so for example it means in some areas we'll have a mountain that's composed of a lower density of voxels and another one they'll maybe be slightly lower poly but that's probably not noticeable but we want to have mountains that become half the size or something a question I get sometimes is why we didn't just stimulate on a cube but having edge cases at corners literal edge cases in your world seems like a nightmare to
deal with you know having testers come back with problems that only occur in very specific places on your terrain so simulating on the sphere seemed like the right way for us and that sphere to cube transform that's really super simple so we can we can do it just by calculating our high offset above the planet projecting that down onto the sphere just by normalizing that direction and multiplying it by radius and we can calculate which cube face were on just by taking the absolute value of the largest direction so this is a really simple bit of code to write and it's really cheap and we can do it all the time without having a load of concerns about the fact we're working in two spaces at once and our result is it's not on the face of a cube that's the other thing to note is we're when I say we're working on the sphere we're not working directly on the sphere surface we're working on you know a height map or some terrain offset from the sphere so we end up with some space offset from our cube at the other end and going along those lines that means
we're only mapping a limited space offset from the sphere because the further out you get from the surface of the sphere intuitively the more distortion you're going to see so if you imagine the point to the center of the sphere versus the point to the center of a cube that's going to be infinitely small and spyro's you can make it up of a number of regular voxels in the tube and if you progress along that you can see the distortion gets worse and worse as you go inwards or outwards from your sphere so we can only simulate a limited space and we choose about 128 meters of height for the sort of voxel data that we store there which isn't enough I mean 128 meters gives you some little hillocks maybe is not it's not particularly interesting it doesn't give us the kind of deep oceans that we want or the high mountains so what we do instead is we add this elevation data we add it into our transform so rather than considering considering the radius of our sphere to be consistent we choose it
we consider it to be varying based on noise over the surface of the sphere so we have an offset of about 600 meters to a kilometer which allows us to get really high mountains and deep oceans up to that and then still have our 128 meters of voxel data offset from that that's really cheap and we can also cache the results for the local area or in so the one where we're doing those transforms then it doesn't cause a problem either and that's kind of how it fits in with our transforms so really all we're doing is calculating a single point of noise every time we call this transform and then at the other end we're projecting that down still onto our non elevated surface of our cube so working with voxels I've mentioned voxels a few times let's go into some details on how we use them so we consider our voxels in chunks we have regions and some time being I'm just talking about the nearest Lodge where Oliver voxels are one meter cubed so we
take all these regions and we process them individually and each one comes out to be a single single area of terrain our regions are 32 by 32 by 32 meters in games but we need some additional voxel data there so we need one row of voxels around the edge that we can polygon eyes safely because we're creating vertices in between eight of our voxels so we need that extra space to get to Philly fully cover the area but in addition to that we want two polygons eyes a little bit outside each region and have some overlap and that discovery as far as seams between the terrain due to precision issues so in the end we end up polygons izing an area that's about 36 by 36 by 36 voxels and their individual box voxels are about six bytes so we have two bytes of density data applied for by each for two different materials that are made up of soar voxels tell you that they're made of grass or rock or mountain or sand which we need in texturing and placing things on them
later and we have two bytes that tells us the extent to which something is rock or grass versus the other materials that it's made up of so we retain these in memory right throughout running the game so there's definitely limited quantities that we can store that's just to let us do really quick terrain edits and we do height tests and other tests against the voxels fairly often so if you're supposed to keep around but it would be possible to discard it and load it again similarly it would probably be possible to compress it and we just haven't done that because it's an expense and also because compression is a lot less effective than if we have something like Minecraft where your voxels are binary 1 or 0 because we have varying density data and we we want any compression that we do to be lossless so it's probably something that we'll look at in future as we try and regain more memory from the game to put in new features and fill it with other stuff but for the time being is just uncompressed in memory of course our 36 by 36 by 36 meter regions
we can only have a limited number of those they're taking 4 amount of memory so it's pretty obvious that we're going to need to deal with mods especially since we're flying off to space and back so we want to have a bunch of these that'll be quicker to generate and what we do is simply subdivide our regions done so we deal with 6 logs each one being twice the size of the left and again we still have that overlap of the edges so our lower log terrain has half the densities so it's going to be lower poly is going to be less interesting but we tend to match up at the edges just by polygons izing a little bit over and we tend not to get holes between between loads and is far enough from the player that you can't notice that you're going from a lower density to to a higher one directly in most cases the other thing is that we reduce density within those regions so again just as a memory saving thing and based on you know a visual decision of what looks acceptable to us
we we reduce the density within that so our lower logs are actually 36 by 36 by 36 voxels we might have that reporter that and we tend to do it in the height a lot more than in the X and said just because that looks okay we can get away with reducing the data there the other thing is we're splitting these boxes done and these regions done by half but we only have this 128 meter just area to fill so we have four regions two stacked on top of each other you know at 32 meters in the nearest logs but quickly we start having to do that and when we get to lower logs so the point there is that really quickly we end up with lower logs that are incredibly cheap which means we can have close to a high density voxel data and far away from us really low poly data that fills in up to the horizon and we store those in an octree where you know binary subdividing things it kind of makes sense in maps well it lets us keep up to date with
where our reagent are as we move around the cube and it's really quick to find lots of regions when we're within one of them or want to look up one of them the thing to note there is that our cube is actually around the surface of a cube so we have our octet the region's though exist our ones around outside the surface so when was projected to from our sphere to our cube and we have the data existing outside the edge of the cube that also for exists in the octree those get even low resolutions those get pretty expensive and we can't cover one of our large planets with even our lowest lava voxel data so we also have a much cheaper low voxel odds they dispersed on it we have a high octrees that exists one for the whole solar system and we just swap it between the planets transfer cancel creating regions as we need to as we move around but we also create just as you fly into the system these low density voxel spheres
they're just two voxels high so there's really very little data there at all they're they're pretty cheap and we just generate six separate polygons Ice Cube faces that map onto our sphere and that gives us those planets in a much cheaper way from any point in system all of the time okay so next I'm going to talk through our generation pipelines to how we fill in that voxel data what we do with it once we've got a whole load of voxels and we need to render it and turn it into a game we we play so we do some generation at load time well there's kind of a hierarchy of where you want to do your generation so ideally if we could do everything offline that would be super cheap in the game but we can't so we do as much as we can a load time and then we do what we have to as the player is moving around so the kind of thing that we can do at load time sort of rendering some procedural textures loading any vertex data that we need in order to create models but creating the terrain itself because there's so much
of it we can't generate a whole planet we have to do that continuously as we're moving around as the player is playing the game so we just do it in in the background along with things like texture streaming so here are stages that we go through so we have our voxel region and we want to take that through to something that's playable we go through the following stages so first we generated that's filling in the voxel data from noise until we have our completed density data for that region we polygons eyes it so we have a vertex mesh we then spherify it so we've done those two stages just in as a voxel cube and we then stare five at vertex data so that will fit on our sphere planet we then construct a physics mesh we construct like a nav mesh for creatures and then we finish off by covering that region in plants and creatures and buildings gameplay and thing that we need to make a playable so of course if we're going to do all the stuff is we're moving around
we have to do it using a we have to do it off the main thread and we do it using a job system so threading in our game is relatively simple we have a main update thread and a main graphics threads and we have a sync point each frame for those and we try to make the terrain interfere with that as little as possible as we're going around on PC all these jobs are handled on the CPU but on ps4 we do some of them in compute shaders are so to see how our threading kind of works in terms of all the other numbers points we can do in jobs and then all of the other points are a point where we have to interfere with the world so at some point we have to get hold of a vertex data buffer to fill in at some point we have to add our physics to the main physics of the world we have to add all our creatures and position models and things like that but almost everything else we can split off and just run as a job and of course what that means is we have all these voxel regions round about us and we need a tactic for ordering those jobs I can
kind of show that filling in here so this is this gif is pretty much real-time run on my laptop before and I think it's loud loud too so maybe the second farthest away mod from the player so you can see we're dealing with a lot of regions each one of those little squares is a region that we're creating and you can see it filling in in real-time so when it goes again you'll see each of those regions flipping really quickly through a number of colors and that's them going through their generation polygons ization all of those stages the way that we order those is based really highly on visuals there's no real driving factor aside from what the player experiences and what they see so when those regions are going blacks that's them being filled in by a mirror log so we're able to fill in this low LOD real quick and then we start to bring in more detailed terrain over the top because that's the most beneficial to our player we generate using a point based system so the stuff in front of us we go now generates first and then the stuff around about us
spreading out from the camera so now we've seen how our region's progress through the steps I'm going to talk about the steps in a little bit more detail starting with our terrain generation I'm not going to go into loads of detail on all our noise based techniques but Shaun Murray is giving a talk tomorrow at half five and that does just focus on terrain generation and the specific mass and noise techniques of that so you should go to the pond so it helps hear when we're going to talk about generation to have a bit of an understanding of how we look at generation in no man's sky in general so we see generation as this top-down approach always you're always feeding data through one generator coming up with some more data feeding that into the next generator and just doing that continuously until you end up with what you want so in the case of terrain we're starting by knowing which solar system we're in and we know that by a
positional seed we feed that through and generate some info about the solar system how close the planets are to the Sun what kind of sky it has for the atmosphere is like and then we can feed that data through to each planet along with the planets position basic seed generate some information about whether it should be rocky or cliffy or cliffy I don't think of the word but it has cliffs you know or have mountains or oceans and we can feed that through into our terrain generator which will then come out with the voxel data that we have and this is this might seem like a really trivial thing and it is it is simple but it is really important because the significant part here is that any point in between those generators we have a piece of data we actually have it mostly as XML data that we can write out and store so when it comes to debugging these processes that's usually useful because anytime that we see a bug or something we can step into this generator at as many different levels as possible to see what might have gone wrong we can load up future data to check that we can we can
see the same things again we replicate the same problems and we can store past planets and load them again to check for you know performance degradation things like sorry alright so with that in mind when it come came to writing this particular generator the generator that would output our terrain which is you know one of a number of generators long with our texture generator and model generator so I'll just independent things that are taking data as input and then putting something that we can use in the game or something we can use in another generator so we have a number of requirements that we've set up for writing that the first is that it has to be direct and consistent and that comes back to what I was talking about at the very beginning that our artists or a designer needs to have control over the output and they need to be able to to work that out from the parameters that they're going into it actually in the case of the terrain is largely shaunt of
the person that wrote a lot of the generation techniques that's actually set up the parameters but he still needs to be able to sit separate to being a programmer and fill in those values and get some meaning from what he's writing there it needs to be real time of course we need to generate this as the game is running all the time it needs to be varied so the output space should be large so we want a load of different terrains and we want them to work you know and not have holes in them but to look different to the player we want to create things that are both real-world and abstract shapes we want our whole system to be adaptable modular easy to add to and then there's a final point we want our generation to be data local and that's the kind of interesting and tough point in all of this so if we're generating a single voxel it can't know anything about any of the other voxels round about it is stateless so it can't know whether it's halfway up a mountain or at the top of the mountain aside from that it is a mountain that has you know maybe 50% of a mountain and that becomes
a real problem when you want to to mattify like water flowing and things like that so that means we have to look at generation techniques that look as though they've evolved over time that look as though they know information about next to them we have to model erosion but you don't model erosion as the process of eroding you model it as the end state of all those things you model something that looks like it has eroded over time so to break that down to how we actually do it let's start with 2d terrain generation and so our first stage as an optimization more than anything else but also because it simplifies things conceptually is to block out some shapes in 2d so we'll split areas into mountains into maybe some smoother planes down there there's a river on there and and this doesn't come out as voxel data this is just a series of values that are saying the extent to which this this voxel is a mountain or is smooth or as a river so it's a much larger amount of data but only retaining
it for a short period of time until we go on to 3d generation and we do this essentially for each voxel column so if you imagine we were generating on flat plane it would be across the exed but because we're generating on the sphere then it's across the the surface of our sphere but without any height so what what comes out of this is like generating a height map you know without any overhangs or caves we have the height of hills things like that so to step through how that looks so we have our terrain there's no noise it's probably a real boring game and then we generate our elevation so that generated this noise like I said in the same way as anything else so what you can really see here is that our elevation data is really low in interesting points it's just some really smooth noise which is why it's really cheap and we store that at this point into a 2d array so that'll be cheap to look up later as well and then we can start to add some 2d features so this is our height map that I was talking about
with our overhangs or caves but with some points of interest there's some rubble in there there's some noise this is generating without thinking too much about materials at this point I'll talk about that later which is why it's all flat and Sandy and brown but we've got pretty far just talking about our distorted height map but we want more interesting terrain we need those 3d shapes that's why they come on to next so our 3d terrain generation works in a really similar way to our 2d you know in that we're layering purlins or simplex noise or other direct techniques like some Voronoi noise or cellular noise and but in 3d and we're having some turbulence on there in positions and that creates nice like pinching shapes and things like that and the the the significant thing is that if you generate a 3d noise field and polygon eyes it what you'll tend to see is like blob data in 3d you'll have big floating islands there won't be any meaningful shapes like hills or mountains so we have to we have
to fade through that and try and cut off the floating islands which we do just by reducing the density by height as you move away from the surface of the planet and that keeps us with nice mountains and Hills that can't possibly have a high density when you go up high if we didn't have one lower done and like I said we just write this out into our our cube space for the moment but we're generating as though we're on a sphere so each of those voxel positions I'm showing it as a cube but then we're we're mapping it here we're generating as though we're on the sphere and that avoids our distortion so here are some some 3d shapes that we've created we've got some purlins worms going on there and those are just some Perlin noise that was threshold on it so we can take a slice through that noise and get some cool-looking 3d shapes the blue thing that you can maybe see there is some good noise so a nice technique that we do is we consider a grid over the surface of our terrain and we just pick
some of those points to put some shapes in we can put in cubes or more distorted and more natural-looking spaces just spaced out periodically and that's really useful for something like terrain resources we let the player in mine resources from it and we have real control over how often they show up so this was really useful but we don't just do additive techniques we also do subtractive so we can generate caves and things by again taking those purlins worms but subtracting them from the terrain and considering the mouths of caves to be big open spheres and things like that just to try and build up our toolbox of techniques that we can apply to try and make a diverse range of terrains so all right after going through those steps that leaves us with our our region that's made up of boxes and it's just a load of essentially density data it has some information on materials as well but the density data is a significant thing from which we have to generate our colligan grids we use that using dual contouring we started out with marching
cubes and probably on the left note the right your left your right as a yellow diagram and you see the typical marching cubes sort of diagram so when we polygon eyes in this way the significant point of this is that if you imagine you have your eight bottles you're creating polygons between them marching cubes will only create polygons that lie on the edges of those so it's really bad for creating corners it loses a lot of data to do with shapes when you have really sharp angles so that's why we moved to using your contouring and there's some really good information on that not just on the technique but on other isosurface techniques as well just in the bottom link there which is where that leftmost diagrams from and that shows how we retain the corner data we do have to do a little bit more work on that to avoid corners that lie way outside of our cube we have to consider math points and things but is it's basically pretty simple to work through some of the code and gets us away nicer results and that's what gets us for
example the hills in this image but the thing we do with our voxel data is we don't just polygons eyes at once we polygons eyes it through different polygons eyes errs to get different sets of data so looking at the cubes in this image we also do a cube based polygon Iser to get these nice terrain resource indicators and that's more similar to the way in which something like minecraft polygons eise's so it tends to be vertex heavy but it's quite cheap so we're just considering any point considering the faces around it we consider if there's a fine difference so if you have a dense region with a non dental on next-door through mountain with air next to it then we just create a flat plane there and we can build up that cube data fairly easily but like I said is quite vertex intensive so we only do that in near logs words will generate the actual terrain as far as you can see and finally we have our third super cheap polygon Iser which is just a flat plain polygon Iser for the water surface the point to note on this is because we use elevation then
sometimes we're generating water planes that are way above where our voxel data exists so we're not just generating within those regions we have two polygons eyes across the in sort of a planet to see whether we should be putting water there I think in future we'll probably move away from polygons izing water will probably do it entirely implicitly in a shader but for the time being we've still got there running all right so moving on from that to how we actually get our terrain looking like an interesting terrain that's not all flat brown and sandy like the one you saw before so when we polygons eyes we don't just create our vertex positions we also output normals and we choose to retain two normals a smooth normal and a face normal and they're the only reason to do that is visual is just a visual decision that we've made the smooth normal we use for texturing or it's the face normal we used for lighting and that gives us a slightly low poly look but lets us get continuous blends across the surface and we just store that octahedron encoded so we can stick it in effect for and we
also store our two materials so before I was saying that in our voxel data we have two materials and when we polygons eyes we're not just considering a single voxel or polygon our vertex comes from the eight box was round about it so we're losing some data there is it would be really nice if we could afford to store a whole array of different materials that are voxels could be made up of in the vertex data and use that to texture but it just wouldn't be performing so instead we have two materials and the blend value between them so the voxel will be whatever it's made up of most of so grass and rock for example might lose some data that also we would like to blend a mountain texture in there but generally look okay and then we can use that to try planar texture or sphere so basically if you haven't encountered try planar texturing that means taking our texture and projecting it along three accesses with a lens own as is incredibly badly
circled on that diagram so the thing to know about that is we are in fact projecting across the whole sphere so we're not projecting on an axis that's local to a bit of terrain it's across our entire planet what you would think would have really bad artifacts in some areas you think that blend zone would be across an entire region of the planet surface and we'd have an area where we're blend in between two textures in a really ugly way but actually we find that wasn't the case just because of how our terrain is shaped we tend to distribute those blend zones across the whole planet fairly fairly easily we tend to come up everywhere but not be overwhelmingly ugly to look at anywhere and in terms of the texturing what we're passing in is basically a height map there so I said that our vertex data had those materials in the blend value what that actually means is that we have an atlas of textures that relate to those different materials and we choose those and blend between them based on a height texture and and that's just an artist created
thing we recolor it in the game but it's an area where our artists creating something really carefully really outweighed trying to synthesize these textures the other thing to note is that we apply these textures at two different scales so we have a lower detail texture and mapped over a much larger scaled higher detail a higher size texture and we just continuously replace those as you fly away from or towards the terrain so far from the planet you'll see the same texture but at a much larger scale and when you zoom in close then we'll continuously replace and half those sizes and replace them done until we have our two scales of texture still and that helps us with our terrain blend as we fly into the planet all right so we have our terrain we have a textured off in our shader is polygons eyes we can we can render it but it's not very interesting we have to do stuff to it for it to be useful in the game so a real important point is that when you're
generating your terrain and gain your work isn't just generating that terrain things that you'd normally baked offline for example physics or navigation meshes you also have to calculate as jobs in real time and that takes up a way more significant chunk of our times and actually generating or apologizing the terrain and the the first step in that is placing a bunch of objects and again that can end up to be quite a significant cost is something that we do in compute shaders on ps4 and the basic approach is really similar to the noise that we're using for generating the so this is kind of a top-down of view so hopefully you can see the kind of green bits or graphs and there are some rocks and plants in there and you can kind of picture quite quickly that that might have come from some simplex noise something like that and we're just placing objects at with cutoff at the highest point and we're also using applying an additional layer of noise that just cuts down on the density to kind of really quickly give us control over the spacing that we want the
driving factors here are artistic and this is something that Kate Compton talked about before is that if you ask an artist then if you if you have a tree that's kind of nice you can have a tree on the terrain if you have a tree with a small rock next to it or a small bush that's much nicer and if you can work all the way down in scale recursively continuously the more stuff you adds a nicer kind of get so let's have a tree with some bushes with some small plants with some pebbles at the bottom and we start to build up our terrain in a nice way so there's noise based technique is our way of doing that we additionally use an offset grid and that's just similar to the terrain based techniques that I was talking about before so that we can place gameplay objects when we really need control over how far apart those are so we just split our terrain into grid cells and choose how many of those should be active so stepping through we also play Sur terrain our object separately on a terrain across the log so we can place much larger objects on our lower log terrain so here's not too large one we're
starting to add in some bushes and things and Bob one we have our full set of objects and we have our grass that's only appearing up close where with that large comes in and that presents a problem because we're placing our trees for example on that lower lot of terrain where we're replacing that that whole terrain with something higher detailed as you get closer so we need to reposition them onto the surface and we do it something like this so there you can see them fading between impostors two real models and also readjusting to the surface so it's kind of cheesy that they interpolate like that but it's as far better than than popping into position and generally it tends to be much further off from the camera this is me flying really quickly in flight onto an area and it's just slightly more subtle than Dundas poppin building placement we use our really similar techniques so these are buildings are kind of the one thing that we need to see from space we need
to know about our points before we get to the planet which means we need a technique we're easily we can take any point on their sphere and determine the nearest building so we use an offset grid technique so if we split our terrain down into regions and we can consider each of these points is offset from the center of that and we can quickly recalculate that from any position you can generate or on a diagram of this real easily you can see your nearest building from any point okay so now quickly I'll go through actually simulating on this world that was just generated and covered in plants and physics and things the first thing to talk about is our creature routines they're the one of the things that deter that very most based on how our terrain is generated and not knowing where they can go as a significant thing so as you can see in this gift we generate these paths for them to follow but we don't actually add the creatures till you get in really close to them so we know ahead of time where there potentially will be a creature of where that creature is going to be and whether the camera is
going to reach that point and and but we don't bring it in until you there's actually an intersection to go through that again so there's a gray path pink needs to become active so we know there's creature in that area and then we get close enough for them to actually come in which means we can go away and come back and have those creatures remain in their same positions and we do a really similar thing with all of our objects we fade them in as you fly away and come back and we use this dither base technique just in a shader we pass in a zero to one value for all of our terrain and our object so we can just use to make sure it comes in appropriately as you're flying around so again we've got some gifts of that so here you can see the terrain generating around you and again this is me flying really quickly to a point and bringing all of the terrain in so it's really noticeable that we're doing this that we're starting with really low res terrain and bringing in some slightly nicer terrain over the top but this a little bit more subtle as we're flying
around so you can definitely still notice it but it's not quite as in-your-face as as when I showed you before so this there you can see that blue Rocklin existed in the nearer Vlad so it it faded in there so this is all all time based we kicks up fading off as that region is ready to come in we fade it in and then we're able to see it but we also do a difference based fade for things like grass so this is just thinning out grass and that's just a cut down on the quantity of grass that we're rendering you can see that the grass is slightly different to the terrain underneath it and thins out as we move away I would really like to look move a lot more of our fading to be distance based I think it's much more subtle you don't notice it so much as you're flying around so that's definitely something that we'll look at in the future but it needs you to have generated enough terrain far enough away from you that that you can afford to do it based on distance whereas if your terrain comes in quite late then you really need to fade it in as quickly as possible alright and
finally I want to talk about evaluation and evaluating our content and our world and evaluation of procedural content in general so I've spoken about different things on the land sky a bunch of times and I kind of like to to finish on the importance of this because it's really meaningful to us it's meaningful to the artist when they're generating content that they don't just see their content in context they don't just create a model and look at it in the game they see vast quantities all the assets that come from that model and that's true for our planets as well we need to not just create a planet and look at one of them we need to be able to really quickly go through loads of planets and say where all my planets read is valid that one time it would be read but there's clearly a bug going on there that's caused all of them to look like this or there's this whole space that we haven't explored in terms of generation and we could maybe look into that in future that's a really big one for the artist to go back and back to especially but it's true for us looking at generation techniques for a terrain things as well but it's also an important thing for a
performance that were we're not just looking at one time it that we're looking at a vast quantity and that we're looking at it regularly so this is Simon smoke test tool which is really fundamental to us while we're working on the game so we can see performance degradation and things over time we just every time we run a build than we see all these these screenshots would get these captures and we know how we're doing in terms of performance and it's important that we're doing that on the same planet because we're generating loads of different planets and some of them will be way more performant another some will be filled with foliage in life and will be really pushing us and some will be really cheap and they're not a problem at all so we need a way of keeping track of that throughout the project and I think if you're doing any generation stuff at all focusing on these tools is a really significant thing to do so to summarize this talk I've just got a few important takeaways I don't know if all have said today in terms of the specific
techniques is useful to you maybe it's interesting to you and I'm happened happy to talk some more into more technical detail to those of you that are interested but I hope the way that we're making this game is interesting I hope that people will consider it for games in future I hope they'll think about the fact that we can make interesting spaces in games we don't have to work on a flat plane we can work on on spheres are on a torus and we can achieve loads of interesting gameplay that we haven't looked up through that we can make deformable voxel worlds we can do that in a large-scale game we can do it on current hardware and again people think about voxels and look at like Minecraft but there's so much more that we can do and we can keep doing with that we can have procedural based games where artists remain in control of the content that's coming up we don't have to look at procedural generation as a way to replace our artists we can look at it as a way to augment them and to create more content and finally we can create generative worlds and we can create them in real time as the game is running and we can do that today again
on current hardware you know if we can do that and ship a game as our tiny team there are so many more options for people with more resources out there I think it's a really valid Avenue for us to be pursuing as game developers I think is hugely exciting all right so thank you all again for coming today if you want to ask me questions I'm going to head over to one the wrap-up rooms but also feel free to shout me online and standard plugs for my company I love it very much you should come work with me it's great and thanks [Applause] you
Auto-generated captions from YouTube — names and numbers may be misheard.
Distilling the key insights…
Game Developers Conference · 2026
Game Developers Conference · 2025
Comments