Devlog #2


How the project went:

It started quite simply and with a single goal: Create a cube. Obviously there is not a single model in the project, everything is made through the code! I don't have millions of cubes but many chunks of cubes stitched together.

And so I spent a whole day trying to understand how Godot manages meshes and procedurally generated shapes:

This cube was my introduction to the Godot way. I have to deal with the way the engine works with meshes if I want to make it work, but thankfully the difficult part about the procedural generation was something I knew already. I only needed to translate the previous attempts to Godot. (The biggest problem, to me, is that I decided to start the project using a beta version of Godot 4.0. Every version of it brings changes and many times I had to rework and change part of my code to fit the new ways and features).

This is also where I used my first implementation of the addon system for players: The blocks are supposed to be found in a "block atlas". This is a collection of blocks in a single texture which allows each face of the cube to fit to a position on it.

It looks like this:

But there is a BIG problem with this atlas... What if I wanted to add more blocks? What if I needed to resize it? I would need to change every single block configuration. I also need to cound the X and Y positions on the atlas to know where the texture is placed to fit the new image every time! And if players wanted to add their own blocks, they would also need an atlas... That's not a good solution.

So I used a similar approach as Minecraft: A dynamic atlas!

The players simply needs to drag and drop their textures, give them a name, the blocks know which texture to use by name. And with the help of a simple tool I've written, those textures are taken by the game and generate an atlas on the go while telling each block where the textures are. Now you just need to ask the atlas where the texture you need is located on and it gives it to you! That's a big step towards user-made content :D

The next step was obvious. Now that I had a cube, all I needed was a chunk: A whole mesh made of cubes! And so I did:

(Notice that I also added some Perlin noise to the chunk, this is what gives those nice shapes on the terrain)

But a chunk made out of cubes is a problem... Each cube has 6 faces, a chunk (in my case) can go up to 11000 cubes... This is 66000 faces and that's a lot to render! Especially in a world made of chunks. So I had to optimize for the first time: Every single face that you can't see won't be rendered, which makes the chunks completely hollow and blocks between blocks are hidden.

From there I could easily add more chunks and create a world. It was simply a matter of where to create them and giving each chunk their own coordinates.

Here, just like with the atlas and the textures, I decided that every block would be defined through their own files. This way it's easy to edit a block and they just had to be loaded by the game so I could add and remove them as much as I want, and give the same freedom to the players!

Once that was done, I added some decoration to the terrain with trees, grass and flowers.

It wasn't as easy as I thought it would be...

First, the grass and flowers were not cubes. They are "billboards", flat faces to make the shape of a cross. So I needed a new shape for my blocks. And this is where I used the same approach as I had with the blocks and the textures, I allow players to create their own shapes and have the game load them.

Then, the other problem came with the trees... As you know, chunks are collections of blocks. But each chunk need to know about their neighbor and which block they have. The issue comes when generating trees on each chunk since they are added one by one: Did the previous chunk add a tree? Because the new chunk will need to create some of the leaves. What about chunks which were generated before, if I need a new tree here... I would have to go back and give them the new blocks I want to place!

As you can see, this is one of the most confusing parts of the world generation. But I made it work!

Now what I needed was a player controller. I wanted to walk around and place blocks... And I didn't expect it to give me so much troubles...

I managed to implement it! My solution took me the whole day but it worked. Since the world was generated, I thought of converting the meshes into collision shapes and use the physics system of Godot but... It would not work... It was clearly unoptimized and the large number of blocks and chunks would double the amount of meshes. So I went with a simple solution instead and checked which blocks were around the player to see if there was a collision. And it worked! (As long as I didn't walk diagonally or too fast...)

I think I spent 80% of the time tweaking values to make sure the collisions were fine and didn't let the player clip through the blocks or get stuck.

And that's also where I remembered something that gave me a headache when I generated the first block: Godot's inverted Z axis! Which means that the player needs to go towards -Z to more forward... I had to deal with it when creating the blocks, and now again with the controller. But I went through it.

Now that I could walk around, place and remove blocks, I decided to add a few little features I had in mind and had to implement at some point.

And so I decided to add block rotation:

I have to admit, this simple idea ended up taking way longer than expected. But for once, I managed to do it quick and it was mostly me testing and tweaking values.

(I was actually VERY lazy and didn't want to deal with the whole -Z problem, so I just placed blocks, checked if it was right, and if not I just changed values until it worked :) )

After that, the other little ideas I had in mind were simple. Such as fixing the problem where windows are visible through windows. 

It simply allowed me to add even more control over how the blocks look and generate and I allowed players to have control over it as well!

Here I took a big break.

The project was going quite well and I decided to watch some Minecraft videos for inspiration. And this is where I saw something awesome... Something that was stuck in my head for a few days and that I even checked in Minecraft myself: SEUS Shaders

They look like this:

The rain is what got me intrigued the most but there was a BIG problem... I never made any shader. It was always too difficult for me and never gave it a proper shot (besides Blender or Unreal with their visual shader editors. I still had some basics and concepts).

So I had to learn. I made a few Godot projects just for shaders, tried with a few models and then I was ready!

So I spent some time on it and here is how it turned out:

At this point I was really happy with the results. It obviously needed more work and I was waiting for the next release of the Godot 4.0 beta for some fixes. But I was finally getting better results than I ever imagined.

And here was me taking another break, but I wanted to go way further.

Leave a comment

Log in with itch.io to leave a comment.