Godot CSG Basics: Carve a Room Out of Blocks and Prototype a Walkable 3D Level

Created: 2026-09-23Last updated: 2026-10-10

Even without models, add and subtract CSG boxes to make a room with a doorway, walk it to check the dimensions, and then transfer it to GridMap.

When building a 3D stage, deciding the dimensions the character can pass through before you work on the visuals cuts down on rebuilding. With Godot's CSG, you can add and subtract boxes to make just the shape of a room inside the editor, and walk through it to check the same day.

Build the visuals first and add the character later, and you find it can't fit through the door or gets stopped by a step, and you end up rebuilding the whole room. The further you've worked on the models, the bigger the fix becomes.

This article covers carving a doorway with CSG to make a walkable room, and transferring the settled dimensions to GridMap cells.

Two panels: "decide the dimensions," where a figure walks through the door of a room made only of stacked boxes, and "transfer to cells," with the same room built from grid cells

What You'll Learn

  • What you decide first in a prototype is the dimensions the character can pass through, not the look
  • How to add and subtract boxes to open a doorway, and make it walkable with Use Collision
  • Why steps can't be climbed but slopes can
  • Steps for transferring settled dimensions to GridMap cells

Tested with: Godot 4.7

Sponsored

Deciding the dimensions the character can pass through

In Godot's 3D, one unit is one meter. Because of this, a room's size can be decided in meters rather than as "a vaguely big box."

The reference is the character's thickness and height. A 3D character's collision is usually a tall, rounded tube (a capsule). Until that's decided, neither the door width nor the ceiling height can be.

A capsule with radius 0.4 and height 2.0 determines a door width of 1.6, a wall height of 3.0, and a step it can't climb

This article uses the following numbers throughout. They're decided from the capsule, not from how the room looks.

  • The character's capsule has radius 0.4 and height 2.0 (the height is the full length including the rounded ends). Its origin is at the center, so to stand it on the floor, use y = 1.0
  • The room's interior is 8 × 8. Wide enough to take a few seconds to cross
  • The floor is 1.0 thick. Center it at y = -0.5 so its top surface is at y = 0
  • Walls are 0.4 thick and 3.0 high. Their center is at y = 1.5
  • The doorway is 1.6 wide. That leaves 0.4 of room on each side of the capsule
  • An unclimbable step is 0.5 high. It's placed to confirm that the character stops
  • A climbable slope rises 0.6 over 3 m, about 12 degrees. Up to 45 degrees is treated as floor

A CSGBox3D's origin is the center of the box. To align the top of a floor 1 thick with y = 0, put its center at y = -0.5. Get this wrong, and the character is half buried in the floor the moment you play.

Adding and subtracting with CSG (Operation)

CSG is a system for making shapes by adding and subtracting boxes, cylinders, and so on. You can make a room's shape entirely inside the editor without opening modeling software.

How shapes are combined is chosen in a field called Operation.

  • Union: adds to the parent's shape. Floors and walls use this
  • Subtraction: carves from the parent's shape. Doorways use this
  • Intersection: keeps only the overlapping part. Not used in this article
Three ways to combine a large and a small box: Union adds, Subtraction carves, and Intersection keeps only the overlap

In other engines: prototyping levels inside the editor sits in the same place as Unity's ProBuilder or Unreal Engine's Modeling Mode.

The important thing is that this adding and subtracting only works within a chain of connected CSG nodes. Put an ordinary Node3D in between, and the chain breaks there, making a separate shape.

The other thing is order. Children lined up under the same parent are combined from the top of the tree down. Put a Union after carving with Subtraction, and the overlapping area comes back. When something you thought you carved is filled in, look at this order.

Making collision with Use Collision

Just placing boxes, the character passes right through them. The visible shape and the collision are separate things.

CSG has a field called Use Collision that makes collision from the shape after the adding and subtracting are done. Turn it on, and without placing a single CollisionShape3D, the collision includes the carved hole.

With Use Collision off, the capsule passes through the wall; with it on, the capsule stops at the wall and only passes through the doorway

Put it on the topmost node of the CSG tree. Putting it on the floor box or a wall box doesn't make separate collision for just that box. Put one on the CSGCombiner3D that groups the room (a node with no shape of its own that only combines its children), and everything under it becomes solid.

Conversely, siblings that aren't in the same tree aren't included. For a box placed apart from the room, like the slope that comes later, turn on that box's own Use Collision.

The Collision Layer and Mask, which decide what collides with what, mesh with CharacterBody3D at their initial values (Organizing Collision Layers and Masks).

How to carve a doorway

The most common stumble in prototyping is that the hole is visible but the character stops there. The cause usually lies in how the cutting box is placed.

In cross-section, a cutting box as thick as the wall leaves a thin threshold at the doorway, while one sticking out past both sides of the wall and below the floor cuts cleanly

Make the cutting box stick out about 20 cm past both the inside and outside of the wall. Line the faces up exactly, and you're adding and subtracting on the same plane, which can leave thin plates or triangles behind. It looks open, but that one spot is solid.

The bottom is the same. Stop it level with the floor's top surface and a threshold can be left, so sink it about 5 cm into the floor. That leaves a shallow groove in the floor, but adding the outside floor after carving fills it in. This is where order matters.

Sponsored

Steps and slopes

Put a 0.5-high box on the floor and try to get onto it, and the character stops. CharacterBody3D doesn't come with a feature that climbs steps automatically.

What's confusing is Floor Snap Length. Its initial value is 0.1, but it's the length the character is pulled downward to keep from leaving the floor, which is a different thing from the height of a step it can climb.

A capsule stops in front of a vertical 0.5-high step, while on a 12-degree slope it climbs 0.6 up while staying upright

Slopes, on the other hand, can be climbed. Floor Max Angle's initial value is 45 degrees, and surfaces shallower than that are treated as floor. The character stops at a vertical 0.5-meter step, but can climb a 12-degree slope that rises 0.6 meters over 3 meters.

To make sure the character can climb stairs, keep the visible steps as they are and make only the collision a single slope. If the vertical faces of the steps remain in the collision, the character stops there.

Transferring to cells with GridMap

Once the dimensions are settled, you'll want to line up the same room over and over. That's where GridMap comes in.

GridMap is a node that places pre-registered meshes along a grid of cells. Its roles are split the same way as 2D's TileMapLayer: MeshLibrary is the paint box, and GridMap is the side that places things.

Coming from 2D, there's one place you're sure to get caught.

A mesh-only tile lets the capsule fall through, while a tile with StaticBody3D and CollisionShape3D can be stood on

MeshLibrary items have no collision with the mesh alone. Put a Node3D at the root of the source scene, and line up a MeshInstance3D for each item under it. Under each MeshInstance3D, stack a StaticBody3D (the body of an unmoving collision), then under that a CollisionShape3D (its shape), assign a shape to the CollisionShape3D, and then export. For a floor tile, the shape is a BoxShape3D. Export with Scene → Export As... → MeshLibrary..., saving as .meshlib or .tres. Exporting the CSG room as-is doesn't become an item, so use a mesh baked with the method in the next section, or a separately made mesh.

On the placing side, add a GridMap node and assign the exported file to Mesh Library in the Inspector. Select the GridMap, and a list of items appears in the GridMap dock at the bottom of the editor. Choose an item, enable Paint in the dock, and click a cell in the 3D view to place it.

Two more things to know up front so you don't get lost.

  • Cell Size: its initial value is (2, 2, 2). Place a 1-meter box as-is, and gaps open between cells. Match it to the size of the mesh you're making into tiles (for a 2-meter-square floor tile, the initial value works as-is)
  • Make openings with tiles: GridMap has no Subtraction. For a door, prepare a wall mesh with an opening cut in it as one item and place it. Just leaving a cell empty makes the opening as wide as a cell
Sponsored

Baking CSG into fixed meshes (Bake)

CSG recalculates its adding and subtracting every time something is placed. With a few rooms it's not noticeable, but place dozens and the editor hitches every time you move something.

When you want to fix it in place, select the CSG root and open the CSG menu at the top of the 3D view. Bake Mesh Instance makes a MeshInstance3D for the visuals, and Bake Collision Shape makes a CollisionShape3D for the collision shape. Move the baked CollisionShape3D under a StaticBody3D, and remove the original CSG. Leave it, and the collision is doubled.

When moving from prototype to production, what you keep are numbers: the door width, the ceiling height, and the angle of slopes that can be walked. The boxes themselves can be thrown away.

Hands-On: Build One Walkable Room

A top-down dungeon, third-person action, first-person exploration—in any genre, the first two things to check are "can it pass?" and "does it stop?" You'll make just one room and check both on screen.

The hands-on scene tree, and the settings where only Room and Ramp have Use Collision on and the camera is Orthogonal

① What to place

Create one new 3D scene. Enter angles in degrees in the Inspector's Rotation, and leave every node's Scale at (1, 1, 1).

  • Put a Node3D at the root as Main, and set it as the Main Scene (if asked when you play with F5, choose this scene)
  • Under Main, place a CSGCombiner3D as Room. Turn on Use Collision
  • Under Room, place eight CSGBox3Ds, in this order
NameSizePositionOperation
Floor(8, 1, 8)(0, -0.5, 0)Union
WallN(8.8, 3, 0.4)(0, 1.5, -4.2)Union
WallS(8.8, 3, 0.4)(0, 1.5, 4.2)Union
WallE(0.4, 3, 8.8)(4.2, 1.5, 0)Union
WallW(0.4, 3, 8.8)(-4.2, 1.5, 0)Union
DoorCut(1.6, 3.2, 0.8)(0, 1.55, -4.2)Subtraction
Porch(3, 1, 4)(0, -0.5, -5.6)Union
Step(1, 0.5, 1)(2.5, 0.25, 2.5)Union
  • Under Main, place one CSGBox3D as Ramp. Size (2, 0.4, 3), Position (-2.5, 0.11, 1.5), and -12 for X in Rotation. Turn on Use Collision. Its lower end is on the -Z side (the top of the screen with this camera)
  • Under Main, place a CharacterBody3D as Player, Position (0, 1, 0). Under it, place a CollisionShape3D (CapsuleShape3D, radius 0.4, height 2.0) and a MeshInstance3D (CapsuleMesh, radius 0.35, height 1.9)
  • Under Main, place a Camera3D, with Projection set to Orthogonal (parallel projection without perspective), Size 14 (14 meters visible vertically), Position (0, 18, -1.6), and -90 for X in Rotation
  • Under Main, place a DirectionalLight3D, set its Rotation to (-60, -30, 0), and turn on Shadow's Enabled
  • Assign single-color materials of different brightness to Floor, the four walls, Step, and Ramp (create a New StandardMaterial3D in the Inspector's Material and change Albedo's Color; see StandardMaterial3D Basics). Looking straight down, they're all faces pointing the same way, so without different colors you can't tell them apart

The walls' length of 8.8 and centers at ±4.2 come from adding the wall thickness of 0.4 on both sides of the interior's 8. The corners overlap so that no gaps form. DoorCut sticks out 20 cm past both sides of the wall, and its bottom goes 5 cm below the floor's top surface. That leaves a shallow groove in the floor, but Porch is added after it, so it gets filled in. Swap the order and it doesn't. The top is cut all the way past the top of the wall, so seen from directly above it's a gap.

The Camera3D faces straight down from above. The walls are 3 high, so seen at an angle, what's beyond the door is hidden by the wall.

② Put it together

The script on Player exists only to check whether the room can be walked.

# player.gd (Player's CharacterBody3D)
extends CharacterBody3D

const SPEED := 4.0

func _physics_process(delta: float) -> void:
	if not is_on_floor():
		velocity += get_gravity() * delta        # fall when in the air
	var input := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	velocity.x = input.x * SPEED                 # left and right on screen
	velocity.z = input.y * SPEED                 # the up key is -Z = the top of the screen
	move_and_slide()

get_gravity() returns the gravity currently acting as a vector. Input uses the built-in ui_left and the others as-is, so you don't touch the Input Map. It moves with the arrow keys.

There's no jump and no camera follow. Walking relative to the camera's direction is in CharacterBody3D Basics.

③ Run it and check

The room seen from directly above, in four frames: standing in the middle, stopping at a wall, going through the door onto the outside floor, and climbing the slope on the left while stopping at the step on the right

Play, and the screen looks straight down on the room, with the character standing in the middle of it. If it sinks into the floor or bounces upward here, compare Floor's and Player's Position, and the capsule's height, against the values in ①.

Walk toward a wall with the arrow keys, and at all four walls it stops where the edge of the capsule touches the wall. Head up with the up key toward the gap in the top wall, and it passes through without catching on a threshold and onto the outside floor. If it stops in front of the gap, compare DoorCut's Size and Position against the table.

Next, move about 2.5 meters left from the middle, then press the down key. The character climbs the slope on the left and drops off the end onto the floor. Go back to the middle, move about 2.5 meters right this time, and press the down key, and it stops in front of the step at the bottom right. If it stops here, that confirms a vertical face 0.5 high can't be climbed.

Two points.

  • One collision at the root: Room's Use Collision makes collision from the result of adding and subtracting the eight boxes. Ramp is in a separate tree, so it holds its own
  • Dimensions are decided by whether the character can pass: the door width of 1.6 is the capsule's diameter of 0.8 plus 0.4 of room on each side. If you want to narrow it, take it from that room

Once this room's dimensions are settled and you're up to a second room, transfer it to GridMap. With 2-meter cells, make one 2-meter-wide wall tile with a 1.6-wide opening cut in it, and place that.

Troubleshooting

SymptomCauseFix
The top of a floor placed with GridMap ends up above y = 0Cell Center Y is on by default, placing the mesh at the middle of the cell's height (with a Cell Size of 2, the center is at 1.0)Turn off Cell Center Y, and lower the GridMap by half the floor's thickness (0.5 for a thickness of 1)
After reordering the tree, the shape of the cutting box shows up instead of a holeThe topmost child becomes the base regardless of its OperationOrder cutting boxes below the floor and walls
Choosing an item and clicking the 3D view doesn't place it in a cellThe GridMap dock is still on SelectionEnable Paint in the dock before clicking
After baking, you hid the original CSG, but collision is doubledEven hidden, the collision from the CSG's Use Collision remainsTurn off Use Collision on the original CSG, or remove the node entirely

Bonus: Good to Know First

  • Lower the walls if viewing at an angle: when you want to look at an angle rather than from directly above, lower just the near wall to about 1 meter high and you can see inside
  • Refine the lighting after the dimensions: the sun's direction, placing street lamps and flashlights, and the brightness on the shadow side are covered in 3D Lighting Basics
Sponsored

Summary

  • What you decide is the dimensions: decide the character's capsule first, and derive the door width and ceiling height from it. A box's origin is its center
  • Adding and subtracting is decided by order: under the same parent they combine from the top down, and a Union after carving fills things back in
  • One Use Collision at the root: collision is made from the shape after adding and subtracting. Don't put it on the cutting boxes
  • Steps can't be climbed: there's no feature that climbs steps automatically. To let the character up, add a slope or a jump
  • Transfer to GridMap once the dimensions are settled: give MeshLibrary items collision yourself before exporting

Start by placing just one floor and one wall, turn on Use Collision, and walk around. How many meters square will the first room in your game be?

Read nextNext in the learning path
3D

Godot 3D Lighting Basics: Switch the Same Plaza Between Day and Night With Three Lights and WorldEnvironment

Read this note
Godot Notes in this section104