Printouts as Games

As we discussed last time, while BASIC Computer Games became a bestseller because of microcomputers, the games themselves dated back to timesharing systems using teletypewriters. As a result, a few of this first generation of BASIC games produced printed output as the primary purpose or as the game itself.

The most game-like of these was Amazing, which would generate a new, random maze that you could solve on the printout.

AMAZING PROGRAM

CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY

WHAT ARE YOUR WIDTH AND LENGTH? 10
??? 10

.--.--.--.  .--.--.--.--.--.--.
I        I              I     I
:--:--:  :--:--:  :  :  :  :  .
I        I        I  I     I  I
:  :--:--:  :  :--:  :--:--:  .
I  I        I     I  I     I  I
:  :  :--:--:--:--:  :  :  :  .
I  I     I        I  I  I     I
:  :  :--:  :  :  :  :--:  :--.
I  I  I     I  I  I     I     I
:  :  :  :--:  :  :--:  :--:  .
I     I  I     I        I  I  I
:--:--:  :--:--:--:--:  :  :  .
I              I     I  I     I
:  :--:--:  :  :  :  :--:--:--.
I        I  I     I           I
:  :--:  :--:--:--:--:--:--:  .
I     I  I        I        I  I
:--:  :  :  :--:  :  :--:  :  .
I     I  I     I        I     I
:--:--:  :--:--:--:--:--:--:--.

The Banner program would print a headline:

HORIZONTAL? 1
VERTICAL? 1
CENTERED? N
CHARACTER (TYPE 'ALL' IF YOU WANT CHARACTER BEING PRINTED)? ALL
STATEMENT?? BASIC
SET PAGE? 1

BBBBBBBBB
B   B   B
B   B   B
B   B   B
B   B   B
B   B   B
BBB BBB

 

AAAAAA
A  A
A   A
A    A
A   A
A  A
AAAAAA


 
S   S
S   S S
S   S   S
S   S   S
S   S   S
S S   S
S   S

 

I       I
I       I
I       I
IIIIIIIII
I       I
I       I
I       I
 
 

CCCCC
C     C
C       C
C       C
C       C
C     C
C   C

And, finally, Calendar would produce a calendar; hardcoded for 1979.

CALENDAR
CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY
 
** 0  ****************** JANUARY ****************** 365 **
 
S       M       T       W       T       F       S
 
***********************************************************
 

2       3       4       5       6       7       8
 

9       10      11      12      13      14      15
 

16      17      18      19      20      21      22

 
23      24      25      26      27      28      29
 

30      31


** 31 ****************** FEBRUARY****************** 334 **

S       M       T       W       T       F       S

***********************************************************


1       2       3       4       5
 

6       7       8       9       10      11      12


13      14      15      16      17      18      19
 

20      21      22      23      24      25      26
 

27      28

 

** 59 ******************  MARCH  ****************** 306 **

S       M       T       W       T       F       S

***********************************************************
 

1       2       3       4       5
 

6       7       8       9       10      11      12
 

13     14      15      16      17      18      19
 

20     21      22      23      24      25      26
 

27     28      29      30      31
 

** 90 ******************  APRIL  ****************** 275 **

S       M       T       W       T       F       S

***********************************************************


1       2
 

3       4       5       6       7       8       9
 

10      11      12      13      14      15      16


17      18      19      20      21      22      23
 

24      25      26      27      28      29      30

 
** 120 ******************   MAY   ****************** 245 **

S       M       T       W       T       F       S

***********************************************************
 

1       2       3       4       5       6       7


8       9       10      11      12      13      14
 

15      16      17      18      19      20      21
 

22      23      24      25      26      27      28
 

29      30      31


** 151 ******************   JUNE  ****************** 214 **

S       M       T       W       T       F       S

***********************************************************
 

1       2       3       4
 

5       6       7       8       9       10      11
 

12      13      14      15      16      17      18
 

19      20      21      22      23      24      25
 

26      27      28      29      30


** 181 ******************   JULY  ****************** 184 **

S       M       T       W       T       F       S

***********************************************************


1       2


3       4       5       6       7       8       9
 

10      11      12      13      14      15      16
 

17      18      19      20      21      22      23
 

24      25      26      27      28      29      30
 

31


** 212 ******************  AUGUST ****************** 153 **

S       M       T       W       T       F       S

***********************************************************


1       2       3       4       5       6


7       8       9       10      11      12      13
 

14      15      16      17      18      19      20
 

21      22      23      24      25      26      27
 

28      29      30      31
 

** 243 ******************SEPTEMBER****************** 122 **

S       M       T       W       T       F       S

***********************************************************
 

1       2       3
 

4       5       6       7       8       9       10
 

11      12      13      14      15      16      17
 
18      19      20      21      22      23      24
 

25      26      27      28      29      30
 

** 273 ****************** OCTOBER ****************** 92 **

S       M       T       W       T       F       S

***********************************************************
 

1
 

2       3       4       5       6       7       8
 

9       10      11      12      13      14      15
 

16      17      18      19      20      21      22
 

23      24      25      26      27      28      29
 

30      31
 

** 304 ****************** NOVEMBER****************** 61 **

S       M       T       W       T       F       S

***********************************************************


1       2       3       4       5

 
6       7       8       9       10      11      12


13      14      15      16      17      18      19
 

20      21      22      23      24      25      26
 

27      28      29      30


** 334 ****************** DECEMBER****************** 31 **

S       M       T       W       T       F       S

***********************************************************
 

1       2       3
 

4       5       6       7       8       9       10
 

11      12      13      14      15      16      17
 

18      19      20      21      22      23      24


25      26      27      28      29      30      31


You can give each of these a spin in this BASIC emulator (every program from BASIC Computer Games can be preloaded from the dropdown menu). Next time, we’ll look at the primitive visualization tools that were packaged as “games”.

History of Game Art: Timeshare BASIC Edition

When I first met Rick Dakan, one of the creators of City of Heroes, we talked about a class he’s teaching at Ringling College of Art and Design in the spring, “The History of Game Art.” The class starts with Spacewar! in 1962 but to my surprise doesn’t cover some of the BASIC games of the timeshare era (circa 1964 to 1976). Yes, some have “art” (in fact, some are only art).

BASIC Computer Games, the first computer book to sell a million copies, is thought of as a collection of microcomputer games. And while the games were edited to run in Microsoft Altair 8K BASIC, almost all of the games were ports of games created on timeshare systems. In fact, many of the games were played by teletype and so produced printed output, output that could be preserved, as art. In fact, the output from some of the examples below was too large to even display completely on one screen on a typical 1970s microcomputer, as you’ll find out for yourself in the emulator.

Here are four examples, all of which you can “play” in your browser. Click the Show output button to have a virtual printout. While these are listed as “Computer Games” they aren’t computer games in any modern sense – diversions, maybe.

Bunny provides an image of a rabbit using the text “BUNNY”.

                                BUNNY
              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY

UN
BUN                                         BUNNYB
BUNNYB                                    NYBUNNYBUN
BUNNYBUN                                UNNYBUNNYBUN
UNNYBUNNY                           NNYBUNNYBUNNYB
 NNYBUNNYBU                        UNNYBUNNYBUNNYB
  NYBUNNYBUNN                    YBUNNYBUNNYBUNNY
   YBUNNYBUNNY                 NNYBUNNYBUNNYBUNN
    BUNNYBUNNYB               UNNYBUNNYBUNNYBUN
     UNNYBUNNYBU             BUNNYBUNNYBUNNYB
      NNYBUNNYBUN           YBUNNYBUNNYBUNNY
       NYBUNNYBUNNY        NYBUNNYBUNNYBUNN
        YBUNNYBUNNYB      NNYBUNNYBUNNYBU
         BUNNYBUNNYBU    UNNYBUNNYBUNNYB
          UNNYBUNNYBUN  BUNNYBUNNYBUNN
           NNYBUNNYBUN YBUNNYBUNNYBU
            NYBUNNYBUNNYBUNNYBUNNY
             YBUNNYBUNNYBUNNYBUNN
              BUNNYBUNNYBUNNYBU
                NNYBUNNYBUNNY
                 NYBUNNYBUN
                  YBUNNYBU
               UNNYBUNNYBUNN
            NYBUNNYBUNNYBUNNYB
          UNNYBUNNYBUNNYBUNNYBU
         BUNNYBUNNYBUNNYBUNNYBUN
       NYBUNNYBUNNYBUNNYBUNNYBUNN
      NNYBUNNYBUNNYBUNNYBUNNYBUNNY
     UNNYBUNN  UNNYBUNNYBUNNYBUNNY
    BUNNYBUN   UNNYBUNNYBUNNYBUNNYB
   YBUNNYBUN   UNNYBUNNYBUNNYBUNNYB
  NYBUNNYBUN  BUNNYBUNNYBUNNYBUNNYB
 NNYBUNNYBUNNYBUNNYBUNNYBUNNYBUNNYB
UNNYBUNNYBUNNYBUNNYBUNNYBUNNYBUNNYB
 NNYBUNNYBUNNYBUNNYBUNNYBUNNYBUNNY
  NYBUNNYBUNNYBUNNYBUNNYBUNNYBUNNY
   YBUNNYBUNNYBUNNYBUNNYBUNNYBUNN
     UNNYBUNNYBUNNYBUNNYBUNNYBUNN
         BUNNYBUNNYBUNNYBUNNYBUN Y
             YBUN YBUNNYB  NYBU   B
              BUNNY   NYBUNNYB     U
             YBUNN  U  YBUNNYB      N
            NYBUNN    NYBUNNY   NYBUNN
           NNYBUNNYBUNNYBUNNY UNN
          UNN   N Y  N YBUNNYBU
         BU     NN   N Y    Y
                     NN  UNNY
                          NNY
                           NY

That’s it. The user can’t even change the text. There is literally no interactivity. This isn’t even sophisticated ASCII art, where letters are chosen for gradients or contrasts. It’s just the word “BUNNY” in a “BUNNY” shape. Yet Ahl elected to include this program in both 101 BASIC Computer Games, published in 1975 with games for timeshare systems, and its successor, published in 1978.

Diamonds introduces a sliver of interactivity. You can specify one of nine different widths of diamonds.

                               DIAMOND
              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY

FOR A PRETTY DIAMOND PATTERN,
TYPE IN AN ODD NUMBER BETWEEN 5 AND 21? 15
      C              C              C              C
     CC!            CC!            CC!            CC!
    CC!!!          CC!!!          CC!!!          CC!!!
   CC!!!!!        CC!!!!!        CC!!!!!        CC!!!!!
  CC!!!!!!!      CC!!!!!!!      CC!!!!!!!      CC!!!!!!!
 CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!
CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!
CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!
CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!
 CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!
  CC!!!!!!!      CC!!!!!!!      CC!!!!!!!      CC!!!!!!!
   CC!!!!!        CC!!!!!        CC!!!!!        CC!!!!!
    CC!!!          CC!!!          CC!!!          CC!!!
     CC!            CC!            CC!            CC!
      C              C              C              C
      C              C              C              C
     CC!            CC!            CC!            CC!
    CC!!!          CC!!!          CC!!!          CC!!!
   CC!!!!!        CC!!!!!        CC!!!!!        CC!!!!!
  CC!!!!!!!      CC!!!!!!!      CC!!!!!!!      CC!!!!!!!
 CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!
CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!
CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!
CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!
 CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!
  CC!!!!!!!      CC!!!!!!!      CC!!!!!!!      CC!!!!!!!
   CC!!!!!        CC!!!!!        CC!!!!!        CC!!!!!
    CC!!!          CC!!!          CC!!!          CC!!!
     CC!            CC!            CC!            CC!
      C              C              C              C
      C              C              C              C
     CC!            CC!            CC!            CC!
    CC!!!          CC!!!          CC!!!          CC!!!
   CC!!!!!        CC!!!!!        CC!!!!!        CC!!!!!
  CC!!!!!!!      CC!!!!!!!      CC!!!!!!!      CC!!!!!!!
 CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!
CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!
CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!
CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!
 CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!
  CC!!!!!!!      CC!!!!!!!      CC!!!!!!!      CC!!!!!!!
   CC!!!!!        CC!!!!!        CC!!!!!        CC!!!!!
    CC!!!          CC!!!          CC!!!          CC!!!
     CC!            CC!            CC!            CC!
      C              C              C              C
      C              C              C              C
     CC!            CC!            CC!            CC!
    CC!!!          CC!!!          CC!!!          CC!!!
   CC!!!!!        CC!!!!!        CC!!!!!        CC!!!!!
  CC!!!!!!!      CC!!!!!!!      CC!!!!!!!      CC!!!!!!!
 CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!
CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!
CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!CC!!!!!!!!!!!!!
CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!  CC!!!!!!!!!!!
 CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!    CC!!!!!!!!!
  CC!!!!!!!      CC!!!!!!!      CC!!!!!!!      CC!!!!!!!
   CC!!!!!        CC!!!!!        CC!!!!!        CC!!!!!
    CC!!!          CC!!!          CC!!!          CC!!!
     CC!            CC!            CC!            CC!
      C              C              C              C

Love is the most artistic selection of these programs.

                                LOVE
              CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY



A TRIBUTE TO THE GREAT AMERICAN ARTIST, ROBERT INDIANA.
HIS GREATEST WORK WILL BE REPRODUCED WITH A MESSAGE OF
YOUR CHOICE UP TO 60 CHARACTERS.  IF YOU CAN'T THINK OF
A MESSAGE, SIMPLE TYPE THE WORD 'LOVE'

YOUR MESSAGE, PLEASE? LOVE IS ALL YOU NEED











LOVE IS ALL YOU NEEDLOVE IS ALL YOU NEEDLOVE IS ALL YOU NEED
L            OU NEEDLOVE IS ALL YOU NEE         ALL YOU NEED
LOV         YOU NEEDLOVE IS ALL YOU                 YOU NEED
LOVE      L YOU NEEDLOVE IS ALL Y                     U NEED
LOVE      L YOU NEEDLOVE IS ALL              IS A       NEED
LOVE      L YOU NEEDLOVE IS ALL           VE IS AL      NEED
LOVE      L YOU NEEDLOVE IS ALL          OVE IS ALL     NEED
LOVE      L YOU NEEDLOVE IS ALL         LOVE IS ALL     NEED
LOVE      L YOU NEEDLOVE IS ALL        DLOVE IS AL      NEED
LOVE      L YOU NEEDLOVE IS ALL       EDLOVE IS A       NEED
LOVE      L YOU NEEDLOVE IS ALL      EEDLOVE IS         NEED
LOVE      L YOU NEEDLOVE IS A L     NEEDLOVE IS         NEED
LOVE      L YOU NEEDLOVE IS A L     NEEDLOVE I          NEED
LOVE      L YOU NEEDLOVE IS   L      EEDLOVE            NEED
LOVE      L YOU NEEDLOVE IS   L       EDLOV             NEED
LOVE      L YOU NEEDLOVE      L                         NEED
L                             L YOU                 YOU NEED
L                             L YOU NEE         ALL YOU NEED
L             U NEE                                        D
L             U NEE                                        D
LOVE      L YOU NEEDLOV   S ALL YOU       VE IS ALL YO     D
LOVE        YOU NEEDLO   IS ALL YOU       VE IS ALL YOU    D
LOVE        YOU NEEDLO   IS ALL YOU       VE IS ALL YOU N  D
LOVE I      YOU NEEDL    IS ALL YOU       VE IS ALL YOU NE D
LOVE I      YOU NEEDL    IS ALL YOU       VE IS A L YOU NEED
LOVE IS      OU NEED   E IS ALL YOU       VE IS   L YOU NEED
LOVE IS      OU NEED   E IS ALL YOU               L YOU NEED
LOVE IS       U NEE   VE IS ALL YOU       VE IS   L YOU NEED
LOVE IS       U NEE   VE IS ALL YOU       VE IS A L YOU NEED
LOVE IS A       NE   OVE IS ALL YOU       VE IS ALL YOU NE D
LOVE IS A       NE   OVE IS ALL YOU       VE IS ALL YOU N  D
LOVE IS AL      N   LOVE IS ALL YOU       VE IS ALL YOU    D
LOVE IS AL          LOVE IS ALL YOU       VE IS ALL YO     D
LOVE IS ALL        DLOVE IS ALL                            D
LOVE IS ALL        DLOVE IS ALL                            D
LOVE IS ALL YOU NEEDLOVE IS ALL YOU NEEDLOVE IS ALL YOU NEED

Finally, Bug is an implementation of The Game of Cootie. And is as little a game as its inspiration: the computer rolls for you, and if you get a new body part of the bug, adds it to your bug, otherwise nothing happens on your turn. You race the computer. All you can do is type “Y” or “N” to decide whether you want to see the illustrations as you go. Here’s an example of the end game:

I ROLLED A 6 
6=LEGS
I NOW HAVE 6 LEGS.
MY BUG IS FINISHED.
DO YOU WANT THE PICTURES?? Y
*****YOUR BUG*****


         A A 
         A A 
         A A 
         A A 
        HHHHHHH
        H     H
        H O O H
        H     H
        H  V  H
        HHHHHHH
          N N
          N N
     BBBBBBBBBBBB
     B          B
     B          B
TTTTTB          B
     BBBBBBBBBBBB
     L L L L L
     L L L L L




*****MY BUG*****



         F F 
         F F 
         F F 
         F F 
        HHHHHHH
        H     H
        H O O H
        H     H
        H  V  H
        HHHHHHH
          N N
          N N
     BBBBBBBBBBBB
     B          B
     B          B
TTTTTB          B
     BBBBBBBBBBBB
     L L L L L L
     L L L L L L
I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!

Arguably the most famous BASIC game of the timeshare era is Star Trek. It starts with an illustration:

                                    ,------*------,
                    ,-------------   '---  ------'
                     '-------- --'      / /
                         ,---' '-------/ /--,
                          '----------------'

                    THE USS ENTERPRISE --- NCC-1701

One program Ahl did omit from the revised edition was the misogynistic UGLY (page 228): “This program draws on the terminal the profile of a woman. It gives you an opportunity to specify the ‘dimensions’ of your woman (termed SPECIAL) or take your chances (CHANCE). The computer draws your figure and then makes a determination whether or not to call your woman ugly or just leave it up to your own judgement.” A wise omission.

Another omission from the original wasn’t even a program. It was simply ASCII art:

(I have fond memories of visiting my dad at work in the 1970s and seeing the mainframe room. One of the techs gave me an ASCII-art Snoopy calendar.)

Clearly art in computer games has come a long way from these modest beginnings. But since I’m mainly interested in the history of BASIC, in future posts, I’ll look at more practical printed output from these “games” and then separately at some of the primitive visualization tools that were included.

Play BASIC Computer Games Online

I was surprised that there was no easy way to play David Ahl’s classic book, BASIC Computer Games, in your browser. You can now play them here:

Play BASIC Computer Games in Your Browser

BASIC Computer Games sold over a million copies as microcomputer users in the 1970s and early 1980s typed its programs into their Commodore PETs, Apple IIs, and TRS-80s (among many other machines). I smashed up Ahl’s listings with Joshua Bell’s Applesoft BASIC emulator to make it easy for you to select any of these programs and run them. (When I reached out to Ahl for permission, he let me know that he had placed all of these in the public domain after selling Creative Computing, and Joshua Bell’s emulator is available under an open-source license.)

While Bell was looking for fidelity to the Apple II, I was looking for fidelity to Microsoft 8K BASIC (the back cover proclaims, “All programs run on Microsoft 8K Basic, Rev. 4.0. Basic conversion table included”). I made a few minor edits to the emulator to turn it into what I’ll call the Banana Jr. 80:

  1. The system now defaults to hi-res mode (80 lines) rather than 40 lines, as most of the games evolved from timeshared machines accessed by teletype. But click the Show output button to see a printout of a program run.
  2. The pseudorandom number generator now has a random seed; no RANDOMIZE command is necessary.
  3. PRINTing numbers now pads them with a space to either side.
  4. TAB(0) had to be changed to not indent 10 spaces.
  5. INPUT now appends “? ” to the prompt.

I will make other tweaks as I test more of the games. If you notice anything else than seems off, please comment here.

An Interactive BASIC with a Punch-Card Mentality

What was included and what wasn’t in the very first version of BASIC might surprise you. First of all, Dartmouth was waiting for the time-sharing system equipment from GE to arrive, but in the meantime Kemeny and Kurtz decided to write a compiler for BASIC, to have it ready once when implementation of the time-sharing system began.

While the two had designed BASIC to be an interactive language, with the goal of removing students from the tyranny of interacting with computers through batch processing of punch cards, the two still envisioned computing through a punch-card paradigm. And, in fact, that very first version of the BASIC compiler required punched cards.

Before the time-sharing environment was ready, the card-operated version of the BASIC language went live, CARDBASIC, permitting one line per card. Because of differences between the teletype and the keypunch, PRINT used a single quote ‘ instead of a double quote “, and the relational operators were EQU, LSS, GRT, LQU, GQU, and NQU instead of =, <, >, <=, >=, and <> respectively. The soon-to-be-removed PAGE instruction started a new printed page. And the famous MAT instructions offered students using the language access to matrix math: MAT READ A(M,N) instead of a FOR-loop, MAT PRINT A, MAT C=A+B and so on, including matrix functions CON, IDN, INV, TRN, and ZER.

While later iterations of BASIC would include file input and output, the first Dartmouth BASIC instead had READ and DATA commands, even with the interactive version. Like a program typed on punch cards, the data would be included with the program stored in the time-sharing system. Here’s the very first example program from the first BASIC manual (October, 1964; page 3):

10 READ A1, A2, A3, A$
15 LET D = A1 * A4 – A3 * A2
20 IF D = 0 THEN 65
30 READ B1, B2
37 LET X1 = (B1*A4 – B2*A2) / D
42 LET X2 = (A1*B2 – A3*B1) / D
55 PRINT X1, X2
60 GO TO 30
65 PRINT “NO UNIQUE SOLUTION”
70 DATA 1, 2, 4
80 DATA 2, -7, 5
85 DATA 1, 3, 4, -7
90 END

In fact, as its card-based pilot implementation did, the first interactive version of BASIC lacked an INPUT command. The only way to tailor data was either to hardcode it in variable LET assignments or to use the READ/DATA capability. While BASIC was meant to let you run commands and see the results immediately, there was no way to write a program that would accept input from the user. (There was no INKEY$ command either, as there were no string variables.) Kemeny and Kurtz thought it was too difficult to implement an input statement in a time-sharing system and instead wanted to provide quick execution of small programs. (Within two years, BASIC would have an INPUT command.) [See Back to BASIC, page 25.]

Here’s the first version of the language:
DIM (), …, (, )
LET =
MAT =
(MAT) READ , , …,
DATA , , …,
PRINT

Note that only a line number could follow a THEN in an IF statement (not other statements, like later IF … THEN PRINT X: GOTO 10). Also, only IF statements could have expressions with relational operators: LET F = A<10 wasn’t allowed. Variable names could be a letter or a letter followed by a digit, mainly to make it simpler to develop the compiler. (Array names, for the same reason, were a single letter.) Note that PRINT didn’t require a delimiter between a literal string (called a “label”) and a following expression: e.g. PRINT “SINE ” SIN(X). PRINT did allow the suppression of the carriage return by using a trailing comma (PRINT I,) though it instead advanced the cursor to the next print zone.

Arithmetic used nine digits of precision for integers and supported floating-point operations: the operators were + – * / ^. Moreover, the first BASIC had a rich library of functions: ABS, ATN, COS, EXP, INT, LOG, RND, SIN, SQR, and TAN. RND ignored its argument and generated a reproducible sequence of random numbers one at a time from 0 to 1 (the same numbers would occur in every program run). Programmers could even define their own single-line functions, FNA through FNZ, but the parameter passed in overrode it’s corresponding variable; e.g., DEF FNL(X) = LOG(X)/LOG(10) would assign the passed-in parameter to X! In other words, all variables were global, and functions had the side effect of changing the value of a global variable.

Once the time-sharing system went live, command-line instructions were added to the language, and included HELLO (to start the user-login procedure), NEW (to create a new program and name it), OLD (to load an old program), SCRATCH (to erase the program but keep the name), RENAME, CATALOG, SAVE, UNSAVE, and LIST (including LIST–70 to list from line 70 on, for example).

The implementation also had two pages of verbose (by later microcomputer standards) error messages, from “ILLEGAL FORMULA” to “END IS NOT LAST”, but strangely no divide-by-zero message. (Microcomputer BASICs would have two-letter error codes or error numbers or, in the case of Palo Alto Tiny BASIC, just three messages: “How?”, “What?”, and “Sorry.”)

The first version of BASIC was intended as an alternative to FORTAN and ALGOL for students, and it was larger and more powerful than the first generation of Tiny BASICs for microcomputers, which would follow 12 years later.

The Tiny BASIC Interpretive Language IL—and Onions

Tiny BASIC implementation onion diagram

In the fall of 1975, the People’s Computer Company (PCC) poured more energy into their “Build Your Own BASIC” project, fired up by the announcement of Altair 4K BASIC by MicroSoft [as it was then] for $150. They wanted to create an implementation that was free for anyone to use. With microcomputers and microprocessors proliferating, they envisioned a virtual machine that could be ported from platform to platform:

When you write a program in TINY BASIC there is an abstract machine which is necessary to execute it. If you had a compiler it would make in the machine language of your computer a program which emulates that abstract machine for your program. An interpreter implements the abstract machine for the entire language and rather than translating the program once to machine code it translates it dynamically as needed. Interpreters are programs and as such have theirs as abstract machines. One can find a better instruction set than that of any general-purpose computer for writing a particular interpreter. Then one can write an interpreter to interpret the instructions of the interpreter which is interpreting the TINY BASIC program. And if your machine is micro-programmed (like PACE), the machine which is interpreting the interpreter interpreting the interpreter interpreting BASIC is in fact interpreted.

This multilayered, onion-like approach gains two things: the interpreter for the interpreter is smaller and simpler to write then an interpreter for all of TINY BASIC, so the resultant system is fairly portable. Secondly, since the main part of the TINY BASIC is programmed in a highly memory efficient, tailored instruction set, the interpreted TINY BASIC will be smaller than direct coding would allow. The cost is in execution speed, but there is not such a thing as a free lunch.

“The machine … interpreting the interpreter interpreting the interpreter interpreting BASIC is in fact interpreted.” These guys were having fun! Geeky fun, but fun.

While writing compilers was just being generalized (lex and yacc were published circa 1975), PCC recognized that hobbyists wouldn’t have access to these new tools. Writing a parser is a very specific domain. Accordingly, they created a simple language, IL (Interpretive Language), to write their Tiny BASIC in and encode the parsing in.

Let’s look at a representative example:

 S1: TST     S3,'GO'       ;GOTO OR GOSUB?
     TST     S2,'TO'       ;YES...TO, OR...SUB
     CALL    EXPR          ;GET LABEL
     DONE                  ;ERROR IF CR NOT NEXT
     XFER                  ;SET UP AND JUMP

A common pattern in IL is to test for a keyword or token, then act on that information. Each test is an assertion as to what is next in the line buffer. If the assertion fails, control jumps to a subsequent label (usually looking for a new keyword or token). Here the system advances its buffer cursor over any spaces and tests for “GO” and if it fails to find it then jumps to line “S3”. If it finds it, execution continues with the next IL command. In this case, the system next tests for “TO”, skipping to line “S2” if it fails (a test for “SUB”, to see if this is instead a GOSUB command). If it passes, control continues; in this case, calling an IL subroutine that starts at label “EXPR”, which parses an expression. In Tiny BASIC, “GOTO X*10+100” (a computed GO TO) is as legal as “GOTO 100” and is the alternative to the ON-GOTO of larger BASIC implementations. The subroutine “EXPR” pushes the result of the expression onto the arithmetic stack (in this case, the line number). “DONE” verifies no other text follows the expression and gives an error if it does. “XFER” pops the number of the stack and transfers (GOTOs) the corresponding line number, if it exists.

The IL listing was concise: just 124 lines long! Just 124 lines to implement a workable BASIC that you can write programs and even games in. It’s very elegant.

IL is simple enough that I thought I could program it in a high-level language in an evening. (It took two, plus another to debug.) I wrote a two-pass assembler from the specs, implementing each command. Then I assembled the program, using the listing that Tom Pittman had shared and corrected a few errors in. As far I can tell, I’m the first person to actually write an IL assembler in the 42 years the language has been around. (Tom had his own version of the IL: he changed the mnemonics to two characters each, to be easier to parse on a microcomputer, and modified some commands, and added others.)

I encountered three different types of problems.

The first class of problems were mental mistakes in the listing and the spec:

  • “CALL VAR” needed to be “TSTV S17”, as the listing has no VAR routine but does have a built-in command to test a variable.
  • The use of “MPY” in the listing for the “MUL” command (all five math functions in IL are the first three letters of their corresponding word: ADDition, SUBtraction, MULtiplication, DIVision, NEGation).
  • The language specification neglected to define “LIT”, which pushes the following byte onto the arithmetic stack.

The second problem was that the language hardcodes jumps: for instance, “DONE” jumps to the third instruction (label “CO”). For what is essentially a finite state machine, I found this to be pretty insufferable. In my implementation, I changed commands to take their destination label. (In defense of PCC, they had to worry about carefully managing 4KB of RAM. I have 16GB: 4 million times more.) I later discovered that Tom Pittman changed “DONE” to “BE” (“Branch if Not Endline”) with a label as his solution to this issue.

The third problem with the program was subtler, and escaped my notice at first. Typically, “RUN” resets all variables (in this case, the 26 variables A to Z) to zero. There’s nowhere for that to happen in the listing. You could do this programmatically in IL:

1
0
STORE
2
0
STORE
…
26
0
STORE

However, 78 added instructions to a listing of 124 instructions (not counting comments) seemed excessive.

Sadly, while IL uses a stack machine, it doesn’t provide any way to actually manipulate the stack: no DUP, no SWAP, no conditional jump based on the top of the stack. If it had, the following would have been possible:

LIT 26    ; START AT THE 26TH VARIABLE
VINIT: DUP      ; DUPLICATE THE TOP OF THE STACK
LIT 0      ; PUSH 0
STORE   ; STORE 0 INTO THE VARIABLE
LIT 1      ; PUSH 1
SUB       ; SUBTRACT 1 FROM THE VARIABLE INDEX
DUP       ; DUPLICATE
JMPC VINIT  ; JUMP IF NOT 0

So I implemented a VINIT keyword to do this instead.

Tom Pittman notes:

The TINY BASIC interpreter was designed by Dennis Allison as a Recursive Descent parser. Some of the elegant simplicity of this design was lost in the addition of syntactical sugar to the language but the basic form remains. The IL is especially suited to Recursive Descent parsing of TINY BASIC because of the general recursive nature of its procedures and the simplicity of the TINY BASIC tokens. The IL language is effectively optimized for the interpretation of TINY. Experience has shown that the difficulty of adding new features to the language is all out of proportion with the nature of the features. Usually it is necessary to add additional machine language subroutines to support the new features. Often the difficulty outweighs the advantages.

This is from The Tiny BASIC Experimenter’s Kit that he wrote 40 years ago. It is well worth reading in detail, as his is the only Tiny BASIC implementation to use an IL. (The first Tiny BASIC, TBX, used the IL as pseudocode for the outline of the machine language program.)

Here are additions I made to the IL to extend my own Tiny BASIC:

  1. I added a single array A(), a la Palo Alto Tiny BASIC’s @(), which can take a subscript from 0 to 255. (But note that subscripts of 230 to 255 map to the values of variables A to Z, since I use the “IND” operator to reference variables.)
  2. I added RND(X), which returns a pseudorandom number from 1 to X.
  3. I added ASC(“A”), which can take as an argument “A” to “Z” and returns the ASCII value from 65 to 90. (This limitation is because it uses the TSTV function as a test for a letter of the alphabet.) I added this because I extended INPUT A to return the ASCII value of the first character if a number is not entered. This is so that rather than “1 FOR YES OR 2 FOR NO” you can write “(Y)ES OR (N)O” and IF A=ASC(“Y”) THEN.

If you have an iPhone, you can download the free version of LowRes Coder and use my Tiny BASIC on your phone.

Whatever its merits as a language, IL helped inspire a proliferation of BASICs to compete with Microsoft. There was Tiny BASIC Extended       , Denver Tiny BASIC, 6800 Tiny BASIC, MINOL, Palo Alto Tiny BASIC, Integer BASIC, and Micro Basic. Palo Alto Tiny BASIC became the basis of TRS-80 Level I BASIC, which launched the TRS-80. Of course, Microsoft BASIC ultimately triumphed, replacing Integer BASIC on the Apple, Level I BASIC on the TRS-80, and being the only BASIC for the Commodore PET. And even today you can buy a Microsoft BASIC for your own use, as part of Visual Studio. Yet IL remains an important landmark in the history of personal computing.

Modified Tiny BASIC IL Listing

;THE IL CONTROL SECTION
START: INIT                  ;INITIALIZE
NLINE                 ;WRITE CRLF
CO:    GETLINE               ;WRITE PROMPT AND GET LINE
TSTL    XEC      ;TEST FOR LINE NUMBER
INSERT                ;INSERT IT (MAY BE DELETE)
JMP     CO
;
;STATEMENT EXECUTOR
XEC:   XINIT                 ;INITIALIZE
STMT:  TST     S1,'LET'      ;IS STATEMENT A LET
TST     S1A,'A('
CALL    EXPR
TST     SYN,')'
JMP     S1B
S1A:   TSTV    SYN           ;YES, PLACE VAR ADDRESS ON AESTK
S1B:   TST     SYN,'='       ;(THIS LINE ORIGINALLY OMITTED)
CALL    EXPR          ;PLACE EXPR VALUE ON AESTK
DONE    SYN           ;REPORT ERROR IF NOT NEXT
STORE                 ;STORE RESULT
NXT     STMT          ;AND SEQUENCE TO NEXT
S1:    TST     S3,'GO'       ;GOTO OR GOSUB?
TST     S2,'TO'       ;YES...TO, OR...SUB
CALL    EXPR          ;GET LABEL
DONE    SYN           ;ERROR IF CR NOT NEXT
XFER    STMT          ;SET UP AND JUMP
S2:    TST     SYN,'SUB'     ;ERROR IF NO MATCH
CALL    EXPR          ;GET DESTINATION
DONE    SYN           ;ERROR IF CR NOT NEXT
SAV                   ;SAVE RETURN LINE
XFER    STMT          ;AND JUMP
S3:    TST     S8,'PRINT'    ;PRINT
S4:    TST     S7,'"'        ;TEST FOR QUOTE
PRS                   ;PRINT STRING
S5:    TST     S6,','        ;IS THERE MORE?
SPC                   ;SPACE TO NEXT ZONE
JMP     S4            ;YES JUMP BACK
S6:    DONE    SYN           ;ERROR IF CR NOT NEXT
NLINE
NXT     STMT
S7:    CALL    EXPR
PRN                   ;PRINT IT
JMP     S5            ;IS THERE MORE?
S8:    TST     S9,'IF'       ;IF STATEMENT
CALL    EXPR          ;GET EXPRESSION
CALL    RELOP         ;DETERMINE OPR AND PUT ON STK
CALL    EXPR          ;GET EXPRESSION
TST     SYN,'THEN'    ;TEST FOR THEN
CMPR    STMT          ;COMPARE -- PERFORMS NXT IF FALSE
JMP     STMT
S9:    TST     S12,'INPUT'   ;INPUT STATEMENT
S10:   TSTV    SYN           ;YES, PLACE VAR ADDRESS ON AESTK
INNUM                 ;MOVE NUMBER FROM TTY TO AESTK
STORE                 ;STORE IT
TST     S11,','       ;IS THERE MORE?
JMP     S10           ;YES
S11:   DONE    SYN           ;MUST BE CR
NXT     STMT          ;SEQUENCE TO NEXT
S12:   TST     S13,'RETURN'  ;RETURN STATEMENT
DONE    SYN           ;MUST BE CR
RSTR                  ;RESTORE LINE NUMBER OF CALL
NXT     STMT      ;SEQUENCE TO NEXT STATEMENT
S13:   TST     S14,'END'
FIN     CO
S14:   TST     S14A,'LIST'   ;LIST COMMAND
DONE    SYN
LST
NXT     STMT
S14A:   TST    S15,'LLIST'
DONE    SYN
LLST
NXT     STMT
S15:   TST     S16,'RUN'     ;RUN COMMAND
DONE    SYN
VINIT                 ;(NEW COMMAND TO CLEAR VARIABLES)
LIT     1             ;(NEED TO TRANSFER TO FIRST LINE OF PROGRAM)
XFER    STMT          ;(XFER MODIFIED TO FIND NEXT HIGHER LINE # RATHER THAN PRODUCE AN ERROR)
S16:   TST     SYN,'CLEAR'   ;CLEAR COMMAND
DONE    SYN
JMP     START
SYN:   ERR     CO            ;SYNTAX ERROR ***
EXPR:  TST     E0,'-'
CALL    TERM          ;TEST FOR UNARY -.
NEG                   ;GET VALUE
JMP     E1            ;NEGATE IT
E0:    TST     E1A,'+'       ;LOOK FOR MORE
E1A:   CALL    TERM          ;TEST FOR UNARY +
E1:    TST     E2,'+'        ;LEADING TERM
CALL    TERM
ADD
JMP     E1
E2:    TST     E3,'-'        ;ANY MORE?
CALL    TERM          ;DIFFERENCE TERM
SUB
JMP     E1
E3:    RTN                   ;ANY MORE?
TERM:  CALL    FACT
T0:    TST     T1,'*'
CALL    FACT          ;PRODUCT FACTOR.
MUL
JMP     T0
T1:    TST     E3,'/'
CALL    FACT          ;QUOTIENT FACTOR.
DIV
JMP     T0
FACT:  TST     F01,'RND('    ;(ADDED RND(X) FUNCTION WHERE X>1)
CALL    EXPR          ;***
TST     SYN,')'       ;***
RND                   ;(ADDED RND COMMAND TO PUSH # ON AESTK)
RTN                   ;***
F01:   TST     F0A,'ASC(''   ;(ADDED ASC("A") FUNCTION)
TSTV    SYN           ;***
TST     SYN,'')'      ;***
LIT     166           ;(A = 231 IN MEMORY SCHEME)
SUB                   ;(REDUCE BACK TO 65 TO 90)
RTN                   ;***
F0A:   TST     F0B,'A('      ;(ADDED 1 BUILT-IN ARRAY)
CALL    EXPR          ;***
TST     SYN,')'       ;***
IND                   ;(CHANGED IND TO SUPPORT 0 TO 255)
RTN                   ;***
F0B:   TSTV    F0            ;***
IND                   ;YES, GET THE VALUE.
RTN
F0:    TSTN    F1            ;NUMBER, GET ITS VALUE.
RTN
F1:    TST     F2,'('        ;PARENTHESIZED EXPR.
CALL    EXPR
TST     F2,')'
RTN
F2:    ERR     CO            ;ERROR.
RELOP: TST     R0,'='        ; 0, =; 1, <; 2, <=; 3, <>; 4, >; 5, >=
LIT     0             ;=
RTN
R0:    TST     R4,'<'
TST     R1,'='
LIT     2             ;<=
RTN
R1:    TST     R3,'>'
LIT     3             ;<>
RTN
R3:    LIT     1             ;<
RTN
R4:    TST     SYN,'>'
TST     R5,'='
LIT     5             ;>=
RTN
R5:    TST     R6,'<'
LIT     3             ; ><
RTN                   ;(THIS LINE ORIGINALLY OMITTED)
R6:    LIT     4             ; >
RTN
EOF:                         ;(ENDS INPUT)

Merch for Games No One Plays

When my youngest was 8, I created a simple microgame for us to play instead of the classic card game of War: Melee in the Mines. We played it about 50 times, so I created a free PDF version to share with other people. (It’s light but with some decisions: it has an average rating of 5 out of 10, compared to 2 out of 10 for War.)

It’s been downloaded less than 100 times, so imagine my surprise when I came across merchandise for it:

Basically, TwiceTheTees.com has created a number of templates for T-shirts for board games, video games, and RPGs, and then hit the BoardGameGeek database to come up with a list of game titles. This screenshot gives a flavor:

I’m certain the products are made to order rather than kept in stock.  We’ve reached the point where it is economical to algorithmically generate on-demand products for markets of virtually no one.

BASIC Microgames in 24 Lines

Growing up, I remember going to friends’ houses and typing in BASIC programs. We’d take turns entering the listing and double checking it, then play whatever game it was. Back then, everyone had a different microcomputer. I had a TRS-80 Model I, the library had an Apple II (too expensive for most of us back then), Ron had a VIC-20, Mark had a TI-99/4A, Mike had a Commodore 64, Chris an Amiga, and so on. Even the Bally Astrocade had a BASIC cartridge.

The iOS app LowRes Coder returns us to those glory days of BASIC programs, though without line numbers and with some structured programming: WHILE loops, REPEAT-UNTIL loops, DO loops, and multiline IF / ELSE IF / ELSE / END IF structures (heck, TRS-80 Level I BASIC didn’t even have an ELSE statement, let alone anything but a FOR loop!). No argument passing into subroutines though: still GOSUB and global variables.

The free version of the LowRes Coder app only lets people write 24-line programs. An arbitrary limit, yet a limit that inspired one user, Was8bit, to post this challenge:

I’ve posted several microgames … I challenge others to post their own microgames; it’s a fun challenge. Must follow these guidelines:

1) 24 lines of code, no more than…

2) Highlight one or a few programming skills or techniques

3) Should help give a new programmer a place to start learning by tinkering with your code, and/or have a concept that inspires similar games….

I’ve burned myself out with it, so I pass the torch to others… would like to see you try at least one microgame to help contribute 😀

The nice thing about a 24-line program is that it can be written and debugged in an evening, so it has a realizable end state. And it actually has some value as a prototyping tool (more on that in a bit). Or as the working version for a planned, fuller game, to be developed agilely.

My initial thinking was that only the classic Teletype interface programs where you enter numbers would be suitable for microgames: Guess, Lemonade Stand, Hamurabi, Lunar Lander, etc. To that end, I wrote Lemonade Stand 24.

But once that was done I decided to take another stab at a Connect Four clone. I had written it on the Apple II at our public library, inspired by my dad’s Tic-Tac-Toe program for our TRS-80. (Dad had built a Tic-Tac-Toe machine on a GENIAC as a kid.) I definitely had to compromise to get something to work in 24 lines: you can’t win by playing diagonally and the AI is pretty poor. (Check out The Complete Book of CONNECT 4: History, Strategy, Puzzles.) Clearly this is a programming exercise that would be mainly about the AI rather than the UI. Here it is: 4 In A Row.

I’ve been wanting to replay the Trek 80 program from my TRS-80 – it was my favorite game back then, but I haven’t been able to track it down. Turns out there were a lot of different Trek implementations. This video gives you a taste of the experience in the 1970s, though my version didn’t have those snazzy graphics: my version had =-0 for the Enterprise and >-0 for the Klingons. It did show a photon torpedo (an ASCII period) close in on its target though. So here’s Trek 24, where you must destroy all the Klingons before they destroy the Enterprise.

I wanted to take a stab at a Pong-era arcade game. (I can remember playing video games that were in black and white at the first arcade I ever went to.) I wasn’t sure what I could fit in 24 lines, but started over-ambitiously with a platformer – it instead evolved into a game of avoiding a sentry robot as it moves more and more quickly through level after level. The game supports 16 levels of accelerating velocity, almost each a different color, before restarting at the slower pace: SentryBot 24.

I’ve been interested in writing my own roguelike for a while now, but that always seemed too ambitious. Limiting it to 24 lines however – now there was a project I’d be able to actually finish. So, yes, I implemented a roguelike with 20 monsters and 18 items: in 24 lines of code! Roguelike 24.

When Was8bit started this challenge, I didn’t think you could do much with 24 lines. Perhaps some guessing games or simple simulations. But, in fact, you can accomplish a lot in 24 lines. Beyond the competition, the approach is useful to rapidly prototype an idea. I can see using it again for prototyping games, game subsystems, and levels, too. If you’re writing a new dungeon crawler, whether a card game, board game, or video game, why not prototype it as an ASCII roguelike first? A microgame is a great way to see if the foundation of a game design provides a sense of engaging play.

Tips for Writing Microgames

Interested in writing your own 24-line programs? Some tips I’ve discovered.

Push complexity from the game to the documentation. The list of monsters and objects in Roguelike 24 is close to 40 lines alone! With any game, much of the complexity and verisimilitude is in the player’s mind anyway, not the game itself. Hence the continued niche appeal of pixel games, interactive fiction, and ASCII roguelikes. And Dungeon & Dragons and Pathfinder games mainly take place in players’ imaginations.

Oversimplify the game design to concentrate on essentials. In my 4 In A Row, you can’t win diagonally – too hard to implement given the limit on the number of lines of code. In Roguelike 24, the strength of a monster is its ASCII code minus 64: Ant, 1; Bat, 2; Dwarf, 4; Zombie King, 26. I curated the list of monsters around this property (no D for Dragon and G for Giant in this scheme, for instance) and made it a Zombie King and not a Zombie. In Trek 24, instead of having Klingons detected when going to a new region, I have them show up in the region you just left—much simpler to code! Instead of detecting collisions, presumably the Klingons warp out of the way when you try to ram them. And so on.

Create the world as the player moves. When lines of code aren’t the constraint, it’s typically better to initialize the world and then store the state of the world (e.g., whether a room has been explored; see my Colossal Cave Adventure 101 for an example). In a microgame, create each quadrant of the galaxy or cell of the dungeon as it is explored.

Oversimplify data structures. Typically, clear data structures produce code that is easier to read and maintain. But that’s a luxury when you have 24 lines. Instead of having a two-dimensional array to represent a grid in Trek 24, I used a one-dimensional array. Couldn’t afford two FOR loops to display a matrix, plus two lines per move (e.g., X = X+1 and Y = Y+1 for Mark 8). I also made the arrays larger than necessary to eliminate the need for bounds checking. For Roguelike 24, I gave up on the array altogether and just manipulated a single string that represented the dungeon grid and used a fixed-width font to print it across multiple lines without line breaks.

Use strings for lists and sets. But don’t tell Mr. Ryden, my high-school computer-science teacher. Since 8-bit BASICs lack user defined types, use strings liberally. If you are using another language, user defined types probably would take too many lines of code, anyway. In Roguelike 24, new items are appended to INV$ to track inventory, and INSTR is used to determine if an item is in the inventory when trying to use it. Easy since items have a one-character code but I’ve used CSV (Comma-Separated Values) in other programs: e.g., “,ANT,BAT,GIANT,”, with the series string beginning and ending with a comma and with INSTR(MONSTERS$, “,”+M$+”,”) so that substrings aren’t false positives (e.g., so “ANT” isn’t found in “GIANT”).

Forget AIs to instead rely on random behavior—or no behavior. A game like Atari 2600’s Adventure implemented simple behaviorism through Finite State Machines for the dragons and the bat. But even such a simple model is too much code for this challenge. In Trek 24, Klingons never move. In 4 In A Row, the computer plays in the column you just played to or one of its neighboring columns at random. (Which is technically a tiny AI: the first version just selected a column at random, which was even easier to beat; now the game usually at least makes you work a little bit for the win.)

Specific Programming Tips

Writing to an arbitrary line limit does obfuscate the code in places, as a side effect. Here’s some tips for staying within 24 lines, readability aside.

Collapse multiline IF statements or refactor. For instance:

IF X=0 THEN
Y=1
Z=2
ENDIF

…becomes…

IF X=0 THEN Y=1
IF X=0 THEN Z=2

Or perhaps you can use SGN(). For instance, 10*SGN(PLAYER-ENEMY) gives a 10-point penalty if the player is weaker, a 10-point bonus if stronger, and has no effect if the player and enemy are equal. Better for minimizing cyclomatic complexity.

GOTO considered helpful. Helpful for saving lines, that is. In “Micro Game – Frog”, Was8bit adopts an old assembly-language technique of overincrementing so that one routine can fall through to the next (math is faster than jumps and saves code):

DORIGHT:
  PX=PX+16
DOLEFT:
  PX=PX-8
  LAYER 1
  CLS
  CIRCLE PX+4,60,4 PAINT

Offset values from 0 instead of initializing. For instance, instead of:

SHIELDS = 100
SHIELDS = SHIELDS-10
PRINT "SHIELDS AT " + SHIELDS
IF SHIELDS <= 0 THEN PRINT “YOU LOSE”

…use…

SHIELDS = SHIELDS-10
PRINT "SHIELDS AT " + (SHIELDS+100)
IF SHIELDS <= -100 THEN PRINT “YOU LOSE”

Move initialization FOR loops into the game. Part of the general philosophy of building the world as play goes on rather than procedurally generating it up front includes initialization, not just discovery.

FOR X= 1 TO 10
  A(X) = RND*10
NEXT X
…
FOR X =1 TO 10
  PRINT A(X);
NEXT X

…saves two lines when done this way…

FOR X=1 TO 10
  IF A(X)=0 THEN A(X) = RND*10
  PRINT X(A);
NEXT X

Tolerate errors. You can’t error check all user input and all game conditions. In 4 In A Row, playing your checker to a full column just causes you to lose your turn rather than prompting you for a different column selection. (This might be a nice equalizer against the AI, in this case, but the AI actually does this far more often than a human player would.)

To force user input into a range, use this formula:

MAX(1, MIN(M, 8))

If the player enters a number lower than the minimum, it is treated like the minimum (in this case, 1). If more than the maximum, it is treated like the maximum (in this case, 8).

Use strings as lookup functions instead of having arrays or READ/DATA statements. Here is an example for Trek 24 for navigation from Mark 1 to Mark 8:

MID$(" 1-7-8-9-1 7 8 9", CMD*2-1, 2)

This is analogous to the Excel function CHOOSE; e.g., CHOOSE(CMD, 1, -7, -8, -9, -1, 7, 8, 9). Here’s the lookup for movement distance in Roguelike 24:

MID$( "+0-8+8+1-112",INSTR("NSEWT",CMD$)*2+1,2)

North is -8, South is +8, East is +1, West is -1, and Teleport is +12. If no command is found, +0 is returned.

In Roguelike 24, INSTR is used to find the relative strength of each weapon and also to find the bane (from a 26-character string) that corresponds to the monster being fought.

Call to Code

So you’ve been wanting to design a game but are overwhelmed by the size of the project? Try a microgame instead! If you have an iOS device, download LowRes Coder or try the language of your choice in a browser (Try It Online).

Happy coding!

Colossal Cave Adventure 101

Colossal Cave 101

When my 11-year old wanted to learn to program last spring, I got him a book on writing games in JavaScript. It had the source code for four games, but my son found it difficult. Four games?! A far cry from the 101 BASIC Computer Games that was my go-to (ahem) when I was his age, programming a TRS-80 Model I.

So I looked at a number of different BASIC implementations for his iPod Touch, eventually landing on LowRes Coder, which turns an iOS device into an 8-bit microcomputer circa 1979. I jokingly describe it as “turning your iPhone into an Apple II”, but – having programmed an Apple II – I can tell you that LowRes Coder is a lot more powerful. While it lacks functions and procedures (GOSUB rules the day here), it has a rich variety of sprite commands. And, thanks to the Internet, people can easily share their BASIC programs with one another without having to retype them or, shudder, load them from cassette. The point of it being “low resolution” is that no one has to worry about the quality of their art: the fun is in making the games.

And my son found, as I did before him, that it is easy to write BASIC programs. Loving math, he’s written a number of math programs, and of course some graphical experiments, and an adventure game.

The sample adventure program that he based his game on, though, was menu-based, and his aspirations went beyond that. So a few weekends ago I ported Colossal Cave to LowRes Coder, streamlining it for BASIC and adding random maps. While it has a two-word parser system, it’s driven by INKEY$, so selecting the first letter shows the entire word: no guess-the-verb problems here.

The app is free if you’re just going to play other people’s games. Here’s Colossal Cave Adventure 101. (And here’s my card game inspired by Colossal Cave.)

 

 

The Cult of the New: Preferences for New Board Games

The “cult of the new” is the obsession with new titles, which makes hobbyist gaming much like the movie industry. The online site, Yucata.de, offers free online games with human players. Here are the plays averaged across 111 games, relative to when each game was first introduced to the community. You can see that a new game peaks in 3 months, then gradually declines to half its peak after 2 years, dropping only slightly after that for the next 3 to 5 years.

Plays of Tabletop Games on Yucata.de In First Months of Release

Year Month Plays
0 1 394
0 2 1252
0 3 1434
0 4 1265
0 5 1137
0 6 1043
0 7 980
0 8 933
0 9 894
0 10 935
0 11 877

Plays of Tabletop Games on Yucata.de In First Years of Release

Year Month Plays
1 12 847
2 24 716
3 36 671
4 48 665
5 60 596
6 72 618
7 84 571
8 96 617

Source: Analysis of Yucata.de Play Data

Because new games are made available at once to all players, this data from Yucata removes the delay of the adoption curve typical of selling games through retail. In the real world, people have to learn about the game, read reviews, play it with friends, then buy it, then find time to play it. Yucata presents a clearer picture of the embrace and abandonment of games.

This cult of the new makes it hard for new games to breakthrough and sell on an ongoing basis.

To supplement this behavioral data, Researchscape surveyed online consumers to ask whether they preferred to play a game they had played before or one new to them. About a quarter of respondents had no preference, regardless of type of game. However, the least novelty was desired in card games, the most in video games: 3.4 times as many consumers want to play a familiar card game as a new card game, 2.6 times for a familiar board game vs. a new on, and just 1.4 times for video games.

Which card/board/video game would you prefer to play, one that you had played before or one new to you?

Card game Board game Video game
Familiar : New 3.4 2.6 1.4
One played before 38% 32% 13%
One new to me 11% 13% 9%
No preference 25% 26% 24%
Don’t play card/board/video games 25% 29% 54%

Sample Size: One-Question Polls; 115-262 responses; weighted by age,
gender, and/or region

This is an excerpt from a free Researchscape ebook, which you can download now: “Boardgame Concepts to Crowdfund: Dynamics of Tabletop Games”.

Last Game Played – Board Game Survey Results

Researchscape conducted a series of one-question polls as background research to its survey of Kickstarter backers.

In a poll conducted March 23, 2016, half the U.S. online consumers interviewed had played a game this year: 18% in the past week, 17% within the past month, and 16% earlier in the year. The other half had played in 2015 or earlier or couldn’t recall.

How long has it been since you played a card game or board game? (In real life, not on an electronic device.)

Option

Response
%

Cumulative
%

Within past week

18%

18%

Within past month

17%

35%

Earlier this year

16%

50%

2015

9%

59%

2014

3%

62%

2013 or earlier

7%

69%

Don’t know

31%

100%

Sample: Poll; 418; weighted by age, gender

When asked in a separate poll to distinguish whether their last game played was a card game or board game (an admittedly fuzzy distinction), 46% of players had played a card game, 25% a board game, and 29% couldn’t recall.

What is the last game that you’ve played? (In real life, not on an electronic device.)

Option

Response
%

Cumulative
%

Card game

46%

46%

Board game

25%

71%

Don’t know

29%

100%

Sample: Poll; 407; weighted by age, gender

The most commonly played card game is poker, played by 12.6% of respondents (not counting the 1.6% who named Texas Holdem). Uno is a distant second, at 9.4%. The family of rummy games was third in popularity, mentioned by 6.4% of respondents (variants mentioned included Gin Rummy, Progressive Rummy, Aggravation Rummy, and 500 Rummy).

The most commonly played board game is Monopoly, dominating its category at 33.2% of respondents. A distant second is The Game of Life, at 5.8%, followed by Scrabble at 5.2%.

What is the last card game that you’ve played? (In real life, not on an electronic device.)

Rank

Option

Response

1

Poker

12.6%

2

Uno

9.4%

3

Rummy

6.4%

4

Spades

5.4%

5

Solitaire

5.2%

6

Blackjack

5.0%

7

Cards Against Humanity

3.8%

8

Go Fish

3.2%

9

Euchre

3.0%

10

Hearts

2.4%

11

Pitch

2.2%

12

Cribbage

1.8%

12

Phase 10

1.8%

14

Texas Holdem

1.6%

15

War

1.4%

16

Canasta

1.2%

17

Apples to Apples

0.8%

17

Magic: The Gathering

0.8%

17

Rook

0.8%

17

Skip Bo

0.8%

17

Spoons

0.8%

22

Bridge

0.6%

22

King

0.6%

22

Old Maid

0.6%

22

Speed

0.6%

Never played cards

4.2%

Sample: Poll; 599

What is the last board game that you’ve played? (In real life, not on an electronic device.)

Rank

Option

Response

1

Monopoly

33.2%

2

The Game of Life

5.8%

3

Scrabble

5.2%

4

Candyland

3.5%

5

Catan

3.3%

5

Sorry

3.3%

7

Chess

3.2%

8

Checkers

2.7%

9

Risk

2.5%

10

Trivial Pursuit

1.7%

11

Apples to Apples

1.5%

11

Cards Against Humanity

1.5%

11

Yahtzee

1.5%

13

Clue

1.2%

14

Trouble

1.0%

15

Ticket to Ride

0.8%

15

Uno

0.8%

17

Pictionary

0.7%

17

Rummikub

0.7%

17

Sequence

0.7%

20

Backgammon

0.5%

20

Battleship

0.5%

20

Chutes and Ladders

0.5%

20

Cranium

0.5%

20

Cribbage

0.5%

Never played a board game

5.8%

Sample: Poll; 599

Despite the proliferation of brand tie-ins and thematic knock offs, the classic, original edition of Monopoly is the primary version of Monopoly played, by 70.4% of respondents. The most popular tie-ins were Star Wars (mentioned by 2.1%) and Disney (mentioned by 1.1%). Monopoly Electronic Banking was the only specialty edition mentioned by at least 1% of respondents (1.1%). Over 40 editions were mentioned, including opoly games (not licensed from Hasbro).

Monopoly Editions Played

Back To The Future Millionaire
Beach Body Monopoly Cards
Bible Monopoly City
Buildings Monopoly Millionaire
Christmas NFL
Cleveland Nintendo
Deal Pokemon
Disney Red Sox
Doctor Who Rolling Stones
Dogopoly Satanism
Dr. Who Simpsons
Electronic Banking Soccer
Girl Monopoly SpongeBob
Hard Rock Star Trek
Harry Potter Star Wars
Horses Steelers
Irish Teenage Mutant Ninja Turtle
Las Vegas The Nightmare Before Christmas
Marvel Comics Toy Story
Michigan Vegas

Sample: Poll; 378

This is an excerpt from a free Researchscape ebook, which you can download now: “Boardgame Concepts to Crowdfund: Dynamics of Tabletop Games”.