1985 · Hewson Consultants

Paradroid

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/paradroid with me to Gold.

The player is a helmet that rides robots, changing hosts by winning a circuit game against each one. Every host burns out at a rate set by its class, and the code holds the helmet to the same rule: left on its own, the 001 burns out and ends the game in a little over eight minutes.

01 · The game

A helmet against a freighter full of robots

A fleet of robot freighters has been hit by a beam that turned every robot aboard against the crew. The player is the 001, an influence device beamed onto the first ship to clear it.

The title screen: PARADROID in grey block letters, by Andrew Braybrook
The title screen.
The 001, a small white droid, on a blue deck seen from above, beside an alert panel
The 001 a second after boarding, beside one of the deck's alert panels.

The ship has sixteen decks joined by lifts, and the screen scrolls over one deck at a time, seen from above. Each robot shows its three-digit type number, and the first digit is its class: a 123 is a small disposal robot, and the 999 is the command cyborg that waits on the bridge.

On its own the 001 is weak. Holding fire with the stick centred readies it for transfer, and touching a robot then starts a short circuit game for control of it. A win puts the 001 into that robot, its host, with the host's speed, weapon and energy. A loss throws the 001 out again, and a loss with no host ends the game.

Consoles on the decks show a plan of the deck, a side view of the ship and a robot enquiry, a page on each type up to the host's own. Energisers recharge the host, for a price in points. When the last robot on the ship is gone, the 001 moves on to the next freighter.

02 · The droids

What the console knows about each droid

The robot enquiry draws each type and prints its specification. Pick a type to see its page, and what the code does with the same numbers in play.

The picture is eight sprites, four rows of two, from the shapes the type's 64-byte record names ($EB00), each row's right half mirrored from its left as droid_picture ($3629) does. The text is the record's bytes looked up in the game's dictionary at $C000, laid out as one page here where the console turns several. Both are checked for all 24 types against the game's own code run on the listing's bytes: every sprite's shape, place and colours, and every line the console prints. The figures under it come from the type tables at $EA00-$EA9F and the class tables at $6DDE-$6DFF.

The console only lists types up to the host's own (enquiry_pick, $2CF0): the 001 can look up the 001 alone, and the bigger robots' pages open only to a player who has taken one over. Every figure on a page is read from the record, but the height is printed as "1." followed by the record's two digits, so every droid stands between 1.00 and 1.99 m (Discoveries).

A type's class is the first digit of its number, and it sets most of what matters in play: how fast a host burns out, how many points the robot is worth, and how many pulsers each side gets in a transfer. The player's shot does more the better the host's weapon and the smaller the target (player_shot_damage, $1C0F). The twin laser, which the 001 and every host without a gun fire, does nothing at all to the seven types from the 711 up.

03 · Sound

Sound: the title makes up its noise as it plays

There is no music in this game. The title's sound is put together at random, frame by frame, and play has 31 effects on two voices. Press any of them.

The page runs the game's own sound driver, sound_frame ($0500-$0767, with the effects at $C610 and the instruments at $EAA0), on the kit's 6502 once a frame, as the deck's raster interrupt calls it, and plays what it writes through the site's model of the SID. Every register write of every button matches the driver run in the kit's simulator for 3,000 frames. Each button starts its effect as the game asks for one, by its number in channel 0's request.

An effect is 16 bytes (effects, $C610): an instrument, which gives the waveform, the envelope, a pulse width and how long to hold the note, then a starting frequency, a slide added every few frames, how many times to add it, a pulse width with a slide of its own, and an effect to chain to when it ends. The driver keeps two channels on the SID's first two voices. The third voice runs noise at its highest frequency with its output switched off, and every random number in the game is a read of its waveform ($D41B).

The title's sound (title_sound, $054A) uses that noise to choose. Every 128 frames it starts one of the three title effects, $1D-$1F, at random; twice in every 64 frames it plays the lift's effect, $10, on the second channel; and every 16 frames it pushes the first channel's slide up or down by a random amount. No two visits to the title sound the same, and neither do two presses of its button here. The decks hum with one effect, $18, whose three slide bytes deck_start sets for each deck from $6E60, $6E70 and $6E80.

04 · One frame

One frame of play, rebuilt from memory

Four raster interrupts change the video chip's settings as the screen is drawn, so the status bar, the deck and the strip above it each get their own character set. Press one to see the lines it rules.

The whole frame, as the video chip drew it.

Drawn by the page from one frame of play recorded in VICE: every write to the video chip with the line and cycle it landed on, and the memory the drawing reads, rebuilt with the site's renderer. 0 of the 104,448 pixels differ from VICE's own picture of the same frame.

The chain starts at line 254 with irq_bottom, which sets up the top of the next frame: the text font at $7000 for the status bar, and every robot sprite pointed at a blank shape so none shows over it. At line 91 irq_top sets the deck's colours and fine scroll, and a blank character set for the strip above the deck. At line 118 irq_deck switches to the deck's own character set at $7800, copies the frame's sprite shapes into place and runs the sound driver. The last, irq_collide, comes at line 246, or earlier, at the moment two sprites first touch.

The main loop counts frames by those interrupts: irq_bottom sets a flag and irq_deck clears it, and one pass of the game waits on it five times, so a pass takes at least two frames (main_loop, $13DA). In a recording of play the game managed 66 passes in 200 frames, a little over 16 a second, and every timer in play counts passes.

05 · Decks

How a deck is stored

A deck is drawn from 32 blocks of 4 by 4 characters, and its plan names a block for each cell of a grid 64 wide and 16 deep. Press a cell to see its block.

Press a cell of the deck.

Drawn by the page from the listing: the plan found through plan_ptrs ($F100), unpacked into the map as build_deck ($3590) does, each character in its own colour from the colour table ($0800) and the deck's scheme ($6A44). The map matches build_deck run in the kit's simulator for all 16 decks. Every deck is drawn on the Maps tab.

The plan is run-length packed: a byte with bit 7 set is a cell repeated as many times as the next byte says, and any other byte is one cell. The long corridors and empty space around a deck cost two bytes each, and the sixteen plans take 3,500 bytes for maps that unpack to 16 KB at $8000. Characters with bit 7 set are walls, which stop the player, the robots and line of sight alike.

Colour is a second table. Every character of the deck's set belongs to one of 16 groups (the high four bits of its entry at $0800), and a deck's scheme, one of eight at $6A44, gives each group a colour. When the last robot on a deck is destroyed, the deck changes to scheme 7, the lights go out, and 500 points are paid (update_droids, $174B).

06 · Robots

Robots walk from waypoint to waypoint

Each deck has a set of waypoints, and a robot's whole route is a string of random choices between them. Press a waypoint to see where a robot may go from it.

Press a waypoint.

The waypoints of the same deck from way_lists ($C810): a column, a row and a byte with a bit for each of the eight ways on, drawn at the centre of their cell. Each line runs from a waypoint in a way it allows to the next waypoint that way; a dashed stub is a way with no waypoint along it.

A robot that reaches a waypoint takes the first three ways its byte allows, counting from left round to up-left, and a random number picks one of the three, a third of the time each (choose_way, $1CAD). A waypoint with fewer than three ways leaves a gap in the choice, and a robot that draws the gap stands still for 8 passes. A wall in the way stops a robot for 2 passes. The choice reads the waypoint and the random number and nothing else, so a robot never heads for the player.

What a robot does about the player depends on sight. It is drawn, and can fire, only while a line from the player's cell reaches its cell without crossing a wall (line_of_sight, $24AE). Each robot starts a deck at a waypoint of its own: place 12 of the deck's row at waypoint 2, place 11 at waypoint 3 and so on, and the bridge's 999 at waypoint 1. Waypoint 0 is where the player beams in (load_deck, $1664).

07 · The ship

A new ship's robots are rolled as the 001 boards

The game does not store where its robots are. It rolls them at random for every ship, from two numbers for each deck and the ship's number, which rises by one with each ship. Board again to roll another.

build_ship ($15E8) ported, with the page's own random numbers in place of the noise voice. It gives the same table and the same count as the game's routine run in the kit's simulator on 645 ships, each fed the same random numbers, and on ships where every random number is 0, 3, 12, 15 or 255.

Each deck has a base type (deck_lowest, $C830), and the ship's number is added to it, up to type 19, the 821. The deck then fills one fewer places than deck_places ($F170) says, twelve at most. The first seven places it fills get the base type plus a random 0 to 3; the rest get half a random 0 to 15, halved again until it is below the base plus 3, which makes small robots, types 1 to 7 on most decks, or an empty place. Place 13 of the bridge always holds the 999.

So the ships do get harder: on the eighth ship each deck's base is up to seven types higher than on the first. The ship's number stops at 8, and so does the difficulty, since the same number sets how often robots fire (robot_shoot, $3450).

08 · Energy

Bigger hosts burn out faster

A host's energy limit falls by a point at a pace set by its class, from every 128 passes for the 001 to every 16 for the 999. Pick a host and its energy to see how long it lasts.

From burn_masks ($6DDE), kill_points ($6DEC) and ram_points ($6DF6), by class. Seconds assume 16.5 passes a second, the pace of play recorded in VICE; a busy deck runs slower.

Every 16 passes the alert routine (alert, $3E32) checks the pass count against the host's mask, and when it matches, the energy limit drops by one and the host's energy is held under it. A host whose energy reaches 0 burns out and leaves the 001 on its own with 7 points of energy (burnt_out, $1573). Taking a new host is the only way to stop the clock. The briefing says as much: "change the host robot often to prevent the device from burning out".

The same 16-pass tick runs the alert. Each robot destroyed adds its type to an alert count, which falls by one each tick, and its top two bits light the deck's alert panels green, yellow, amber or red. Each tick pays 0, 5, 10 or 25 points by that colour (alert_points, $6DE8), so a player who destroys big robots quickly is paid for keeping the alert up. Standing on an energiser gives a point of energy every fourth pass, up to the host's limit, and takes 5 points of score for each (floor_cell, $2E7B).

09 · Transfer

The transfer game

Touching a robot in transfer mode starts a duel on a board of twelve wires. Each side fires pulses along its wires to light the middle column in its colour, and the side holding seven or more of the twelve when time runs out takes the robot.

The transfer board: yellow wires on the left, purple on the right, a column of twelve cells between them
Choosing a side: the countdown runs while the stick picks yellow or purple.
The transfer board near the end, the middle column mostly yellow
Near the end: the middle column shows who leads.

The pulsers each side gets, from show_pulsers ($E46D): the host's class plus 3 for the player, the target's class plus 4 for the robot.

The board is dealt afresh for each transfer (place_piece, $E222). Each wire may carry a piece: an auto-pulser, a terminator, a colour changer, a splitter or a joiner, each one time in 16, and plain wire the rest. A pulse lasts 80 steps, and the cell of the middle column takes the colour of the last powered segment on its row. When the time runs out at six cells each, the status bar shows "Deadlock" and a new board is dealt (count_middle, $2057).

The robot's side plays by a simple rule (opponent, $2109): it moves its cursor a row every other pass towards a random row, fires there and picks the next, with rows 5 to 8 twice as likely as the rest. A win gives the player the robot's type, its energy and its points. A loss from a host costs the host's ram points and throws the 001 out; a loss as the bare 001 burns it out and ends the game. Either way the robot is gone (Discoveries).