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

The Status Panel

Display HP, attack, defence, floor number and gold below the viewport — a readable HUD for the dungeon.

31% of Dungeons Of Dorin

The player has stats, but no way to see them during play. A status panel alongside the viewport shows HP, attack, defence, floor number, gold, and points — all the information needed to make decisions. Should I fight this monster or flee? Can I afford to take damage? How deep am I?

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; "Q/A = up/down"
42 PRINT AT 11, 2; INK 7; "O/P = left/right"
44 PRINT AT 14, 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
82 LET g = 0: LET e = 1
84 DIM d(16,16): DIM v(16,16)
90 REM === generate floor ===
92 GO SUB 1000
94 LET x = u(1,1) + 1: LET y = u(1,2) + 1
96 GO SUB 380
98 CLS
100 GO SUB 300
102 GO SUB 500
104 REM === main loop ===
106 PAUSE 0: LET i$ = INKEY$
108 LET t = x: LET t2 = y
110 IF i$ = "q" OR i$ = "Q" THEN LET t2 = y - 1
112 IF i$ = "a" OR i$ = "A" THEN LET t2 = y + 1
114 IF i$ = "o" OR i$ = "O" THEN LET t = x - 1
116 IF i$ = "p" OR i$ = "P" THEN LET t = x + 1
118 IF t = x AND t2 = y THEN GO TO 104
120 IF t < 1 OR t > 16 OR t2 < 1 OR t2 > 16 THEN GO TO 104
122 IF d(t2,t) = 1 THEN GO TO 104
124 LET x = t: LET y = t2
126 GO SUB 380
128 GO SUB 300
130 GO SUB 500
132 GO TO 104
300 REM === draw viewport ===
302 FOR c = -3 TO 3
304 FOR o = -3 TO 3
306 LET t = x + o: LET t2 = y + c
308 LET i = 1: LET i2 = 0
310 IF t < 1 OR t > 16 OR t2 < 1 OR t2 > 16 THEN GO TO 340
312 IF v(t2,t) = 0 THEN GO TO 340
314 LET i = d(t2,t)
316 LET i2 = 7
318 IF i = 1 THEN LET i2 = 4
340 LET t3 = 3 + c: LET t4 = 11 + o
342 IF o = 0 AND c = 0 THEN LET i2 = 7: LET i = 6
344 IF i2 = 0 THEN PRINT AT t3, t4; " ": GO TO 370
346 IF i = 0 THEN PRINT AT t3, t4; INK i2; ".": GO TO 370
348 IF i = 1 THEN PRINT AT t3, t4; INK i2; CHR$ 143: GO TO 370
350 IF i = 6 THEN PRINT AT t3, t4; INK i2; "@": GO TO 370
352 PRINT AT t3, t4; INK i2; "?"
370 NEXT o: NEXT c
372 RETURN
380 REM === update visibility ===
382 FOR c = y - 2 TO y + 2
384 FOR o = x - 2 TO x + 2
386 IF c >= 1 AND c <= 16 AND o >= 1 AND o <= 16 THEN LET v(c,o) = 1
388 NEXT o: NEXT c
390 RETURN
500 REM === draw status ===
502 PRINT AT 8, 2; INK 7; "HP:"; h; "/"; z; "  "
504 PRINT AT 9, 2; INK 4; "AT:"; a; "  "
506 PRINT AT 10, 2; INK 5; "DF:"; f; "  "
508 PRINT AT 8, 20; INK 6; "FL:"; e; " "
510 PRINT AT 9, 20; INK 6; "AU:"; g; "  "
514 RETURN
1000 REM === generate floor subroutine ===
1002 FOR i = 1 TO 16: FOR o = 1 TO 16
1004 LET d(i,o) = 1: LET v(i,o) = 0
1006 NEXT o: NEXT i
1010 LET s = INT (RND * 3) + 3
1012 DIM u(5,4)
1014 FOR i = 1 TO s
1016 LET u(i,1) = INT (RND * 10) + 2
1018 LET u(i,2) = INT (RND * 10) + 2
1020 LET u(i,3) = INT (RND * 4) + 3
1022 LET u(i,4) = INT (RND * 4) + 3
1024 FOR c = u(i,2) TO u(i,2) + u(i,4) - 1
1026 FOR o = u(i,1) TO u(i,1) + u(i,3) - 1
1028 IF c >= 1 AND c <= 16 AND o >= 1 AND o <= 16 THEN LET d(c,o) = 0
1030 NEXT o: NEXT c
1032 NEXT i
1034 FOR i = 1 TO s - 1
1036 LET t = u(i,1) + INT (u(i,3) / 2)
1038 LET t2 = u(i,2) + INT (u(i,4) / 2)
1040 LET t3 = u(i+1,1) + INT (u(i+1,3) / 2)
1042 LET t4 = u(i+1,2) + INT (u(i+1,4) / 2)
1044 IF t <= t3 THEN FOR o = t TO t3: IF t2 >= 1 AND t2 <= 16 AND o >= 1 AND o <= 16 THEN LET d(t2,o) = 0
1046 IF t <= t3 THEN NEXT o
1048 IF t > t3 THEN FOR o = t3 TO t: IF t2 >= 1 AND t2 <= 16 AND o >= 1 AND o <= 16 THEN LET d(t2,o) = 0
1050 IF t > t3 THEN NEXT o
1052 IF t2 <= t4 THEN FOR c = t2 TO t4: IF c >= 1 AND c <= 16 AND t3 >= 1 AND t3 <= 16 THEN LET d(c,t3) = 0
1054 IF t2 <= t4 THEN NEXT c
1056 IF t2 > t4 THEN FOR c = t4 TO t2: IF c >= 1 AND c <= 16 AND t3 >= 1 AND t3 <= 16 THEN LET d(c,t3) = 0
1058 IF t2 > t4 THEN NEXT c
1060 NEXT i
1062 RETURN

How It Works

Lines 500-514 are the status panel subroutine. Each PRINT AT places a stat label and value at a fixed screen position beside the viewport.

Line 502 shows HP as a fraction: current HP over maximum HP. Seeing both numbers tells the player how badly hurt they are relative to their full health. White INK makes it prominent.

Lines 504-506 show attack and defence. Attack uses green INK (4), defence uses cyan INK (5). Each displays the base stat plus any equipment bonus — a + w for attack (where w is weapon bonus) and f + r for defence (where r is armour bonus).

Lines 508-512 show floor number, gold, and potions on the right side. Floor uses yellow INK (6), gold the same. Potions use cyan INK (3). The trailing spaces in each PRINT statement clear any leftover digits from previous values — without them, a value dropping from 100 to 99 would leave a stray digit.

Layout Decisions

The status panel sits beside and below the viewport, using the space that the 7x7 viewport does not fill. The layout keeps all information visible at once — the player never needs to switch screens to check their stats. Each stat has a two-letter label (HP, AT, DF, FL, AU, PT) to save horizontal space.

Colour coding is important. When the screen is mostly black with white and green dungeon cells, coloured stat labels stand out. The player can glance at the status area and immediately find what they need. Red for danger (low HP) would be even better, but that refinement comes in Phase 2.

Trailing Spaces

The " " at the end of each PRINT statement is not decoration. When a number shrinks — HP dropping from 20 to 8, for instance — the old digits remain on screen unless overwritten. A two-character pad after each value ensures old characters are cleared. This is a common BASIC display technique and avoids the cost of clearing the entire screen on every update.

Try This

Rearrange the panel. Move stats to different screen positions. Which layout is easiest to read during play? Consider grouping combat stats (HP, attack, defence) together and progress stats (floor, gold) separately.

Add colour to HP. Print HP in green when full, yellow when below half, red when below a quarter. Use IF statements to choose the INK value before the PRINT.