Professional Documents
Culture Documents
Jet Set 40-40 - Readme
Jet Set 40-40 - Readme
Jet Set 40-40 - Readme
'Jet Set 40-40' is a redesign of Matthew Smith's classic ZX Spectrum 48K game 'Jet
Set Willy'. It can be played on a real Spectrum, on the Sinclair ZX Spectrum
Vega/Vega+ or on a computer, game console or another device using a ZX Spectrum
emulator.
The layout of 'Jet Set 40-40' is very similar to that of the original 'Jet Set
Willy' (henceforth abbreviated as 'JSW'), but the number of rooms has been reduced
to 40. There is one item per room, but the player has to collect four complete sets
of items; once the last item of one set has been collected, the items of the next
set will appear. The difficulty of the game will increase with each consecutive set
of items, as more and more guardians threaten Willy's progress through his mansion
and its surroundings.
The player is offered a choice of rooms in which they can start the game. An option
of playing without some of the most extreme challenges can also be chosen. We hope
you will enjoy this 'quadruple quadragesimal' challenge!
Contents
II. Instructions
----------------------------------------------------------------------
- David S. Reidy and Keith Warrington, the authors of 'Skool Daze' (Microsphere,
1984), the game from which the sound effects audible after selecting the starting
screen and upon reaching the bed just before the toilet run have been copied.
- Jon R. Lemmon and Tim Kemp, the authors of 'Project-X: The Micro Man' (Compass
Software, 1985), the game from which the font has been copied.
- Richard Hallas, for coding 'Wheels', one of the in-game tunes, and the 'Radetzky
March', used in the game as the 128-byte-long 'victory tune'. Furthermore,
Richard's document 'A Miner Triad' (http://hallas.net/Software/music.htm) is an
invaluable guide to creating music for JSW/Manic Miner games.
- Andrew Broad, for his 'Lord of the Dance' coded in the JSW48 format, used as one
of the in-game tunes, for his JSW-related technical documents and for establishing
and managing the Manic Miner & Jet Set Willy Yahoo! Group
(https://groups.yahoo.com/neo/groups/manicminerandjetsetwilly/info).
- Stuart Brady, for his Cell-Graphics Bug Fix, which ensures that all cell graphics
are drawn as the designer intended.
- Norman Sword, for his optimised routine dealing with ropes, which freed up a
sizable chunk of spare space, later used for other purposes. A discussion with
Norman on jswmm.co.uk also inspired Ian Rushforth to carry out further optimisation
of the item-handling code (with an additional benefit in terms of speeding up the
program).
- Jonathan Graham Harston, for his 'Full Z80 Opcode List Including Undocumented
Opcodes' (http://www.z80.info/z80oplist.txt), for his 'JSW' related documentation
(http://mdfs.net/Software/JSW/) and for his elegant Pause Bug Fix.
- Jan Bobrowski, for his Qaop/JS HTML5 ZX Spectrum emulator, which was used by Ian
Rushforth in playtesting.
- The authors of the games from which various sprites have been borrowed (a
detailed list is included below).
The rooms
Most of the rooms preserve their general layout from the original 'JSW'.
Modifications (such as the diptych 'East Attic' - 'West Attic') are mainly the work
of Andy Ford, who also defined the game's map (especially in where it differs from
the original).
The sprites
The majority of the sprites in the game are Matthew Smith's classics from the
original 'JSW'. The remaining ones are (only examples of where they appear in the
game are given, the list of their appearances is by no means exhaustive):
- The '1 ton' vertical guardians in 'Master Bedroom' and the 'penny-farthing'
guardians in 'Front Door' were copied from 'Technician Ted' by Steve Marsden and
David Cooke (Hewson Consultants Ltd, 1984).
- The rightmost, red vertical guardian in 'Master Bedroom' was copied from 'The
DrUnKeN mAsTeR!!!' by the DrUnKeN mAsTeR!!! (BaSe1 PrOdUcTiOnZ, 2002).
- The white and yellow vertical guardians in 'Orangery' were copied from 'JSW
(Sunday Afternoon Graphical Remix)' by Darren McCowan (2001).
- The magenta vertical guardians in 'Orangery' were copied from 'Jet Set Willy II:
The Final Frontier' by Derrick P. Rowson (Software Projects Ltd, 1985), originally
created as an Amstrad version of 'JSW' by Derrick P. Rowson and Steve Wetherill.
- The stationary 'forcefield' guardian in 'East Attic' was copied from 'The Deadly
Mission' by Adam Britton (1985).
- The bright green horizontal guardian in 'West Ballroom', the magenta horizontal
guardians in 'Security Guard' and the red 'trap door' guardian in 'First Landing'
were copied from 'Willy's Holiday' by Adam Britton (1985).
- The swordfish sign was copied from 'Manic Miner' by Matthew Smith (Bug-Byte,
1983).
The music
The title-screen tune is the original tune from 'JSW', i.e. the 'Moonlight Sonata',
coded by Matthew Smith, originally composed by Ludwig van Beethoven (the Piano
Sonata No. 14 in C♯ minor 'Quasi una fantasia', Op. 27, No. 2, 1801).
- The original tune from 'JSW' ('If I Were a Rich Man'), coded by Matthew Smith,
originally written by Sheldon Harnick and Jerry Bock for the 1964 musical 'Fiddler
on the Roof' (audible e.g. in 'The Bathroom').
- The original tune from 'Manic Miner' ('In the Hall of the Mountain King'), used
also in 'Jet Set Willy II: The Final Frontier', coded by Matthew Smith, originally
composed by Edvard Grieg (1875) (audible e.g. in 'Driveway').
- 'Lord of the Dance', coded by Andrew Broad (first released as an Easter egg in
his 2004 game 'Party Willy'), originally written by Sydney Carter (1963), although
the tune is, in fact, a traditional Shaker tune (audible e.g. in 'At the Top of the
House').
The font
The custom game font was added by Andy Ford. It was taken from 'Project-X: The
Micro Man' by Jon R. Lemmon and Tim Kemp (Compass Software, 1985) with a few very
minor alterations to its layout.
The title screen was designed by Andy Ford. It was initially created in BASIC using
the built-in graphics, and then modified using ZX-Paintbrush to create the final
layout.
The loading screen was designed by Daniel Gromann, using ZX-Paintbrush and various
other tools.
The ZXK file to map the Vega controls to the ZX Spectrum keys used by the game was
created by Ian Rushforth. Ian also tested it on a real Vega to ensure it was fully
functional.
----------------------------------------------------------------------
II. Instructions
The object of the game is to guide Willy and collect all of the flashing items
scattered around his mansion, avoiding the moving and unmoving guardians and the
stationary nasties which may kill you (as will falling from an excessive height).
With all the items collected, the player needs to go to 'Master Bedroom' where
Maria will no longer be blocking access to Willy's bed. The whole process has to be
completed before midnight.
At the start, there is one item to collect in each of the 40 rooms of the game.
After the last item of the first set has been collected, the items of the second
set will appear (as will some additional guardians). This process will repeat after
collecting the items of the second and third set. The fourth set of items is the
final one.
After pressing ENTER to start the game, the player is asked whether or not they
want to face maximum difficulty. Choosing 'Y' will allow the game to be played in
its most difficult permutation. Choosing 'N' will result in ten guardians (and one
lethal arrow) which create the hardest challenges for the player being omitted, and
one guardian being converted to a less threatening incarnation! These guardians
will be restored if 'Y' is chosen at the start of the next game.
The player is then presented with a 'Starting Room Selection' menu screen. Press a
number key from 0 to 9 to choose the room in which the game will start and to
launch it.
Use O-Left, P-Right (or a combination of keys from the top row of letters) and
SPACE or any of the letters from the bottom row to jump.
A-G pauses the game; any other key unpauses it.
H-ENTER/RETURN toggle the music ON/OFF.
Pressing SHIFT+SPACE together at the same time abandons the current game.
'Jet Set 40-40' has been fully and extensively playtested by Daniel Gromann. It is
possible to complete the game in either difficulty mode, before the in-game clock
strikes noon, and without losing a single life!
----------------------------------------------------------------------
The 'Jet Set 40-40' project was started by Andy Ford at the end of July 2017 as
'JSW with 40 objects and 40 rooms - that simple'. Apart from modifying the layout,
Andy introduced various other tweaks such as:
- a custom font;
- minor adjustments to the 'lower screen' (the status area) display such as the
lives colouring and the text positioning;
- removal of unwanted routines such as the colour-code keypad and inactivity timer.
At the end of July 2017 the project was presented in the Contributor Lounge of the
Jet Set Willy & Manic Miner Community, where Ian Rushforth and Daniel Gromann
joined in and became engaged in its further development. Daniel came up with the
idea of having 4 sets of 40 items each, and a theoretical technical solution for
it. Ian then created and implemented a different, much more efficient solution, as
well as a tweak to have the guardians appear 'in instalments'. Andy and Daniel
defined the placement of the additional Item Sets. Daniel added new guardians, some
technical features (various in-game tunes, colourful arrows), the Starting Room
Selection Screen, the choice of difficulty level at the start and a number of
special effects related to the completion of the game. He also created the loading
screen. Ian, in turn, added one more guardian (which appears in a room that is not
normally accessible during gameplay…), an additional tune coded by Richard Hallas
and some technical tweaks. Finally, Andy created a custom BASIC loader and the
final TAP and TZX files of the game.
Following Andy's initial decision to make room 40 ('Master Bedroom') the last
screen in the game as far as the code is concerned, during the development of the
project a part of its challenge was always keeping everything below room 40's code
addresses. This has been achieved thanks to various optimisations and consolidation
of the code when new features were added.
By the time the project was ready for release, almost 1200 posts had been exchanged
between the contributors in the pertinent topic at jswmm.co.uk.
The game was released on Friday 26th January 2018, two years to the day after the
release of the authors' first joint project, 'Jet Set Willy: The Nightmare Edition'
(http://jswmm.co.uk/topic/161-file-jet-set-willy-the-nightmare-edition/).
----------------------------------------------------------------------
The game contains a number of features which go beyond the standard JSW48 game
engine (i.e. the game engine used by the original 'JSW'). Some of them are
described below.
Preamble: In the original 'JSW' game engine, the items are handled as follows:
- The item definitions are stored in a table across pages #A4 and #A5 of the code
(two definition bytes per item, one in each half of the table). The table is
populated 'from the last entry downwards', i.e. Offset #FF (the addresses
#A4FF/#A5FF), then Offset #FE, etc.
- The address #A3FF is a fixed variable which is used as an index pointing at the
first item. It holds the low byte of the address of the first entry defined in each
half of the table (so for example, in a game with three items, #A3FF would hold the
value #FD - meaning that the first item's definition bytes are found at the
addresses #A4FD and #A5FD).
- The 'Game initialisation' routine, which starts at #87CA, picks up the value of
#A3FF and uses it to establish a loop, pointing the HL register-pair at each
defined item entry in the half of the Item Table occupying page #A4 in turn, and
setting Bit 6 for each byte. This bit acts as the item's Collection Flag. The L
register is incremented during each pass through this loop, in order to point HL at
the next item entry (H has a fixed value of #A4 throughout). The loop is sustained
until L is incremented past #FF to #00 (thus setting the Zero Flag), at which point
all items will have been marked as 'uncollected' (Bit 6 set).
- The 'Game initialisation' routine also initialises the value of the address
#85DE. This is a counter of the number of items remaining, expressed as a negative
number in the range -256 (#00) to -1 (#FF). At the beginning of each game, the
value of #A3FF is copied to #85DE, and then the former remains fixed during the
course of the game, whilst the latter is incremented during runtime each time an
item is collected.
- The 'Game initialisation' routine initialises the values of the addresses #857C
to #857E to #30. These three addresses are displayed on the physical screen as an
ASCII counter of the number of items collected throughout the game (beginning with
'000').
- The address #85DF acts as an indicator of the current Game Mode. This is
initialised to zero, to indicate that there are items left scattered around Willy's
house, and he cannot go to bed until he has collected them all.
- Once the game is running, the routine at #93D1 is called during every pass
through the game's Main Loop. This routine picks up the 'Index of the first item'
from #A3FF, and then sets up a loop via HL, to consider each item defined in the
game in turn.
- If an item is located in the room currently occupied by Willy, AND if that item
is flagged as still being uncollected, then the routine checks whether the cell in
which the item is located (determined by the rest of the relevant entry in the Item
Table at pages #A4 and #A5) contains white INK. This is used as an indicator that
Willy (whose colour attribute is white) has touched the item under consideration.
- If there is no white INK present, then the item remains uncollected and therefore
its graphic is drawn at the appropriate coordinates.
- If white INK is present, then the item is collected, which involves several
aspects: the on-screen ASCII tally (#857C-#857E) is incremented, a sound effect
takes place, the pertinent entry in page #A4 of the Item Table has its Bit 6 reset
(marking it as 'collected'), and finally the value of the internal item counter
(#85DE) is incremented.
- If that last step has incremented the value of #85DE 'up' to #00, then the Zero
Flag will be set, and this is interpreted by the code as a sign that there are no
items remaining uncollected. Willy has finished tidying up his house and is now
allowed to go to bed. The value of the Game Mode Indicator is set to #01, which
means that Maria will no longer be present in the Master Bedroom, preventing Willy
from reaching his bed!
In the 'Jet Set 40-40' game engine, the items are handled as follows:
- Items appear in the game in sets of 40 (one per room); each set has to be fully
collected before the next set appears.
- The item definitions are still stored in a table across pages #A4 and #A5 of the
code, but the items are arranged sequentially in (reverse) room number order. If a
room's number is expressed as a negative number, then this gives the index to point
at the first item definition for each room, and then the entries for the next three
items for that room can be accessed in turn by subtracting 40 from the entry for
the previous item.
- Thus the entries in the Item Table from #A460/#A560 to #A4FF/#A5FF are used to
store the item definitions, e.g. the first data entry in the table, representing
the fourth item in Room 40, is located at the addresses #A460 and #A560: -{40 + (4-
1) x 40} = -160 = -#A0 ≡ #60: hence Offset #60. (Note that all addresses prior to
that in the Item Table, which are not used for item data - i.e. the addresses
#A400-#A45F and #A500-#A55F - have been 'recycled' and used by the program for
various other purposes.)
- The use of the address #A3FF as a fixed 'Index to the first item' variable is no
longer needed. #A3FF is redesignated as a runtime variable, keeping track of the
current Item Set that Willy is collecting. Its default value in the game file is
still set to #60 (so that the JSWED editor, which isn't aware of the changes to the
game engine, still respects #A3FF's old purpose and therefore displays all the
items in its GUI).
- However, as soon as the game is loaded, the 'Game initialisation' routine sets
the value of #A3FF to #01 (representing Item Set 1). The routine then points the HL
register-pair directly at the address #A460, before performing the same loop as
occurs in the original 'JSW', to set the Collection Flag (Bit 6) for each item's
entry in page #A4 of the code.
- The 'Game initialisation' routine sets the value of #85DE to an initial value of
#D8, which equates to a negative decimal value of -40. The variable at #85DE
performs a similar role as it did in the original 'JSW', except that in 'Jet Set
40-40' it keeps a tally of the number of items remaining to be collected FROM THE
CURRENT ITEM SET.
- The 'Game initialisation' routine also initialises the values of the ASCII
counters at #857C to #857E. However, the number of items in each set is limited to
two digits, so only #857D and #857E are 'zeroed' to #30 and used for the purpose of
tallying items collected. The address #857C is redefined as the ASCII counter of
the current Item Set under consideration, and is therefore assigned an initial
value of #31 (the ASCII character code for '1').
- As in the original 'JSW', the address #85DF acts as an indicator of the current
Game Mode, and it is initialised with a value of #00.
- Once the game is running, the routine at #93D1 is called during every pass
through the game's Main Loop. This item-handling routine has been restructured, so
that it only picks up the value of one pair of entries from the Item Table (the
corresponding offsets in pages #A4/#A5), representing the single item from the
current Item Set in the room that Willy is presently occupying (the current room
number variable being stored at the address #85CB). This arrangement gives rise to
a noticeable speeding up of the running of the game, since the program is no longer
needlessly taking into consideration every single item in the whole game, during
each time-frame of the game!
- However, when Willy clears the final item from the Item Set currently under
consideration, the program jumps to a new piece of code at #96F4, to handle the
transition between Item Sets. Depending on the circumstances, flow of execution
here branches off in two different directions:
- If Willy has just finished collecting Item Set 1, 2 or 3, then the 'Current Item
Set' variable at #A3FF is incremented, along with the on-screen ASCII 'Item Set'
counter at #857C. But the 'Number of Items Remaining' counter (#85DE) is reset back
to #D8 (-40), so that this variable can begin to count the next set of items, and
the on-screen ASCII 'Items Cleared' tally (#857D-E) is reset back to '00' for the
next Item Set.
- If Willy has just finished collecting the final Item Set (Set 4), then his
mission is complete, and the Game Mode Indicator at #85DF is incremented to #01 to
move Maria out of the way of Willy's bed.
- There are also some special effects which take place during the transition
between Item Sets / Game Modes. There now follows a disassembly of the restructured
item-handling routine and the 'Next Item Set' code.
At #93D1, 'Draw the item in the current room, or collect it if Willy is touching
it':
But if the item has encountered white INK, then the item is collected as flow of
execution of the routine continues:
If the command at #96FF did not have the effect of setting the Zero Flag, then flow
of execution proceeds straight to #9701:
In the original 'JSW' code, at #8929 in the 'Initialise the current room' routine,
there is the following command: LD A, #08.
In 'Jet Set 40-40', the 'Game initialisation' routine sets the operand of the
equivalent command (which is now at #891A-B, due to code shuffling) to a value of
#03 at the start of each game. This means that at the beginning of the game, there
are a maximum of three entities per room.
However, once each set of items has been cleared by Willy, this game parameter is
increased (by editing the value of address #891B - see the disassembly in the
previous section), so that the occupancy limit of each room expands when the game
moves on to the next Item Set. This gives rise to a 'Multiplying Guardians' effect,
ratcheting up the difficulty level of the game as the player progresses.
The general rule is that two further guardians are added to each room, every time
the game proceeds to the next Item Set. However, the initial occupancy rate during
the first Item Set is three, rather than two guardians, to allow the tripartite
'Evil Priest' guardian in rooms such as 'The Chapel' to appear in all its glory
from the outset.
Note that after moving on to the next Item Set, the player will not observe an
immediate increase in the number of guardians per room; the effect does not
manifest itself until the next time that Willy moves into a different room (or he
is 'respawned' after losing a life).
The way the in-game tune is chosen in each room in 'Jet Set 40-40' mirrors the
solution created jointly by Daniel Gromann and Ian Rushforth which had first been
applied in the Special Edition of 'Willy's New Mansion' (2016).
Offsets #DF and #E0 in each room's data (which were unused in the original 'JSW')
specify the (reversed) address of the in-game tune to be used in this room. The
instruction at #8B4D - #8B4F (changed from LD HL,#865F [21 5F 86] to LD HL,(#80DF)
[2A DF 80]) loads this address (from the room's data copied into the room buffer)
so that the routine which plays a note of the in-game music knows where to look for
the tune (instead of the permanent address #865F, the start of the tune is defined
by the value of Offsets #DF and #E0 in the room buffer). The appropriate values for
the start of each tune have been set in each room's data.
The way the colour of arrows is defined in each room in 'Jet Set 40-40' mirrors the
solution created jointly by Ian Rushforth and Daniel Gromann which had first been
applied in the Special Edition of 'Willy's New Mansion' (2016).
In the original 'JSW', all arrows are white. The following code sets the arrow's
colour there:
9286 7E LD A,(HL)
9287 F6 07 OR #07 set the INK to #07 (white) regardless of the
background's INK colour ('background' here meaning whatever character square the
arrow is passing through)
9289 77 LD (HL),A set the INK to white at the arrow's location
In 'Jet Set 40-40', the code has been modified in the following way:
9286 3A ED 80 LD A,(#80ED) pick up the arrow's attributes from Offset #ED in the
room buffer
9289 77 LD (HL),A set these attributes at the arrow's location
As a result, the arrow's attributes are defined in Offset #ED of each room (unused
in the original 'JSW'). In rooms with no arrows the value of this offset has been
set to #00 (it could be anything, as it has no bearing on the game).
The code which deals with this issue starts at #A50C. The code modifies the values
of the first byte of (two-byte-long) guardian specifications within the room data
(i.e. in the #..F0 - #..FF range). If the player chooses 'Y', proper values are
written for twelve most difficult guardians (so that they will appear in this game,
even if they had been wiped out by a choice of 'N' at the start of the previous
one). If the player chooses 'N', the first byte of data of eleven of these
guardians is NOPped out (so that they will not appear in this game, being replaced
by 'blank guardians'), and the first byte of data of one guardian is modified (so
that another entity appears in place of the one from the 'maximum difficulty'
version).
The screen which prompts the player with 'Maximum difficulty? Y/N' will also
respond to the player pressing the '6' and '7' keys for the 'Y' and 'N' options,
respectively. This has been implemented by Ian Rushforth in order to make it
possible to map the Vega control buttons to all of the ZX Spectrum keys used by the
game (the mapping had to be done for numerical keys for each of the ten starting
rooms and the 'Y/N' difficulty options - twelve options in total, while there are
only eleven buttons on the Vega unit). Ian also provided a code which checks
whether the player is still holding the '6' or '7' keys, and does not allow them to
proceed until they have let go of the key in question (the code is at #99CE -
#99D9). This prevents a situation in which, due to one of these keys being pressed
for too long, a starting screen of either 'Priest's Hole' (option 6) or 'Tree Top'
(option 7) would be inadvertently selected on the Starting Room Selection Screen.
The code which deals with this screen starts at #86AA. When the starting room is
chosen, not only is the current room number set (which in the original 'JSW' is
done at #87EA - #87EE), but Willy's pixel y-coordinate (in the original 'JSW'
initialised at #87E5 - #87E9), Willy's attribute coordinates (in the original 'JSW'
initialised at #87EF - #87F4), Willy's facing direction (not initialised in the
original 'JSW') and frame of animation (not initialised in the original 'JSW') are
defined as well. As a result, for each of the rooms which may be selected, Willy
always starts the game in exactly the same position and stance (in the original
'JSW', Willy's animation frame and the direction he is facing at the start of a
game are whatever they were when he died in the previous game).
Thanks to the code provided by Ian, mentioned above, after the player presses one
of the numerical keys on this screen, the program will not proceed to load the
starting room until the player has let go of that key. This prevents a situation in
which, due to '0', '5', '6', '7' or '8' being pressed for too long, Willy would
jump or move prematurely after the starting room has loaded.
These were added to 'Jet Set 40-40' by Daniel. It was a relatively easy task thanks
to Richard Dymond ('SkoolKid')'s disassembly of 'Skool Daze' (see the links in
section I above). Some necessary adjustments were made to the code to accommodate
it in 'Jet Set 40-40'. The routine which plays the tune is at #8356 - #837E and
#B496 - #B4B0. The data for the tune played after the starting room has been
selected is at #A400 - #A421, and the data for the tune played upon reaching the
bed in 'Master Bedroom' after all items have been collected is at #A422 - #A444.
Note duration and pitch data for the tunes is at #A500 - #A50B. The code which
launches the tune after the starting room has been selected is at #99C2 - #99C7
(with a call to #B4AA) and the code which launches the tune played upon reaching
the bed in 'Master Bedroom' after all items have been collected is at #B4B1 - #B4BE
(with a relative jump to #B4AA). The latter makes sure that the tune is played only
once, by checking the variable at #8FBF (otherwise the tune, which is triggered by
Willy's x-coordinate, would be played twice before he changes his x-coordinate at
the start of the toilet run - which would be too much).
----------------------------------------------------------------------
'Jet Set 40-40' is freeware, and all of its innovative elements may freely be
reused in other projects. If you do so, please acknowledge their authorship.
----------------------------------------------------------------------
We hope you enjoy playing 'Jet Set 40-40' as much as we did writing it!
If you have any queries, comments or general feedback, please contact us on the
email address below, or come and visit our Jet Set Willy & Manic Miner Community at
jswmm.co.uk to join in with Willy-based discussions! Do let us know you've had a go
at 'Jet Set 40-40', even without any specific comments - the biggest gratification
and encouragement for anyone designing free games is to know that someone else has
played them.
Andy Ford, Daniel Gromann & Ian Rushforth, 26th January 2018
projects@jswmm.co.uk