Skip to navigation

Elite on the BBC Micro and NES

Ship blueprints

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:

The ship identification poster

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:

#ShipConfiguration variable
1Sidewinder-
2ViperCOPS
3Mamba-
4Python-
5Cobra Mk III (bounty hunter)-
6ThargoidTHG
7Cobra Mk III (trader)CYL
8Coriolis stationSST
9MissileMSL
10AsteroidAST
11CanisterOIL
12ThargonTGL
13Escape podESC

The enhanced versions of Elite contain rather more ships; here's the list from the BBC Master version:

#ShipConfiguration variable
1MissileMSL
2Coriolis stationSST
"Dodo stationSST
3Escape podESC
4Alloy platePLT
5CanisterOIL
6Boulder-
7AsteroidAST
8SplinterSPL
9ShuttleSHU
10Transporter-
11Cobra Mk IIICYL
12Python-
13Boa-
14AnacondaANA
15Rock hermitHER
16ViperCOPS
17SidewinderSH3
18Mamba-
19KraitKRA
20AdderADA
21Gecko-
22Cobra Mk I-
23WormWRM
24Cobra Mk III (pirate)CYL2
25Asp Mk IIASP
26Python (pirate)-
27Fer-de-lance-
28Moray-
29ThargoidTHG
30ThargonTGL
31ConstrictorCON
32Elite logoLGO
33CougarCOU

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.