Spectrum pages
Home -> Spectrum -> Adventure 1


Adventure 1 (Abersoft)

Adventure 1 is a port of the original Crowther/Woods adventure to the 48k Spectrum. It was originally released by Abersoft in 1982, and subsequently rereleased as 'Colossal Caves' by CP Software and 'Classic Adventure' by Melbourne House.

Since the maximum score in this version is 210 points and its author is John Jones-Steele, I think that it would be referred to by taxonomists as JONE0210.

Two versions are known to exist. As the walkthrough points out, the original will not let you drop the bear to scare the troll away, while the fixed version (and the rereleases) will.

Internally, the game is implemented using the methods described in Ken Reed's 1980 article in Practical Computing — the same article that was the inspiration for several other game engines, including The Quill. The data tables describing the game occupy memory from 6979h to 0DF35h, and are followed by 4k of free space.

Although the game is written with separate game engine and database, I'm not aware of any attempts to use the engine with a different game database, though it no doubt helped in porting the game to different platforms.

In comparison with the 350-point mainframe original (I compared against Mike Goetz's FORTRAN version, GOET0350):

The amount of free space in the game suggests that memory pressure isn't responsible for the absence of the dwarves and the pirate. It's more likely that they would have needed additional support in the game engine, and the author didn't have the time to add this.

The cause of the bug with the bear is:

Original version                       Bugfixed version
GET  BEAR			       GET  BEAR 
	PRESENT 0x35  ; Gentle bear	       PRESENT 0x35  ; Gentle bear
	NOTPRES 0x4e  ; Chained?	       NOTPRES 0x4e  ; Chained?
	GET	0x35			       DESTROY 0x35
	OKAY				       CREATE  0x36  ; Bear following you
					       GET     0x36

That is, the original has you carrying the 'gentle bear', while the fixed version replaces the 'gentle bear' with the 'bear following you'. The DROP BEAR handler only checks for the latter.

(I think there may also be another bug in that logic. The chained bear is object 0x4c, not 0x4e).

[C] Here's C source for a simple utility that dumps the 'Adventure 1' database. The input file should be in +3DOS format; use tapsplit to extract it from the .TAP / .TZX file containing the game.

Internal storage format

General note: Data tables tend to be lists of offsets. The game engine will then add a base address to get the address of the actual item in question.

Offsets are frequently 1-based; the first compression token is found at offset 1, not offset 0.

The length of an object is given by offset[objectno+1] - offset[objectno]. The offset table will therefore have one more entry than objects, so that the length of the last object can be calculated.

0x6979: Offsets for expansion tokens (each offset is 1 byte)
	DB 1,4,5,7 ...

0x69BC: Expansion token text
	DB 'the', 'a', 'of', 'You' ...

Each expansion token is a whole word. The game engine seems to handle insertion of spaces before/after a token.

0x6ABA: Offsets of location descriptions (each offset is 2 bytes). 
        There are 140 locations; the table allows space for 148.
	DW 0,97,184,226 ...

0x6BE6: Location text. Bytes 0x81 and higher correspond to expansion 
	tokens. Byte 0x7F is a newline.
	DB 83h,84h,'standing',91h,82h,81h,7Fh,'road' ...

0x901D: Vocabulary. Standard format: 4 bytes ASCII followed by one byte word 
 	ID. There is free space for five extra words in the table.
	DB	'ROAD',2,'HILL',2,'ENTE',3 ...

0x9491: Offsets of location movement tables. This table is sized for 173 
	locations, though there are only 140 in the game.

0x95ED: Location movement tables. Two bytes per entry; word ID, followed by
	room number.

0x9AB1: Offsets of object descriptions. The table is sized for 100 objects,
	of which 78 are used.

0x9B79: Object descriptions. These are ASCII and do not use compression
	tokens, though many of them start with a 0Dh (CR) byte.

0xA7F9: Object states. Two bytes per object. The first is the location
	where it starts, and the second is 0 for a normal object, 10h for 
	a treasure. In play, bit 0 of the second byte is set when the
	object is carried.

0xA8C1: Response table. 6 bytes per entry:
	DB verb
	DB noun	;0xFF to match any noun
	DW cond	;Offset of conditions
	DW act	;Offset of actions

	The parser will pattern-match each entry in the table against its
	input. If they match, it will check each condition. If they are all
	true, it will execute the actions.

	As usual, the lengths of the condition and action lists are found
	by deducting the offsets in this entry from the offsets in the
	following entry.

0xB3B1: Conditions for response table.
	Each condition is two bytes: opcode, argument. The opcodes are 
	fairly standard:
		00	AT	room    true if player is in specified room
		01	PRESENT	obj     true if object is here or carried
		02	RAND	chance  true if random number 0-100 < chance
		03	NOTPRES obj     true if object is not here or carried
		04	NOTZERO flag    true if flag is nonzero
		05	ZERO	flag	true if flag is zero
		06	CARRIED obj	true if object is carried
		07	HERE	obj	true if object is in current room
		08	NOTHERE	obj	true if object is not in current room
		09	NOTCARR	obj	true if object is not carried
		0A	EXISTS	obj	true if object exists within game

0xB7FD:	Actions for response table. Again, each action is two bytes: opcode,
	argument. This means that on a few actions the argument is ignored,
	and placing an object in a location takes two distinct actions.
		00	INVEN		List inventory
		01	GET	obj	Move object to inventory
		02	DROP	obj	Move object from inventory to location
		03	MESSAGE	n	Display message number
		04	DESC		Describe room, prompt for next input
		05	END		End processing, prompt for next input
		06	GOTO	room	Move player to specified room
		07	SET	flag	Set flag to 255
		08	CLEAR	flag	Set flag to 0
		09	EXIT		End game
		0A	OKAY		Print "Okay", prompt for next input
		0B	QUIT		Ask "Are you sure?"
		0C	CREATE	obj	Create object in the current location
		0D	DESTROY	obj	Destroy object, move to location 0
		0E	LET	flag 4	Set specified flag to 4 (not used?)
		0F	SCORE		Display player's score
		10	TARGET	room	Set room to use for next PLACE opcode
		11	PLACE	obj	Place object obj in room specified 
					by TARGET.

0xBF69: Process table. 4 bytes per entry:
	DW cond	;Offset of conditions
	DW act	;Offset of actions

	Like the Response table, but executed before player input. There is
	no verb/noun matching, so all entries are processed.

0xC031:	Conditions for the process table.
0xC0F9:	Actions for the process table.

0xC289: Offsets of messages.
0xC419: Message text. Like room descriptions, these use compression tokens.

0xDF35: Free space, up to 0xF2FE. 
0xF2FF: Start of game engine proper.


John Elliott 2016-10-10