62 comments

[ 43.0 ms ] story [ 1084 ms ] thread
Inspired by the 45th anniversary of the IBM PC, I got my slopmachine cracking on a port of DONKEY.BAS to work in a browser. Pretty happy with the result. As a young person I remember being fascinated that you could make a game like this with so little code.
> I got my slopmachine cracking on a port

For 131 lines?

On my machine, it is flickering like _crazy_, as if it's trying to shift back and forth between two resolutions.

OSX, Firefox, browser size 3326×2830 pixels. Only happens at or around that particular size - resizing the window fixes the issue.

my car keeps hitting the donkey when switching lanes even though I'm already well past it..
I haven’t looked at the code but the collision detection was buggy even back in the day. You have to switch lanes while there is nothing or a donkey in front of you. If the donkey is in the other lane it registers a hit even if it looks like you passed it

Edit: line 1750 is where it does a simple collision check and yep looks like it registers a collision without checking you’re past the donkey or not

Nice job. The sound effects are a bit too advanced because early IBM computers shipped with pretty simple, magnetically driven dynamic speakers.

On a related note, I’ve actually spent the last four months working on a 100% faithful adaptation of both QBasic and QuickBasic 4.5 that runs entirely in the browser on a virtual CPU and hardware abstraction layer. It’s a love letter to everyone who learned to program on Microsoft’s BASIC interpreters in the ’80s and early ’90s.

The best compliment I’ve received so far is from friends who grew up in the same era I did: when I fullscreen the browser, a few of them assumed it was a virtual machine running the real thing.

A QBasic port of the original BASIC-based DONKEY.BAS was one of the first programs I got running in it:

https://mordenstar.com/share/qbasic-core-demos

Do non-magnetically driven speakers exist?
You used to be able to do surprising things with those old speakers using a timer interrupt: on an IBM XT it was possible to get 8kHz quality out of it, enough to make 4-channel MOD playback sound about as good as hearing it over a phone.

But your more typical use case was to play a single tone for some significant fraction of a second.

Amazing. This is nostalgia heroin for me.

How far does the HAL go? Screen 12 and 13, and writing directly to VRAM? WAIT for vsync? Call absolute for mouse usage?

How comes the modem panel is not “shader-ized” (scanlines + distortion)?
I once heard a digitized version of "Daisy Bell" (DAISY.COM) which sings through IBM PC speaker although of poor bitrate.
It runs fairly well in dosbox in a browser though right? Why port directly?
> early IBM computers shipped with pretty simple, magnetically driven dynamic speakers

Yes the PC & donkey.bas were monophonic design, but the PCjr shipped with 3-channel polyphonic sound plus a noise generator. It might have been capable of doing the sounds in this port of donkey that took “some liberties”. ;)

I remember some sound demos on the PC that emulated polyphonic sound by fast/audible switching between notes in a chord. Hey it seemed cool at the time. :P I just looked and couldn’t find any quickly enough but bumped into examples of even better true polyphony on the PC achieved by assembly hacking.

Ahhh I never saw donkey.bas, and only saw the Microsoft one. You know, when that company cared about being part of the industry, as opposed to being the entire industry, and really want to be 5 other industries to, as they do now.

Gorillas.bas (it's more or less like worms, except with only 1 gorilla per team)

On the plus side: it was much prettier.

It says something about what a thoughtful development environment these early BASICs were, that you could make a full simple little game like this in only 131 lines even though they're ostensibly far less powerful than modern languages. I'm not sure if you could even get an SDL window open and game loop running in 131 lines of (non-golfed) C.

Never mind how compact, beginner-friendly, and just plain fun they were to use. It's been said countless times but I'll say it again - we've lost something over the years.

Python is the modern Basic replacement, and also has similar fundamental design trade-offs. VB6 was the peak of the OLE/Multimedia paradigm, and was functionally replaced by the web browser script sandbox.

> we've lost something over the years.

Indeed, Information Appliances were never general-purpose computers. Some people used to care about that sort of thing, and left civilization the GNU compilers as one of the most important intellectual artifacts of our generation. =3

It was really cool! The ease of getting started was definitely one of the selling points for the “home computers” of that era (GW-BASIC ran on IBM compatible PCs instead, but the appeal of BASIC was the same). Brevity was an important feature since a lot of people obtained programs by typing them over from a magazine or recording them from the radio. And of course, there was no such thing as auto-complete (let alone AI generation).

That being said, SDL isn't actually that bad either. A minimal example is about 40 lines of code [1], not counting comments and blank lines, but including lines with just a curly brace which you could easily remove if you were concerned about size. A slightly more serious implementation of Snake runs about 345 lines of code [2].

And to be fair, DONKEY.BAS is also cheating slightly on the line metric by stuffing lines full of statements, like for example:

    A$=INKEY$:IF A$=CHR$(27) THEN 1298 ELSE POKE 106,0:IF LEN(A$)>0 THEN LINE (CX,CY)-(CX+28,CY+44),0,BF:CX=252-CX:PUT (CX,CY),CAR%,PRESET:SOUND 200,1

1. https://examples.libsdl.org/SDL3/renderer/01-clear/ 2. https://examples.libsdl.org/SDL3/demo/01-snake/
SDL is incredibly terrible based on that example - I imagine it would be about five lines of qbasic?
>I'm not sure if you could even get an SDL window open and game loop running in 131 lines of (non-golfed) C.

The basics (window, events, renderer) can be done in about 30 lines:

    #include <SDL3/SDL.h>
    #include <SDL3/SDL_main.h>

    static SDL_Window* window;
    static SDL_Renderer* renderer;

    int main(int argc, char* argv) {
        SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_GAMEPAD);
        SDL_CreateWindowAndRenderer("test", 640, 480, SDL_WINDOW_RESIZABLE, &window, &renderer);
        SDL_Event event;
    
        while(true) {
            while(SDL_PollEvent(&event) != 0) {
                if (event.type == SDL_EVENT_QUIT) {
                    goto ENDGAME;
                }
                //events go here
            }
            
            // update here
            SDL_SetRenderDrawColor(renderer,0,0,0,255);
            SDL_RenderClear(renderer);

            // render here
            SDL_RenderPresent(renderer);

        }

        ENDGAME:
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        SDL_Quit();
    }
I don't think you could get all of donkey.bas done in 131 lines, though. SDL3 does ship with an embedded debug font but that seems like cheating. You probably couldn't replicate the drawing code easily, it would probably need to be faked with images, and you'd need a font atlas for the text.
131 lines and about 10% of them are the title/copyright banner. Genuinely impressive in it's terseness
What we lost is simplicity across the stack.

I learned to program with BASIC. It was awful. I didn’t know how awful it was until many years later. So I don’t miss the language. But something I miss is how easy it was to learn what your machine was doing.

The DOS boot and config involved only two files: CONFIG.SYS and AUTOEXEC.BAT, that was it. Most programs were self-contained, so you could copy the directory to a floppy disk and run them on another machine. If you broke something, copy the files again and restart; that was it… I “broke” config and programs many times, and it was a good way to learn.

BASIC was higher level (or anyway, more batteries-included) than C. You could probably do this game in 131 lines of javascript straightforwardly.
Back in the days you would buy printed magazines that contained full basic source code of programs and games and type them on your own text editor. I was a bit too young to do that but I remember watching my older brother just do that and then play games (after finding the typing errors for a while).
Brings back memories of GORILLA.BAS! https://en.wikipedia.org/wiki/Gorillas_(video_game)
We used to do quick tests of PC builds with GORILLA.BAS. It was later replaced by the 'Doom test'.
speaking of GORILLA.BAS I made a multiplayer browser room: https://franz101.github.io/gorilla
One small snag, when playing vs CPU the angle and velocity are set to whatever the CPU used. So I need to memorise my previous settings if I want to fine-tune my aim.
I remember hacking GORILLA.BAS code, which was on our office computers, to randomize gravity for my opponent, the result being they could not accurately predict where their bananas would go. I was an unbeatable legend for a while.
Someone gave my grandfather a Games BASICA floppy that had this and other games on it. But this copy had a few games that had been "modified". I remember in DONKEY.BAS, it would curse at you if you hit the donkey. "YOU STUPID SONOFABITCH". We thought it was hilarious. My grandfather was less pleased. He took it away from us when he found out.
I learned most of the best cursing I've ever done from my grandfather. He took pride in teaching his grandkids to curse.

He was involved in setting up the radar systems at Pearl Harbor, much good that did.

Modifying those games were the first times I ever touched code! There was one that existed somewhere between DOS 2.0 and 3.2 that simply asked your name, then asked how the hell you got that name. It was maybe half a dozen lines, but easy enough to modify output and learn a bit about variables.
As a kid I modified DONKEY.BAS for my younger brother who wanted to play as a donkey avoiding cars. It was a clumsy modification, I didn't account for the differing size of the pseudo-sprites, but it made him happy.
tangential: I still remember how disappointed I was in PCs being used to a C64 (which was released in 1982) The quality of the games & sound effects was just not on the same level (C64 being much more advanced)
PC was a clear winner for RPGs, adventure games, and wargames/strategy, even in the early days of PC/XT. Anything that could make use of more RAM and disk, while also not demanding too much of graphics or audio, was great on PC.
I once heard the rumor that DONKEY.BAS was the last piece of code Bill Gates wrote himself at Microsoft. I wonder if it's true.
That has all the hall marks of urban legend, but why let the truth get in the way of a great story.

I have said it for a very long time, Gates wasn't innovative in technology but he absolutely innovated in bringing the most ruthless business practices into software.

This is what got me into programming. When I was a kid, I had a shitty 386 because my father got a computer second hand from a friend (we were poor). I was playing the game and then pressed a key and it took me to the basic editor. I was confused with what I saw and started changing things. I changed a number and the size of the explosion on the banana got bigger. My best friend at the time went to computer camp and explained to me that it was code. 30 years later I'm still programming.
It turned out that Dino run has deep roots
Clearly this needs to be replicated as GTA minigame.
The game theory is all wrong, this is a cooperative game, either they both win or both lose. I don't see how the Donkey getting hit by a car should be classified as "Donkey wins"
(comment deleted)
A greyscale photo of a donkey appears if you lose badly enough. Surely that wasn't possible in basic with 16 colors??

EDIT: That must be the easter egg mentioned in the repo.

I’m partial to Gorrila.bas
> 1296 PRINT "THIS PROGRAM REQUIRES ADVANCED BASIC -- USE COMMAND 'BASICA'":COLOR 15,0,0:FOR I=1 TO 9000:NEXT: RESUME 1298

TIL there is an “Advanced Basic”. I hope the naming was tongue in cheek.

Not tongue in cheek, but called that to distinguish it from ROM BASIC. AFAIK, Advanced BASIC had to be loaded from the DOS disk and mostly added disk management and graphics features.
Is it an easter egg that I can move the donkey with A/D rather than move the car with Space?