1988 · Ocean

Where Time Stood Still

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/spectrum/where-time-stood-still with me to Gold.

A 128K-only game that keeps a different piece of itself in each of the machine's memory banks. Its title music comes round a second time a semitone higher than the first, because the code that changes key never changes it back.

01 · The game

Four survivors of a crash on a lost plateau

A plane comes down on a plateau high in the Himalaya. The four people who climb out of the wreck have to cross it to a mountain pass on the far side, the only way home.

The control selection screenThe four survivors beside the wreck at the start of play

The control selection screen, and the start of play beside the wreck, in ZEsarUX 13.0.

The player steers Jarret, the pilot, and the other three follow him: Clive, a rich man, Gloria, his daughter, and Dirk, who is engaged to her. The view scrolls in every direction over an isometric landscape of cliffs, rivers, swamps and forest. Dinosaurs live on the plateau, and so do tribesmen who trade with the party and take captives for a sacrifice.

Each of the four gets tired, thirsty and hungry, and loses patience with a leader who sits about. The menus on the SPACE bar pass objects between them and use them: tins of food, a bottle, a rope, a stick of dynamite. The panel under the view shows the leader's portrait, three bars for his needs, a score that is the percentage of the game done, a light for day or night, and a calendar of the days since the crash. Reaching the pass ends the game.

02 · The cast

Sprites: most of the people's frames have no mask, so the drawer cuts one from the picture

The people and creatures are sprites drawn over the view: 255 frames in twelve classes, each class's frames in one bank, which bank 3's table at $EAC8 names with the class's list of them. Pick a class to see every frame it can show.

· Pixel position across ·

 

Drawn by this page from the frame lists and pictures in banks 0, 1 and 6, paper in white and ink in black. test_cast.js runs the game's own drawing ($A6F8 to $A6F4) on the kit's Z80 for every frame of every class, plain and mirrored, at four pixel positions across and on every row of a character row, and the screen it leaves is the same as this page's, byte for byte. Point at a frame for its bytes.

A frame is six bytes in its class's list: its width, its rows, and the addresses of its picture and its mask ($A493). Most of the people's frames are 16 pixels wide and have no mask. The 16-pixel drawer ($A277) makes one from the picture as it draws, through two tables of 256 bytes, $8100 for a row's left byte and $8200 for its right. They keep the scenery to the left of the pixel before the row's first and to the right of the pixel after its last, and the row between becomes paper, so a figure stands on a silhouette a little wider than itself that keeps it clear of the scenery behind. Where a row starts at the frame's first pixel, the edge pixel before it is carried in from outside the frame, and at pixel position 0 the drawer shifts nothing and that pixel is lost: choose position 0 above to see the left edges thin.

The creatures, and the people's wider frames, are 24 pixels wide and carry a mask of their own, three bytes a row beside three of picture ($A079). Three frames of types $10 to $13 name $8521 as their mask, which is the visibility mask, all set where no scenery stands in front, so with nothing in front those frames draw no paper. Mirrored, a row's bytes swap ends and each is reversed through a table the start-up builds at $8000.

Types $14 to $1B are drawn in two pieces ($A725). Their frame number picks four bytes from a table, $F26A in bank 1 for $14 to $17 and $E2EF in bank 6 for $18 to $1B: the first piece's frame, the step across and down to the second, and the second's frame. Tick "Colour the second piece" to see where each piece ends.

The pictures show which creature each type is, which the code alone could not say. Types $10 to $13 are a tentacle that rises out of the swamp, $14 to $17 a pteranodon, $18 to $1B a tyrannosaur, $1C to $1F a black, shaggy beast on four legs, $20 to $27 a beast with a spotted, armoured back, $28 to $2C a round rock that turns over as it goes, and $2D an arm that reaches out of a rock. The pteranodon is the creature that flies off with a victim: event 6 at the end of an animation ($F26E) carries the victim away, and only its animation list, at $E412, has animations that end in that event.

The tyrannosaur's body is up to 45 rows, and the visibility mask is 48 ($8521 to $85E0). A sprite's first row takes the mask's row numbered by where its top row falls in a character row, 0 to 7, so with its top far enough down the body's last rows read on past the mask into the code at $85E1, and up to four pixels of its feet are not drawn where that code has a 0.

03 · The music

Music: the title tune comes back a semitone higher

The music plays on the title screen and in play. Its sections run in a chain and then loop, and every time round after the first is a semitone higher than the first.

 

The recordings are the game's own sound driver ($7000) run on the kit's Z80 from the listing, one call at a time as the interrupt makes them, 50 calls a second, and played here through a model of the 128K's sound chip. test_music.js makes them again from the listing and holds the page to them. In ZEsarUX 13.0 the chip's registers followed the recording frame for frame through 79 seconds of the title tune and of the second tune.

A tune is a chain of sections, each with a handler in the table at $70BF. Section 14 sets the three channels' instruments and chains section 15, and sections 15 to 25 play the patterns. Section 26 starts section 14 again ($7339), so the music loops. Pitches are kept in 48ths of an octave, four to a semitone, and turned into the chip's periods from one octave's table at $7AA5.

Section 23 moves the whole tune between keys: the top three bits of its step count become the transposition at $7992 ($72E4), so its first 32 steps play in the written key and its last 32 a semitone up, and it leaves the transposition there. Only a request for a new tune clears it ($707E), and the loop back to section 14 is not a request. So the first time round, sections 15 to 21 play in the key they were written in, and every time after they play a semitone higher. Press "First time round" and then "Every time after" to hear the difference from the first note.

The third button is a second tune of 192 steps, sections 1 to 3 ($7117), which the game never plays: no instruction writes 1 to the request byte at $7002. The tune is Parry's "Jerusalem". Its melody is on channel B, and the first eight notes rise 4, 3, 2 and 3 semitones and fall 3, 2 and 2, the hymn's first line, "And did those feet in ancient time". Section 3 flips the transposition between none and a semitone and plays section 2 again, so the hymn repeats with every other time a semitone higher ($7143).

The driver plays the hymn in the chip music style of its day, with its chords broken into arpeggios and a melody that sweeps between some of its notes. Channel A plays the harmony one note at a time. The top four bits of each of its notes pick a row of the table at $7995, and the row adds 0, 4 and 7 semitones in turn, a fiftieth of a second each, for a major chord ($7693); other rows make minor, diminished and suspended chords. The melody's row lifts each note an octave for one fiftieth of a second in every four, once the note has sounded for a fifth of a second. A melody note whose byte has bit 7 set sweeps to its pitch a quarter of a semitone each fiftieth of a second, instead of jumping there ($75D9, $761C). "Feet", the fourth note of the first line, sweeps up this way.

04 · The view

One frame, rebuilt from memory: the view is a window onto a map of blocks

Each area of the plateau is a map of 64 by 32 blocks, and each block is 4 by 4 characters. The view is a window 28 characters across and 18 down onto the map, and it scrolls a pixel row at a time up and down and half a character across.

·

 

The view at the start of play, drawn by this page from area 13's map, the block definitions in bank 0 and the characters in bank 4. Every byte is the same as the view the game builds in its buffer at $AE10, both in ZEsarUX at the start of play and in test_maps.js, which runs the game's own drawing ($A012). The four characters are not here: they are sprites, drawn over the view after it is copied to the screen ($A6F4).

The map lives in bank 0 at $C000, a byte a block. The block's number picks one of the area's definitions through the list at $C800, and a definition is 16 character numbers. A character number counts from the first character of a set, which a small table at $E840 gives for each range of definitions, and the set's 8-byte characters are in bank 4 from $CD40. Point at the view to follow one character through those steps.

Each area has a split. Blocks numbered above it take their definitions from a second run, 256 further on, and their sets from a second table at $E864. The split is not kept in a variable: the loader writes it into the operand of the comparison at $9C12, so the instruction itself changes from area to area. In area 13 the split is $57. Tick the box above to see which blocks of the view are numbered over it.

Every area is drawn whole on the Maps tab.

05 · Sound effects

Sound: what sets off each effect

The menu's sound icon swaps the music for sound effects. In that mode the driver plays tune 4, which is silent, and the game starts an effect by writing its number into a channel's byte.

Each effect is the game's driver run as it is in sound-effects mode, with the number written into the channel the game uses for it (channel A for those it never asks for), recorded until the effect's last sound or for three seconds. The bytes of the 24 effects are at $7795, 16 to an effect.

EffectChannelWhat sets it off

The three channels' bytes are $7006, $701F and $7038. The driver takes a number from one of them at its next call and clears the byte ($76D3). Effect 1 plays nothing, and effects 6, $0C, $0D, $13, $14, $15 and $16 are in the table but the game never asks for them.

06 · The party

Clive complains first because his limits are the highest

Each character has eight need bytes and a limit for them. Energy, water, food and patience fall, and a character who drops far enough below his or her limit complains, rests, or leaves.

CharacterLimitComplains, when the four have the same needs
Clive$A0first
Gloria$80second
Dirk$70third
Jarret$60last

The limits are at bank 3 $D5E3, the needs at $D5C3. The order of the complaints is worked out from the limits: how fast each character's needs fall in play was not measured.

Every 32 passes of the main loop the needs move (bank 3 $D603). Energy rises while a character stands, twice as fast while resting, and falls while walking. Water and food fall all the time. Patience falls while the leader rests, unless the character is hungry, and rises otherwise. A falling need queues a complaint for the conversation window when it comes to 32 above its limit, and again at 16 above ($D69A), so the higher the limit, the sooner the complaint.

Further down, the needs act ($D70A). A character more than 32 below the limit sits down to rest. With no water or food left, a character loses strength, and with no strength left, he or she dies. Patience more than two below the limit makes a character leave the party and walk off along one of the plateau's routes.

07 · Creatures

Creatures by what they do

The people and creatures of the plateau are 46 records of eight bytes, each numbered by its type. A record near the view becomes one of eight actors on the screen, and the type decides how the actor behaves.

TypesBehaviourCode
0 to 3The four survivors. The leader goes where the player steers him and the others follow.$DF8B
4 to 7The tribe. It greets the party and trades, and turns hostile when given nothing.$FCF0
$10 to $13Live in swamp ground and pull a victim under it.$F1D6
$14 to $17Chase, looking only ahead, seize what they catch, fly off with it and drop it.$F202, $F26E
$18 to $27Look all round, seize a victim within three units and hold it until it dies.$F14A
$28 to $2CRun along their routes, from area to area.$D6BA
$2DStays where it is and holds the leader until it is fed the ham.$FE17

The behaviour by type is from the code. Which creature each type is shows in its pictures: see the cast above.

Records not on the screen still move. Twice a pass the game takes a record that is not an actor and walks it a step along its route, from area to area (bank 3 $E187), so the creatures are not where the party left them. Only types 0 to $0F and $18 to $27 can be hurt: $18 to $27 take four or two hits, and the rest cannot be killed at all (bank 3 $C208).

08 · Time

A day lasts about five minutes

The game's clock counts interrupts, and 12,288 of them make a day. Night falls at the twentieth hour and day breaks at the sixth.

 

The count at $BF2A, from $BEEF: its high byte halved is the hour, and the watch's message is that hour made 1 to 12 (bank 3 $FA73).

On the title screen the clock counts every interrupt. In play, about one interrupt in five comes while the view is being copied to the screen with interrupts off ($963B), and the clock loses it, so a day in play lasts about 15,000 frames, five minutes. In ZEsarUX, standing still at the start of play, the clock counted 2,441 in 3,000 frames.

At midnight the calendar turns its page (bank 0 $F465). It starts at MAY 1, and the month after May is May again: see Discoveries.

09 · Controls

Eight directions fold onto four walks

The joystick or keys give eight directions, and the game folds them onto the four directions of the isometric map, with fire turning each walk into a run.

JoystickWalkWith fire
up, up-leftnorthrun north
up-right, righteastrun east
down-right, downsouthrun south
down-left, leftwestrun west
fire alonefire the way the leader faces, two units of ammunition

The fold is the table at $8D3B, read by $8B81. The manual's figure gives the same eight labels.

The control selection screen offers Kempston, Sinclair and cursor joysticks and keys the player chooses. SPACE is kept for the menus, and CHOOSE KEYS refuses it, as it refuses a key already taken ($AFEC). After 65 passes with no input the leader sits down to rest, and the others sit with him.