Creating Massive 2D Worlds with Godot 4 and C#
Godot 4 C# 2D Tilemaps - Creating Truly Massive Game Worlds With Billions of Tiles! Here's How!
Estimated read time: 1:20
Summary
In this video, 'A Struggle to Survive' shares an innovative approach to creating massive 2D tile map worlds using Godot 4 with C#. The creator demonstrates how to expand a game world's size from millions to billions of tiles without compromising performance. By shifting from a single tile map to a region-based approach, employing a combination of chunking and Perlin noise, the creator showcases step-by-step optimizations and coding techniques to achieve a seamless and vast gaming experience. Additionally, the video explores the technical challenges of managing large-scale world generation, including navigation, rendering speeds, and data management.
Highlights
- Understanding region-based world generation enhances game scalability. 📚
- Perlin noise aids in generating diverse and expansive terrains. 🏞️
- Chunk-based loading maintains performance while expanding world size. 🚀
- Efficient use of Json files ensures quick loading and saving times. 📂
- Explore innovative coding solutions for massive game worlds in Godot! 🎮
Key Takeaways
- Building billion-tile worlds in Godot 4 is possible with a region-based approach. 🌍
- Switching from a single tile map to regions increases scalability and manageability. 🔄
- Perlin noise and chunking offer creative solutions to expansive world generation. 🎨
- Optimizing data storage and retrieval speeds up game world performance. 💾
- Json handling in Godot is fast, even for large datasets. ⚡
Overview
In 'Godot 4 C# 2D Tilemaps - Creating Truly Massive Game Worlds With Billions of Tiles!', the creator ventures to expand game world size exponentially without sacrificing speed. By transitioning from a static tile map to responsive region-based generation, the video highlights a significant leap in gameplay experience. Utilizing Perlin noise for terrain diversity, each region becomes dynamically unique, granting players an engaging and varied exploration experience.
Key to handling billions of tiles proficiently is the transition to a chunking-like system, cleverly adapted for C# and Godot4. The creator details the decision-making process that led to abandoning the wrapping world concept and instead integrating seamless region transitions. The innovative approach of stamping sections of the map helps balance performance with world size, ensuring massive worlds are manageable and quick to navigate.
Through extensive demonstrations and hands-on coding insights, the video delves into the nitty-gritty of implementing and optimizing these techniques. By prioritizing fast Json data handling, the method sharply reduces load times, contributing to a smooth player experience. With such a methodological approach, developers are provided with the tools and insights to rethink their strategies for huge game worlds.
Switching from a single tile map to region-based approach increases scalability and manageability. Perlin noise and chunking offer creative solutions to expansive world generation. Json handling in Godot is fast, even for large datasets.
Chapters
- 00:00 - 00:30: Introduction and Overview The chapter titled "Introduction and Overview" introduces the creator and the primary focus of the channel, which is centered around a hobby project—a single-player 2D survival game called "A Struggle to Survive." This game is set in 1820 America during the era of the Beaver trade and the Rocky Mountain rendezvous. The creator invites viewers to like and subscribe if they find the content appealing or informative. In this particular video, the creator outlines a technique used in the development of the 2D game.
- 00:30 - 01:00: Expanding the Tilemap Scope This chapter discusses how the speaker expanded the scope of their tile map game world from millions to billions of tiles without compromising game performance. It promises to explain the methods used to achieve this scalability and to demonstrate these methods in the speaker's game.
- 01:00 - 02:30: Initial World Generation The chapter discusses the technique for generating billions of tiles in a game. The author reflects on an earlier version of the game where the world was represented by a single tile map measuring 512 by 512, resulting in a total of 262,144 tiles.
- 02:30 - 04:00: Challenges of Large Tilemaps The chapter discusses the challenges associated with generating large tilemaps in a game. The speaker illustrates the process by highlighting the time it takes from the moment a new world generation button is clicked until the world is fully generated.
- 04:00 - 08:00: Concept of Regions The chapter explores the concept of regions in a 512 x 512 world map context. The speaker discusses interacting with the map, specifically focusing on the speed of its generation, taking roughly 5 to 10 seconds. The point of origin or the upper left corner of the map is highlighted as 0, 0, and the seamless nature of transitioning through the map regions is emphasized.
- 08:00 - 10:00: Moving to Massive Tilemaps In the chapter titled 'Moving to Massive Tilemaps', the game world size is specified to be 512 by 512 units, allowing for in-game navigation and exploration. This segment explains the setup when the speaker initially created this expansive map environment.
- 10:00 - 15:00: Understanding Region and Water Generation The chapter discusses strategies for creating a vast and immersive gaming world, specifically focusing on 'wrapping' the game map so that players do not encounter boundaries, enhancing the feeling of an endless environment. The initial game space covers 262,144 tiles, however, advancements in the design have increased this to between one and two million tiles. Despite this significant expansion, the chapter hints at challenges faced in sustaining such a detailed and expansive game world.
- 15:00 - 25:00: Coding Implementation The chapter titled 'Coding Implementation' delves into the challenges faced when generating extensive game worlds. The narrative highlights the exponential increase in generation time from smaller environments, like a 512 x 512 tile, to significantly larger ones comprising up to a million tiles. In particular, it mentions the delay of 40 to 50 seconds in generating such expansive worlds, which the author finds unacceptable and seeks to address.
- 25:00 - 33:00: Performance Demonstration In the 'Performance Demonstration' chapter, the speaker reflects on design decisions for a project. They contemplate whether certain features, like a wrapping world, are necessary. Ultimately, they determine that a wrapping world is not needed and consider other alternative designs. This chapter highlights the speaker's thought process and decision-making in design.
- 33:00 - 35:00: Conclusion and Invitation to Subscribe In this chapter titled 'Conclusion and Invitation to Subscribe', the discussion revolves around the concept of not using a chunking engine in game development. A chunking engine typically allows the creation of a game world where, as the player moves around—usually dictated by physics—the game's environment is dynamically loaded or unloaded as the player moves from pixel to pixel. This chapter likely ties up loose ends on the discussed topic and invites listeners to subscribe for more insights or content.
Godot 4 C# 2D Tilemaps - Creating Truly Massive Game Worlds With Billions of Tiles! Here's How! Transcription
- 00:00 - 00:30 hello world welcome to my channel I'm bound to be coding and this channel is all about a single player 2D Survival game hobby project of mine that I'm working on called a struggle to survive it is set in 1820 America during the time of the Beaver trade and the Rocky Mountain rendo if that pequs your interest or if you find this video interesting or helpful please consider liking and subscribing I sure would appreciate it in this video I'm going to explain a technique I used to take my 2D
- 00:30 - 01:00 tile map Game World from one or two million tiles all the way up to a world of billions of tiles and I did this without jeopardizing my game's performance stick around and I will tell you how I did this and then I will show you in my game let's get started okay before I show you
- 01:00 - 01:30 my technique for generating billions of tiles I wanted to take you back to a version of my game where I had a single tile map world the world size was 512 by 512 so if we take a look at take our calculator here and we do 512 squared this world is made up of 262,144
- 01:30 - 02:00 tiles now what I want you to notice as I show you this is how long it takes from the time I create I click the button in the game to create the world until the world is generated let's do that now so here I am in my game and I'm going to click new and when I click new this is going to generate a new world
- 02:00 - 02:30 512 x 512 this world has U and I just clicked it and you can see how long it takes to generate wasn't too bad right um maybe 5 to 10 seconds perhaps and you'll notice here as I'm moving around I'm at 0 0 this is the this is the uh upper left corner of the map and you notice that it's uh seamless I
- 02:30 - 03:00 can maneuver and navigate around the map and I just wanted to show you that the game World itself uh is 512 by 512 okay so there we go five z0 to 511 511 so that is the size of this game world and back when I did this uh my goal was to
- 03:00 - 03:30 have a wrapping world so if you you never hit the edge of the map and the game world is like I said it's it's a pretty good size Game World 262,144 tiles now taking this same technique I was able to bring the size of the game World up to one to two million tiles but the problem that I had was
- 03:30 - 04:00 that that delay that you know you just saw when I generated a 512 x 512 exponentially balloons up until when I'm generating a world of a million tiles for example it would take 40 50 seconds before it was able to generate that game world and that was just unacceptable to me and I wanted to do something about it
- 04:00 - 04:30 and so I asked myself a couple of questions uh particularly with the design that I'm going for um I asked myself for example um do I need a wrapping world do I need a world that wraps around and the answer is no I don't really need a rapping World um I could get by with uh a world that did not wrap around um another question I asked myself myself was um do I want to stick
- 04:30 - 05:00 with this concept of not using a chunking engine and so for those of you that don't know what a chunking engine is um the design of a chunking system basically allows you to use uh to create a game world and as the player moves around the game world and typically this is done with physics so as the player is going from Pixel to pixel moving around
- 05:00 - 05:30 the game World new sections of the world are loaded in ch a chunk at a time so if I'm heading east the chunks from the East would start loading in as I'm making my way East if I go west of course the West chunks would start loading the idea being that the player can move around the game World never see the edge and the chunks whatever the size are would load into memory and then
- 05:30 - 06:00 unload as the player uh moves into an area of the game world or leaves an area of the game world now chunking is great especially if you're using physics um because like I said you never see the edge of the world and everything kind of loads incrementally with uh via the chunks that are loaded into memory and this works I when back in several years ago when I was in unity I
- 06:00 - 06:30 developed the chunking engine it worked great I had no issues with it I I really enjoyed um as a developer riding that engine it was really fun to work on and I enjoyed it it was a challenge and I I had great fun with it but as I have begun in the last couple of years working in gdau I started thinking how could I I
- 06:30 - 07:00 maybe not reimplement my chunking engine in in the gdau game engine at that time I had not actually uh ported my code over um wouldn't have taken much to do it was in written in C in unity and it's and I work in C with gdau um but I kind of got obsessed with this idea of how big can I make the game world and um without using a chunk a chunking system and that kind of led me to this take on
- 07:00 - 07:30 it where the player moves and now this isn't using pH physics but the player's moving uh tile-based U movement and The Game World wraps so you never see the edge similar to chunking but the problem is time and that's what I alluded to earlier it takes a long time to spin up a tile m map world you know
- 07:30 - 08:00 of millions of tiles so I decided recently that I would step back and kind of rethink this and reconsider how I'm implementing my game my game is a single player 2D Survival game it doesn't have to be as big as an MMO but at the same time I want it big enough to give the player you know hundreds of hours of playtime so how do I do that and still make maintain
- 08:00 - 08:30 performance and how do I accomplish my goal of a of a game world that is bigger than what I was able to get with this technique and get it to a point where um I felt happy with the implementation and so what I decided to do was instead of creating the game world as one big tile map I decided to go with the concept of regions
- 08:30 - 09:00 now regions is a little different than chunking chunking the player is moving with physics based movement so every you know the the player's animated moving pixel to pixel from one tile to the next tile using using uh the physics system and the chunks are loading in as the player gets close to them with a region-based solution the player basically uh region loads the player
- 09:00 - 09:30 walks around in that region and reaches the edge of the region stepping from one region to the next region is simply reaching the edge and stepping over to the next region and I struggled with this when I first thought about it because I thought well that's going to that's going to hinder the concept of being in a big massive world and but the more I realized uh the more I thought on that
- 09:30 - 10:00 the more I realized that you know what it actually doesn't and this might work so I started playing around with it and uh I came up with the solution that I am about to show you all right so I've loaded up my latest build and I'm going to show you my new implementation that takes me from Millions to billions of
- 10:00 - 10:30 tiles now in this version I've got a World Builder so rather than just automatically generating the 512 x 512 262,000 whatever it was I'm going to generate a game world that is comprised of 32 by 32 regions not tiles but regions so that's 1,024 regions encompassing in this example a world
- 10:30 - 11:00 size of 67 million tiles now that already this right here alone has increased the size of my Game World 30 fold so um let's see what this does I have a random seed I'll go ahead and generate and while it's generating you can enjoy some paintings from the 1800s and then it brings you into the world and this
- 11:00 - 11:30 this basically gives you an overview shows you the world map um along with some native tribe placements of the in different regions um all a work in progress okay so taking a look at it each square is a region each region is 256 by 256 tiles that is uh
- 11:30 - 12:00 65,536 I think it's what that is tiles so each region is 6 65,000 plus tiles okay and that's how we arrive at the 67 million now that didn't take a whole lot of time to generate um but we're ready to go uh at this point I can jump into the game I can select the starting region I can jump into the game and from here start playing the
- 12:00 - 12:30 game and I don't have to wait and I can only imagine how long it would take to generate a world of 67 million tiles in a tile map I'm not even sure what the maximum size of a tile map in gdau uh This is gdau 43 so we're looking at tile map uh layers instead of the tile map which is deprecated but I can only imagine how long it would take I would
- 12:30 - 13:00 it would take hours to generate that so I'm just going to pick a a region I'll just pick this guy right here and I'll jump in all right so I'm in I am in the region that I selected okay so I am in region 43 and this fog represents the edge of the
- 13:00 - 13:30 region and I can walk around and I can run around the game won't be this fast but uh just to give you kind of an idea I'm I'm showing you the performance of it so I'm going to I'm going to come down here and I'm going to hop to the next region let's see how long it takes uh this is a testament to the speed of gdau the speed of C dictionaries because uh every tile is stored in a
- 13:30 - 14:00 dictionary and the loading and saving of Json data encrypted Json data which I covered in I think my previous video I talked about that um but I just want to show you this is this is really fast and I'm very very happy with it so there we are so I just unloaded a region saved it to disk loaded the next
- 14:00 - 14:30 region in the world map and uh brought that and loaded that in so you can see it's it's very fast it's very performant and I can just simply run from region to region and and load the load into each region now the the forest regions take a little bit longer to load I don't remember where there was a forest in my world map
- 14:30 - 15:00 and I haven't created the ability to look at the world map from here yet but forests take a little longer to load and that's because each individual tree has its own set of properties and there's more properties in these trees than there would be in the grass and and other other features of the game and so it takes a little longer to load but it's not bad not bad at all and I'll show you maybe when I we'll take a look at a larger game world and I I'll be
- 15:00 - 15:30 sure to show you how fast a an all Forest uh region loads all right so how did I do this how did I accomplish this that's what I want to show you next all right here we are in paint.net and I've thrown together this little chart to or this uh graphic to show you essentially the theory behind what I'm doing with my region okay now I just mentioned that I have
- 15:30 - 16:00 these seven region types okay now in order to achieve the massive World size that I'm going for I create a master region now the master region is generated using pein noise just like I would if I was going to create a world map all right I would go in and I would and I'll show you uh how I implemented this in my code um
- 16:00 - 16:30 but if you've ever worked with pear and noise you know basically that when you generate your noise and i' I my noise is generated in a scale of 0 to one and so each pixel in the pear and noise map is going to have a value and that value is going to range from zero to one and in my code I let's just for the sake of of
- 16:30 - 17:00 illustration I've decided that 0 to. 33 is a forest 34 to 66 is a plane 67 to 1.0 is a mountain now at the pixel level that would be really easy to render because I just simply uh create my Game World read those pixels determine what tile type it is and from that display the the correct uh tile in my Game World and that's it
- 17:00 - 17:30 I'm done and of course uh and I again I keep alluding to water I'll we'll talk about that in a second but um but that's basically how it would work so to create a game World exponentially larger what I'm doing is I'm taking that same concept of creating a map world map and I'm generating it for the purpose of M matching these T these uh um pixel
- 17:30 - 18:00 values to create certain region types what do I mean by that okay since in my game I have three uh core tile types plane forest and Mountain I need and and my my Game World uh region side is 256x
- 18:00 - 18:30 256 so with the 256x 256 I want to create a master region where I can compare at least three values to determine how I'm going to generate or decide what my region type is going to be all right let's look at this so here in the upper left corner here's the first four pixels that I'm going to read
- 18:30 - 19:00 from my peino master region now the master region is four times the size of my Game World region so each region is 256 by 256 so my master region is going to be 512 by 512 that's because I'm going to Loop through my X and Y coordinates and I'm going to pull in four pixels at a time and I'm going to look at them and I'm going to compare
- 19:00 - 19:30 them see the values and determine from from this four what my first region is going to be so 38 that's a plane 31 that's Forest 3441 those are planes so this combination and I have logic that determines you know do I have one type represented in these four pixels do I have two types do I have three types and then from that I decide what that region
- 19:30 - 20:00 is going to be so this region or these four pixels from this I my code determines that this is going to be a plane region why because I have three plane and one Forest so my code says hey if you've got three plane and one Forest then we're going to make that an all plane region so we have a a dictionary
- 20:00 - 20:30 the region dictionary the key is a vector 2i and there's a I have a class a region class that I store some region data in and in that dictionary I'm going to say my first region in the upper left corner up here is going to be all plain then I move down through my y the next Y and my XY uh loops and I look at this one and I say okay well this one's plain and this one's plain this one's mount mountain and this one's mountain now I
- 20:30 - 21:00 have a mountain plane type so because I have two and two I'm going to translate that into a mountain plane here and then I move on and I make my way all the way down I get back up here and I start over here and I say okay well I have four Forest four Forest is going to translate to all forest and so this this
- 21:00 - 21:30 region entry in my region dictionary is going to say this region type is all forest and then when I get down here I have plane forest and two mountain and my code determines that hey if you have three different types then we're going to go ahead and make that a region type MTH which is this guy and so this guy this
- 21:30 - 22:00 region here becomes mixed the region dictionary uh at this position Vector 2 is going to be so 1 one 0 1 0 1 so 1 one is going to be uh mixed and I continue that process all the way through the size of my Game World and so using a master region I can look at the pixels the pein noise
- 22:00 - 22:30 values in these pixels and construct or determine what each region is based on the comparison of the four uh pixels that I'm looking at from my master region now once I do that I can I'm essentially examining a 512 x 512
- 22:30 - 23:00 region converting the pixels into region types that I'm going to be using in my 256x 256 region World once I have that the next thing I need to do is figure out how I'm going to handle water now in my game it was very important to me that my water uh stretched from region to region you can imagine how frustrating it would
- 23:00 - 23:30 be to be in a canoe in a region and you're following the river and you get to the edge of the region and you pass to the next region and you end up on dirt on land I didn't want that I wanted the uh regions basically the water to span across the regions now when I was showing the demo a few moments ago
- 23:30 - 24:00 you noticed the 32x32 loaded and it probably took I don't know maybe 5 to 10 seconds to load in truth the vast majority of that time I would say probably 95% of that time was generating my water stamp you see the larger the pear and noise area is that you're trying to capture the longer it takes to
- 24:00 - 24:30 generate and so there's a and and on top of that there's a certain limit to the size of images in gdau I want to say it's uh 16384 by 16384 um is the largest image size that gdau can handle now in this case my water stamp here is 2048 by
- 24:30 - 25:00 2048 in other words my water stamp covers a region Block in my in my world map of 8 by8 or 64 regions so what happens when let's say the game world is you know a lot bigger than what's represented here in this graphic well what I do is I take I take my water stamp and I call it a stamp
- 25:00 - 25:30 because I'm going to be reusing this okay so I take my water stamp and I I basically assign the water to these 64 regions and when the player reaches this upper right corner here and moves from this region to the next region I simply repeat the water stamp over here now you might think well if you repeat it then the players going to be able to notice that and and and to be honest with you
- 25:30 - 26:00 um that could happen but I'm not worried about it because the player would have to Traverse eight regions to get to a duplicated water zone or a water stamp in my mind that's plenty um there's no reason that it has to be um necessarily different from that um I could make the water stamp 16 by 16 but when I I do that I'm essentially
- 26:00 - 26:30 copying or mimicking exactly what I did in my old method where I was creating a game World of 512 by 512 um and allowing and and trying to calculate all the pear noise and assign all the the tiles based on that in other words keeping these images small keeping the pear noise generation and the image that is pulled from that pear noise small keeps the time
- 26:30 - 27:00 frame quick and that's basically how I have done this I've basically taken a region uh generated a world map that's four times the size of the region that I'm using then calculating a region type based on comparing four pixels four pixels and just working my way down this master region storing those type
- 27:00 - 27:30 assignments into a region dictionary and then when the player jumps into the game world I generate a 256x 256 uh region based on the region type now I'm going to cover this in a in another video but you might be asking well if you have this region type called for example all planes okay if you have an all planes region
- 27:30 - 28:00 type does that mean that every region that is of plane is going to be exactly the same no it's not and the reason for that is I take that that player seed and I perform some math on that player seed using the XY coordinates of the region itself and I'm able to generate a unique region based on the regions X and y-coordinate coupled with the player seed value and that allows every region
- 28:00 - 28:30 to be different even though those regions are of the same type uh a plane region is going to be different from another plane region in the distribution of the Flora in the distribution of um the river or water assets because basically the water stamp is stretched across 8 by eight regions
- 28:30 - 29:00 and so that's going to make this region different from this region different from this region and it allows also for the player to sail through region to region in a canoe and be able to navigate and work the work their way around the game World in that way all right so here we are in my code
- 29:00 - 29:30 and let me preface this by saying um if you are thinking that you're going to be able to reproduce What I've Done by looking at the code that I'm going to show you um I'm going to have to apologize that you're not going to be able to do that because I'm not going to be able to show you all the methods all the classes and all the codee that I've used to pull all of this together really
- 29:30 - 30:00 the goal here is to explain the theory behind how I'm able to accomplish my goals here with the World by creating these regions and to give you kind of the logic of how it works and then you can take if you understand the logic if you understand what I'm how I'm doing this you should be able to implement this in your own game um so this is more of an advanced um tutorial in a sense not
- 30:00 - 30:30 really a tutorial but more of an an exam an example of how I implemented something hoping that you'll be able to take what I'm going to show you and implement it in your game if you choose to do so so it's not really for a beginner per se now I am a c developer by trade um and so I'm I'm all of my code will be in C so on that screen where I'm generating
- 30:30 - 31:00 the world there's a call to this method generate preview world so once the player selects the SI the size of the world region size in my example earlier it was 32 by 32 this method gets called and um it's on a background thread which uh basically passes an uh passes back and a progress and that's how I'm updating the progress bar as we're uh working our way down in this code but anyway so I'll
- 31:00 - 31:30 just give you kind of a brief rundown of what this is doing so we take our region section size um and we determine how big the region the master region is going to be we take the world region grid size x * 2 and y * 2 and this is going to give us the four the four times the size so that we can go through the four pixels um to represent each region
- 31:30 - 32:00 okay um here's my here's my land fast noise light for my world now what I'm doing here is I'm generating a mixed region on purpose the master region is the m is going to be a mix right because I want a little bit of everything all the region types uh in my final game world so in order to do that I'm going to create a mixed region or a mixed Master region map and
- 32:00 - 32:30 that's this is how I'm doing it and I found these values work really well um in fast noise in the fast noise light um implementation of pear noise these values work work pretty well uh let me pass a nugget on to you that I learned just yesterday I believe it was um I found out that the seed value for fast noise light in
- 32:30 - 33:00 gdau 43 you notice that it is an integer value now integers can range from -2 billion to positive2 billion something or another I can't remember exactly the number fast noise light will not be able to handle all of those values what I have found is that the if the seed value gets bigger than 999 million 999,999 or when it reaches 1 billion
- 33:00 - 33:30 every seed value higher than 1 billion up to two billion 2.1 or whatever it is the integer max value will produce the same noise so be aware of that I wasn't aware of that and when I was tweaking my uh formulas that I was using for land world seed and water world seed based on the players seed I it was produced in the same noise regardless of what um seed value I
- 33:30 - 34:00 random seed value that I was giving it and ended up troubleshooting and figuring out that that's what was happening so just keep that in mind you're limited to values under uh one billion for the seed okay all right so once I generate the pear noise I grab my land image and this land image is my is my regen my m region okay I then save it to disk just because
- 34:00 - 34:30 it's cool to save it to dis so I can look at the uh the raw pein noise then I uh instantiate a brand new copy um my game region dictionary which is I explained in in my uh paint.net uh presentation excuse me okay so what I'm doing doing here is I'm looping X and
- 34:30 - 35:00 Y through my region size or region section size um this is pretty self-explanatory I'm basically getting the pein values from the pixel determining what kind of uh pixel that's going to be a mountain a forest a plane um forest plane and mountain and this pattern creates my my mixed world my master region and then once I have that I can then go and
- 35:00 - 35:30 loop through I'm going to do two two Loops I'm going to Loop through the world region grid size so how big my game world is going to be okay for X and Y directions then I'm going to Loop an X and Y and I'm going to pull four pixels here all right um x0 and X1 and y0 and y1 and I'm
- 35:30 - 36:00 going to store them in this list so there's four values that are stored in this list then I basically do a quick Zone count Zone count is basically I'm grouping these four pixels so I can get an idea of um what the group is going to look like then I do um I basically get some Zone totals here I group group order by descending so I can figure out okay what is the most popular of those
- 36:00 - 36:30 four um we're going to put that that zone type at the top and I get a count for the first Zone the second Zone and the third Zone some of this is deprecated actually um not necessary because um before when I did this when I was working on the original concept for this I was creating a a region Master region map that was way larger than it needed to be since I'm
- 36:30 - 37:00 only dealing with three types and a possible seven combinations of those three types I only need a uh region map that is four times as I explained in my paint.net presentation okay so if the Zone count is one all four pixels are the same then it's whatever that pixel type is so the region type is going to be all mountains all forest or all Plains depending upon um what what those pixel values are
- 37:00 - 37:30 otherwise if it is if the Zone count is two then I I do some uh uh checking and determining okay well if it's two then if Zone one is a mountain and zone two is a forest or forest and Mountain then it's going to be a Mountain Forest and these are my combinations of uh dual zone types okay otherwise then it's going going to be mixed so I either have
- 37:30 - 38:00 all four pixels that are the same or I have two different zones where we do not have a third type represented and when with that I basically determine how I'm going to set the region otherwise it's mixed and that's it so then I add that to my game region dictionary and once I am done with that um I decide uh I step down and I say okay now that we've taken care of the terrain let's look at the
- 38:00 - 38:30 water so I get my water seed I create my water fast noise light water only this is going to be the 2048 by 2048 and this is going to give me my water stamp so I save my water stamp and I'm done and at that point um my map gen scene is going to have the data that it
- 38:30 - 39:00 needs to generate the preview world that I have and uh yeah that's that's pretty much how I'm able to do that um I'm trying to think is there anything else that I need to show you um this next method here is how I generate my re region when the when the player actually gets into the
- 39:00 - 39:30 game how the region is generated um basically um determining how many water stamps I need based on the world size um this is a technique that I played around with rather than um taking the water stamp and just copying it from left to right from top to bottom you know I tried playing
- 39:30 - 40:00 around with the idea of flipping vertical and horizontal but of course you know when you have a uh a water stamp that um essentially is uh seamless then it's going to generate some really cool patterns that look really cool but it all it does really is um um make it more evident that have copied the water region and so I decided against doing
- 40:00 - 40:30 that now let me that brings me to a thought that I want to I want to mention here it is very important for for my game it's very important if I want to be able to travel the world via the waterways then I need to make sure that my water stamp is get seamless image I want it to be seamless it it absolutely has to be seamless otherwise uh it won't line up when I go from Reg to region whereas
- 40:30 - 41:00 my up here when I did my land I chose not to use a seamless image now I could have I could have done this I could have said you know what just like I created in my previous version a 512 x 512 wrapping world I could create a 32x32 region wrapping region by
- 41:00 - 41:30 basically doing a get seamless image on the land world and using that so that if there is for example Forest on the far right then when the player reaches the far right and goes over and I and I do provide that in my game so if the player starts the player makes it all the way to the top of the game world and hits and steps to the next region they will end up back down at the bottom so the world does wrap in that sense it does
- 41:30 - 42:00 not currently uh wrap into the same kinds of region or the same uh uh different sections of region inside so the tiles might be Stone in the region and you go to the next region and they turn into Forest that's okay I'm I'm good with that at least for now uh I may end up changing my mind later I don't know but I noticed that using get
- 42:00 - 42:30 seamless image doesn't provide as much variation in the uh pein noise and OB and for obvious reasons because it has to adjust itself to be a seamless image and that's that's what this little uh where is it that's what this little this little Gap here is um this is the skirt that goes around the region or excuse me the water image that allows it to line
- 42:30 - 43:00 itself back up so that it's it is a seamless image so I use seamless for the water and not seamless just a standard pear noise image for my land and let me see what else do I need to cover in this video um really I'm I'm just getting I'm I'm getting well okay so so right
- 43:00 - 43:30 here you might wonder how am I how am I generating my regions so I've got my big Master region and that Master region determines the world map kind of shows you the world map by looking at the pixels determining the tile types but but remember I store all of that in a in my in my dictionary and so I get the land noise image here and I believe I believe
- 43:30 - 44:00 actually that I this this piece of code here might be deprecated now since I have my regions loaded into a region dictionary I can I can simply load the region dictionary data and from that determine what my tile type or what my region type needs to be and then from that yeah I think I'm going to end up having to to deprecate that but anyway that's what happens when you're developing you you work on a piece of
- 44:00 - 44:30 code you you write out a method and you start developing other methods and other parts of the game and then you go back and you look and you're like you know what I can refactor this I can make it cleaner I can make it faster I can make it better I guess that's why I love uh software so much I love I love uh writing code and organizing and it's fun stuff for me but anyway all right so that's pretty much um how I accomplished my uh my zone system let me
- 44:30 - 45:00 call it and what I want to do now is I want to show you just how uh performant this is when we get into uh billions see I've shown you Millions but I haven't shown you billions yet and that's what I promised to do in this video right show you billions so I'm going to go back you've seen the code you've seen the theory of how I've done this now we're going to take it and we're we're going to expand it out and we're going to look at 128 by
- 45:00 - 45:30 128 regions and then there is a uh the largest one which I don't think I'm going to actually have in the game because I think actually it's too big for my game but I'll show it to you anyway so let's jump back into the game all right here we are we're back in the game and you've seen small let's go large let's go large generate
- 45:30 - 46:00 okay that didn't take as uh that didn't take much longer than small um which is which is very impressive in my mind because by using that by reusing that water stamp I don't have to generate plin noise large enough to handle this size game world and if you and you notice um and since I'm talking about that water stamp let
- 46:00 - 46:30 me get rid of Zone let me get rid of terrain let me get rid of tribes let's just look at this okay so I'm going to zoom in now remember I had said that the water stamp was eight I think that's what I ended up doing how I or what I ended up implemented for the implementing for this one two one two three four five six no I think it's 16 10 11 12 13 14 15 16
- 46:30 - 47:00 1 yes it's 16 can you see the pattern see you got that little bit of water there you got that little bit of water there there's the repeat okay now when you when you aren't paying attention it doesn't look to the naked eye at first glance it doesn't really look like it's being repeated so I think it meets my needs I'm I'm happy with it there's a tradeoff
- 47:00 - 47:30 between the uh making that water map water stamp larger but then having the player wait for that additional time and it's exponentially larger the bigger the the image the longer exponentially longer it takes to generate so I'm happy with it here's our zones so as you can see here um here's the terrain so we got a lot going on this is this is big okay say how big
- 47:30 - 48:00 bound Tobe coding how big is it well large size is 16,384 Regions encompassing 1 billi 73 m741 824 tiles that's what is represented here in this map okay pretty fast I uh
- 48:00 - 48:30 originally Drew I I originally placed individual Sprites to make up each region and then and then I switched over to using a uh TI map layer and so what this is is uh 16,384 tiles on a tile map layer just like like tiles on a tile map in the world only this represents
- 48:30 - 49:00 regions and so you can see the power of of this um technique of using a region to create regions that's what we're doing all right so I'm going to leave off with I've got two things I want to show you I want to show you huge which is just an experiment um honestly I I I cannot ma imagine going live with this um I have a
- 49:00 - 49:30 pretty beefy system so I'm really I haven't tested this on a on a uh on a uh less powerful machine but um yeah just having fun with it here's 256 by 256 okay what that means is 256 squared is 65,00 536 regions and each region has
- 49:30 - 50:00 65,536 tiles so what you're looking at what you're about to look at is four billion tiles 4.2 okay so let's uh let's generate and you can
- 50:00 - 50:30 see yeah if I would have tried that in my old method first of all I don't think it would have worked second of all it probably have taken three days to generate um but this is it this is this is what four this is what 65,000 regions look like and by the way this kind of gives you a visual of what a region looks like because it's the same size so each
- 50:30 - 51:00 region in the game is this size this number of tiles okay and only we are representing regions here not tiles so now I promised you that I would show you a an all Forest so here we have here um this is this is all Plains this is all Forest I'm going to start here and step into here so that you can see how long it takes to go from here to
- 51:00 - 51:30 here the transition which is the saving of all the region data uh to uh Json binary encrypted files and uh loading or generating a brand new region when we step over here so I'm going to start now me mental note look at where the look at where the water is we've got water in the upper right corner we've got water stretching from the upper left down to the bottom right
- 51:30 - 52:00 with a dip into the Southwest area of the of the map is this going to translate correctly is this going to match when we get into the game well let's find out okay so here we are I said the water stretched from the upper left down to here let's open this mini map so that we can kind of see how it work works oh oh oh oh oh look look
- 52:00 - 52:30 look there's the dip and it extends all the way over to the far right and then we have if we come up here we've got this little section in the upper northeast corner and we can see that it is all translating correctly and I'm going to step over here because because to the right is where our forest region is
- 52:30 - 53:00 and okay so now I'm going to step through and I'm going to show you how fast the forested regions generate now that was probably well let's see how let's see how much that was let's take a gander I've got some missing textures that's okay all right so region of
- 53:00 - 53:30 containing 25 1,480 Flora generated okay that took 3.2 seconds okay um The View refreshed with 320 that's that's my that's my uh that's another another part of my game that I uh did a video on um creating my own uh system
- 53:30 - 54:00 of blending my tiles together that's that's a whole another topic but anyway you can see how fast that generated and it did now when I leave this Zone and go to the next Zone I have to save all this region data and then either generate the next region or load the region now we know this region over here to the West has already been I arrived there so that region already exists so this so what I'm about to show
- 54:00 - 54:30 you is uh going from one region to the next where we are saving this region that we're in and loading the next region okay and here's how fast it is it's that fast now you saw that it took 4 seconds to generate the all Forest region what I'm going to do now is I'm going to go back to that
- 54:30 - 55:00 region um and let's see how fast it loads this is not a generate this is a load because the region has already been written out to its Json files so how fast is that with all Forest that fast just like that so if anyone tells you that Json is slow and that don't use use Json because you know um it's slow and it loads slow um I beg
- 55:00 - 55:30 to differ it does not load slow okay Json is blazingly fast and that wasn't just loading one dictionary one Json file that was actually loading six different Json files that were encrypted that had to be decrypted and then placed into their tile m M layers accordingly so because
- 55:30 - 56:00 you've got the ground and the trees and the water and and the uh structures the beaver dams and things like that I mean all that data had to load um here so very very very very fast I hope that you have enjoyed my video today if you have would you please subscribe and give me a thumbs up if you have any questions comments requests please uh
- 56:00 - 56:30 leave those in the comment section and I hope that you have enjoyed this time it has run a little long but I hope you you've gained some valuable uh understanding and and knowledge of how you can make your game world not millions billions of tiles in size until next time I'm bound to be coding