The clock-updating code at 8A52 doesn't switch from 'am' to 'pm' until 1pm
(instead of 12 noon), and also doesn't switch from 'pm' to 'am' at midnight.
The sticky bed
After collecting all the items, if Willy jumps onto the bed in Master
Bedroom (which is a conveyor moving right) instead of walking up to the foot
of it, he will stop moving and the 'P' (right) key becomes unresponsive. This
happens because the code at 8F0B flips bit 0 of E - which has already
been reset because Willy is on a conveyor moving right - to 1, thus preventing
the conveyor from moving Willy, and also effectively disabling the 'P' key.
To see this, use POKE 41983,255 to make the tap in The
Bathroom the only item that needs to be collected to complete the game, make
your way to the bedroom, and jump onto the bed.
However, all is not lost. Willy can be moved off the bed by using one of the
other 'right' keys: 'I', 'Y', 'R', 'W', '7' or '8'.
The self-collecting item
The item in Swimming Pool is automatically collected as soon as Willy
enters the room; this is because the room's background tile has white INK, and
the routine at 93D1 collects any item that is drawn on a cell with white
INK. There are no other rooms whose background tile has white INK.
To change the INK of the room's background tile from white to cyan, enabling
Willy to collect the item himself:
In a room with a non-black background, a guardian defined with BRIGHT INK is
drawn with a 'halo': a BRIGHT sprite background that contrasts with the
non-BRIGHT room background. There are four guardians affected by this
The following POKEs modify the section of code at 91D6 so that a guardian is
drawn in non-BRIGHT INK and PAPER when the room background is not black, thus
preventing any halo:
From top to bottom
In a room that contains a rope and has no exit to the room above, Willy can
jump while at the highest point on the rope (when it's at the leftmost or
rightmost extent of its swing) through the top of the room and reappear on the
floor of the same room. The only rooms where this can happen are On the
Roof and The Beach.
To prevent Willy from climbing high enough up the rope to be able to jump
through the top of the room:
The number 15 here determines the highest segment of rope that Willy can reach
(originally 12, three segments higher up). At segment 15, Willy's y-coordinate
never goes below 25 while he's on the rope, and is adjusted down to 24 (see
8FAE) when he jumps off, which is too far from the top of the room (the
maximum height Willy can jump is 20 pixels). At segment 14, Willy's
y-coordinate never goes below 23 while he's on the rope, but is adjusted down
to 16 when he jumps off, which is close enough to the top of the room to be
able to jump through it.
The code at 92E1 adjusts Willy's location depending on where he's hanging on
to the rope. Specifically, his pixel y-coordinate is set to Y-8, where Y is the
pixel y-coordinate of the segment of rope whose index matches the value of the
rope status indicator at 85D6.
Long distance nasties
If Willy falls through the bottom of a room and there is a nasty at the top of
the room in a direct line above him, he will die before he reaches the room
The only room affected by this bug is Under the Roof. Use the
following POKE to start the game in that room and see what happens when Willy
steps off the ledge:
The problem lies in the section of code at 95F8, which sets the attribute
bytes for the cells occupied by and below Willy's sprite. If Willy is below the
level of the floor, HL (which holds the address of the cell in the
attribute buffer at 5C00) is eventually incremented so that it points to the
cell in the ceiling above Willy in the attribute buffer at 5E00. Then the
routine at 961E is called to actually set the attribute byte for the cell,
detects the nasty there, and kills Willy.
Don't mind your head
The code at 8FDC onwards that moves Willy left does not check for a wall
tile at head height, which means Willy can move right to left through a wall
tile at that position. To see this, add a wall tile at head height in
The Bathroom and guide Willy through it:
However, the code at 904E onwards that moves Willy right does check for a
wall tile at head height (at 90A7), so Willy (correctly) cannot move left to
right through a wall tile at that position.
Note that the ability to walk from right to left through a wall tile at head
height comes in handy in The Forgotten Abbey - without that ability,
Willy would not be able to collect the item without sacrificing a life.
Stuck in the wall
If Willy enters The Wine Cellar from the ledge in The
Forgotten Abbey, he must keep moving left until he clears all the wall tiles,
otherwise he can become trapped inside them by the conveyor below trying to
move him to the right.
To get on the conveyor, stand facing left at the top of the ramp in The
Forgotten Abbey (see the first image below) and jump left towards the exit -
Willy will land on the ledge (second image). Then walk left into The Wine
Willy can get also stuck in the wall tiles that make up the elephant's head in
Dr Jones will never believe this. Start at the location shown in the
first image below, and then walk left.
Getting stuck in these places is possible because Willy can walk right to left
through wall tiles at head height, but not left to right (see
Don't mind your head).
The missed note
Each note of the in-game tune is played twice by the section of code
at 8B3C, except the first note when a new game starts. This is
because the in-game music note index at 85E1 is incremented from 0 to 1 on
the first pass through the code before the first note is played.
The blank conveyor
The conveyor tile in Conservatory Roof is completely blank and its
attribute byte is 0xFF - a solid, bright white block - which is characteristic
of unused tiles elsewhere. However, the conveyor tile is used in this
room, and it doesn't look good:
The conveyors in West of Kitchen, The Nightmare Room,
The Wine Cellar and Tool Shed don't look quite as
they should. The reason for this is a bug in the code at 8D51: if a graphic
data byte of the background, floor, wall, nasty or ramp tile in a room matches
the attribute byte of the conveyor tile to be drawn, the 'CPIR' instruction
exits early, leaving HL pointing at the wrong location.
Here are some 'before' and 'after' pictures showing what the conveyors actually
look like and what they look like when drawn properly.
You might be thinking that the fix given above for the corrupted conveyors bug
does not do much for the appearance of the conveyor in The Nightmare
Room. Perhaps that's because the real problem with this conveyor is that its
attribute byte and graphic data - which should occupy addresses
DDCD-DDD5 - appear to have been shifted by one byte back to
DDCC-DDD4 (overwriting the eighth graphic byte of the ramp tile). If they
are shifted along to the right spot, the conveyor takes on a much more
In addition, if the byte at DDD5 (0x55) is shifted back round to DDCC,
it seems to fix the appearance of the ramp tile (by filling the gap at the
Invalid grid location
If the LSB of the system variable FRAMES is 0x8E when the game starts, the
routine at 86C3 will ask for the code at the grid location 'D>', which
doesn't exist on the code sheet.
Should you ever need it, the code for 'D>' is 1444.
The Spectrum will hang when trying to resume the game after being paused if an
Interface 1 is connected. This happens because the C register holds 0x00
instead of 0xFE when the keyboard is read by the 'IN A,(C)' instruction at
Perhaps the most famous of all the bugs in Jet Set Willy, the Attic bug is
responsible for certain rooms becoming impossible to navigate after Willy has
visited The Attic, thus making it impossible to complete the game.
The root cause of the bug is a misplaced arrow, defined by the entity
specification at E9FC. The second byte of the entity specification is an
index into the table of screen buffer addresses at 8200, and determines the
arrow's y-coordinate; the index should be an even number, but the value of the
second byte is 0xD5, which means the arrow-drawing routine at 91BE looks up
the word at 82D5 and finds A06A, way outside the actual screen buffer
at 6000-6FFF. As a result, the misplaced arrow is 'drawn' at the
9F6A-9F89: unused (set to 0x41, with no effect on the game)