Creating the cave
For the first level in Clara’s adventures, we thought of a small place so that you don’t get overwhelmed with building a large layout. Figure 9.1 should help you visualize what we are building. This is a Blender render we’ll try to recreate in Godot:
Figure 9.1 – We’ll be building this small level for Clara to discover
Our world will consist of a dock inside a cave that has access to the sea. When Clara anchors her boat, she sees inside the cave. There isn’t much light to begin with, but as little as she can see, the dock leads to a pier with laid stone. She can also see that there are a bunch of boxes, barrels, and pots distributed here and there. Though the sconces on the walls will start unlit when the game runs, as shown in Figure 9.1, you can see that all the sconces on the walls are lit. This is because we want to show you a later stage in the game so that you can see what we are aiming for. Otherwise, it would have been a dark figure.
In Chapter 10, Making Things Look Better with Lights and Shadows, we’ll investigate how we can create a more dramatic-looking level by utilizing appropriate light types and enabling shadows. We covered some of this in the context of Blender in Chapter 4, Adjusting Cameras and Lights, but we’ll do it in the context of Godot as well.
Level design versus game design versus visual design
If you are new to game development, then some of the names you come across might be confusing. The word design is one such example since it usually implies what people see. However, in actuality, it means a fashion, or a formula to do or conceive something. Let’s discuss it in the right context.
We could have designed the level differently so that access to the door at the end of the pier would be challenging. Perhaps the light conditions are so poor that Clara needs some help to see an important clue. To make progress in the game, game design rules will define how the player will interact with the world. Perhaps it’s enough for the player to click game objects in the world, while other times, it’d be better to have an inventory and a crafting system.
Lastly, the visual design has nothing to do with the previous two design concepts. The cave walls could still be cave walls but instead of having a low-poly and stylized look, they might have looked ultra-realistic, where you could feel the stones were damp and covered with moss. Would this have added anything to the game and been fun? So, all these design principles are equally important and yet distinct.
The level, Level-01.blend
, is available inside the Blender Models.zip
file at the root of this book’s GitHub repository. You’ll most likely need it open so that you can use it as a reference when you are building the level in Godot.
We will start building the level by laying out different sections of it. Speaking of which, we must follow these steps to structure our first level:
- Create a new scene and save it as
Level-01.tscn
inside theScenes
folder. - Place a Spatial node as root and rename it Level-01.
- Create more Spatial nodes inside the root node with the following node names:
- Floor
- Columns
- Walls
- Rails
- SunkWalls
- Props
- Rocks
- Sconces
- Dock
We’ll be using these child Spatial nodes to store different parts of the level since we’ll end up having a lot of parts in this level, despite it being very small. The following screenshot shows the node structure after our last effort:
Figure 9.2 – Different structures for the level are grouped under many Spatial nodes
Inside these Spatial nodes, we’ll place the relevant parts of the level. For example, the floor pieces will go inside the Floor node. We can put down our first asset easily by doing the following:
- Highlight the Floor node in the Scene tree.
- Press the chain icon at the top to instance another scene inside your highlighted node. Alternatively, you can press Ctrl + Shift + A.
- Type
Floor_Standard
in the Search section of the pop-up screen. - Select
Floor_Standard.glb
from the Matches section, as shown in the following screenshot.
This will create an instance of Floor_Standard.glb
inside the Floor node:
Figure 9.3 – You’ll want to use the search area to filter out the unwanted matches
You may have noticed that although we wanted to inherit a scene that should normally have a .tscn
file extension, instead, we instanced a glTF file. In Chapter 7, Importing Blender Assets into Godot, we learned how to create scenes out of glTF files. So, we could have done that and created a Floor_Standard.tscn
scene, then instanced that scene inside the Floor node as well. We took a shortcut instead. Creating scenes is useful when you are going to add additional elements besides the model structure itself. We don’t need additional elements for the floor, so it’s alright to instance just its glTF version.
On the other hand, there will come a moment when we create our level when directly instancing glTF files won’t cut it. For example, when we tackle lights and shadows in the next chapter, it will make much more sense to create a scene out of the sconce model and add a light object to the same scene. Hence, the sconce scene will take care of displaying a glTF model as well as holding a light object so that it can programmatically be turned on or off later. If you simply want to display models, but don’t need anything more than that, instancing a glTF file is usually enough.
After you add the first piece, it will be automatically selected. If it’s not, you can click the floor piece in the 3D view or highlight its node in the Scene tree. Once it’s been selected, you’ll see a gizmo at the center of the model that will let you move and rotate the piece around. The directions of your gizmo may look different if you have rotated your view. The following screenshot shows an example of what we expect to see:
Figure 9.4 – The gizmo for moving and rotating an object
The floor plan we are trying to lay out consists of more standard floor pieces. So, an easy way to get extra pieces is to duplicate the existing pieces and move them aside, as follows:
- Select the Floor_Standard node in the Scene tree.
- Duplicate it by pressing Ctrl + D.
- Move the new floor piece by dragging either the blue or the red axis in the gizmo.
This will add a new floor piece to the scene and move it around. We are intentionally ignoring the green (Y) axis since we don’t want the floor to have any elevation at this point. However, for your games, you can design levels with different height zones and connect them with stairs.
Since our floor plan looks like a grid, it would be nice to have the floor pieces snap to each other. We can do this by moving the pieces in either direction on the XZ plane while limiting their movements to precise increments. To simulate this, delete the most recent floor piece you created, and then do the following:
- Duplicate a new Floor_Standard node.
- Hold down Ctrl and use either the X or Z gizmo arrow to move the piece two units.
Why did we move it by two units? Because the model is designed to fit in a grid that’s 2 x 2 meters in size. You can open the relevant Blender file to observe the dimensions. We are not measuring things in Godot but it’s still respecting the scale and unit aspects set in Blender. That’s why we made sure the scale for the model was set to 1
. If you need a reminder on this, we suggest that you read the Applying rotation and scale section in Chapter 6, Exporting Blender Assets.
After implementing the latest instructions for moving pieces with the snap feature on, you’ll get the following output:
Figure 9.5 – The new floor piece is right next to the old one
All there is left to do at this point is duplicate enough floor pieces and move them around by using the snap feature. Also, you’ll need to instance and place two new models inside the Floor node:
Floor_Standard_Curved_1.glb
Floor_Standard_Curved_4.glb
These curved floor tiles will accommodate curved walls, which means we can keep the architecture consistent. By duplicating enough floor tiles and adding the new curved pieces, and after moving the pieces around, we’ll achieve the following output:
Figure 9.6 – With the two newly added types, the floor is ready
All the floor pieces are now under the Floor node in the scene, and this effort completes our task of constructing the floor. We’ll follow a similar approach to lay the other parts of the cave under separate Spatial nodes.
Erecting the walls
The next order of business in constructing the level is putting up the wall sections. You can do so by instancing wall pieces under the Walls node, similar to the way you did for the floor pieces. As a substitute for providing you with very similar instructions, we’ll use this section to highlight a few special cases you may come across.
For example, you’ll eventually want to place wall pieces that will connect at a corner. So, you need to rotate one of the pieces around its Y axis by 90 degrees. You can do this either by using the gizmo or by typing the exact value in the Inspector panel under Rotation Degrees in the Transform section.
Another situation is with the wall that has a hole in it, which lets a bunch of twigs creep into the dock area. This is a detail you can see on the right-hand side of Figure 9.1. We suggest using Wall_Hole.glb
for that particular section of the level. Similarly, Curve.glb
should be placed over the curved floor pieces we have already established.
Although a door is technically not a wall, we could assume the arch and the door can get along with the other wall pieces. After all, they conceptually belong to the same structure. So, for that section, you can utilize the following pieces:
Wall_ArchRound_Overgrown.glb
Arch_Round.glb
Doors_RoundArch.glb
Lastly, when you lay out all your wall pieces, you can duplicate them and pull them up two units on the Y axis. This will make the walls the same height as the arch and the door. Once you’ve done this, your floor should resemble what you can see in the following screenshot:
Figure 9.7 – The level is starting to look more like our reference picture
As you may have noticed there is a gap on the floor by the curved wall piece near the door. We’ll fill that gap by cleverly placing two green plants soon. Otherwise, you’d have to prepare a floor piece for edge cases like that. Either way is fine and going back and forth between Blender and Godot to complete missing pieces is also part of the process.
Since we’ve been handling the walls, we can extend this effort by using additional wall pieces to simulate the section of the level that meets the seawater in the cave.
Sinking the walls
It seems the architect of this place went to great lengths to have stone bricks laid out to prevent mother nature from tarnishing what’s under the floor. Smart!
To accomplish what the architect had in mind, you can utilize the standard wall pieces to create a curtain-like structure right where the floor is connecting with the water. In the end, when you place these pieces inside SunkWalls in your Scene tree, you’ll be looking at what’s shown in the following screenshot:
Figure 9.8 – The same wall pieces are used to prevent water from leaking under
The ebb and flow of the sea will now be kept at bay. Notice that we didn’t want the sunken wall parts to go all the way around the floor. This is because you can always limit the camera angles to not show the back parts of the structure. It’s a cheap way to keep the asset count low. However, if you want to give full freedom to the player so that they can rotate around the whole structure, you may want to change your level design to accommodate that. We’ll be investigating camera settings in Chapter 12, Interacting with the World Through Camera and Character Controllers. For now, we still need to finish our level.
Placing the rocks
Since we are currently concerned about the parts near the water, let’s add some rocks to the scene. In the Blender file for this level (Level-01.blend
), you’ll see individual rocks. They have been organized to give the illusion of a rock formation. It’s perfectly fine to follow a similar approach and place specific rocks into your scene in Godot too, more specifically under the Rocks node.
However, there is an easier way. What if you exported the left and right rock formations as a single object from Blender? This is entirely possible, and that’s why we have prepared two files for you:
RocksLeft.glb
RocksRight.glb
You can instance these two files and move the instances freely using the gizmo. This means you don’t have to use the snap feature. Adjust the position of the rocks wherever you think is best.
Speaking of moving assets without using the snap feature, perhaps we can practice it a bit more. Since the floor looks empty, it’s time we discuss complementary design elements such as props.
Distributing props
A prop is an object that serves as a support element. Props are also often called necessary clutter since they complete a décor. Otherwise, when things look too sterile, it’s less pleasant to the eye and we start paying attention to repeating patterns or unnecessary details.
Instead, we want the person who’s experiencing the scene to feel at ease. This is also a great way for designers to hide important elements in plain sight. To that end, we will use the following list of props and distribute these assets around the scene:
Barrel.glb
Backpack.glb
Bush_Round.glb
Candles_1.glb
andCandles_2.glb
Cart.glb
Crate.glb
DeadTree_3.glb
Flag_Wall.glb
Pot1.glb
,Pot2.glb
,Pot3.glb
, and their broken versionsStatue_Stag.glb
Once you’ve finished moving the props, your scene will look as follows:
Figure 9.9 – The props have been distributed all over the dock
While you are at it, you may as well instance Column_Round.glb
, make two more copies, and place them under the Columns node. Also, Rail_Corner.glb
and Rail_Straight.glb
could be placed along the edge and near the stag statue. You don’t have to be pixel-perfect with these objects, but if you want to be precise, you can use Level-01.blend
for reference.
Finishing the rest of the level
To finish off the level, we need to place the sconces and construct a pier. These assets are no different than the other ones you have instanced and moved around the level.
However, placing the dock pieces may throw you off a bit as far as positioning goes. You may find that the stairs piece looks slightly off dimension-wise. Sometimes, assets are designed to be generic, while other times, assets will be designed so that they can fit or connect with the other models seamlessly. Regardless, since it’s possible to adjust the final position in Godot, we can recover from these minor issues.
To simulate how we dealt with this issue, we’ll give you the Translation values we used for the positions of both pieces:
- Dock_Long:
4
,-1
,5.5
- Dock_Stairs:
4
,-1.5
,8.9
Your values will most likely be different since you were undoubtedly moving your level pieces in directions that felt natural to you. If your numbers don’t match our example, don’t worry. We would like to point out the relative difference between the two structures. You’ll also most likely have one number that’s the same in one of the axes, either X or Z. Also, an educated guess on our end, your Y for the stairs will be 0.5 lower. This should result in a pier structure that looks like it was designed as one piece. If you want to have a taller pier, then you can create a copy of the stairs and move it accordingly. That’s the benefit of having separate pieces.
We suggest that you add the boat model under the Docks node in the Scene tree at this point since it could be considered as part of the docks area. This concludes the construction of our level. It should look as follows:
Figure 9.10 – The level has been reconstructed in Godot
Despite our claim that the level’s construction is finished, you may have noticed that there are a few odd looking things. We have a dock area with no water – and what are those ugly round things doing by the door? We’ll find out how we can remedy all this in the next section.