1988 · Electronic Arts

Wasteland

This minisite was contributed by air. It’s currently claimed by air who is editing it to reach a Gold tier standard.

All 42 maps, drawn square by square from the game's own bytes, with every square's record decoded.

01 · The maps

Every map, square by square

Pick a map. Point at a square to see what it is, and click it to read its record. An exit's record has a button that opens the place it leads to.

Time Zoom

Each square is drawn the way the game draws it, by a port of $0B53, the engine's routine for one square of the view. A square has three values of its own: a class, a number, and a tile. The class says what the square does, and the tile is its picture. Most squares show their tile, but four kinds show another. A square off the map shows the map's own edge tile. A loot square always shows tile 5. An object square shows the tile its record names. A radiation square shows tile 8 from 18:00 to 05:59, which is why the two times above draw two different maps. A group of monsters is another matter: the game draws a tile for its kind of monster over the square while the party can see it ($94CF), and these maps show the square beneath.

A tile is two character cells wide and two high: 16 by 16 screen pixels of the C64's multicolour bitmap, drawn by $22EA. Its 32 bitmap bytes and 4 colour bytes come from the tile set the map names. There are nine tile sets of 96 tiles. Press a tile in section 05 to see where the map uses it.

The port was checked against the game's own code, run in a 6502 simulator on each map as the game loaded it: every square of all 42 maps, and a ring of squares off each map, at seven hours of the day. That is 455,952 squares, with no difference. The tile drawing was checked against every tile of the nine sets, and the view against a frame recorded in play, pixel for pixel.

02 · The squares

Sixteen classes of square

A square's class picks the routine that runs when the party steps on it. Its number picks the record that routine reads.

ClassWhat it doesWhenCode
0Nothing. Most of every map.$AE0D
1Shows messages, then may change the square.on arrival$BDE9
2A check: tests a skill, an attribute, an item, cash or the size of the party.as the party steps in, or once it is on the square$8DEC, $8E14
3A group of monsters or people.the step is refused$AD5B
4An object, with a tile and a message of its own. It may block the way.on arrival, or as the party bumps into it$833D, $915E
5Loot: items or cash.on arrival$9194
6An action: a module from the disk (the doctor, a shop, the library, the Ranger Center) or a routine of the map's own.on arrival$8839
8A question. The answer changes the square.on arrival$88E3
9Radiation.on arrival$82E0
10An exit, to another map or another square of this one.it may ask as the party steps in; then on arrival$8A36, $89A3
11An obstacle, with a message.the step is refused$915E
12Changes other squares.on arrival$8878
7, 13, 14Nothing. No square of the 42 maps has these classes.$AE0D
15A group placed by a random encounter.as class 3$B015

The routines are in a table of 16 addresses at $ACF3, one for each class. When the party arrives on a square, the game takes the square's class and number ($B12D) and runs the class's routine with the square's record ($ACDB). The square's number picks an entry in its class's list, and the map's record holds the 16 lists' addresses. A routine that changes the square under the party says so, and the game then runs the new square's routine too ($ACC1).

Classes 3, 11, and 15 have no routine of their own in the table ($AE0D does nothing). They act before the step. The game refuses a step for five reasons, in this order ($AD5B): the edge of the map, a group of class 3 or 15, a check square whose tests run as the party steps in and fail ($8DEC), an exit that asks first and gets N ($8A36), and an obstacle or an object that blocks the way ($915E). The port of that rule was checked against $AD5B for every square of every map in all four directions, 221,184 steps, with no difference.

Turn on "Square classes" above to colour each square by its class, or press a class under the map to show only that one.

03 · Exits

How an exit names its place

An exit's record is six bytes: a message, a column and a row, a map, and a change to the exit square itself.

The routine is $89A3. The first byte holds the message in its low six bits. Bit 6 makes the game ask "Enter new location (Y/N)?" before the party steps in ($8A36). Bit 7 makes the column and row an offset from the exit square, not a place ($89E3). The fourth byte is the map. Before moving the party, the game keeps the party's square and map in the party's own table. A map byte of $FF sends the party back to the square it kept last time ($89BA-$89F4). That is how the two maps of houses below send the party back out of the door it came in by.

A map byte from $80 up names a map through a table on the disk, track 35, logical sector 8, which the engine reads before it loads ($2620). Numbers $80 to $BF all load map 5, and $C0 to $FC load map 11. These two maps are the insides of buildings: the 30 house doors of map 1 lead into map 5 by 30 numbers, and the 55 of map 12 lead into map 11 by 53. A map entered by such a number is never written back to the disk ($2858), and a new number makes the engine load the map again ($25BF), so every house starts afresh.

An exit can lead to its own square. The door of the Ranger Center on the world map is one: its exit asks first, leads to column 55, row 62, where it stands, and turns its square into an action square. The game then runs the new square, whose action is the module that takes the party inside. Two squares beside it, north and east, turn it back into the exit.

The port of the exit record was checked against $89A3 for all 1,478 exit squares of the 42 maps. Of these, 15 go back, 168 are offsets, and 85 use a number from $80 up.

04 · Messages

The map's messages

Every map carries its own text. The squares' records name messages by number. Press the button beside a message to see the squares that show it.

The messages of the map chosen in section 01, decoded by a port of the engine's text decoder ($1E0E, $28F4). A dotted underline marks a choice the game makes as it prints: one or more, male or female, or him, her or it. A grey box stands for a name or a number filled in at the time. The list ends with the last message the map names.

A text block is a 60-character alphabet followed by a table of offsets, one for each group of four messages. Each character is a five-bit code into the alphabet, read lowest bit first ($291D). Code 30 makes the next letter a capital, and code 31 adds 30 to the next code, which reaches the alphabet's second half. A message ends at the code whose alphabet entry is 0. To find message n, the engine starts at group n / 4 and decodes and drops the messages before it in the group ($1E0E). The port was checked against the engine for every message number the 42 tables reach, four for each entry: 4,576 in all.

05 · The tile set

The 96 tiles of the map's set

Press a tile to mark every square of the map that shows it.

The tile set of the map chosen in section 01, from $D000-$DD7F: 96 tiles of 32 bitmap bytes, then 96 groups of four colour bytes from $DC00. Tiles the map does not show at the chosen time are dimmed.

06 · Where a map lives

Three layers and a record

A map is loaded to $3400 and up, and its tile layer to $DE00 and up.

The map record's first 92 bytes, for the map chosen in section 01, and the routine that reads each.

The class layer comes first, at $3400: half a byte a square, the even column in the high half. The number layer follows it, a byte a square. Then comes the map's record, at $3A00 for a map of 32 by 32 squares and at $4C00 for the four maps of 64 by 64. After the record come the lists, the records they point at, the map's own code, the monsters, the characters the party can hire, and the map's text, in an order that varies from map to map. The tile layer, a byte a square, is unpacked from a stream of its own on the disk to $DE00, in the memory under the C64's chips.

The record starts with 22 address words: the text, the monster names, the monster records, the 16 class lists, the map's own routines, the characters, and one word for which no reader was found. Eleven bytes of settings follow, then 37 message numbers for the phrases the fights print, two of them with no reader found.

07 · A square without a record

Bug: the check square that reads the processor port

On map 11, the square at column 24, row 13 refuses every step onto it, and says "Ah! Fresh air and open spaces once again."

Every step onto the square was run in the 6502 simulator with the game's own code ($AD5B): each is refused, and message 53 is shown.

The square is class 2, a check, with number 2. Map 11's list of check records holds $0000 for number 2, so the game reads the record from address 0. The C64's first two addresses are the processor's port, not memory. Address 0 reads $2F, the port's direction, and the game takes it for the check's flags. Its bit 7 is clear, so the check runs as the party steps in, and its bit 6 is clear, so there is no test to pass and the step is refused ($8DEC, $8E33). Address 1 reads $35, the port's setting in play, and the game takes it for the message to show: message 53. This square is the only one of the 42 maps whose record is not in the map.

The game does the same in the emulator. With the party at column 23, row 13, three presses of L each printed message 53 and left the party, the square, and the clock as they were, and the processor's port read $2F $35 throughout.