Specifications for all the different types of ship in the universe
Every ship in Elite has a blueprint that defines that ship's characteristics (note that in this context, "ship" refers not only to ships, but also cargo canisters, space stations, escape pods, missiles and asteroids). These blueprints are the in-game equivalent of the last section of the Space Traders Flight Training Manual - a real life version of "Jane's Galactic Ships and Remote Colonial Construction, 5th Edition, 3205" (pub. Trantor House).
This is such an important aspect of Elite that the original game came with a poster showing the range of ships available in the BBC Micro cassette version:
Let's take a look at how ship blueprints are implemented in Elite.
Ship blueprints
---------------
There is a lookup table at XX21 that contains the addresses of all the ship blueprints used in the game. Ship type 1 (the Sidewinder at SHIP_SIDEWINDER) is first in the table, then ship type 2 (the Viper at SHIP_VIPER) is next, and so on up to ship type 13 (the escape pod at SHIP_ESCAPE_POD). For all ships except the Python, the blueprints themselves are stored in sequence just after the table; the Python is stored at SHIP_PYTHON, just above screen memory at &7F00.
The 13 ship types in the BBC Micro cassette version are as follows, along with the configuration variables where they exist:
# | Ship | Configuration variable |
---|---|---|
1 | Sidewinder | - |
2 | Viper | COPS |
3 | Mamba | - |
4 | Python | - |
5 | Cobra Mk III (bounty hunter) | - |
6 | Thargoid | THG |
7 | Cobra Mk III (trader) | CYL |
8 | Coriolis station | SST |
9 | Missile | MSL |
10 | Asteroid | AST |
11 | Canister | OIL |
12 | Thargon | TGL |
13 | Escape pod | ESC |
The enhanced versions of Elite contain rather more ships; here's the list from the BBC Master version:
# | Ship | Configuration variable |
---|---|---|
1 | Missile | MSL |
2 | Coriolis station | SST |
" | Dodo station | SST |
3 | Escape pod | ESC |
4 | Alloy plate | PLT |
5 | Canister | OIL |
6 | Boulder | - |
7 | Asteroid | AST |
8 | Splinter | SPL |
9 | Shuttle | SHU |
10 | Transporter | - |
11 | Cobra Mk III | CYL |
12 | Python | - |
13 | Boa | - |
14 | Anaconda | ANA |
15 | Rock hermit | HER |
16 | Viper | COPS |
17 | Sidewinder | SH3 |
18 | Mamba | - |
19 | Krait | KRA |
20 | Adder | ADA |
21 | Gecko | - |
22 | Cobra Mk I | - |
23 | Worm | WRM |
24 | Cobra Mk III (pirate) | CYL2 |
25 | Asp Mk II | ASP |
26 | Python (pirate) | - |
27 | Fer-de-lance | - |
28 | Moray | - |
29 | Thargoid | THG |
30 | Thargon | TGL |
31 | Constrictor | CON |
32 | Elite logo | LGO |
33 | Cougar | COU |
Each ship blueprint defines a whole range of attributes, such as the ship's maximum speed, the number of missiles it can carry, and the size of the target area we need to hit with our laser. It also contains data that's used when managing the ship once it's spawned inside our local bubble of universe, like the maximum size of the ship line heap.
The blueprint also contains all the data we need to draw the ship on-screen. This includes the ship's vertices, edges and faces, the visibility distances, and the face normal scale factor, all of which are used in the ship drawing routine at LL9. See the deep dive on drawing ships for more details.
Ship characteristics
--------------------
For each ship blueprint, the first 20 bytes define the main characteristics of this ship type. They are as follows:
* Byte #0 Maximum number of cargo canisters released when destroyed * Byte #1-2 The ship's targetable area, which represents how far the ship can be from the centre of our crosshairs and still be locked onto by our missiles or hit by our lasers, as described in the HITCH routine (16-bit value, 1 = low byte, 2 = high byte) * Byte #3 Edges data offset low byte (offset is from byte #0) * Byte #4 Faces data offset low byte (offset is from byte #0) * Byte #5 Maximum heap size for plotting ship = 1 + 4 * max. no of visible edges * Byte #6 Number * 4 of the vertex used for the ship's laser position, for when the ship fires its lasers * Byte #7 Explosion count = 4 * n + 6, where n = number of vertices used as origins for explosion clouds * Byte #8 Number of vertices * 6 * Byte #9 Number of edges * Byte #10-11 The bounty awarded for the destruction of this ship in Cr * 10 (16-bit little-endian value, 10 = low byte, 11 = high byte) * Byte #12 Number of faces * 4 * Byte #13 Visibility distance, beyond which we show the ship as a dot * Byte #14 Maximum energy/shields * Byte #15 Maximum speed * Byte #16 Edges data offset high byte (can be negative and point to another ship's edge net) * Byte #17 Faces data offset high byte * Byte #18 Face normals are scaled down by 2 ^ this value to enable us to store more accurate fractional data in the table * Byte #19 %00 lll mmm, where: * Bits 0-2 = number of missiles * Bits 3-5 = laser power If we are hit by this ship's lasers, the damage taken is half the value of this whole byte, i.e. %000lllmm
Vertex definitions
------------------
Next come the vertex definitions. Each vertex is made up of eight values stored in six bytes, as follows:
* Byte #0 Magnitude of the vertex's x-coordinate, with the origin in the middle of the ship * Byte #1 Magnitude of the vertex's y-coordinate * Byte #2 Magnitude of the vertex's z-coordinate * Byte #3 %xyz vvvvv, where: * Bits 0-4 = visibility distance, beyond which the vertex is not shown * Bits 7-5 = the sign bits of x, y and z * Byte #4 %ffff ffff, where: * Bits 0-3 = the number of face 1 * Bits 4-7 = the number of face 2 * Byte #5 %ffff ffff, where: * Bits 0-3 = the number of face 3 * Bits 4-7 = the number of face 4
Edge definitions
----------------
Then we have the edge definitions. Each edge is made up of five values stored in four bytes, as follows:
* Byte #0 Visibility distance, beyond which the edge is not shown * Byte #1 %ffff ffff, where: * Bits 0-3 = the number of face 1 * Bits 4-7 = the number of face 2 * Byte #2 The number of the vertex at the start of the edge * Byte #3 The number of the vertex at the end of the edge
Face definitions
----------------
Finally we have the face definitions. Each face is made up of four values stored in four bytes, as follows. Note that the visibility distance works in the opposite way for faces than for the ship, vertices and edges, in that the face is always shown when it's further away than the visibility distance.
* Byte #0 %xyz vvvvv, where: * Bits 0-4 = visibility distance, beyond which the face is always shown * Bits 7-5 = the sign bits of normal_x, normal_y and normal_z * Byte #1 Magnitude of the face normal's x-coordinate, normal_x * Byte #2 Magnitude of the face normal's y-coordinate, normal_y * Byte #3 Magnitude of the face normal's z-coordinate, normal_z
To make the source code easier to follow, we use three macros (called VERTEX, EDGE and FACE) that let us separate out the different values, and which squash the data into the above bytes at compile time.