Instead of generating terrain meshes in a single frame (which causes lag spikes), generate meshes incrementally over multiple frames using a queue system. This approach distributes the computational load across frames, eliminating lag spikes while maintaining smooth gameplay. The solution involves creating a request queue where the main thread adds mesh generation requests, and the same thread processes one or a few requests per frame, preventing the main thread from being blocked during terrain generation.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Removing annoying lag spike from terrain generation without multithreadingAdded:
And hello YouTube. And today this is my C++ Minecraft clone made in Raip.
Yesterday we managed to make the terrain endless actually endless.
It it will generate on for forever.
The problem is this is running on the main thread.
Our goal for today will be to polish this up to move it in a separate thread so that we don't have this these lag spikes.
That's the main goal to make this terrain generation butterly smooth and maybe even increase the render distance.
Also, we had another issue of having memory leak.
The memory leak was 40 GB.
Unheard of memory leak.
If possible, we'll try to fix it. And if we have time, I want to add the player.
I want to add the player so that we are able to walk around and explore this industry.
for future stream.
I would also like to have like uh biomes and creative um creative inventory and settings, but that would be for a future stream.
Today, I want this lag spike to be gone.
That's what I want.
Yeah. It it's it's very easy to notice.
Every time we cross a chunk, it has a L spike.
And also we need to fix up these um here where the mesh is missing.
If we destroy a block from this sub chunk, it will update it. This needs to not happen. This needs to be fixed.
And that's the goal for today.
That's the goal for today.
Stream health seems to be uh excellent.
That's the goal.
Let's do it.
So, my idea is I've uh this needs to be put in another thread. this um generation of the meshes and how are we going to do that?
Yo, what's up?
Uh how's your day? How's it going? Um so to move this generation of meshes in a separate thread so that so that we don't get the L spike. Um how are we going to do this? I was thinking about this off stream and I was thinking of having uh to use this design pattern. There was uh something along the lines of like subscribers and publishers design pattern publishers and subscribers. Yeah, publisher subscriber.
This is what I am thinking of using where the player is the publisher and the separate threat is the subscriber or the world is the publisher I don't care but the subscriber should be the separate threat and so the threat will get a signal that some meshes needs to be generated and it will generate them.
The only issue is uh I will have to synchronize the main thread and the um additional thread. I'll have to synchronize the two threads since the main thread is the one that deletes and creates subchunks.
So there is a possibility of where we're trying to generate um a mesh but it's being unloaded and that will be very difficult to do. We're going to publish the source code someday. If I publish it, it's going to be just the source code and I and I don't know who will benefit of that. You you will not be able to run it since there are no texture packs.
H and this is the first thing we'll do to separate the generation of meshes to the threat.
And I'll try to incorporate this design pattern of a publisher and subscriber to I want to see if it's possible for the separate threat to to subscribe to either the player or the world whatever is the publisher.
So maybe the publisher has an array list of subscribers. It is just going to be the threat. So doesn't matter subscribers. Yeah, here it has maybe an array. Oh, this is in JavaScript. Maybe this is some kind of an object.
I don't know what language they're using. Yeah, JavaScript. They're using JavaScript.
They have a callback.
Uh, so this is probably what gets executed when you subscribe. And so here on user added this is just console lo subscribe publish on user added. Oh yeah. So you subscribe with a call back function and that function gets called when you hit this publish function which what does it do? Oh, it goes over all the subscribers and calls their callback with the data if there is one.
And here this is the date. But this is in JavaScript.
Hi, I'm back. Does rendering work? I left yesterday.
Well, yesterday we got this. This is what we got. Uh the terrain is endless, but the problem is since it's running on the main thread, it has a lag spike every time it generates. And these are minor issues here for the um these missing uh pieces since we just need to like everything's there. I just need to manage this properly. But that's an easy issue. My focus is on the L spike. That's a more difficult issue.
And to fix the luck spike, I'll have a separate thread that is constantly running. And I'm thinking of having the separate threads to run uh 20 times a second. That's what I'm thinking. It will be all the time running. It will be running all the time. So, first let's test that. Let's see if we can have a thread that is constantly running.
Let's see if we can have that. And we can test it very easily. Uh let's see if I have to do any commits.
Uh what's this code change? What's the history? Set render distance less than two.
Loading and unloading chunks from main thread. I assume this was the work from yesterday.
Let's push it and we'll be able to start the work on making progress.
Yo, hello. What's up? How's your day?
I'm very excited personally to implement this change. If I'm if we manage to implement this change, that would be very cool. So, let's create a thread that is constantly running.
uh this will be its function uh test thread function. This will be the function for the thread where we will be testing to see if we can keep it running all the time. So we need a while loop.
Let's have it be the same one as the uh as this the relip one until the window should close.
We can do that.
Yo, what's up? How are you?
Yeah. So, right now we need to move the uh mesh generation of the sub chunks in a separate thread. But before that, I want to see if we can continuously run a separate thread all the time. And here h I need it to run 20 times per second. I want to limit it uh just in case like if it's like a while through loop it will be constantly outputting something.
We can test it even like this. We can test it even like this. trace lock uh log info I am in separate threat constantly running yeah let's do that and let's execute it where will we before the while loop here so let's do it with the terrain in generation here std thread constantly running threat and we give it the function that it should run and we'll join with the threat when we quit the game.
So it should be here if the threat is joinable to wait it out. But do we actually need to wait it out since the while loop it has a uh I'm doing desync. Nice. you. Yeah, I'm excited to implement the new feature. What are you making? I'm trying to make the right now the terrain is endless, but every time it generates it has a lag spike. Since it's running on the main threat, I need to move it on a separate thread. That's what that's what the goal for the stream is in the next 3 hours.
Uh, where did I quit again?
Here on when we press the escape key.
Let's run it.
Yes. Yeah, you can see we have the L spikes every time the terrain generates.
But the from the previous stream, we managed to make this endless. This is actually endless. So, we're just polishing things for in this stream.
Uh so let's see here. Yeah, this is the the separate threat and it's constantly running.
Did it stop? Did it stop?
Uh what happened?
Did it stop?
Yeah. Let's close it. Let's start again.
Let's not disturb it. I'll move this outside of here.
I'm looking at the output from the separate thread. And for now, there are no issues.
It's constantly running, which is exactly what we wanted.
And we can see it's moving quite fast.
It's moving quite fast. So, let's slow it down. We don't need it to take up so much compute.
We'll try to limit it to 20 times a second.
Uh there are lots of trees though. I'm guessing you'll adjust that later. The trees is not my focus. Then they are just there so we have something to look at.
Now here is the issue.
We're trying to close the game and it's not working.
And it's not working since it's not working since when we press escape.
Uh I have set it so it waits for the thread to stop. But that's wrong. This should happen where here when we say close window since it has since the threat has a while window should not close we need to actually have this be ending.
Let's see now if we press escape does the game end?
Yeah the game ends. Okay. And the thread stopped outputting. Perfect. We have a thread that is constantly running. We need to now make it not be running um so to not take up so much compute. Let's make it run 20 times a second.
H.
And how are we going to do that? Let's get the uh last update time. Let's have it be the the get time get the last time in seconds since in it window. Sure. And in the while loop here uh if the current time uh let's actually save it.
Double current time.
Uh if current time minus last update time if it has been more or equal than now we want it 20 times per second.
So 60 seconds divided by 20 uh no 20 let me think about it.
20 times per second.
No, no. M think about it.
I think it should be like 0.5.
Can you show how is it for now? Uh go back in the what, man? I showed it like five or 10 times already. We need to make progress. We need to make progress.
Um, if it's 0.5 or 05 time 20. Yeah, it's one.
Yeah, it should be that.
So if if 0.05 05 seconds have passed then we can actually run the code and we set the last update time to be current time. This should make it run 20 times a second.
Let's test it.
H. Now this should be running outputting 20 times per second but it's difficult to um confirm it. So let's lower it even more.
Let's make it uh let's make it output every 5 seconds.
This is so we limit the separate thread to not run so much. Now let's wait and see for an out. Yeah, it should be executing code every 5 seconds. The separate thread. Yeah, that's perfect. Now this is where we need to put the this is where we need to put the mesh generation.
So we made progress. Can you show how is for now? This is it. Uh, when will project be finished? I don't think it will ever be finished. Since I'm making a Minecraft clone, I don't know when it will be over. He'll always up the Lucas.
I know a Lucas. Are you that Lucas?
When will your project be finished?
Uh, you already asked that. Why spam?
Hello. Hello. Okay, let's move on.
Now, this is perfect.
Uh let's move.
So let's move this.
We have it. It's endless right now. It's endless and it locks when it tries to generate new chunks. In order to fix that, we will move it to this separate thread that will output here a message.
Yeah, we'll move the mesh generation here.
We'll move it there so that we don't get this issue. And now it froze up.
All other Lucas are knockoffs.
What's up? Hello.
Hello. What's up? Well, to prove that you need to fight in a tournament and prove which Lucas is the real one.
Yo, hello Peter. Hello. What's up?
We have a separate threat and we've set it to run 20 times per second.
Perfect.
here generate new mesh. Here is where we will generate the mesh for the terrain. This is where we'll do it. And we already have a thread that generates uh this terrain, the initial terrain generation. We'll remove that. We'll remove that the initial generation so that all of the mesh generation happens in a single thread. We'll have to remove it. This is the function that does the code H here. It actually also generates the blocks.
Let me think about it.
We can move.
What if we before that let's try to move this the block generation H to here.
Yeah, here to here. Let's move it here.
the block generation.
Yeah, we need this to generate blocks and we need a block spawner.
That should be it.
Just so the thread only handles mesh generation.
Okay, sure. Fine.
Nice. Now, now the thread only handles mesh generation.
And this is the initial version where it generates the meshes initially when we start the game. I have a thread that generates the meshes for these chunks.
But we need to remove that because we want to move to the um this design pattern the publisher and subscriber.
The idea is the either the world or the player when we go to a new chunk. Let's even open Minecraft.
When we go to a new chunk to publish and notify subscribers to do their work.
That's the idea.
And here they have an example with JavaScript.
I'm not sure sure how that will work with C++, but we'll see.
But I'll just open Minecraft so because there it's easier to visualize what I'm talking about, especially when moving through neighboring chunks.
The debug visualizations here make it easier.
Yeah, this is it.
Uh so this is one chunk this these yellow lines. This is the chunk I'm currently in. And when we move to a neighboring one, look at how it executes code. Like it it loads the new sub chunks and unloads the one behind us. We already have this but we need to move it to a separate thread. And my idea is when we cross here to notify the to notify the threat that it needs to do its work. But actually as I think about it, the design pattern will not be of help because look at how it executes this version. when you subscribe you give it a function and this function when you publish it's executed here it it will execute it in the same thread of the publisher and the publisher is on the main thread either it's the player or the world uh I'll have to think about this how I'm going to approach it uh hello is the Josh battle royale all over again when your game finished. Do you think adding servers?
H uh it will be interesting if there's multiplayer since it would be very cool if my uh Minecraft clone can interact with the Minecraft server like here.
Imagine if you're playing here and you can pray play through my Minecraft clone as well. That would be wild if I can manage to do that.
Uh, but command blocks, I haven't thought about that. Yo, hello creeper.
What's up?
We got some regular viewers.
H. Oh, here they have a Python implementation as well, but they also do it with a callback and for working with threats that will not be of use. Okay, they have a Java version as well. Nice.
Do they have a simple post version?
I don't think they have one.
Yeah, they don't. Bummer.
People already made Roblox and Minecraft crossover. Really? Roblox and Minecraft crossover. That's wild.
If you can do a crossover from Roblox, then with C++ should be way easier.
Yeah. like launcher but different.
How are we going to notify the threat that it needs to h? Let's remove this mesh generation. Let's remove it.
Let's remove that mesh generation.
Where was the terrain generation?
Yeah, here. Generate terrain. Generate all meshes.
We'll just return here.
So, there should be no meshes generated.
Yeah, there are no meshes generated.
Let's visualize a grit so we know where we are.
Yeah, let's draw a grid.
Yeah, there's the grid, but it's far down.
Can we make it? What if we increase here?
Yeah, there's our grit. Let's make it further apart.
Yeah. Oh, what?
Oh, yeah. This is on the main threat. I was wondering what happened. Yeah, that's on the main thread.
Uh, I need to remove this as well. It will happen on a separate thread.
Now, where was the code for that? I need to remove all of these. I don't need them. I don't need this. I don't need this.
like that. Unloading chunks. Generating new subchunk mesh here. Let's remove this.
Let's let's remove that.
And now we don't have we don't have any terrain generation. If we break a block, it will generate a mesh.
Okay, it didn't because there isn't a mesh created. Uh when we break a bro block block it updates the mesh but here there is no mesh to update. Uh but that was an experiment.
Yeah. Now we want the mesh generation to happen in a separate thread. Look at how now when we move around there is no like luck. If there's no luck spikes when we move around now, there are absolutely no luck spikes because the issue was the mesh generation takes a lot of computation.
And we are right now going to move that part.
We're going to move it.
Yo, what's up? There was a guy on YouTube that made the Minecraft clone successfully joined server. I think his project is open sourced.
I'm not interested in looking his code, but um it's the good thing is that it confirms it's possible. So should be able to do it then if it's not that difficult. Can find you people are doing grace mode in Minecraft now. Would it work if it was just a queue of chunks to be rendered? No. Um, a queue of chunks is but I'm using a hashmap since I have a very fast access if I need a particular chunk using its origin. My cousin and place has his own club. Uh, do you use air for assistance sometimes? Uh I'm I I avoid heavily using I avoid using the AI since when the AI does something I don't I'm not I don't have a satisfaction when it's achieved through AI. So I avoid it.
I hope he doesn't. I'm interested. Yeah.
Like you can just look at the streams like how I code during streams is how I code outside of streams.
I called the same way.
Yeah, I removed this and now there are no sub chunks generated.
When do you think AI is ethical to be used? I'm not the person to give you an answer to that. Like I I just make Minecraft clones. Like I have no idea.
I have no idea.
Okay. So h yeah, we need the mesh to generate through the separate thread. We need to notify it that we need a generation of meshes. We need to notify it somehow.
And we are currently in the main thread.
And that other threat is actually running now.
Uh, and I have stopped the output to the console, but it's actually running the separate thread and it's monitoring constantly if I need mesh generation, but I'm not notifying it. And my idea was to use this design pattern uh the publisher and subscriber. My idea was the player to be publisher when I need to generate a mesh to notify the subscriber, which is the separate threat. That was my idea. But here once I looked at the code, they use a callback. This will be called from the publisher here when you hit publish. So when I cross a chunk, I'll need um generated mesh for the chunks and I'll execute this publish from the main thread which will just execute this function which is the callback but I assume it will be running on the main thread. So this idea I don't think it will be of use to me but that was my initial idea of how to notify the threat. That was the initial idea.
Uh I love coding stuff and I'm learning C uh C++ a bit. What version of Minecraft are you trying to replicate? I I prefer to beat the old Minecraft as close to what Notch did on his own since I'm a one person. I don't want to replicate what a company is doing.
So whatever Mojunk or uh or whatever um Microsoft is trying to do, I'll avoid it since I'm a a single developer or is it just trying to make something similar to Minecraft? If you cannot find any docs about the thing you're using, have you ever thought about collaborating with other on this Minecraft clone? uh who do you suppose I should collaborate with?
And I'm not a fan with collaborating for this project like to get a team since I want to be the one to like it's the same with the AI. When the AI like does the progress, I don't get the satisfaction.
If I get a teammate and he does the thing, I don't get a satisfaction from achieving it. And like this is my entertainment.
But uh if it's for like I'm more interested in collaborating when trying to make my own game, that's more interesting. And I'm collaborating with an artist animator. Um but it will not be with a programmer.
A Minecraft clone.
Uh have you fixed the l spikes? And no, we are trying to fix that currently and that's why we have the separate threat.
And what happens if set to 12 or 16 chunks rendering? We'll we'll cover that for sure. 30 minutes and already 20 people. Nice. I I would use a channel.
Oh, send a message to the thread to generate the mesh. Yeah, that's interesting. Then when the thread is done, it adds the mesh to a channel. And the main thread checks the channel every frame for meshes.
Hm.
Let me think about that. Oh, but why not let the thread directly edit the data? Why not do it like that instead of waiting for a response and then the main thread to have to use that mesh?
Because right now my threat I have a um here my previous thread directly had access to uh since my world is a singleton. My world is a singleton has a static like here a function to get the sub chunks and that function gets the data from here this static world data which is just the unordered map and my thread can get access to this.
The only issue is if I give it access to the thread I'll need to synchronize it with the main thread when I make changes. That's the only issue. That's the only issue.
But I think your idea is a better approach. I think it would be easier to do. Yeah. We'll look up on the internet for a channel. If you can synchronize access, then you can access directly.
The channel is basically a way to see.
Yeah. Okay. Yeah. I was thinking of using a mutx to synchronize it. I had it in Where did I have a mutx?
Get block type.
Where did I have a mutx? Oh, yeah. In the template, I think or the mesh pool.
I need to look at the CPP the mesh pool data.
Yeah, here I had a mutx. I was trying to synchronize working with threads with a mutx but with a channel should make it easier to organize everything. I'll look up the channel.
Uh how that would work because I haven't used channels.
Do you plan to add greedy meshing? No, I'll never add greedy meshing. First time cing. I'll I'll attempt I'll attempt to do first time curling. That's very important since it will give huge boost in performance, huge boost that will be really worth it. Greedy meshing.
Even Minecraft doesn't do greedy meshing like I'm doing. What Minecraft does, they don't use greedy meshing since in render doc um you can look at their um you can look at the draw calls you can inspect the mesh and in when inspecting the mesh it shows they don't use greedy meshing and greedy meshing will be very difficult to implement with uh custom uh blocks with custom blocks people already asking to collaborate with you uh if you can uh synchronize access then you can access it direct. Yeah, I read that.
What is greedy meshing? Greedy meshing is when you see like there are many YouTubers uh YouTube.com Minecraft optimization.
There are many videos on YouTube optimizing Minecraft like making a Minecraft clone optimized and some of them use greedy meshing in their video.
And there it they have interesting visuals on how they do that, what exactly greedy meshing is.
You can look up the videos. Maybe some of them will explain greedy meshing. Uh but I I'm avoiding it.
I I have no interest in greedy meshing.
Oh yeah, here remaking Minecraft greedy meshing.
Maybe here they visualize greedy meshing. Basically you instead of having a lot of cubes you the mesh instead of being like um separate cubes they are combined together in a single mesh like a single big cube you could say. Like it's as if uh where's my game?
Yeah, but I removed the meshes.
Like when you have one Oh, I can show you in blockbench.
When you have one cube loud ass does it models.
Let's look at the grass block here. When you have one block, this is actually like uh where's the wireframe shading?
Do they show wireframe?
Solid wireframe. Yeah, this is the wireframe of a single block.
And when you have lots of blocks, you'll have a lot of cubes like the these. But greedy meshing makes it so in like if you have here like let's say two blocks if we copy paste it here. Look at how when creating another block, it creates another mesh. And all of these meshes are like you have to have here additional for each one of these vertices which is the pointy parts of the cube. You have to give it like a lot of data like positions, colors, normals, that's a lot of data. And greedy meshing makes it so instead of having these two separate separate meshes for the two blocks, they get combined into a single mesh. So these at the middle will be gone.
This vertx here will be gone. And this will be it it will be as if you scale this. It's as if you're scaling a single block.
Resize. It's as if you have scaled it.
That's the difference.
And it will be like that.
That's greedy meshing. But then it's difficult to uh fix up the textures here. Now the textures are are stretched. You need to figure out the textures. And what are you going to do with complex blocks?
Here you have like uh the anvil, let's say.
Yeah, you have the anvil. And let's say you have like uh how are you going to greedy mesh an anvil?
Like like I don't know. But I'm not at all interested in greedy meshing. I don't care about greedy meshing.
Uh what's up? Uh when do you plan on adding the hut? I already have the hut but in the Java clone. Uh I'll add it when we have the player.
I don't blame you. Green mic is hard to do all but if you were able to do it then you would probably gain here. I don't care about that. I don't care about that. Put on sensor videos to unstimulated.
What the? Hi. Hello.
Um, I was bros only view mali and now like there people watching bro. It's like watching monolith getting painted.
Muskill's world. Um, yeah. I remember when I implemented the skeletons and all of these chats were just mskill and he was making company.
Um, texturing after greedy meshing is easy. Just clamped. I highly recommend adding it. Very simple. No, I don't.
Yeah. What are you going to do with the more complicated blocks with greedy machine? Like I don't just have dirt blocks. I have anvils. I have What are you going to do with the redstone repeater? the torches, their custom meshes. If implementing greedy meshing once, you can solve the texture. I don't care about the texture thing. I know it's solvable.
I know it's solvable.
Uh, so have you done cut? Yeah, I was watching you when you implement the cursed skill.
Yeah, that was wild. I had brainstorm about pivot.
Yeah, the pivotes were wild. when you had you don't really me the comp. Yeah, sure. Like I can ignore the complex blocks but uh it will just make it a mess to manage everything like some blocks to be greedy meshed other blocks to not be greedy meshed. Uh as of now it's fine like it's fine. The fix was easy bro it's not an issue. You could just ignore using greedy meshing.
We're not doing greedy meshing. We're doing endless terrain. Like let's focus.
Let's focus a bit. It's not easy. We could greedy only. No. Chill. Chill. No.
Let's not get excited about greedy meshing. We're trying to make the terrain endless.
Like right now it's actually endless.
But we are not generating the meshes.
And I'm trying to notify the threat a separate threat to generate the meshes or at least to give me a generated mesh.
At least that. And one of you guys suggest suggested using a channel. So well let's see what a channel is. I have no idea what a channel is. Maybe I've used it in university but I didn't study in university too much. It was very boring.
I I learned I learned more making my Minecraft clone than than in uni since I'm excited to do this. It's it's internal motivation. It's not external like having a exam and a deadline.
Uh channel communication with thread C++ let's see how can we communicate with a thread inter thread communication multi- threading channels CPP channel. Mhm. Multitrading let's see what the channel is there something conditional variable I've seen a conditional variable when I attempted to do a thread pool here I was searching on Google uh tutorial for a thread pool and either it was tack over overflow it was some kind of a page and they had this thread pool like to use it and they use conditional variables. That's where I've heard about conditional variables but I stopped using this since it was too complicated. I just use uh a simple threat here. I just execute uh create a simple threat and that's it.
Yeah. Let's see what conditional variable is and if they talk about channels h um what did I miss?
We need fix RAM problem. Yeah, RAM we went the the memory leak was like 40 GB.
We haven't fixed that.
We haven't fixed that. What it working on making the train endless. How much RAM does it br?
What if you gave me this one megabyte?
How are you meshing right now? Right now I'm using ray lip.
Uh relip has a class class for creating a mesh here. I have yeah this is to generate a mesh. I go over all the blocks in the current sub chunk and I go over the neighbors the top neighbor bottom neighbor. This is for killing the faces.
But then I have to go over through more neighbors. This is for ambient occlusion.
And then I then I have to create the I need to get the data for the block itself that I generate through the JSON files. For example, this is for the anvil. And here it has like for cink as well the yeah I generate the block data through the JSON file. Then I then I have the data I need to insert it in my arrays here. The arrays these arrays I need to insert it here.
Um, I have to think of a way to not rely on like arrays like this.
Uh, then I calculate how many indices I will need to give them an offset since I change the order sometimes for the ambient occlusion. And here's the actual mesh preparation. I'm using the rail mesh class here. The relip mesh class needs vertices, texture coordinates, normals, colors, and the indices. I fill up the data.
I fill up the data here, which is just going through what I have collected through all the blocks that I've iterated through. And I have to allocate some memory for all of the arrays. I have to allocate memory. And yeah, I just set this flak to true that the mesh has been generated.
And then a model needs to be created.
And and no, this mesh needs to be uploaded. Yeah, the mesh needs to be uploaded which relip handles. Raip uploads the mesh and then I need to load the model from that mesh. This is again from then I just draw the model with the appropriate like shader textures. That's the process for generating the mesh. As of now, there's no greedy meshing.
Are you going to get sued by Mojang?
Well, if I don't release the project, we're fine. I assume I assume bro made the bro made the calculations etc. Game was supposed to use. Yeah, game needs to be a lot less RAM. He's going to get working on my inject client. and wire links over and does it also happen? I don't know about Python. Like here the um here in C++ I'm managing the memory myself like in Java in C you have a garbage collector that manages the memory for you. And so in C++ since I'm creating like pointers like here is an example like here this data I created in the heap. This is memory I have created that I have to delete. I manage this memory this array of like block ids and when I destroy the sub chunk I delete the array from the heap.
If I don't delete it that's where the memory leak comes from. I need to see what data I have created that I have not deleted. That's where the memory leaks leak comes from. And we managed to reach 40 GB of RAM memory leak in the previous stream.
Bros like modern Minecraft using 3 GB and my clone using. Yeah, Mali has very good memory for some reason. That's very good memory. Uh I don't I don't think you can get memory leaks in Python. You can use uh concurrent Q for inter thread communication.
Oh, concurrent Q. I get it. Yeah, let's Yeah, let's use a data structure that's good for multi- threading.
Let's use a that's a good call. We can try it and see what happens.
Concurrent Q and we'll make the queue of requests. M no I will need to receive back the mesh data maybe two cues one for the requests and another queue for the results and they are concurrent and that's how I can do it yeah that's how we can do it yeah that's thank you for that plug and play that's what we want plug and play I want to be easy and simple is difficult If you do, you should get an award. Uh there is a server where you can play from Halfife one. At the same time, there's also even more games. So for me, yeah, that's cool and awesome. How much optimization have you done? I'm not focusing on optimization. I'm focusing on adding features. I much prefer to have all the mobs, the dragon, etc. to have the player and not be optimized than to be optimized but to have nothing as features. I want the game to be playable just like my Java clone.
Probably negative if consider be you don't have to call manually in there. I see what you're doing. Makes sense. Um just change the texture of the blocks.
Uh the only way you could get suit using texture sound. Pretty sure there are project likes that use texture and sounds. What do you think of simple smart pointers? I'm already using them.
I'm using them. smart pointers in the block factory. Here I have a cache of like block classes and when I need extra like data for like is a block transparent instead of storing it for every like block in a sub chunk which is many many many blocks. I just have classes and I go to the singleton block factory call this function with the ID of the block and either it will create a class and it will give give me a shared pointer of it or it will give me a cached one here in the cache which is a hash map of like shared pointers of the block class which before it had abstract methods but right now it doesn't have any abstract methods.
like I was doing the this function is transparent. I had it abstract and the other ones overrode it but I didn't need to do that. Now they are just very simple. They're like uh here the grass block in the constructor. I just set up the configuration. I set it here like a boolean is transparent false. What is the JSON model? and here to add a custom collision box that I use for the block hover.
But uh that's where I use uh shared pointers. I use them here like smart pointers.
I was thinking of using unique pointer since share pointer keeps reference of how many like axises we have but I couldn't think of how to do it with a unique pointer. I don't think it would be possible.
use concurrent Q on GitHub. Okay, we'll look at it as well.
We'll check check that out as well.
Concurrent Q. What's this?
A fast multi-roducer multi-consumer log free concurrent Q. That's interesting.
But first, we'll try the is this in let's do C++ please. that I think was for something else.
Concurrent Q class. Yeah, this is what we'll try if we have any defaults from the like default libraries. If not, we'll try this. We have many options. I have the worst memory ever.
Uh any lip is I'm using cr and I'm using what else I'm using? I'm using library to parse JSON files. I'm using a library for pearly noise which is a single header file and I'm using trac for profiling. This physics one I'm not using it. This is my library where I wanted to implement physics from a book but I'm not using it right now.
I'm not using it right now.
Yes, you can double buffer too. I feel bad but cuz Oh yes, you can implement yourself. It's very lightweight though. Single header.
Are you looking for texture? I'm not looking right now. You should make a Discord server for this. I had one but I deleted it. It was too distracting.
It was too distracting. Why another JSON script CPP another H? That's a good question actually.
Okay. Um, I need to make them separated.
I need to make them separated since like here the anvil Jason doesn't have a value for if it has like Okay, let's look at the dandel. No, let's look at the the leaves. Let's look at the leaves. I need them here. They have a property that they're transparent here.
The leaves. This property. Where am I going to get that property from? I need it. That's why I need the separate header file, the separate JSON file and and it's only those two.
There's no CPP. Uh but it that's how I did it in my Java clone because I need to have a class for every block. I need to have that since uh for example, how am I going to handle redstone? The redstone needs a separate block. Where's my red stone?
Uh for the redstone logic here, redstone torch. When you uh place it, when you place the redstone torch, uh it needs to give out signal and on update it needs to handle some logic.
own removal needs to remove S signal but as the just the torch the redstone itself like they need a separate class they need it like why are anvil JSON and CPP separated what are header using for pearly noise ple noise it's a single header is this one is this one just search for this you will find But uh that's what I found from a simple Google search. There may be better options. Yo, hello. What's up? I have a question. What data are you keeping for each block? For each block, right now I'm keeping only like the block type only that as of now.
Where is it?
In the sub chunk. Yeah, here I'm just keeping the block type. But in the Java clone, I have more data for each block.
In the Java clone, I have the skylight source. I have the uh block light, skylight uh bottom direction like in Java, I have more per each block.
Yo, what's up? Yo, uh hope this can help out.
Chill, chill, chill. Like I'm really thankful for like uh giving support but like uh uh like it would be if if we think about it it would be better if you like keep it for yourself like while watching the stream use that money to buy to treat yourself with a snack with some coffee like use that money for that like while you're enjoying the stream to like get something for yourself that would be uh enjoyable but yeah like but still thank you man like it means a lot.
Um, yeah, even I'll save you. This is the first one.
I'll put you to Excal here.
Yeah.
Uh the first so humble uh why do you stop working on your Java clone?
Oh. Um because uh the blocks are entities. That's interesting.
Um yeah, but thank you again. You're the first one. That's significant. Why do you stop working on the Java clone? um in the Java clone um because I reached um like an end to it like because here I will show you in an example like I have this entity like I I saw how unity those entities and I copied it for my Java clone here and using components but I had an old entity system and I'm still using it. I cannot easily remove it. It became quite a mess. And for the blocks, I started using the JSON files here. I started using the JSON files, but some other blocks um don't use them. They I have multiple old systems and new systems running at the same time. The project became uh a big mess like Mali can tell you about that. If you want good textures, I recommend Mind Test Game Block. It's open source. When will you have version of God do?
When will we have a version of God do?
Well, I have a God do version, but it's just the terrain generation.
I really wanted to try God dot to see how it is like in good dot. And I I really like the experience, but I liked Railip more and I stuck with Railip.
I stuck with Railip.
Yeah, I have the terrain generation in good dot.
If I would have to pick between Unity and God do, I would have picked God do.
My only issue was that uh um you didn't have you couldn't work with entities from the scene here while the game is running. But a viewer told me that that's not true. You can actually change objects while the game is running.
Uh where was that?
In remote here you have access to everything that's generated here. This is everything generated all the meshes here. This is one of the mesh and you can play around with them. It's just like in Unity. That was the only thing stopping me from uh switching to go do and this like was really cool here. I can change them while the game is running and everything is updating.
So like god dot is a perfect option to use if you want to use a game engine but right now I'm enjoying relip a lot more because relip offers me opengl direct access to openg here I have rip library the source code and I can change whatever I want in relip and they use open gel for rendering like I love rel is perfect for me.
Um, I have a question. What are the blocks in Minecraft? I don't know how it how it is in Minecraft, but here they say in Hightail the blocks are entities.
H, that's very weird.
Like for example, the piston in Minecraft. I'm pretty sure like here if we add a piston here game mode creative here if we add a piston right now it's a block I'm pretty sure in Minecraft. And if we put here a torch during the animation, I think it becomes an entity during the animation. Look at how here you have ambient occlusion. And while the animation is running, that ambient occlusion is gone.
Like even now it's gone. Like I think here it's a block and now it's an entity.
So I think Minecraft does both. Like both some blocks are just blocks and others are entities.
Project management was so bad at Java com bro had waste whole stream just to fix simple book like skeleton. The project management legit made me question bro sanity.
Uh thank you.
Thank you. Thanks. GDScript is very simple like Brawl nerfing himself with the project management.
Uh, one thing I learned is that I don't generate notes to create chunks.
One thing I learned is that I don't generate nodes to create chunks. I send them directly to the rendering server.
Oh, you have a rendering server. This optimize the number of nodes and consequently the engine's calculations.
Let me think about that. So we have a rendering server.
One thing I learned is that I don't generate nodes. What's a note? What's a note? to create chunks like you don't generate uh classes or like heap data or send them directly to the rendering server. Uh some blocks are entities, some are not but mostly not entity. An empty block in Minecraft is the item frame.
Uh chest setter counts as entity like how Goku and Rocki wear heavy clothes use put instead of C++ note are the things that scene object single. Oh notes yeah notes notes I get it. This one. Oh, yeah. Here.
Here. Yeah. Yeah.
So, when we run this, it's these ones. So, you don't create these notes. I get it. I see. Yeah. But this is the good old project. Uh, I'm not giving it that much attention. Yeah.
Let's make progress, man. Let's make progress.
Let's make progress. Uh for me nodes will be entities.
That would be note in my in my game.
That would be a note for me like in um with the components. So here in the Java clone the entity I will just have an entity and here the map of components.
Here I would have a component for like um here this mesh instance 3D I would have a component that's this that's how it would be in my game. Yeah.
So let's try to communicate with the thread with this concurrent queue. Uh do we have it directly?
Can we directly access it?
in the world in the data where is the here in the world data let's add some concurrent cues and let's see are they in like the std concurrent concurrent current um where is it concurrent Q and not this I think concurrent Q do we have it here let's just test it do we have to implement include yes we have Wait a minute is it std concurrent Q is not a it's not a template Really?
Oh, STD.
And it says it's not no member conc.
It's not in STD. Where is it?
Yeah, template and the type. I should be able to give it type.
Uh so here I should be able to do vector 3 for example concurrent Q.
Uh let's look at example that will solve all my questions.
example or any kind of documentation.
Oh, don't tell me he has his cultus images.
That's weird at this point or greedy mesh some type recurring Friday cartoon will allows you to create classes using in the future which will be very useful for you if you I'm waiting for the 900 hour video of learning god dot and recreating Minecraft. Yeah, using an engine is very helpful.
Yeah, I'll save this comment as well as future reference.
I'll bookmark you right next to here.
H then how do I get it? Concurrent Q. I need this Q to communicate with my threat.
Namespace concurrency. What is this namespace?
Concurrency.
Oh my god. Concurrency.
What? And it's with a a capital letter.
What is this name space concurrent Q? Okay. Okay. We have a we can communicate with the uh threads this way. So let's have requests request here we will request to render the meshes but h I think I was thinking of giving the request to be the position of the player something like that. So here to request the request to be the position of the player and the threat to know okay I need to generate like the sub the meshes around him but that will not be okay because when we move around how will the thread know if some chunks need some sub chunks needs a thread a mesh to be generated the thread doesn't need to know that. So, let's have the request to be just the subjunk that needs a mesh generated. That will be it.
That will be it.
And should we get the result back?
That's what I'm thinking. Should we get the result back?
Um, rendered meshes and here to be a mesh.
Should we get the result back is what I'm wondering.
Um, let me think about it.
If we get it back, we need to go over this queue. We need to go over it and to give this mesh to the appropriate subchunk. So, it will it will need an indication of which mesh that is, it needs an indication.
So some kind of a structure like um um red mesh result something like that. And here to be the mesh rendered mesh and here the vector three mesh origin something like that. and here to give me the result.
Something like that. And I can go through the rendered meshes and give them to the appropriate uh subjunk.
And this will actually work most likely.
Most likely this will work.
Most likely.
Uh you going to make it downloadable?
Probably not. For a while I was doing nothing but today I decided make a comic or animation. Have a nice day. When I do serious progress I will share with you.
Make a video about it. Document your progress. That will be of big use to you. WSG I don't know what that is. You grinding on the project even sometimes you have zero give me inspiration. Well when there are zero viewers I make a lot more progress. So I benefit in both cases either when people are watching or not.
I like I have their pros and cons in both cases. Even if there are zero viewers, it's like going in a library.
Like I don't procrastinate. I'm much more focused.
I'm much more focused.
Yeah. by Maskelly, thank you for joining and making company here to me and chat.
Now, uh I need to fill up these requests. That's what I need to do. So h here when we this is only where we will focus here or actually we can do it here as let me think about it. Yeah let's do it here. Here instead of generating the mesh like before we can um we can instead of generating the mesh we need to give a request.
We need to give a request and we need to create a function for that.
static void um request subchunk mesh generation vector 3 mesh origin um subchunk origin actually subchunk origin and then let's create this let's create this and we'll just fill up the queue with a request.
Let's fill it up.
World data request um push at push subchunk origin. Um, can't we do a con reference?
Yeah, let's update the definition as well.
And instead of in the main thread generating the mesh, we will request it.
That's the difference. We'll request it here.
So in the world um request and we will request the position. That's the difference.
And let's comment this out. Now we are doing the request and the thread needs to check for that request. It needs to go over the queue.
Needs to go over the queue here.
H.
Let me think about it.
Should it go over all of the requests?
So a while through loop or how should I go about it? Yeah, let's do while world uh I need reference to it. I need reference to it. So let's make a function get subchunk mesh generation requests.
Let's comment this out.
And the return type will be what will be the return type?
Where is the world?
Um, have fun. Thank you. I hope this time skeletons won't cause problems by Yeah. Hey, what's up?
What's up?
Um, I need to get reference to it.
H need to get reference to it. So, it's this.
It's that.
So, can I make it like a reference?
Probably.
And I need to have the include be there.
Let's go in the header.
And no, not in the header. In the CPP. This, let's remove it. needs to be in the header so it doesn't cause me issues here. And let's do an implementation where it just returns it world data request.
Yeah, that's it. And the threat.
And the threat.
Where is the threat?
here.
Yeah, I'll call it here. But uh I need here to include it as well.
Uh do I include the world? Yeah, include the world, which should automatically include that as well.
Uh but let's get a reference to it.
Concurrent concurrent Q of vector 3 um requests to equal this and I need to implement it. Now I need to include the header.
Sure.
Let's include the header.
And what's up? Concurrent.
What did I use? Concurrency. My butt.
Let's remove the include. Most likely I'm getting it from the world. Yeah, I'm getting it from the world header. Yeah.
So while this is not empty empty while it's not empty I need to get a vector tree um sub chunk origin to be requests pop try pop excuse me why try Yo, what's up? Um, I'm trying to make the world endless.
It's actually endless, but I'm moving it in a separate threat, the mesh generation, so that it doesn't have a lag spike. You should get a team to do this. Yeah, but it will not be fun. Then for the Minecraft clone, I don't want a team. If I make a game of my own, I'll definitely need a team. I'll need an artist. I'll need somebody that makes music, somebody that can make Steam capsule art, but that's if I do my own game. This is just a project where I learn how to code games.
So, we have a clear, we have an empty, we have push tripop. Yeah, we need to do a tripop.
We need to do a tripop.
And what's up this?
Oh, I need to give it reference.
Oh, like I need to give it an object. Yeah, tripop. Okay, I see. And why is it try?
Why is it try? if it was successfully decued.
Oh, it returns a boolean. Okay, so I I have to do an if check if if this is true.
If it has successfully gotten a subchunk request and now here we need to generate its mesh.
So let's here I have an idea for the subchunk. Let's make the generate mesh function be static and to return a generated mesh. Let's do that. So sub chunk, let's go inside of the header and generate mesh. Let's make it return a mesh, an actual mesh.
Let's make it return an actual mesh and make it static.
Generate mesh. And the only Yeah, that would be damn it that would be here. I would need uh position vector con reference uh subchunk origin and let's copy this subchunk origin.
H yeah, let's remove this mutx lock and it needs to return a mesh here.
But um yeah yeah yeah actually mesh generated mesh will be equal to this initialized with a zero. That's what we'll return.
That's what we'll return here.
Return this.
And we'll not be able to use this flag and generated mesh here.
It will be all of these.
Now, how can I quickly select all of them?
like this.
Like that. Yeah, that's it. Sure. And I need to handle all of these errors.
But in the end, it will return a mesh that I'll reuse.
Hey yo, what's up? Proud to be your subscriber. Plus one subscriber. Yo, nice. Yo, what's up? Plus channel. How's your day? Joined a few minutes ago. How far have you gotten here? We're pretty close actually. We are pretty close. Um, since we got help from a viewer, it was very helpful suggest suggest suggestion on how to communicate with the thread uh by using a concurrent queue. And I'm sending requests to the thread to generate meshes.
But um I need the thread now needs to generate them. That's what we're doing here.
The threads needs to generate them. H I need a reference uh pointer to the current subchunk which would be from the world get subchunk.
Let me think about it.
um subchunk origin and if it's no pointer will return and there is a huge issue actually there is a huge issue since um while the thread is working with this pointer to a subchunk there is a huge issue since um that data could be deleted.
Since uh in the main threat when the player moves around um when the player moves around some subchunks get deleted and when they get deleted the destructor gets called. This which like all of this will be gone but we have a pointer to it here. We have a pointer to it. That's very bad actually.
That's very bad. I'll have to think about it how I'm going to do it. What's your PC specs here? You can look at the Minecraft, the Nvidia card, the you can screenshot it and look at it. It's on the right.
The CPU can look at it there.
Hi, how are you? I'm a bit I'm struggling a bit and just so you guys know there is a storm right now and where I am at when it rains I have issues with the electricity and internet. I'm not living in the like u like here it's the electricity and internet is very volatile. So if the stream is suddenly gone, just know there's a storm here.
It's uh just so you know, but while the stream is live, I'll continue on doing it, continuing on to progress.
But we managed to reach a tough spot.
We man yeah we managed to reach a very tough spot since here I get I'm working with pointers and I'm getting a reference to sub chunks the current one and the neighbors and and that's very bad because they can get deleted at any moment since this is running on a separate thread that's very But H and man, so what does the thread actually attempt to do here? It has a request, this thread to generate a mesh. The mesh generation needs to happen here.
Absolutely. It needs to happen here in the separated thread. It needs to happen here because if the mesh generation for the subchunks the terrain happens in the main thread, you'll get a lag spike and that's and that is unplayable. here in Minecraft.
The entire when you move around it, look at how smooth it is. The generation of the chunks, it's very smooth.
And for me, for that to be smooth, I needed to make it work in the uh separate thread. And here, even in Minecraft, in the options, you have an option for um changing this. Actually, I think in Minecraft you can change it to not be in a separate threat. That's very interesting. I managed to find it at some point performance maybe chunk updates lazy chunk loading chunk builder threaded. Yeah, this is it. Semiblocking update player affected chunks instantly. Fully blocking update all nearby chunks instantly.
Threaded updates may briefly show holes in the terrain. Fully blocking updates may cause significant luck spikes. Yeah, let's see how they manage to do without threats.
It does it lag for them. Without threats, how is it still running smoothly without threats for them? That's interesting.
How fast is their mesh generation?
Let's increase the render distance.
That's sub that's surprising actually that without threats it does they don't have a lag spike.
That's very interesting.
It's even faster than with threats.
Actually, it's even faster than with threats.
Surprising how they do it.
I'm pretty sure I turned off threads here. Yeah, fully blocking and now thread it.
Yeah, that's very interesting how they don't have l spikes. I have lag spikes even on a 5x5 world.
Um, are you are you purchased the game?
I Yeah, I have the game Minecraft. I also wanted the game, but I don't have that much money. So, can you What are you suggesting? Suggesting I'm not loaded, man.
Um yeah, that's what we are trying to do the mesh generation to make it on a separate threat. But the issue is here I have the request here. All it says is please generate please generate the mesh for this sub chunk. That's it. And the thread has gotten the request. I assume probably I haven't run it. I haven't run that code.
We could test it here with a simple console lock. if it's actually working.
Uh that would be useful. But before that, um it would be a lot more worth it if we figure out how to solve this issue since I have the reference to all the neighbors.
Like I I don't care if the neighbors are missing or not. The issue is keeping the reference when it it gets deleted because I can get the reference to a subchunk here. I can get the reference and while I'm doing work it can get deleted and and all of the data gets deleted might donate like one or two like you don't need to donate like don't don't think about that just the it would be a lot more helpful for the stream if you just watch if you just like uh like just watching, liking, subscribing that uh to tell the algorithm that there is interest for the content. That's uh that will go that's beneficial for both of us. But uh donating that's um beneficial mostly for the platform YouTube and Twitch since they take a cut.
This is my blockage. This doesn't allow me to continue uh and progress with my with my goal. This stops me from reaching my goal. Only this part right here in the code, this stops me.
What's can I what would be the alternative to this? The alternative would be if the request also has the data needed.
Let me think about it.
Why do I need this reference actually?
Why do I need it?
It's only to get the neighboring blocks to ne to get the neighboring block data h or or the deletion of subchunks. I could make it into a request system as well.
I could make it in a request system as well.
like uh instead of deleting the subch because that's the what that's what's stopping me here. I get a reference to the subchunks but the main thread could delete them at any moment and it would invalidate everything. But if I handle the deletion in a different way, that could solve it. But the easiest way to make progress is to keep it simple and stupid and with ugly code like just to get it working and we can improve it later. We can polish it later. So what would be the easiest next step we can actually do right now to get past this blockage?
What would be the easiest next step?
We wanted we got we got to here. We got to this problem because um I wanted to generate the meshes of subchunks in a separate thread. That's why we're here. That's why we're here.
the easiest. It would be easier if instead of moving it to a separate thread to instead of moving it to a separate thread here, instead of moving it to a separate thread to improve it so that it doesn't have the luck spike without threats because here in Minecraft we can look at video settings performance. If I remove threads and it's fully blocking, you can see even with this big render distance, there are no luck spikes, zero lag spikes.
So, what I could do is optimize my clone so that there are no luck spikes and not have to bother with multi-threading.
That would be interesting if it's possible because I assumed it's not possible.
I just assume that.
That's very interesting how the game is not lagging without multi- threading. That's very interesting because when we add an additional thread, when we make the code multi-threaded, it makes it a lot more complicated and harder to manage. That would be the simplest next step if I think about it instead of doing these requests.
Yo, Splits here on another account. Yo, hello Splits. What's up? It will be difficult for me to remember you that you are Splits uh later on or if you join another day, just so you know.
What's your graduation? Then I graduate computer science um like a bachelor's degree but I didn't go for the next step like some masters etc. Just a bachelor's bro practically said upload a game for us so Mojang can see you and we have it for free. I graduated Harvard free seat.
Yo Mojunk Microsoft is doing every game which Minecraft like. Yeah, Phoenix made a video like Phoenix is a popular YouTube Minecraft content creator.
Yeah, Phoenix made a video how more junk. Um, here I'm not subscribed since this is my life channel. I'm subscribed on my main channel.
Um, but uh he made a video how Minecraft made issues to a Minecraft clone like kind of like a co Oh, not this game. It was another game I think. Yeah, I don't know. Maybe it was this game that was released on Steam that looked like Minecraft and more junk went after them.
H Yeah, I probably won't. I'm new here. So, how much progress have you made since when?
Since when? I'm trying to make the world endless. We made it endless, but um it it had a lot of luck spikes. Like this is the original Minecraft and I made it endless, but I had luck spikes and I was thinking of fixing the l spikes by using multi-threading. But here in Minecraft in options in video settings and performance, you can set it to not use multi-threading. And there and look at in this big render distance.
There are no luck spikes.
Uh let's actually save and quit and load it again to be absolutely sure is that's the case.
Yeah, we're not using threats.
We're not using threats and there are no luck spikes. That's crazy, man.
It That's crazy.
Is it possible for us to do it like that?
Is it possible instead of trying to make it multi-threaded to keep it on the main thread since it will be simpler the code and easier to manage to keep it on the main thread and to figure out how to remove the L spikes?
That would be interesting.
We can I think we can even attempt to do that.
We can attempt to do that.
Uh let's comment this code out and let's bring back the here. Let's bring it back how it was before.
Gen let's remove let's bring back the mutx lock and here make it void and let's bring back the mesh generation.
I changed it to make requests, but I'll have to bring it back.
What does generate mesh want? Yeah, let's remove this as well.
Let's remove that.
Yeah, now we're generating from the main thread.
And what's up with this? Oh, it's a static. I need to remove the static generate mesh. Any issues?
Doesn't look like it. Sure. And um let's bring back where is it?
Here. Let's remove this return.
And this is the current world. Let's remove the grit.
Draw grit. Let's remove that.
Let's remove that. Okay. So, this is the current situation. Look at how we have L spikes. And my idea was to move this the chunk loading to move it in a separate thread. That was the idea.
But we noticed, we found out in Minecraft, they don't have flag spikes.
Even when they don't use threats, it's fully blocking. Update all nearby chunks instantly. It's fully blocking and they don't have L spikes.
So instead of trying to make it multi-threaded, we can try to just fix the L spike from the main thread.
We can just do that and we're done. If we just fix the L spike from the main thread itself.
What did I miss? Minecraft isn't endless though. It's endless enough. It's endless enough. In clothes I made a few years ago, I used Core routines, but this was in C. Have you planned to make your clone become totally different game further? Um, uh, if not exactly. If I make a game of my own, it will be a Vau game like Minecraft, but it will be a different project. It will not be this project.
Why don't you use name space std? I do use it, but not for the concurrent um the concurrent queue. Why don't you pirate the game? Kame wasn't really just a clone. Was a scam to get personal info from. Steam sucks in detecting scams.
I'm also a deaf. Okay. Uh nearly a Minecraft trips have m uh chat. How many devs are there? Just get it from a key. Probably most of the viewers are developers. I assume that the key with making this work well on a single thread is to process the chunks over multiple frame. Yeah, that was that's what I was thinking as well to not process it at the same time. You don't process every chunk around the player at once. That will never Yeah.
Except me, I guess. Uh except me, I guess. Everyone 6x6 blocks is massive still. You want to build the meshing in the background constantly over frames and render them all when complete.
Processing all chunks at once, but it doesn't. GPU offloading is better than what's empty multi-threading.
Uh what's GPU offloading?
uh to let the GPU do computations or was that I followed your Aspir tutorial. It was very helpful.
Yeah. Um I'll make another version for 2027.
I'll make a new Aspirate tutorial for next year so I keep it updated. 6 million by 6 million.
Yeah. Um let's see let's see if we can make this uh continue to generate in the main thread.
In the main thread H if we are going to do this in the main thread how would that work? It should happen in uh multiple frames.
We could we could we could do it uh in a queue not concurrent queue a regular queue in the world here we can do a regular queue we can do a regular queue and that's if we do it like that we don't have to worry about um here the the issue here with the subjunk references since everything is on the main thread there's no concurrency issues here with accessing neighboring sub chunks that wouldn't be an issue. But uh we'll see about that actually. We'll see about that.
Let me think about it. Generating the mesh or I could there's an other thing we could do in the sub chunk.
Am I live? I should be live.
Should be live.
Yeah, something happened. I should be live.
Yeah. Okay, I'm live.
Something happened.
Yeah. Uh, okay.
Uh, I was thinking of in the sub chunk. Look at how the subchunk stores the data. And when we destroy the subchunk, we delete the data. But we can make a change to that.
We can make we can separate the data from the subchunk.
We can separate it and have the data.
we can separate it because I I still think we'll get issues um here when we access the neighbors here when accessing the neighbors if we just get the reference to the data that never gets deleted then it will be different.
Um, I got a Minecraft PCK for £13, I think. Could you technically stop floating point precision errors by doing keros space program does for future got update but um is scam okay they call me croissant bro guys you know but here we have Indian rupees what are you working on today I'm trying to make it endless I'm trying to make the world endless so here this it's actually endless but I have luck spikes so I the first attempt in this stream was to have multi-threading so that we don't have the luck spike but as a viewer suggest suggested we could keep it single threaded since it's simpler that way we can keep it single threaded and have the generation of meshes happen over time over a few frames so that we can remove the L spikes but keep it single threaded. It will keep it uh simpler.
It will keep it simpler.
Uh in my country we use euros. We transition from lever to euros in this year.
Welcome Indian rupee. Uh GPU offloading is the practice of transferring heavy parallel computations from the CPU to GPU. So do are you suggest suggesting I should use like a compute shader?
Um it would make it difficult offloading to the GPU when I use RAIP since if everything is on the GPU like I've done it for another Minecraft clone the 10 million TNT clone. I offloaded everything to the GPU. Uh but um but I'm not sure if I'll be able to do it with RIP and it will make everything a mess. I'll have to make a lot of changes here when blowing up 10 million TNT.
I offloaded everything to the GPU.
when I blew up 10 million TNT here. This project everything was with compute shaders in the GPU.
Uh but uh I will have to refactor too much code. I'll I'll keep the work in the CPU. When will it be done? I have no idea. 6 million blocks is the bar you have to hit. Well, hopefully we'll hit it.
Is flatter. You should profile to see what actually causing the lux the profile uh the l spike is the mesh generation is the l spike when because I'm trying to generate the mesh for like everything computer sh wouldn't be overkill here I would um so what are you going to tell built in steps build all blocks arrays in the view range first then yeah I'm I've separated it first I built all the block arrays I do that first I I have them separated and I wanted to transition the meshes in a separate chunk but in a separate thread but I'm thinking to do it in the main thread uh they have four neighbors in the view range that way you'll never get um I'll never get the neighbor block issues sure yeah that's true uh but Um there's still the issue of like in the multi-threaded um case if the main thread unloads a chunk it will delete the block array and that's an issue but I'm thinking on keeping everything on the main thread where not why are you not subscri why should I be I'm highly unfortunate that's what said couldn't you preload meshes to put them in couldn't Don't you preload meshes to put them in when chunk generation? Yeah, but that pre-loading still needs to happen at some point. I'm from Bulgaria.
Uh hello, how are you jetting the mesh?
Um I go through every block and I look at for every block the neighbors. I look at the neighboring chunks as well, their blocks. Yeah, this is a single trade approach I'm talking about. Never handled multi. Okay, let's building steps.
Then you build all meshes. Yeah, but building all meshes uh creates a L spike here.
Actually, how many meshes get generated?
Yeah, just these meshes cause the L spike.
The unloading is fast generating uh these faces. We'll ignore them since if we just remove this like it fixes it like this is not an issue right now.
This is a priority the last spike to do it in multiple frames in multiple yeah multiple frames.
Um guess what you do it over multiple frames as I said before. Okay. Okay.
Okay. You're con uh do you uh Thank you.
Do you actually generate mesh data for every block? I think you should have one instance for each unique mesh and then use a different position for each draw call.
One mesh is the an entire um subchunk is one mesh. It's 16x 16x 16 blocks. And each mesh is like uh uh I think you should have one instance for each unique mesh. Most of the meshes are unique. Most of the meshes do actually gen uh for every block. Okay.
For every block I actually generate mesh data vertices. Yeah. For every block I actually generate for every but I need to do it since it's conditional.
Uh it's conditional like for every block. Um because here uh I have killing. If I have an instance, if I have an instance for every block, how am I going to have killing? How am I going to have it? That's why I generated um the vertices, normals, UVs for every block.
And I need to do it this way since I have complicated ones like the anvil. I also generate the anvil.
And the anvil has cing for example.
Probably at the bottom.
Probably at the bottom has culling.
Yeah. Here the down has kill face down.
Even um the meshes are different and ambient occlusion makes a change as well. I'm not sure how this will work. It will stop those missing block faces if you read all my comments. I have to go and take care. I'll check in from time 10 time. Okay. Yeah, I'll go back to what you said. Um I'm just going through all the other comments, but I'll go back to what you said as well. The entire chunk is a mesh. Uh only a sub chunk 16x 16x 16. I'm an Indian viewer. Hello. Uh I don't know if you have already but you maybe consider using for block data. Uh I'll see about that.
I'll see about that. Right now it's an enum but I am not worrying about that right now. GP floating is a non-blocking approach that moves heavy parallel work from CPU to GPU main thread stalls improving performance. You should try uh right now I want to see if I can do it in a single thread in the CPU.
I got no clue what we are doing in the back end but I'm still all for it. Yeah, that's totally fine. Uh that's totally fine. Why don't you use AI to help you?
Because if the AI does the work, I will not get satisfaction once the work is done. Uh so that's why I don't need it.
Like why would I use it right now? Right now I don't need it.
Like it would be so boring if I have a problem then the AI solves it. Like the goal healer is for me to learn. I don't want to offload my thinking for this particular project. If I'm doing another project that I don't care about, sure like whatever. I don't care about that.
But this is important project for me. I want to I don't want to off offload my thinking.
Uh let's look at um um his comments.
Build in steps. Build all block arrays.
Sure, I'm doing that. I'm building all block arrays.
Where is it?
Where is it?
Loading new chunks.
Here I generate the blocks. I go over all the new chunks and if there are new ones I generate their blocks. If I should remove and here I unload the ones I don't need.
I am doing them doing it in steps. I'm doing it in steps.
Then you build all meshes for all chunks that have four neighbors in the view range. But the issue here is I said that already. If I build all meshes, that's a L spike. That's a L spike for all chunks that have four neighbors in the view array. That way you will never get neighbor block issue. And if and you said that this will work even if it's in a se in a couple of uh you said this will work even if I do the mesh generation in a multiple frames. But I am I'm not sure how that will be possible since in the let me think let me think about it actually let me think about it before I comment.
So I'll have to remove this since this is what causes the L spike here. And if we run it, we get the unloading.
We get the generation of the blocks just not of the mesh. The mesh doesn't get generated. And here there are no L spikes. The the generation of the meshes cause causes the L spike here. This part is what causes the L spike since we do it for too many subchunks and in a single frame we try to do it to remove the L spike. This needs to happen in multiple frames and we could do that by here in the queue.
Um here this here to use just a Q a regular queue we don't need concurrency anymore.
We don't need concurrence.
Yeah, like this. Um, uh, let's remove this. Yeah, like that.
Yeah, like that.
So here instead of generating all the meshes we'll just put a request for them. That's it. We'll put a request and this is still all on the main thread.
And so here every frame we can process like just one subchunk.
Um here comes int li limit how many mesh per frame generated?
Let's do one per frame. Generate one mesh per frame.
Yeah, here. So if uh let's do it after we process the input here and after we update the camera here. If if um we need to get reference to the Q of vector 3 requests world get get requests and here if there are requests empty if there are requests if it's not empty we'll get one of the request quests.
Um, let's pop it.
Um, requests. Let's pop it.
Does it give a reference? What does it give?
It's a void.
Oh, it just removed. So, I need to get the front.
What does this give?
Uh, do I need to get get a reference? I don't care about that. Request pop.
And now h and let's keep count of how many we've gotten.
Handled requests equals zero.
Here we'll increase it by one. And here we can do while.
While while we have requests and the handled requests are less than the limit to execute this code.
So we'll generate uh subchunk mesh like uh once one subchunk mesh per frame will generate at most and we'll uh play around with how many we can do.
So we have the request we need to now generate it.
H.
Let's look for it if we if we can if we can find it. And if we And if the mesh is not generated to generate the mesh.
That's it. That's it. Let's test it.
Build failed. Why uh std?
Is it generating anything?
Uh, is it doing it?
I don't think so. Oh. Uh, have I implemented? Yeah, I push it.
H main.
Do I get to here? That's what I want to see. We're very close.
Yeah, we get to here. We get to here.
The subjune position is if it lets me see it locals.
How can I?
Okay, let's make it as a note reference.
Yeah. Okay. Yeah. Let's continue.
Uh, no.
Let's try again. Debug. Oh, it's in the We're in the release.
Let's actually debug it.
Uh so we have the position that we request and we actually get it from the world and we ask for the mesh to get generated and so does it do it?
We'll have to use a profiler.
We'll use a profiler to see what's up.
Um, what did I miss?
What did I miss?
Um, yeah, you could just have your sub chunks draw data be a list of mesh position orientation.
So, a 14 point floating block might be six.
Uh, yeah, I'm confused here. I probably won't even do. I'll look at your question later.
I'll look at it later.
Uh, hello. How's it going? Uh it's going very well actually because the idea of not going not using multi-threading to solve the problem. Uh I really liked it.
We got a sneaky moderator in chat.
There's no moderator here. I don't have a moderator. I don't know who the moderator is, but it's it's not me. It's not me and I don't have moderators.
Maybe I'll make Mascalia a moderator.
We'll see.
use clothes for just a little work.
He doesn't want to off his thinking.
Don't cost him money.
But I got three concrete reasons why what you do pixel art yourself.
Um I will never do the art myself because I'm not a good artist. I'm just a programmer.
Hopefully I can find a teammate. He wants to learn from this. And do Yeah, I want to learn from this. Do you have your code somewhere? No, I don't have it. I think we could give more. No, that's fine. That's fine. You just watch and enjoy or work um in parallel like do your own work as if we're in a library.
Uh we can both be accountable to each other. It will cost you money to work properly.
Don't some progress.
You subscrier vector 3 subjunk position equals vector 3.
Yeah. What is this about?
You forgot to close the constructor call.
the constructor call the subjunk position.
Yeah, I'll just uh search it in the Ctrl+ F.
It's not finding it. Maybe it's in another place here. Maybe.
Yeah, most likely it's this.
It looks fine.
Yeah, let's move on. Uh, I will look at this later. If there makes mistakes, it will be hard to resolve.
Uh, okay. Then I'll give you a challenge.
Wait, there's so many messages. I'm going prompt.
What happens?
What happens if you add the spider? Uh, I have a creeper and a skeleton, but that's in the Java clone.
Create a bro thinks we're going to make a game cuz Okay, there's a long long long chat.
I joked about the game. Okay, let's make progress. Let's make progress.
Yeah, let's uh open the Tracy.
Let's open Tracy.
Let's enable it.
Let's enable Tracy and see what's up.
Uh we'll see in the profiler what's going on going on. Oh, actually, let's stop it. Actually, let's stop it.
Let's stop it. We need to add messages for the profiler in the new code here.
Here we need hand uh profile scope and what should it be called?
Um what should be the name here? Um generate mesh frame by frame attempt or attempt and here no we we'll be able to notice it. Yeah.
Let's start the profiler.
Let's wait for the terrain to load.
Okay, everything has loaded and let's try to move and let's look at the profiler. Let's see what happened here.
Here in the main loop called when crossing chunk. Okay, that's different. called when crossing chunk is different here. What's this?
What's this?
That's different. We don't care about that. Here, attempting to generate mesh frame by frame.
Generate mesh. Go through all blocks.
It's actually generating a mesh. And here, what's this?
What's this? position details.
Get block.
That's different. Maybe attempt to generate mesh frame by frame.
Frame by frame. Yeah, it looks like it's working, but we're not seeing the generated mesh. We have to see why we are not seeing Oh, maybe because I removed the flak. Maybe because I removed the flak and I didn't Oh, no. It's not that. is different.
It's different mesh is actually generated and from the and from the profiler it looks like it's actually generating a mesh. Oh no, actually that's not the case actually because here we get to go through all blocks.
That's where we go to. And we don't have We're going through all blocks, but uh there's more to it. There's more to it.
There's Where is it? Here.
Uh we are missing mesh preparation actually.
So we are going through this but we are not going through mesh preparation because of here the return.
Okay we'll debug here but after we generate the initial terrain.
Yeah after we generate this.
Okay let's put the debug point here. Do we get here at some point? No, we don't get there. So, that's the issue.
That's the issue.
That's the issue.
It's actually running this code, but the indices are zero.
The indices are zero for some reason.
Why would that be the case?
That's interesting.
H That's interesting.
I still I don't have a original game idea.
I don't have an original game idea for now. I'm just making a one to one copy.
So when we go through all the blocks, we get the current block H.
Let me think about it.
Oh. Uh let's do a break point before this so that we can see uh what data is in the arrays. Let's do that. But let's wait the terrain to load.
And let's do it now. Let's do it here.
It should reach here. Yeah, it reached there.
H.
So positions is empty. Really?
Empty.
Yeah. Position. So position size all the time is zero.
That's weird.
And so we don't reach here here. So the killing is because of the culling. This says if H.
So why would that be the Oh, let's actually do a break point there.
Let's do a break point there. Do we have any of the neighbors?
Some of the neighboring chunks are no pointers. And what does the blocks data look like?
Blocks. Uh, we need to do + 0 then 16 by 16 by 16 something like that.
Um or like let's do like let's do like 4,000. Doesn't matter just so we can look at the array. Yeah, it's all grass blocks.
So there is data actually. So what's the issue? That's really confusing, huh?
That's really confusing. But um where are they separated?
Come on, man.
Yeah, like that. Okay.
Uh let's see if we are making a mistake before all of this.
Um here.
How did we generate them?
Yeah, I have to see them.
Here we do a request.
We do a request.
and generating subchunk mesh. That's what we did before. We did the request, but before it was this. Let's do it like this. Let's remove this. Let's remove the request.
Uh let's try again.
Now, let's move around.
Huh.
Yeah, we have a big big L spike, but uh it's managing to Yeah, it manages to generate new terrain. Sure.
Uh but um this is the approach we had before. This new approach makes it so generating assumption happens frame by frame by okay we get the position but we get it as a reference.
Is that the issue?
Uh, let's make it just be a copy.
That would be the fastest way to check if that's the issue. Let's try again.
Now, let's move No, it's only unloading, but it's not creating the new mesh. And the code is pretty much the same almost.
So here in the request we push the position in the while through loop while does this need to be a reference.
That's not the issue.
Um, handled requests. Sure. Yeah. Okay. I get the position of the subchunk that needs generation. And here it gets to here for sure. And I hit generate mesh for that sub chunk.
The limit is one per frame. Sure.
And I get the front and I pop it and I hit generate mesh.
So what's the issue?
Or I can the the issue is that with uh subchunk the issue is we looked through the we debug the code. The issue is that there are no like the code never reaches here. Never goes past this.
Never.
That's really weird for something to be zero. Value can be corrupted.
Yo, what's up?
The old system.
There is not much difference between the old and the new. The only difference is I make the mesh generation happen over frames to not happen in a single frame.
That's the main difference.
That's really weird. Use integer coordinates.
No, find works uh without issue. Like the debug shows the find is actually working. Um it stops uh here. This is what stops it. It doesn't reach here like the positions are always empty most likely because of culling. It's killing everything but I'll see about that. Call generate mesh on the I'm using the main thread.
I'm not doing it multi-threaded. Set me generated true after execution. I set it to true as well. Add logging inside generate mesh. I have the profiler. I I don't need logging.
Have a challenge.
No, I don't have Oh, to confirm. Oh, yeah. Let's remove the limit. Yeah, you're right. Let's remove the limit.
Yeah, you're right. You're right.
How it determines G.
Uh, I'll do that. I'll do that. He's working uh with C++ and relip there is no other so can generate.
Yeah, let's do that. That was a good suggestion actually to remove the limit.
So it will be almost the same as before if we remove the limit here this thing.
Let's remove it. So it will it should happen in a single thread. So, we should have the uh L spike.
We should have the L spike.
Yes, it happened. Okay. Okay. We can do something else. We can do something else where uh we in change the limit to be more sub chunks per per frame. So here, let's do uh how many? Like let's do 100 per frame.
Let's do 100 per frame.
What?
Okay, let's do 50. Let's do 50. And let's switch to release mode since it's faster.
Let's do 50.
Let's do 50 and see what's up.
It's working, man. It's acting very weirdly.
those stutters.
Let's do 25.
Let's do 25.
H.
It's not like before.
It's actually pretty good, but it's acting very weirdly.
Oh, it Let's remove the profiler because it reached again 40 mgabytes of RAM.
Oh, let's remove the profiler.
Yo yo, it's perfect.
It's perfect. And it's running on the main thread. Well, I'm not sure if it's actually perfect. There are no L spikes and I'm not using multi-threaded code.
It's all on the main thread everything.
That's cool.
Yeah.
That's cool.
That's cool.
It's actually endless.
Yeah, that's cool. Now we can have biomes, but we need to fix some stuff. If we look behind us, don't get jump scared.
We have these missing faces.
Um we have this missing face and uh some trees get cut out. But these are minor issues. The these are minor issues.
We can we to fix that we need a buffer around the visible chunks to have invisible chunks so that we can get what's the data there and it will solve this issue. But uh it's cool we don't have luck spikes. And the inspiration came from how Minecraft does it because in Minecraft in the settings I randomly I picked here to not use threaded here. Thread it means to use like threads in the background for generating the chunks. But there's an option to be fully blocking and hitting that option. Look at how there are no luck spikes in Minecraft. And I was like, okay, since Minecraft can do it in one thread, why cannot we do it?
That's really cool. And that was my inspiration.
And so here we're running it in a single threat.
Yeah, that's cool. That's cool.
Yeah. Yeah, let's see what's up with chat.
Uh, they generate in anticlockwise parallel because I coded them like that.
We can easily change it in whatever order we want.
Increase or adapt the per frame mesh generation limit. Kink uses updated bounding boxes so new sub chunks are actually rendered.
No way bro actually broke the character.
When did he say he was family friend?
Why why did generate he 40 me?
Uh, no. It was 40 GB of RAM because of the memory leak. Yo, yeah, I told you.
Nice rendering. Very nice. Single thread in Big 2026.
How did you make it run on one thread?
Well, watch the stream, man. Watch the stream. Not a lot is happening. So, only chunk action really is going, bro.
Actually fix the run.
No mobs, no blocks breaking, just render. No, I have block breaking. I can block I can break blocks.
Uh, but it's not finished. It's like just really simplified.
Uh, let me run it again.
Yeah, that's cool. Yeah, that's cool.
Yeah, that was cool.
No mops. Yo. Oh, he fixed. No, I haven't fixed the RAM issue. There's still a memory leak. I'm sure of it.
Yeah, I'll increase the render distance.
Use time budget mesh generation. Time budgeted mesh generation.
What's that? Update bounding boxes for culling nearby subchunks.
Yeah, I'll I'll just copy your message and think about it at another time.
I think if you test different render distance. Yeah, I'll test different render distance. Yeah, lot gravity and inventory.
Increase render. This amazing. Let's torture this. Increase 40 G.
I was saying you weren't.
Uh yeah. Okay. Let's Yeah, let's increase the render distance. Let's see what happens.
Let's see what happens. Uh right now it's How much is it? Right now it's 8 by 8. Let's do 12 by 12 and see if it actually generates.
Okay, this is the world.
It's generating.
Yo.
It's generating.
There isn't a lag spike.
There isn't a l spike. Uh, let's increase it more.
Let's increase it to 20 by 20.
20 by 20 world size.
This is bigger. Let's see. Now it's generating.
Yo, and there are no L spikes.
And all of this is running on a single thread on the main thread. There's no multi-threading. And that's cool.
Yeah, that was way better approach because it simplifies the code. It simplifies the code.
It's not the fastest generation. It's not the fastest, but uh the goal was the first the previous stream the goal was to make it endless in this stream was the goal was to remove the L spike. That were that was the goal.
This uh that it's slow. Uh that's not an issue for me. Let's do 20. Let's do let's do 35 by 35 world size.
This is 35 by 35.
And there are no like spikes but it's slowly generating.
It's very very slowly generating.
Um, it's slowly generating, but the unloading is fast. The unloading is fast.
But at least we don't have lag spikes.
Yeah, it's still generating just slowly.
Uh, what's up?
That was easy.
How big is 32 chunks? Like I'm doing um 35 by 35 world. How big is 32 render distance?
Is it like 32 * 2 + 1?
So, uh 65. Let's do 65 by 65 and let's see what happens.
Uh this generation is not the endless terrain. This is still the initial generation. I'm waiting it for the for it to finish. It has finished. And let's now see if the terrain is endless.
Is it generating anything?
Is generating there.
H. But uh h it looks weird if I move around the mouse. It looks weird when it's a big render distance.
Oh, this will be the goal for a different stream. This problem, I know how to fix it. I know how to fix this problem. Uh I'll have to prioritize the chunks around me and it will make it faster. Minecraft doesn't generate it like that. We saw that Minecraft um here Minecraft. If we go really fast, uh let's go game mode spectator.
If we go really fast, you'll see how Minecraft prioritizes what's around us.
Here, look at how it prioritizes what's in front of me when you go fast. Here it prioritizes the chunks around me. This is what we need. But this will be for a different stream. And look how look at what we got. And this is impossible in my current code. This is impossible in my code.
I need to make it uh prioritize the blocks around me.
Yeah, this is what we need to do. We are very close to handling big render distance.
Why are you making it to learn?
It's actually what is total uh let's not look at the RAM. Let's not look at use time budget loop recal bounding boxes. Yeah. Um uh I I screenshotted that. I'll look at later.
Fix extremely fast to force more chunks to load.
Rip it through.
No, it's nothing. But infinite. Yeah, making infinite world generation.
Yeah, for that that will be in a different stream. Um, we showed it moving fast Minecraft pro loads the chunks around us. Yeah, we'll we'll do it in a different stream.
Do you uh current CPU? I've shown it before.
Is there a segment in the screen where I made Minecraft to except I made it into my own thing? That's nice that you've managed to made it make it in your own thing.
Yeah. I need to know what chunk the player is in. Yes. Now that's will be in a separate stream for sure. Uh this initial generation is multi-threaded.
Uh this this is multi-threaded. The initial generation this is from the old code. I haven't deleted it. But the generation after that is from me. The generation after that is from me.
uh is from a single thread. So if we put it back at 5x5 this is from this is from the single thread. This is single threaded. The initial terrain generation is using a separate thread but this is just on the main thread.
We'll make it prioritize just around the player but it it will not be today.
Yeah, I'll add I'll add biomes. Uh the reason I wanted uh infinite terrain is to add biomes.
I wanted to add the snow biome because it will be cool if we have the snow biome.
Uh what if you set it one to one generation it will it should still work think that part of the issue on lot no we I don't care about lot cr making war gen much three blocks first oh yeah water um water will be a in a separate dream.
But this was the the goal to remove the L spike.
We achieved our goal.
We achieved our goal.
Here is that one by one.
This is one by one. It's still working.
And this is one by one.
But we achieved our goal of making it and uh not have a L spike.
I cannot do minus one. Like it's impossible to it will not even start if it's minus one here. Minus one. Let's see what happens. It will not even start. like uh if it starts. Yeah, it will not even start.
It will not even start.
Okay, I'll try zero. I'll try I'll try zero. But it's your suggestion. It's not mine. Yeah. Here we don't have any chunks. We don't have anything. I'm moving the mouse around and I don't see anything.
That was zero.
And this is 12.
Actually, I think we can even uh even fix this. I think we can fix it if we set this to be how much should it be?
13 by3 maybe.
Uh but here here it should be where is it?
Here it should be the visible visible size I think.
That should fix it probably.
Yeah, because doing it this way it's getting the neighbors probably. Yeah, we don't have I think the missing sub chunks. What's up with you? No, it's perfect.
Yeah, now we don't. Now we have a buffer. We have a simulated distance. We fixed the issue with the missing faces.
I think I think we fixed it. The missing faces.
There were some meshes missing and I think we fixed that.
I think we managed to fix that.
Yeah. Now I don't see any issues.
Now I don't see any issues.
That's cool.
Yeah, that's cool.
Yeah, it's actually infinite.
Um, here we have a generated flower under the tree.
Yeah, that's cool.
And all of this in is in a single threat.
That's cool.
Yeah, that's cool.
And this is the initial solution.
We I I haven't done any additional changes. We may get some ideas to make make it different.
Yeah, that's cool.
And it's I don't see missing faces.
I don't see L spikes.
It looks fine. And this was the goal to remove the L spikes.
Initially I wanted to use smoothly threading but we managed to do it in a single thread.
Okay, let's do frame time.
The FPS it's around it's around if I don't move is 1,000 if I don't but this is 5x5 world this is low FPS since we don't have first time killing if we have first time killing FPS will be a lot Oh, frame spikes. Um, yeah, we'll see about uh measuring frame spikes.
We'll see. I don't know how to tackle that. Maybe from Tracy the profiler.
We'll see. Or maybe to implement something my own. We'll see about it.
But this was it for this stream. We achieved the goal. We are close to 3 hours. This is it for the stream.
We managed to reach the 3-hour limit. We managed to make progress.
That's it for today.
And I have a limit of the hours so that I don't burn out and I can stream mostly every day. Yeah, I'll I'll look at your sug suggestions.
I'll look at your suggestions, Marco. Marco, I'll look at your suggestions. But uh after I I end the stream sun stream.
So implementing sand convert large histograms in positive positivity measure.
Yeah. Yeah. So thank you guys for being here and making company. We'll have to end it.
Um, for the next stream, we'll see what we will add. Maybe the next stream we'll do either the snow biome or maybe adding the player or maybe creative inventory.
We'll see about it. But that's it for today.
Yeah. Bye, guys.
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
🚀 BCS613C Compiler Design | Module 1 to 5 Schema Evaluation 🔥 | VTU 6th Sem 💯 #VTU #bcs613c #exam
Pranavaa-y4y
104 views•2026-06-02











