Learn to write games for the BBC Micro with Eben
Long-time fans of the Raspberry Pi will know that we were inspired to make a programmable computer for kids by our own experiences with a machine called the BBC Micro, which many of us learned with in the 1980s.
This post is the first of what’s going to be an irregular series where I’ll walk you through building the sort of game we used to play when we were kids. You’ll need a copy of BeebEm (scroll down for a Linux port if you’re using a Pi – but this tutorial can be carried out on a PC or Mac as well as on an original BBC Micro if you have access to one).
I’m going to be presenting the next game in this series, tentatively titled Eben Goes Skiing, at the Centre for Computing History in Cambridge at 2pm this afternoon – head on down if you’d like to learn how to make scrolling ascii moguls.
Helicopter tutorial
We’re going to build a simple helicopter game in BBC BASIC. This will demonstrate a number of neat features, including user-defined characters, non-blocking keyboard input using INKEY, and positioning text and graphics using PRINT TAB.
Let’s start with user-defined characters. These provide us with an easy way to create a monochrome 8×8-pixel image by typing in 8 small numbers. As an example, let’s look at our helicopter sprite:
Each column pixel position in a row is “worth” a different power of 2, from 1 for the rightmost pixel up to 128 for the leftmost. To generate our 8 numbers, we process one row at a time, adding up the value for each occupied pixel position. We can now create custom character number 226 using the VDU 23 command. To display the character, we change to a graphics mode using the MODE command and display it using the PRINT command.
Type the following:
10MODE 2 70VDU 23,226,0,248,32,116,126,116,112,0 RUN PRINT CHR$(226)
You should see the little helicopter on the screen just above your prompt. Let’s define some more characters for our game, with character numbers 224 through 229. These represent leftward and rightward flying birds, a rightward flying helicopter, the surface of the sea, and a landing pad.
Type the following:
50VDU 23,224,0,14,12,104,16,28,8,0 60VDU 23,225,0,112,48,22,8,56,16,0 80VDU 23,227,0,31,4,46,126,46,14,0 90VDU 23,228,0,102,255,255,255,255,255,255 100VDU 23,229,255,255,0,0,0,0,0,0
Trying running your program and using print to view the new characters!
Now we’re ready to use our sea and platform characters to build the game world. Mode 2 on the BBC Micro has 20 character positions across, and 32 down. We’ll draw 20 copies of the sea character in row 30 (remember, rows and columns are numbered from zero) using a FOR loop and the PRINT TAB command, and pick a random position for the platform using the RND() function.
Type the following:
110FOR I%=0 TO 19 120PRINT TAB(I%,30) CHR$(228); 130NEXT 140P%=RND(20)-1 150PRINT TAB(P%,30) CHR$(229); RUN
You should see something like this:
Don’t worry about that cursor and prompt: they won’t show up in the finished game.
It’s time to add the helicopter. We’ll create variables X% and Y% to hold the position of the helicopter, and Z% to tell us if it last moved left or right. We’ll initialise X% to a random position, Y% to the top of the screen, and Z% to zero, meaning “left”. We can use PRINT TAB again to draw the helicopter (either character 226 or 227 depending on Z%) at its current position. The whole thing is wrapped up in a REPEAT loop, which keeps executing until the helicopter reaches the ground (in row 29).
Type the following:
160X%=RND(20)-1:Y%=0:Z%=0 180REPEAT 260PRINT TAB(X%,Y%) CHR$(226+Z%); 290UNTIL Y%=29 RUN
You’ll see the helicopter sitting at the top of the screen.
We’re almost there: let’s give our helicopter the ability to move left, right and down. On each trip round the loop, we move down one row, and use the INKEY() function to read the Z and X keys on the keyboard. If Z is pressed, and we’re not already at the left of the
screen, we move one column left. If X is pressed, and we’re not already at the right of the screen, we move one column right.
Type the following:
210IF INKEY(-98) AND X%>0 THEN X%=X%-1:Z%=0 220IF INKEY(-67) AND X%<19 THEN X%=X%+1:Z%=1 230Y%=Y%+1 RUN
You should see something like this:
The game is much, much too fast to control, and the helicopter leaves trails: not surprising, as we didn’t do anything to erase the previous frame. Let’s use PRINT TAB to place a “space” character over the previous position of the helicopter, and add an empty FOR loop to slow things down a bit.
Type the following:
190PRINT TAB (%,Y%)""; 280FOR I%=1 TO 200:NEXT RUN
Much better! This is starting to feel like a real game. Let’s finish it off by:
- Adding a bird that flies back and forth
- Detecting whether you hit the pad or not
- Getting rid of the annoying cursor using a “magic” VDU 23 command
- Putting an outer loop in to let you play again
Type the following:
20REPEAT 30CLS 40VDU 23,1,0;0;0;0; 170A%=RND(18):B%=10:C%=RND(2)-1 200PRINT TAB(A%,B%) ""; 240A%=A%+2*C%-1 250IF A%=0 OR A%=19 THEN C%=1-C% 270PRINT TAB(A%,B%) CHR$(224+C%); 300IF X%=P% PRINT TAB(6,15) "YOU WIN" ELSE PRINT TAB(6,15) "YOU LOSE" 310PRINT TAB(4,16) "PRESS SPACE" 320REPEAT UNTIL INKEY(-99) 330UNTIL FALSE RUN
And here it is in all its glory.
You might want to try adding some features to the game: collision with the bird, things to collect, vertical scrolling. The sky’s the limit!
I created a full version of the game, using graphics from our very own Sam Alder, for the Hackaday 1K challenge; you can find it here.
Appendix
Here’s the full source for the game in one block. If you get errors when you run your code, type:
MODE 0 LIST
And compare the output very carefully with what you see here.
10MODE 2 20REPEAT 30CLS 40VDU 23,1,0;0;0;0; 50VDU 23,224,0,14,12,104,16,28,8,0 60VDU 23,225,0,112,48,22,8,56,16,0 70VDU 23,226,0,248,32,116,126,116,112,0 80VDU 23,227,0,31,4,46,126,46,14,0 90VDU 23,228,0,102,255,255,255,255,255,255 100VDU 23,229,255,255,0,0,0,0,0,0 110FOR I%=0 TO 19 120PRINT TAB(I%,30) CHR$(228); 130NEXT 140P%=RND(20)-1 150PRINT TAB(P%,30) CHR$(229); 160X%=RND(20)-1:Y%=0:Z%=0 170A%=RND(18):B%=10:C%=RND(2)-1 180REPEAT 190PRINT TAB(X%,Y%) " "; 200PRINT TAB(A%,B%) " "; 210IF INKEY(-98) AND X%>0 THEN X%=X%-1:Z%=0 220IF INKEY(-67) AND X%<19 THEN X%=X%+1:Z%=1 230Y%=Y%+1 240A%=A%+2*C%-1 250IF A%=0 OR A%=19 THEN C%=1-C% 260PRINT TAB(X%,Y%) CHR$(226+Z%); 270PRINT TAB(A%,B%) CHR$(224+C%); 280FOR I%=1 TO 200:NEXT 290UNTIL Y%=29 300IF X%=P% PRINT TAB(6,15) "YOU WIN" ELSE PRINT TAB(6,15) "YOU LOSE" 310PRINT TAB(4,16) "PRESS SPACE" 320REPEAT UNTIL INKEY(-99) 330UNTIL FALSE
29 comments
Andrew Oakley
Looks like your content management system has munged the listings. I’m pretty sure there should be a space between the line numbers and the start of the commands. For exmaple, “10 PRINT” rather than “10PRINT”. Lovely to see some 80’s listings, though, especially the bitmap custom characters.
Liz Upton
I’ve just asked Eben about this: he says that the space is optional; and that omitting it will make the program smaller (not important in this case, but a good habit to get into when you’re working with limited memory). So it’s something he tends to do reflexively – not a bug!
crumble
It’s more a _bad_ habit.
I don’t know the BBC, but a normal 8Bit machine got its Basic from M$.
They stored the the commands of the program as tokens, not in full text. Line numbers were much smaller integers than ASCII.
Readability was even back than a huge thing ;)
Speed as well, so store the value of INKEY() and call it only once in the loop ;)
Andy Barnes
BBC Basic also tokenised its commands in memory to save space. This article from Matt Godbolt talks about BBC BASIC V but it equally applies to the BBC Micro’s version https://xania.org/200711/bbc-basic-v-format
dave j
BBC Basic has a LISTO command that defines the format of program listings. LISTO 1 will display a listing with a space after the line number. Other values let you also indent loops. So you can get pretty listings and small programs.
INKEY() with a negative number returns if a particular key is pressed so those two calls are checking different things.
Bitbeisser
The BBC Micro had its own BASIC, not even remotely related to any M$ BASIC.
In a lot of ways, it was more versatile than MS/GW-BASIC, but also had some quirks, like you HAD TO enter all commands in uppercase,or it would throw a hissyfit on that line. The optional space after the line number is just another quirk.
Ken C
The BBC Micro. What excitement and enthusiasm it created. It stepped over from Clive’s machines and gave users the opportunity to learn computer languages. I had the book (BBC Basic or something like that) to learn programming along with brilliant fun with binary coloured games (black and white). There was a TV programme to accompany the BBC machine to help us amateurs get started and along with PCW mag it was computer heaven for me. I wrote a couple of programs/games and even managed to get them up for sale on Prestel and made the huge sum of £20. Here we are in the 21 century and Back to the Future with Raspberry Pi and Python. Now I am showing children the power of computer programming and stirring the same excitement and enthusiasm there was way back then. Brill.
Andy Barnes
Worth mentioning Matt Godbolt’s Javascript based emulator for trying things out in your web browser too -> https://bbc.godbolt.org/
Shannon
VDU? I had to define data statements and pokes to build custom characters on the VIC20. You guys were spoiled! LOL!
Is this going to be a recurring topic? I hope so.
Eben Upton
I hope so too. Today’s session (writing a downhill skiing game) was a lot of fun to run. Massive enthusiasm from the kids (and their parents).
Aric Caley
his is very interesting and timely, for me. I’ve been looking at ways to teach programming to my son who is interested. What do I do? Set him up with an IDE and game framework and such on a modern computer? Thats a lot of stuff just to get to where you can do a simple thing. I miss the old days. I think we’ve lost something along the way.
I had the most success with, of all things, just firing up a sinclair spectrum emulator (since that is what I learned on)! And despite all the influence of modern games and such, he was thrilled just learn how to plot a low res pixel on the screen.
I think there is something to this. I don’t think BASIC is the horrible thing we’ve all been taught to believe it is. I think its a good thing to start with, almost specifically because it IS something you will hopefully outgrow quickly…
Eben Upton
There’s this ridiculous idea, due to Edsger Dijkstra, that BASIC leaves programmers “mentally mutilated beyond hope of regeneration”. If this is true, most of the best software engineers I know are doing very well to overcome their mutilation.
You learn it, and then you move on. Maybe Python’s a better choice these days because the ladder goes up further, but nothing wrong with BASIC.
Roger O’Donnell
In many ways BBC BASIC addressed a lot of Dykstra’s issues with the language – other than the line numbering the language is heavily structured, in the Pascal sense of the term. There are Procedures, and functions, hard typing (although there’s no declaration), it’s recursive (not very far on OG hardware, but you can). There’s even a type of jagged array support.
BBC BASIC was what I coded my final year dissertation implementation on (an Electron in my room in halls, transferred to ADFS Disc for running on the Uni’s BBC Bs) Effectively, it was a superset of the foregoing versions of BASIC.
I doubt he looked into the dialects very far when he made that assertion.
Bensimmo
If you’re on Android then the Java page doesn’t work.
Beebdroid (playstore) should work but you’ll have to type it all in if you can get past Chuckie egg, frack and hopper.
http://www.bbcbasic.co.uk may work for you, but it doesn’t on my HUDL2, it errors and get locked with the keyboard up at different stages. Also it’s not so user friendly and you have to figure out how to even start entering a program.
But it may work for you. Also you’ll find him on the forum.
Harry Hardjono
It’s too bad that C doesn’t support graphic natively. I have to use BASIC to make interesting games. Fuse basic is being ported to Nintendo Switch, so hopefully, that will catch on.
Extremely annoying that SDL2, despite being written in C, is presented as C++ programs. About the closest thing that I like is tcc games. That’s Tiny C Compiler using SDL2 to make games.
I’m seriously considering using GameMaker(!) to write my programs because it’s portable across platforms, albeit expensively.
Simon Smith
I still have a fully working original BBC model B (a few dry joints needed fixing on some keys). Can you cover simple game programming in assembler too?
Eben Upton
I could. The challenge is to create something worthwhile that’s short enough to serve as an introduction for beginners. The full helicopter game on Hackaday is quite a nice example of how much you can squeeze out of 20ms of 6502:
https://hackaday.io/project/19168-bbc-micro-50hz-helicopter-score-attack
but even that is quite a substantial body of code.
scruss
BeebEm? Lawks, that’s a bit old (2006). All the cool (*cough*) kids are running b-em – https://github.com/stardot/b-em – these days. It’s lovingly maintain by Stardot forum members. It’s a little crashy on some Linux platforms, but seems stable on the Raspberry Pi and Raspbian. You may need to install the liballegro5-dev and zlib1g-dev packages to get it to compile.
If you want a native version of BBC BASIC, Richard Russell’s version is pretty neat: http://www.bbcbasic.co.uk/bbcsdl/ . You’ll most likely need to change line 280 to use some variant of the WAIT command to make it playable.
Another native interpreter is Brandy. There’s an ancient one in the repos, but I’m completely taken with the Matrix Brandy fork: https://github.com/stardot/MatrixBrandy . It may need a few packages installed to get it to build (libsdl1.2-dev might be a good first try), but it’s really fast. For cross-platform happiness, change line 280 to WAIT 10. If you stick to using a FOR loop, you might have to have it as high as 2,000,000 on a fast computer!
Lastly, if you want to run the game in a browser, JSBeeb to the rescue: https://bbc.godbolt.org/?autorun&loadBasic=https://gist.githubusercontent.com/scruss/f5a8eb83f28b85d6399142cac460c806/raw/74c4e39de7661bb2e3dd7f435840dd8db7172589/helicopter.bbc
It’s a bit slow in Chromium on a Raspberry Pi, but it does work!
Neil
RasPi too complicated for you, Eben?
Eben Upton
Yeah, never could get the hang of that thing.
Richard Russell
The program runs fine in (Raspbian) BBC BASIC on a Raspberry Pi itself, or at least it would bar one serious flaw: the speed is controlled by a FOR…NEXT loop (line 280) so it runs far (far!) too fast on that machine. To slow it down so it’s playable, change line 280 as follows:
280 TIME=0:REPEAT I%=INKEY(1):UNTIL TIME>=20
Raspbian BBC BASIC is available from https://www.bbcbasic.co.uk/bbcsdl/
Soruk
A cross-platform and speed-independent way of doing the delay on line 280 could be something like:
280 T%=TIME: REPEAT I%=INKEY(1): UNTIL TIME-T%>=10
This could, of course, be abstracted to a PROCwait(x) so the delay could be used elsewhere in the game if so required.
This should work on all versions of BBC BASIC, also Matrix Brandy.
Chris Ainsley
Excellent post. It’s really important to get kids coding something simple, and moving something on screen, simple as it is, is hugely satisfying.
To that end, I’ve been developing a system called Adventuron, as a first programming language, but coming at it from the angle of text (or story) based games. The cool thing is that Adventuron’s IDE is entirely in-browser, with syntax highlighting, realtime-validation, code-completion, and the games it makes can be exported to a standalone html page, that has no online requirement. They also look authentically retro too.
https://youtu.be/KY1_kZBYHkI
If you are looking for a fun yet hugely creative and educational activity to perform with your kids, give it a try.
Chris Ainsley
Excellent post. It’s really important to get kids coding something simple, and moving something on screen, simple as it is, is hugely satisfying.
To that end, I’ve been developing a system called Adventuron, as a first programming language, but coming at it from the angle of text (or story) based games. The cool thing is that Adventuron’s IDE is entirely in-browser, with syntax highlighting, realtime-validation, code-completion, and the games it makes can be exported to a standalone html page, that has no online requirement. They also look authentically retro too.
If you are looking for a fun yet hugely creative and educational activity to perform with your kids, give it a try.
Eben Upton
This looks awesome. Going to spend a bit of time with Adventuron this week…
Chris Ainsley
Thanks. I hope you have fun!
Bryan Hogan
This program will also run fine (but rather fast!) by installing RISC OS on the Pi and using the ARM BBC BASIC built into that.
Install RISC OS Pico for that really authentic BBC Micro feel :-)
https://www.riscosopen.org/content/downloads/raspberry-pi
Roger O’Donnell
I thought that the current RPi 3 firmware breaks Pico.
Anne Carlill
Thanks for this. I am now in my 60s and learnt BBC BASIC with my children so it’s the language I know best. Also, the programming language on my trusty TI-83 graphic calculator is similar to it. And, I often find, writing a quick bit of code on the TI-83 is still the quickest way to solve a mathematical/engineering problem, particularly if I’m on the move. So you’ve done me a great service by reintroducing BASIC here. Yes, I am learning Python – but for everyday quick problem-solving, by people like me who are not coding professionals, BBC BASIC is usually adequate. So thanks!