1985 · Hewson Consultants

Gribbly's Day Out

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/gribblys-day-out with me to Gold.

Gribbly never moves sideways on the screen: the world scrolls round him, and the wall at its right-hand end is the left wall seen one row down. In play the sound chip's third voice stays silent, because the game reads it for every random number.

01 · The game

Gribbly's job: eight Gribblets into the cave

Gribbly Grobbly, "the no-armed, one-footed but strangely cute beastie from Blabgor" of the title page, rescues baby Gribblets. Each of the sixteen levels has eight, scattered over a map 256 tiles wide, and he carries them one at a time to a ledge in the cave he starts beneath.

The title page: Hewson Consultants presents Gribbly's Day Out, featuring Gribbly Grobbly, brought to life by Andrew Braybrook The first level just after Gribbly appears: Gribbly on the ground under a ledge, the psi and bank bars, score and clocks in the panel below

The Scenario page, one of the two title pages, and level 0 a moment after Gribbly appears beneath the cave, with the status panel under the play view. Both from the emulator.

On the ground Gribbly bounces, and pushing up lifts him into the air, where he can float in any direction. Fire picks up or puts down a Gribblet, blows a bubble at a creature, or switches part of the web: the glowing triangles strung across each map. A lit line of the web knocks Gribbly back and costs him psi, his energy, and a level whose psi runs out is played again.

Creatures hatch and breed while he works, and Seon, the guardian, waits a while before he comes after Gribbly. A level is over when each of its Gribblets is saved or lost. Save six or more and the game moves on to another of the sixteen maps, chosen partly by how well you played.

02 · Music

Music: the title tune plays 65 cents flat on a European C64

The tune plays only on the title pages. Its note table holds equal-tempered pitches for the American machine's clock, so a European (PAL) machine, whose clock is 3.7 % slower, plays every note about two thirds of a semitone flat.

The player needs the site's sound script, which loads when the page is served with the rest of the site.

The game's own driver (sound $7554), ported and played through the site's model of the SID with the filter of a 6581, the original chip. The player stops where the game loops back to the first note. The port was run against the driver in a 6502 simulator on the game's bytes: 38,796 calls of the driver, tune and effects together, gave the same 300,119 register writes in the same order.

The driver runs from a timer interrupt on CIA 1, every 47,288 cycles, 20.8 times a second (irq_title $7413). Every fourth call the driver reads the next byte of three note lists at $FE00, $FE80 and $FF00. A byte's high four bits are the octave and the low four the semitone, so $40 is C4 and $49 is A4; 1 holds the note and 0 silences the voice. The three voices use a sawtooth, a triangle and a pulse wave, and the third, the bass, runs through the low-pass filter.

NoteTable valueOn an American (NTSC) C64On a European (PAL) C64
A2, $29$070C110.0 Hz105.9 Hz
C4, $40$10C3261.6 Hz252.0 Hz
A4, $49$1C31439.9 Hz423.8 Hz

The note table is at $FD00, two bytes a note with the high byte first. The f5 and f6 keys on the title pages change the tune's volume, which starts at 5 of 15. The keys have no effect on the sound effects in play, which always run at full volume.

03 · Sound effects

Sound: the third voice is the game's random number generator

The effects play on voices 1 and 2 only. Voice 3 runs white noise at its top frequency with its output switched off, and whenever the game needs a random number it reads that voice's oscillator at $D41B.

The player needs the site's sound script, which loads when the page is served with the rest of the site.

The same port of the driver, called every other frame as the play loop calls it, with each effect requested on the voice the game uses. Each effect is a 16-byte record at $FB80: an instrument, then a start frequency and a sweep, a step counter, a repeat count, a pulse width and its sweep, a mode, a reset frequency and an effect to chain to (start_effect $7706).

An effect with bit 7 set in its request cannot be cut short by the next one on its voice: saving a Gribblet ($94) and the web's power-down ($98) are two.

Two effects chain into another when they end: the end of a level into effect 22, and the power-down into effect 13. A chain is read from the wrong byte on voice 2, from the voice's repeat count, which has just run out, so an effect played on voice 2 never chains. The game requests both chaining effects on voice 1.

04 · Gribbly's face

Gribbly's face moves in pieces, each on its own timer

Gribbly is one sprite, and his face is not a series of pictures. The game redraws pieces of it inside the sprite while he plays: his antennae, his eyes, and his mouth, each at its own rate and for its own reason.

 

The shape on screen, enlarged, in level 0's colours, and every piece the game can draw into it, from its tables at $7DF5-$7F33, with the one in place outlined. Under them: one cycle of 128 frames, about two and a half seconds, and where the picture is in it. The face is drawn by a port of animate_face ($6AAD), run beside the game's own routine on the kit's 6502 simulator for 2,048 calls, every frame number eight times with random noise and points; the three shapes matched after every call. In the emulator, on level 0, the antennae changed only on frame 2 of every 8 and the eyes only on frames 2, 8, 10 and 16 of every 128.

The antennae change on every eighth frame, about six times a second. Rows 0-4 of all three of Gribbly's shapes get one of four poses, picked from the noise of the sound chip's third voice added to the raster line ($6AC2), so the antennae wave whichever way he faces. A pick can land on the pose already there, which makes the waving uneven.

The eyes run on a cycle of 128 frames, and only in the shape that faces you (eyes $6B36). On frame 2 of the cycle the lids come half down, on frame 8 they shut, on frame 10 they are half open again, and on frame 16 the eyes open wide, looking one of six ways. That look stays for the rest of the cycle, so Gribbly blinks every two and a half seconds and glances somewhere new as he opens his eyes. The look comes from the sound chip's noise as well. Its values 6 and 7 both give look 0, so look 0 comes up three times in eight.

The mouth is redrawn on every other frame, from the score ($6AE5). Gribbly smiles while points are waiting to be added and frowns while points are waiting to be taken off; otherwise his mouth is straight. Points reach the score at one a step, 25 a second (score_tick $6FF0), so the expression lasts as long as the points take to count: four seconds of smile for the 100 that saving a Gribblet earns, and under a second of frown for the 20 that putting one down away from the cave costs.

The joystick picks which of the three shapes is shown: left shows $C2, right $C3, and once he has stopped moving sideways, $C1, the shape that faces you (gribbly_physics $68F5). All three get the same antennae and mouth, so nothing jumps when he turns. The side shapes keep the eyes they were drawn with. The face goes on moving while the game is paused (pause $72E5) and between levels (wait_frame $5BBD).

05 · The play screen

An invalid video mode hides the switch to the panel

The play view and the status panel are two different character screens with two different fonts. Four raster interrupts switch between them on every frame.

Drawn by the site's renderer from one frame of level 0 recorded in the emulator: memory as the frame began and every write to the video chip during it. 104,442 of the 104,448 pixels match the emulator's own picture. The 6 that differ are on line 197, where irq_panel turns the display back on partway along the line.

LineHandlerWhat it does
44$745AShows the play screen at $0800 with the tiles at $2800, in multicolour, with the fine scroll and the level's background colour.
182$74E0Latches the sprite-to-sprite collisions for the main loop. Two sprites touching also fire it early.
189$7424Blacks out the line, then switches to the panel's screen at $0400 and font at $2000.
197$74AFTurns the display back on, hi-res and unscrolled, and tells the main loop the play view is finished.

The black line hides the switch. irq_blank writes $D011 = $7F, which asks for bitmap mode and extended colour mode at once. The video chip shows that invalid combination as black, so the moment the screen and font change is never seen.

The view is 40 tiles wide and 18 high, redrawn from the map in full on every other frame (draw_view $6702), with the hardware's fine scroll for the pixels in between. Gribbly's sprite never moves sideways. He is always in the view's column 19, and the world scrolls round him: his speed is the scroll speed.

The map has no right wall. The yellow wall on the right of the picture is the map's left wall, one row down: draw_view reads on past the end of a map row into the next one, and level 0 opens close enough to the end for the view to run over it (the maps show where).

06 · Gribblets

Gribblets are characters until they jump

A Gribblet sitting on a ledge is two tiles in the map, drawn by the character screen like the scenery. Only when it hops, falls from a Flyer, or rides inside one does it borrow a hardware sprite.

Left: the Gribblet tiles from the play font at $2800, $38-$3B paired with $3C-$3F, and $40/$41, a Gribblet a Topsy has knocked onto its back. Right: the sprite shapes $CC-$D3 a Gribblet uses in the air ($3300-$34FF). All drawn from the bytes in the listing, in level 0's colours.

Sprites are scarce. Gribbly has one, and the game has seven to share between Gribblets, bubbles, Seon and the creatures. A creature off the screen gets none at all: it moves as numbers in a table ($0368-$03F7, sixteen slots) and takes a free sprite only when it comes into view (free_sprite $620B).

The character animation gives the sitting Gribblets their life. Every eighth frame animate_chars ($6651) cycles the faces through the four tile pairs, so every Gribblet on screen looks about at once, and copies random rows into the flipped Gribblet's legs so that they wave.

A Gribblet that hops (gribblet_hop $62E5) is erased from its ledge, flies as a sprite, and is drawn back into the map where it lands. Off the screen, a hop moves the tiles and nothing more.

07 · The creatures

From seed pod to Flyer

One creature grows into the next. Seed pods fall and land as Topsies, which flip Gribblets onto their backs. A Topsy can turn into a chrysalis, the chrysalis hatches a Stomper, and a Stomper that walks onto a flipped Gribblet absorbs it and flies off as a Flyer.

Each creature steps through its frames as its mover does, at the game's speed: one step every other frame, 25 a second, and the Flyer one in two. The seed pod jumps 8 pixels right on frame $D4 and back on $D7, which is its jiggle. A chrysalis plays its five frames once as it forms and then holds the last; here it starts again. Seon takes a random frame of $39-$3C every other step, and $3D-$3F once every 256 frames. The sprite shapes are at $3000-$3FFF and Seon's at $0E40, in the colours their movers give them (level 0's Gribblet colour for the falling Gribblet).

Each change has its own odds. Once every 256 frames, about five seconds, a seed pod may appear at the top of the map while there are fewer than level + 8 creatures (spawn_seed_pod $5D8B). Once every 256 frames, too, a Topsy may turn into a chrysalis and a chrysalis may hatch, each with a chance of spawn_chance in 256, where spawn_chance is level x 2 + 20 + your performance (level_start $4573). Playing well makes the creatures breed faster.

What happens when two sprites touch comes from one table of 64 bytes, collide_table at $1000. The row is the sprite that is affected and the column the sprite it touched. Press a cell to read it.

 

The bytes at $1000-$103F as the listing holds them. Bit 7 kills, bit 6 turns round, bit 5 stuns Seon, bit 4 is the Topsy rule and bit 3 makes a Flyer drop its Gribblet (apply_collision $56A8). An empty cell does nothing.

A bubble pops on whatever it hits, and what it does to the creature is in the bubble's column. It kills a seed pod or a chrysalis, turns a Stomper round, stops Seon, and makes a Flyer let go of its Gribblet. A Topsy dies only when the bubble comes from behind; from the front it turns round. Bubbles score the creature's type less 2, times 20: 20 for a seed pod, 40 for a Topsy, 60 for a chrysalis (creature_hit $574F).

08 · Psi energy

Every level starts with exactly 40 psi

Gribbly's energy, psi, is a number from 0 to 64. Before each level the transfer stage moves energy one unit at a time between psi and the bank until psi is 40 (transfer_stage $5FC1).

EventPsiRoutine
A game starts1, with 119 in the banknew_game $4504
Hitting scenery or a lit web line in flight-4gribbly_collides $6CC3
Touching Seon-3sprite_collisions $5604
Eating a psi-grub+3 to +6bounce_tiles $61A5
Saving a Gribblet in the cave+8gribblet_fire $6098
Psi above 64capped; the excess x 8 in pointsadd_psi $604D

Psi left over at the end of a level goes into the bank, which holds up to 255, and a level started short of 40 draws on it. When psi reaches 0 the level ends and is played again on the same map, with the Gribblets already saved still saved. With both psi and the bank empty at a transfer stage, the game is over.

09 · Progress

The better you play, the further ahead the next level can be

A level is over when each of its eight Gribblets is saved or lost. Save fewer than six and the same level is built again. Save six or more and the next level is chosen by level_result ($64F3).

 

The routine, ported, with the random number drawn here in its place. Green levels are done; the outlined one is being played; press a level to mark it done or undone. The port was run against level_result in a 6502 simulator on the game's bytes over every performance, saved count, level and 37 random values, on 45 sets of levels done: 674,325 cases, all the same.

The performance starts at 0 and rises by the number saved beyond five, to at most 14. The routine takes a random number from 0 to 15, keeps the smaller of it and the performance, and picks the highest level not yet done at or below that. If every level there is done, the routine takes the first undone level counting up from 1. Level 0 always comes first, and since the performance never reaches 15, level 15 always comes last.

A player who saves exactly six every time raises the performance by one a level and meets the levels in order, 0 to 15. Saving all eight raises it by three, so later levels can come early. Finishing all sixteen adds 6,809 points and ends the game. The number turns up twice more: as the best score the game starts with, which start_game ($42C0) sets to 6809, and in the name of level 7, "Seon is the 6809 beast!".

10 · Seon and the web

Seon stays still for minutes unless you wake him

Seon, the guardian, is a creature like the others but waits before he moves. His timer starts at (28 - level) x 2 and counts down once every 256 frames, so on level 0 he waits nearly five minutes.

Touching Seon ends the wait at once, at a cost of 3 psi and 10 points. So does the web's power-down, which starts when seven of the eight Gribblets are saved, lost, or inside a Flyer (web_power_down $4E6D).

Once the wait is over, however it ends, Seon's aggression rises by one every 256 frames, to 14. Whenever a random number from 0 to 15 is below the aggression, Seon steers towards Gribbly (seon_move $49AF). A bubble stops him and lowers the aggression by 2 (seon_stunned $57A7).

The web is five bands of 14 triangles laid across the map at every level start (web_band_a $684D), each trimmed by one byte of the level's layout. A lit line bounces Gribbly off it and costs him psi. A line switched off is drawn with the same character codes plus $80, whose shapes are blank, so it vanishes and nothing collides with it. The power-down kills the controls first, one row of them every other frame, then puts out every line. Seon bounces off lit lines at four times his speed, and when he crosses a live control he switches it with a chance of your performance in 32 (seon_web $4B10).

11 · A leftover

Secret: a memory editor that nothing calls

The game's code begins with a small memory editor, $4000-$41F7. start_game sets it up, but no instruction anywhere in the program calls or jumps to the routine that runs it, monitor_step at $4011. Its line in the status panel is headed ABMON, most likely the author's monitor: Andrew Braybrook's own development tool, left in the shipped game.

The editor's line as it would have appeared in the status panel: the string at $4273 drawn with the game's double-height font at $2000, with the address and byte digits as the image holds them.

The editor reads the keyboard directly (monitor_key $41A7). A turns the editor on and D turns it off. Comma and full stop move the cursor between the four digits of an address and the two of a byte, and J and M count the digit under the cursor up or down. The byte is written to memory as soon as it changes.

12 · Quirks

Things the manual does not mention