1986 · Palace Software

The Sacred Armour of Antiriad

This minisite was contributed by air. It’s agent-generated and needs a human editor. Clone https://github.com/gamesexplained/gamesexplained and follow kit/START.md to curate games/c64/the-sacred-armour-of-antiriad with me to Gold.

In its 69 rooms the game never looks at a shape to decide what is solid: it reads the colour of each cell to decide what Tal can stand on, walk through or get hurt by. The music is tuned for an American C64, and every sound in the game comes from the same driver as the title tune.

01 · The game

Tal and the Sacred Armour

Long after a nuclear war, aliens have come out of an old volcano and set Tal's people to work in their mines. Tal is sent to find the Sacred Armour of Antiriad, an anti-radiation suit from before the war, and use it to destroy the aliens' power centre.

The title screen: the ANTIRIAD logo between two statues, the armour standing below with a drone above it
The title screen.
The first screen of play: Tal on a ledge in the jungle, the status panel below
The first room of a new game, with the status panel below.

The world is 69 rooms, one screen each, joined left, right, up and down. Tal starts on foot at one end of the bottom row of rooms, with stones to throw and five lives. The armour stands empty in room $3F, further along the same row. The first time he climbs into the armour, the suit wakes, the status panel lights up, and from then on he can pick up recharge cells for the suit's energy and four add-ons.

The add-ons are what make the suit useful. The Gravity Displacer lets it fly, the Pulsar Beam lets it shoot, and the Particle Negator shields it in the two rooms at the top of the world. The fourth, the Implosion Mine, destroys the power centre in the topmost room, which ends the game.

02 · The title tune

Music: the title tune changes speed twice

Richard Joseph's title music is three tunes played one after another, each at its own tempo.

The page runs the game's own sound driver, its code and tables from the listing ($AFC5-$C1A9, the instruments at $F7C9-$FBAA), on the kit's 6502, called from the two timers as the game sets them, and plays what it writes through a model of the SID. test_music.js checks every write of 60 seconds of each button against the same driver run on the simulator over the game's whole memory. The tempo matches the emulator, where the first part took 826 steps in 19.66 million cycles; the effects timer runs about half a per cent fast here, most likely because on the machine the raster interrupt can run inside the music routine and hold it back, which the player leaves out.

The driver is called from two of CIA 1's timers instead of once a frame. Timer B is the tempo: each time it runs out, music_tick ($AFC5) moves each of the three voices one step through its track. Timer A runs out 98.5 times a second, and sound_tick ($B47D) then works each instrument's pitch slides, note steps and pulse sweeps and copies the game's own copy of the SID's registers ($022F) into the chip.

Before each part of the title tune starts, the game stores a new value in timer B's latch, which is the whole of a change of tempo.

MusicTimer B latchSteps a secondSet by
Title, part 1$5D0141.4title_tune_part1
Title, part 2$435957.1title_tune_part2
Title, part 3$411A59.1title_tune_part3
Everything in play$516147.3title_sequence

Each voice plays a track, a list of notes below $C0 and commands that set a duration, a filter, an instrument, a hold, a restart or a stop (track_command). The title moves on to its next part when voice 1's track ends. After the third part it waits for voice 2's instead, and then starts again from the first.

In play the tempo stays at 47.3 steps a second. The short tunes heard in the game, the suit waking, the panel powering up, a life restored and the ending, are tracks of the same driver.

03 · The screen

Two character sets share one screen

The playfield and the status panel are both drawn in characters on the same screen at $4000. The raster interrupt changes the character set and the colours where the panel begins, and again at the bottom of the frame.

One frame in room $2B with the suit worn, recorded in the emulator and drawn here from the screen at $4000, the two character sets, colour RAM, the sprites and every register the game wrote during the frame, by the site's renderer. All 104,448 pixels of the drawing match the emulator's own picture of the frame.

The interrupt comes three times a frame (raster_bands, $AE92). At line 250, in the bottom border, it sets up the playfield for the next frame and then runs the game's work for the frame: the timers, Tal's joystick, the creatures' paths and animations, the collisions and the Q key. At line 50, as the playfield starts, it scrolls the message strip and rolls the score. At line 178 it switches to the panel.

The playfield's character set is rebuilt for every room (section 04), so one screen code draws jungle in one room and rock in another. The panel keeps its own set at $7000. The message strip and the score's digits are characters in that set whose shapes the game rewrites as they move: the strip scrolls two pixels a frame, and each digit rolls up to the next like an odometer.

04 · The rooms

Each room borrows a strip from both neighbours

A room is eight tiles across and four down, and each side of the screen shows one column of tiles from the room next door, so neighbouring screens overlap by 64 pixels.

Click a tile to see where it comes from.

Room $2B, the one in the frame above, drawn from the listing by a port of build_room ($852C). test_rooms.js checks the screen, colour RAM, every character's shape and the multicolours of all 69 rooms against the routine itself run on the simulator, and the sprites against place_room_sprites. The monkey is characters the game redraws every eight frames (animate_tiles, $8C30), as here. Maps / levels draws every room.

The map of a room is 32 bytes at $0B00 plus 32 times its number: four rows of eight tile numbers. A tile is 16 character codes, four by four, from the 256 tiles at $1400. build_room draws the room's tiles into screen columns 4 to 35, then the last tile column of the room to the left into columns 0 to 3 and the first of the room to the right into columns 36 to 39 (draw_edge_column).

The tiles name character codes, and the shapes behind the codes change from room to room. Each room picks one of nine character lists (room_charset, $F761), and a list copies runs of shapes and their colours out of a pool of 748 at $2400 into the playfield's character set at $7800. The neighbours' lists are loaded first, so their strips keep their own shapes, and then the room's own.

The colours come with the shapes: each of the pool's shapes has one colour, and colour_room ($869C) writes it into colour RAM for every cell that uses the shape. A room has two more colours of its own for its multicolour characters (room_mc_colours, $F71C), and nineteen rooms have none, so they are drawn in high resolution.

05 · Walls and floors

The colour of a cell decides whether it is solid

The game never looks at a character's shape to see whether Tal can stand on it. It reads the cell's colour in colour RAM and looks it up in three short tables.

Each room as build_room leaves it, with every cell marked by what its colour-RAM nibble does in open_colours_floor ($CE12), open_colours_wall ($CE1C) and hazard_colours ($CE2C).

Ten colours let Tal and the suit pass up or down through a cell, and every other colour stops a fall or a climb (check_floor, check_head). Twelve colours let him pass sideways, and the other four stop a walk (wall_left). Colour 5, the green of the leaves in the high-resolution rooms, is in the second table and not the first, so a branch there holds Tal up and lets him walk through it.

Colour-RAM nibbleStops a fallStops a walkHurts
0-2, 9, 12, 14nonono
3, 6nono4 a touch
4, 15nono8 a touch
5, 11yesnono
7, 8, 10, 13yesyesno

The four colours that hurt are open in both directions: Tal can walk into a thorn. In the character lists they belong to the thrusting thorns, the monkey, the dragons' fire and most of the machine gunner. A touch costs Tal 4 or 8 energy, or the suit half of that, a quarter with the Particle Negator, and the game waits 25 frames before the next touch counts (scenery_hits). The game skips the check in room $00, at the top of the world.

The tables hold the whole nibble of colour RAM, with the bit that marks a multicolour character. That bit is bit 3, so in a multicolour room the nibble 15 is a shape in yellow and the room's two colours, and 13 a shape in green.

06 · The effects

Sound: every effect is a track of the music driver

Footsteps, stones, the Geiger counter and the typing of the panel's messages are tracks like the title tune's, asked of one voice each.

The same driver on the same 6502 at the tempo of play, each button asking the voice the game asks for that track. test_music.js checks these as well. The footstep, Tal's fall and a creature's death are pitched far down, between 16 and 170 Hz, which laptop and phone speakers barely play. The typing and the power centre's drone repeat until the game stops them.

A sound is asked for by putting a track number in a voice's request byte ($035E-$0360), and the next tick of timer B starts it (start_requests).

Each voice has its own sounds. Voice 1 plays Tal's footsteps and the suit's hum, voice 2 the effects of stones, shots, creatures and pick-ups (play_effect), and voice 3 the Geiger counter's clicks and the typing as each letter of a message appears. The power centre's drone plays on voice 2 and is the only sound that uses the filter. While the drone plays, play_effect drops every effect asked of voice 2.

While the suit is waking for the first time, the driver starts a request only when voice 1's is one of the three activation tunes (activation_tracks, $C605), and then starts the other voices' requests with it. Every other sound waits until the panel has powered up.

07 · Tal and the suit

Tal turns to face you before he walks the other way

What the joystick does depends on Tal's picture. Left and right turn him one view at a time through facing the player before he walks, and fire does nothing at all while he faces you.

Tal and the suit are two sprites each, one above the other, run from the animations at anim_ptrs ($FCA6) at the game's speed of 50 frames a second, in the shared multicolours the game sets on foot and in the suit.

The joystick is read every seventh frame, and not at all while Tal is jumping, falling, dissolving or appearing (tal_control). On foot (foot_control), up from a side view jumps straight up, fire while walking jumps that way, fire while standing throws a stone if the last one has landed, and down crouches. Crouching is how he picks things up.

Facing the player is the only view in which he can climb into the armour or use the teleporter (tal_touches).

In the suit (suit_control), up takes off only with the Gravity Displacer fitted, left and right turn and then speed up to 3 pixels a frame, and fire shoots the Pulsar Beam if it is fitted. Left or right on the ground climbs out, except in the ten rooms of the top five rows, where the radiation is highest.

08 · The panel

The panel's messages run on into one another

The panel scrolls 22 messages through an eleven-letter strip. A message ends by stopping, by starting again, or by naming the message that follows it.

The messages from message_ptrs ($C1AA), scrolled as scroll_message ($AA68) scrolls them, two pixels a frame, in the panel's letters from its character set at $7000. The strip is in multicolour, as the lit panel shows it: dark grey and light blue from the panel band's $D022 and $D023, and cyan from the strip's colour, 11.

The text is plain ASCII. Each letter becomes a panel character (code + $5B), and every fourth frame the next one is copied into a buffer at $0672 and rolled into the strip's eleven characters a pixel at a time (shift_message), twice a frame, so the letters move one multicolour pixel each frame. With each new letter, voice 3 types it if it is free.

"YOU HAVE THREE" and "YOU HAVE TWO" both end by naming message $94, " REJUVENATIONS REMAINING", and most messages go on to $92, eleven spaces, which scroll the last words out of the strip.

The game-over and ending messages start again from the top until fire is pressed, and an add-on picked up on foot repeats its message until Tal is back in the suit (addon_message).

09 · The creatures

A creature's damage is four times its hit points

The game keeps one number for how hard a creature hits Tal and works out from it how many hits the creature takes to kill.

The 25 animations in enemy_anims ($C618), each with its points (enemy_points, $C631) and damage (enemy_damage, $C64A), drawn from their animations in the shared multicolours of Tal on foot.

When a room is built, each creature's hit points are its damage divided by four (set_enemy_stats): 2 for one that takes 8 energy on contact, 1 for one that takes 4. A stone takes one hit point and a Pulsar Beam shot two (sprite_hits), so the creatures that hurt most take two stones or one shot, and the rest one of either.

A creature that touches Tal takes its damage from his energy, or half of it from the suit's, a quarter with the Particle Negator, and then dies, scoring its points. Sixteen animations cannot die: the drops and their splashes, the bomb-thrower, the empty armour, the recharge cells, the add-ons and the teleporter (unkillable_anims, $C608). A drop that splashes on the floor appears again where it started and falls again (spawn_enemy), so it costs 4 energy on every frame it touches Tal, for ever.

The round striped creature holds back everything listed after it in its room, and a stone kill pays double (Discoveries).

10 · Radiation

The higher Tal climbs, the faster radiation drains him

Every room has a radiation level from 0 to 3, set by how high it is. Out of the suit, Tal loses that much energy every second.

The rooms on the C64-Wiki's grid, columns A to O and rows 1 to 14, coloured by room_radiation ($F7A6), with the meter's sprite picture for the level ($70 plus 3 minus the level, panel_sprites) and the wait between Geiger clicks (radiation_click_waits, $06B4).

Tal's energy runs from 0 to 31. On foot he loses the room's level every 50 frames (energy_tick), so level 3 empties him in about ten seconds. In the suit he gains a point every 100 frames and cannot die, and the suit's own energy is not spent on it. The suit loses energy only to creatures and harmful scenery, and 2 points every 100 frames in room $00.

The two rooms at the top, $00 and $01, empty the suit's energy as Tal enters them unless the Particle Negator is fitted (room_change), and in the top ten rooms the suit will not let him out (leave_armour).

The meter on the panel shrinks from a full ring at level 3 to a sliver at level 0, and the red warning lamp beside it lights only at level 3.

11 · The ending

The mine goes off only on top of one pole

The power centre is room $00. The Implosion Mine is set off by landing the suit on the cap of the lower pole of its force field, three characters wide.

Room $00 drawn as in section 04, without its sprites, with the three cells check_detonation ($9850) looks for marked: screen codes $C9-$CB at row 12, columns 18 to 20. Set off, the panel's strip scrolls message $93 as section 08 does, and then the playfield dissolves as victory_sequence ($8AD9) dissolves it, which test_ending.js holds to the routine step by step.

While the suit stands on the ground, check_detonation reads the screen code in the cell below and to the right of Tal. When it is one of the three in detonator_chars ($CE30) and the Implosion Mine is fitted, it starts message $93, "IMPLOSION MINE DETONATION SEQUENCE INITIALIZED", which counts down from FIVE to ZERO as it scrolls, about seven and a half seconds.

When the message has gone, the ending tune plays and the playfield's characters dissolve in nine steps (victory_sequence). Each step ANDs all 2,048 bytes of the room's character set with a 64-byte mask from $0800, a new mask each step, and then flips the border and background between black and white and the fine scroll between 3 and 0, so the whole picture jumps three lines up and back. A step takes 17 or 18 frames: about eight while the processor works through the bytes, between the frame's other jobs, and then a wait of ten.

After the ninth, the colours and scroll go back to normal and the panel repeats "THE OPPRESSORS ARE DEFEATED YOUR RACE IS FREE PRESS FIRE TO PLAY AGAIN" until fire starts a new game.

There is no clock. The game ends only three ways: the mine, fire after the fifth death, and Q.