Akalabeth

20 thoughts
last posted March 30, 2014, 12:43 a.m.
0
get stream as: markdown or atom
0

It is hard to overstate the influence the Ultima series had on my teens, both just in terms of playing the games but also motivating me to really dive into programming.

I had the opportunity to tell Richard Garriott this at SxSW in 2004 and occasionally via Twitter more recently.

0

Ultima IV was the first game I really got into although I went back and played the earlier ones, including Akalabeth.

In my teens I remember hacking the map files for both Ultima IV and Ultima V. A couple of years ago, I redid that work in Python: https://github.com/jtauber/ultima4.

0

Of course, many of you know I've written an Apple ][ emulator in Python (https://github.com/jtauber/applepy) although haven't got disks working yet.

Five years ago, I wrote a Python script that could at least retrieve the CATALOG and raw files (if text) from Apple ][ disk images (of which there are many archived on the Internet).

0

A couple of days ago, Richard posted a photo of Akalabeth running on his original Apple ][+.

I asked him if it was true that Akalabeth was written in BASIC and, if so, if the source was available.

He confirmed it was BASIC and said he'd look for the source for me.

0

Last night, still reminiscing about the Apple ][ days (as I often do), I dusted off my Apple ][ disk image reader and put it up on Github: https://github.com/jtauber/a2disk.

I then decided to go looking for disk images of Akalabeth to see if I could extract the source from those (I hardly wanted to bug Lord British himself).

0

I found a bunch of Akalabeth disk images on the archive.org backup of the Asimov Apple ][ Archive.

a2disk could read their CATALOG perfectly.

0

The results fell into two categories.

Some disk images had:

Disk Volume 254, Free Blocks: 394
A 003 HELLO
*A 011 AKALABETH INSTRUCTIONS
*A 002 AKALABETH START
A 086 AKALABETH
view raw gistfile1.txt hosted with ❤ by GitHub

Others had:

Disk Volume 254, Free Blocks: 280
*A 003 AKALABETH
*A 005 AKA0
*A 002 AKA1
*B 034 AKA2
*B 034 AKA3
*B 018 AKA4
*B 034 AKA5
*A 086 AKA6
view raw gistfile1.txt hosted with ❤ by GitHub
0

The A indicates Applesoft BASIC.

The Apple ][ stored BASIC programs in tokenized form on disk, very similar to how they were stored in memory.

So I decided to write a de-tokenizer, which now ships with a2disk.

0

Here's what HELLO looks like de-tokenized:

1 TEXT : NORMAL : HOME : VTAB 6
3 INVERSE
4 PRINT SPC( 9);
5 PRINT "ULTIMA I - AKALABETH!";
6 PRINT SPC( 9)
7 NORMAL : VTAB 20
8 PRINT
10 PRINT "Ready ?? ";
13 GET A$
20 IF A$ = CHR$ (27) THEN 999
25 PRINT A$: PRINT
30 PRINT CHR$ (4)"RUN AKALABETH INSTRUCTIONS"
999 END
view raw HELLO hosted with ❤ by GitHub
0

And AKALABETH START looks like:

10 POKE 103,0: POKE 104,64
20 HGR
30 PRINT CHR$ (4)"RUN AKALABETH"
view raw AKALABETH START hosted with ❤ by GitHub
0

AKALABETH INSTRUCTIONS looks like:

8000 HOME : TEXT : HOME
8010 PRINT : PRINT : PRINT " MANY, MANY, MANY YEARS AGO THE": PRINT "DARK LORD MONDAIN, ARCHFOE OF BRITISH,": PRINT "TRAVERSED THE LANDS OF AKALABETH": PRINT "SPREADING EVIL AND DEATH AS HE PASSED."
8020 PRINT "BY THE TIME MONDAIN WAS DRIVEN FROM THE": PRINT "LAND BY BRITISH, BEARER OF THE WHITE": PRINT "LIGHT, HE HAD DONE MUCH DAMAGE UNTO"
8030 PRINT "THE LANDS.": PRINT : PRINT "'TIS THY DUTY TO HELP RID AKALABETH OF": PRINT "THE FOUL BEASTS WHICH INFEST IT,": PRINT "WHILE TRYING TO STAY ALIVE!!!": PRINT : PRINT : PRINT " (PRESS SPACE TO CONTINUE)";: GET Q$
8100 HOME : VTAB (2): HTAB (12): PRINT "THE PLAYER STAT'S:"
8105 PRINT : PRINT : PRINT : PRINT "HIT POINTS- AMOUNT OF DAMAGE A PLAYER": HTAB (13): PRINT "CAN ABSORB BEFORE DEATH"
8110 PRINT : PRINT "STRENGTH--- RELATED TO DAMAGE INFLICTED": HTAB (13): PRINT "BY PLAYER AGAINST MONSTERS."
8120 PRINT : PRINT "DEXTERITY-- RELATED TO THE PROBABILITY": HTAB (13): PRINT "OF A PLAYER HITTING A MONST."
8130 PRINT "STAMINA---- RELATED TO PLAYER DEFENSE": HTAB (13): PRINT "AGAINST MONSTERS"
8140 PRINT : PRINT "WISDOM----- THIS ATTRIBUTE IS USED": HTAB (13): PRINT "IN SPECIAL (QUEST!) ROUTINES"
8150 PRINT "GOLD------- MONEY!! CASH!! ASSETS!!"
8160 PRINT : PRINT : HTAB (8): PRINT "(PRESS SPACE TO CONTINUE)";: GET Q$
8200 HOME : PRINT : PRINT " THE TOWNS AND BUYING ITEMS:"
8210 PRINT : PRINT : PRINT " TO BUY ANY ITEM ONE NEED ONLY": PRINT "TYPE THE FIRST LETTER OF THE ITEM"
8220 PRINT "WANTED. THE COST OF THE RESPECTIVE": PRINT "ITEMS IS DISPLAYED WHILE IN THE TOWN."
8230 PRINT "THE GAME IS STARTED IN A TOWN SOMEWHERE": PRINT "ON THE 20X20 MAP."
8240 PRINT : PRINT : HTAB (12): PRINT "FIGHTERS AND MAGI"
8250 PRINT : PRINT " THE DISADVANTAGE OF BEING A": PRINT "FIGHTER IS THE LACK OF THE ABILITY TO": PRINT "CONTROL THE MAGIC AMULET, WHEREAS MAGI": PRINT "CAN NOT USE RAPIERS OR BOWS."
8270 PRINT : PRINT : HTAB (8): PRINT "(PRESS SPACE TO CONTINUE)";: GET Q$
8300 HOME : PRINT : PRINT : HTAB (16): PRINT "MOVEMENT:"
8310 PRINT : PRINT : PRINT "-KEY-";: HTAB (10): PRINT "OUTDOORS";: HTAB (24): PRINT "DUNGEON"
8320 PRINT : PRINT " CR MOVE NORTH MOVE FORWARD": PRINT " <= MOVE WEST TURN LEFT ": PRINT " => MOVE EAST TURN RIGHT"
8330 PRINT " / MOVE SOUTH TURN AROUND": PRINT " S STATISTICS STATISTICS": PRINT " A N/A ATTACK ": PRINT " P PAUSE ON/OFF PAUSE ON/OFF"
8335 PRINT " X GO INTO TOWN CLIMB LADDER": PRINT " X GO CASTLE GO HOLE ": PRINT "SPACE PASS PASS "
8350 PRINT : PRINT : HTAB (8): PRINT "(PRESS SPACE TO CONTINUE)";: GET Q$
8400 HOME : VTAB (5): PRINT " THOU DOEST NOW KNOW THE BASICS OF": PRINT : PRINT "THE GAME, EXPERIMENT WITH THE COMMANDS."
8410 PRINT : PRINT "THERE IS MUCH THAT IS LEFT UNSAID FOR": PRINT : PRINT "THEE TO DISCOVER IN THE FUTURE..."
8420 PRINT : PRINT : PRINT " GO NOW UNTO THE WORLD AND SEEK": PRINT : PRINT "ADVENTURE WHERE THOU MIGHT!!!"
8430 PRINT : PRINT : PRINT "P.S.-SEARCH OUT THE CASTLE OF": PRINT "LORD BRITISH, USE THE -X- KEY TO GO IN!"
8450 PRINT : PRINT : HTAB (8): PRINT "(PRESS SPACE TO CONTINUE)";: GET Q$
8999 PRINT CHR$ (13) CHR$ (4)"RUN AKALABETH START"
0

That's the files in the first type of disk image. What about the second, the one with the AKA0-6?

0

AKALABETH in the first disk image is identical to AKA6 in the second. That's the main game (which will get to in a lot of detail shortly).

0

AKA2-5 are binary files. We'll return later to decoding those.

0

AKALABETH in the second disk image is:

0 TEXT : HOME
1 IF PEEK (55) = 253 THEN END
2 POKE - 16292,1
10 ONERR GOTO 100
20 PRINT "NOMON I,O,C": HOME
22 POKE 977,1: POKE 978,3
26 DATA 32,234,3,162,2,173,0,224,201,76,240,7,202,157,128,192,16,243,2,162,20,76,18,212,184,3,166
27 FOR I = 952 TO 975: READ J: POKE I,J: NEXT : FOR I = 1010 TO 1012: READ J: POKE I,J: NEXT
30 TEXT : HOME : PRINT "RUN AKA0"
99 END
100 GOTO 0
view raw AKALABETH hosted with ❤ by GitHub
0

AKA0 is:

1 TEXT : HOME : NORMAL : VTAB (5): HTAB (9): PRINT "WELCOME, FOOLISH MORTAL": VTAB (7): HTAB (14): PRINT "INTO THE WORLD": VTAB (9): HTAB (16): INVERSE : PRINT "AKALABETH!": NORMAL
2 VTAB (11): HTAB (7): PRINT "HEREIN THOU SHALT FIND GRAND": VTAB (13): HTAB (16): INVERSE : PRINT "ADVENTURE!": NORMAL
3 VTAB (16): PRINT " CREATED BY LORD BRITISH": PRINT : PRINT "(C) 1980 BY CALIFORNIA PACIFIC COMPUTER"
4 VTAB (23): HTAB (8): PRINT "(PRESS SPACE TO CONTINUE) ";: GET R$: PRINT
5 PRINT "BLOAD AKA4"
6 POKE 254,32: POKE 255,32: POKE 32840,169: POKE 32841,0: CALL 32768: POKE 32840,177: POKE 32841,8
7 PRINT "BLOADAKA2,A$2000": POKE - 16302,0: POKE - 16297,0: POKE - 16300,0: POKE - 16304,0
8 PRINT "BLOADAKA5,A$4000"
9 CALL 32768
10 PRINT "BLOADAKA3,A$4000"
11 POKE 32769,39: POKE 32888,136: POKE 32890,255: CALL 32768: POKE 32769,0: POKE 32888,200: POKE 32890,40
12 FOR O7 = 1 TO 4000: NEXT O7
13 POKE 32840,169: POKE 32841,0: CALL 32768: POKE 32840,177: POKE 32641,8
14 FOR O7 = 1 TO 500: NEXT O7
15 POKE - 16303,0
8450 VTAB (23): HTAB (8): PRINT " (LOADING PROGRAM) ";
8997 PRINT
8998 POKE 33,1: POKE 34,23
8999 PRINT "RUN AKA1"
view raw AKA0 hosted with ❤ by GitHub
0

And AKA1 is:

10 POKE 103,0: POKE 104,64
20 HGR : POKE - 16302,0
30 PRINT CHR$ (4)"RUN AKA6"
view raw AKA1 hosted with ❤ by GitHub

Same as AKALABETH START in the first disk image.

0

I strongly suspect the second disk image is the original and the first disk image is some simplification.

It has the odd "Ultima I" reference and also includes instructions which presumably were provided in printed form in the original game.

0

I think I'll use child streams to separately explore the preamble files and main game file.

Child Streams

Akalabeth Main Game File

31 thoughts
updated April 5, 2014, 6 a.m.

Akalabeth Preamble Files

27 thoughts
updated March 30, 2014, 10:53 p.m.