Jet Set Willy: Bugs

| Bugs

- 12:30am in the afternoon
- The sticky bed
- The self-collecting item
- The invisible item
- The inaccessible items
- The uncollectable item
- Guardian halos
- From top to bottom
- Long distance nasties
- Don't mind your head
- Stuck in the wall
- The missed note
- The blank conveyor
- Corrupted conveyors
- Very corrupted conveyor
- Corrupted nasties
- Invalid grid location
- The pause bug
- The Attic bug

12:30am in the afternoon
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'.
To make the bed unsticky:
POKE 58326,254
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:
POKE 57248,5
Note that this changes the rope's colour from white to cyan.
The invisible item
There is an item in First Landing, but you could be forgiven for not knowing because it's invisible. To give the item a shape and make it visible:
POKE 56548,24: POKE 56549,24
But now that the item is revealed, we can also see that it's unreachable:
To add a ledge and open the wall to make the item reachable:
POKE 56350,0: POKE 56358,0: POKE 56365,170
The official Software Projects POKE to fix this bug is
POKE 42183,11
which moves the item to The Hall (where it is still invisible, but now reachable).
The inaccessible items
The items in Conservatory Roof can only be collected by entering the room from the ledge on the lower left in Under the Roof, but that ledge is unreachable.
The official Software Projects POKE to fix this bug is
POKE 56876,4
which makes it possible to access the right-hand side of A bit of tree (and from there the lower right side in Under the Roof) from The Banyan Tree.
The uncollectable item
The item on the far right in Conservatory Roof cannot be collected because there is an unavoidable nasty in the way.
The official Software Projects POKE to fix this bug is
POKE 60231,0
which removes the nasty next to the item.
Guardian halos
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 phenomenon:

On a Branch Over the Drive | I'm sure I've seen this before.. | Emergency Generator

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:
POKE 37371,40
POKE 37372,2
POKE 37373,203
POKE 37374,177
POKE 37375,177
POKE 37376,205
POKE 37377,201
POKE 37378,147
POKE 37379,79
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:
POKE 37782,15
POKE 37786,15
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 below.
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:
POKE 34795,42
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.
POKE 38452,208
POKE 38453,253
POKE 64976,203
POKE 64977,76
POKE 64978,202
POKE 64979,182
POKE 64980,144
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:
POKE 57708,32
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 Cellar.

Willy can also get 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:

See also Unanimated conveyors.
Corrupted conveyors
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.

West of Kitchen |  |
The Nightmare Room |  |
The Wine Cellar |  |
Tool Shed |  |
| Before | After

To fix the bug:
POKE 36178,151
POKE 36181,9
POKE 36183,205
POKE 36184,38
POKE 36185,255
POKE 65318,9
POKE 65319,190
POKE 65322,75
POKE 65323,35
POKE 65324,201
See also Corrupted nasties.
Very corrupted conveyor
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 reasonable appearance:

Before | After

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 bottom):

Before | After

Corrupted nasties
The nasty tiles down the right hand side of A bit of tree don't look quite as they should. The reason for this is the same bug in the code at 8D51 that causes the corrupted conveyors: if a graphic data byte of the background, floor or wall tile in a room matches the attribute byte of the nasty tile to be drawn, the 'CPIR' instruction exits early, leaving HL pointing at the wrong location.
Here are the 'before' and 'after' pictures showing what the nasties actually look like and what they look like when drawn properly.

Before | After

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.
POKE 34556,180
The pause bug
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 8B24.
POKE 35615,62: POKE 35620,219: POKE 35621,254
The Attic bug
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 following addresses:

- 9F6A-9F89: unused (set to 0x41, with no effect on the game)
- A06A-A089: the third byte of entity definition 0x0D through to the second byte of entity definition 0x11 (set to 0xFF); this affects the guardians in Rescue Esmerelda, I'm sure I've seen this before.., We must perform a Quirkafleeg, The Bridge, Entrance to Hades, The Chapel and Priests' Hole
- A16A-A189: the third byte of entity definition 0x2D through to the second byte of entity definition 0x31 (set to 0x41); this affects the guardians in Out on a limb, East Wall Base, Tree Top, Inside the MegaTrunk, The Kitchen and West of Kitchen

The official Software Projects POKE to fix the Attic bug is
POKE 59901,82
which sets the pixel y-coordinate of the arrow to 41.