Skip to content
Game 15 Unit 3 of 32 1 hr learning time

Carving Rooms

Place randomly sized rooms at random positions in the wall grid — the first step of procedural generation.

9% of Dungeons Of Dorin

A dungeon made entirely of walls is not much use. Rooms give the player space to move, places to find treasure, and corners to hide behind. This unit carves randomly positioned, randomly sized rooms into the wall grid using RND. Run the program several times and each dungeon looks different.

The Program

5 REM === DUNGEONS OF DORIN ===
10 BORDER 0: PAPER 0: INK 7: CLS
20 PRINT AT 3, 4; INK 7; BRIGHT 1; "DUNGEONS OF DORIN"
30 PRINT AT 6, 2; INK 6; "Descend ten floors of"
35 PRINT AT 7, 2; INK 6; "darkness. Find the Heart."
40 PRINT AT 10, 2; INK 7; "Press any key to begin"
50 PAUSE 0
60 CLS
70 REM === define stats ===
80 LET h = 20: LET z = 20: LET a = 3: LET f = 2
90 REM === create dungeon grid ===
100 DIM d(16,16)
110 FOR i = 1 TO 16: FOR o = 1 TO 16
120 LET d(i,o) = 1
130 NEXT o: NEXT i
140 REM === carve rooms ===
150 LET s = INT (RND * 3) + 3
160 DIM u(5,4)
170 FOR i = 1 TO s
180 LET u(i,1) = INT (RND * 10) + 2
190 LET u(i,2) = INT (RND * 10) + 2
200 LET u(i,3) = INT (RND * 4) + 3
210 LET u(i,4) = INT (RND * 4) + 3
220 FOR c = u(i,2) TO u(i,2) + u(i,4) - 1
230 FOR o = u(i,1) TO u(i,1) + u(i,3) - 1
240 IF c >= 1 AND c <= 16 AND o >= 1 AND o <= 16 THEN LET d(c,o) = 0
250 NEXT o: NEXT c
260 NEXT i
270 REM === display grid ===
280 FOR i = 1 TO 16: FOR o = 1 TO 16
290 IF d(i,o) = 1 THEN PRINT AT i + 2, o + 6; INK 4; CHR$ 143
300 IF d(i,o) = 0 THEN PRINT AT i + 2, o + 6; INK 7; "."
310 NEXT o: NEXT i
320 PRINT AT 20, 4; INK 7; s; " rooms carved"
330 STOP

How It Works

Line 50 decides how many rooms to place: between 3 and 5, chosen randomly with INT(RND * 3) + 3.

Line 52 dimensions an array u(5,4) to store each room definition. Each room has four properties: x position, y position, width, and height.

Lines 54-72 loop through the rooms. For each one, lines 56-62 pick a random position (leaving margin from the grid edges) and a random size between 3 and 6 cells in each direction. Lines 64-70 carve the room by setting every cell within the rectangle to 0 (floor).

Line 68 includes a bounds check — IF c >= 1 AND c <= 16 AND o >= 1 AND o <= 16 — to prevent writing outside the array if a room extends past the grid edge. Without this check, the program would crash with a Subscript wrong error.

Procedural Generation

This is the first time a game has created its own content at runtime. Previous games used DATA statements for levels, predefined boards, or fixed layouts. Here, the dungeon is different every time because RND produces different numbers on each run.

Procedural generation follows a pattern: define rules (how big rooms can be, where they can go), then let randomness fill in the details. The rules prevent impossible layouts — rooms stay within bounds and have a minimum size — while the randomness creates variety. This balance between constraint and chaos is what makes generated content feel both surprising and fair.

Storing Room Data

The room array u(5,4) serves a second purpose beyond carving. Later units need to know where rooms are — to connect them with corridors, place the player in the first room, and put stairs in the last room. Storing the room definitions lets other subroutines reference them without scanning the entire grid.

Try This

Force a single large room. Set the room count to 1 and the size to 12x12. The dungeon becomes a single chamber. How does this change the feel?

Run it ten times. Press RUN repeatedly and watch the rooms change. Do any runs produce overlapping rooms? Overlapping is fine — it just creates larger open areas.