OXP standards

From Elite Wiki


The purpose of this document is to outline ways in which OXPs should be written and packaged to best make use of modern features and to avoid obsolete features, as the "best" way to implement many OXP features has changed since the 1.65 release. While the intent is that almost all obsolete features for OXP development will continue to exist in future 1.xx releases of Oolite, they will not receive further development and may have other disadvantages such as inefficiency, lack of features, or a tendency to encourage incompatibility between OXPs.

New OXPs should be written to the latest published standards version, or to the anticipated standards version if they are written using unreleased features from the next Oolite version. Existing OXPs should be brought closer to the latest published standards as maintainer time permits.

The standards document will be updated with each Oolite release. Anticipated standards for future releases will also be documented when known.


  • discouraged: while the OXP features for this way of doing things are not themselves obsolete, using them is this manner is not recommended as a better alternative exists.
  • obsolete: this feature is considered obsolete. No further developments will be made to it, existing bugs might not be fixed, depending on severity, and testing that it continues to work as expected will be limited. OXP authors should avoid this feature in new code, and try to replace it in existing OXPs.
  • recommended: this way of doing things is strongly recommended for all OXPs, especially new ones, and may replace a previously recommended method in a previous version.


The initial standards version is 1.77.1. A few general points which do not depend on Oolite version are mentioned first.



Every public release of the OXP is recommended to have a unique version number, such that the later versions have higher numbers than earlier versions. Even the smallest update to the OXP should give a new version number, to avoid confusion about exactly which code is being run. The version number is recommended to be placed in:

  • the name of the .oxp folder
  • the documentation files


It is recommended that the documentation of the OXP includes a statement of licensing to make clear if other people may redistribute the OXP or release modifications to it. If no license is included or stated elsewhere, this is legally equivalent to a ban on redistributing or modifying the OXP, and even were this not the case the community prefers to respect authors wishes for how their OXP is used, erring on the side of caution. The "Creative Commons" licenses are often used by authors wanting a relatively permissive and generally understood license.

Prefixing to avoid conflicts

All entries in the OXP are recommended to be prefixed with a string intended to be unique to the OXP, unless the entry is intended to override a core entry or one provided by another OXP. Entries in this context includes:

  • filenames of files in the AIs, Images, Models, Music, Scripts, Shaders, Sounds and Textures folders.
  • the this.name value of any script file.
  • the name of any key in descriptions.plist, missiontext.plist, shipdata.plist or shipyard.plist
  • the equipment key (e.g. "EQ_MYOXP_SCANNER") in equipment.plist
  • various script-accessible global properties such as mission variables, marker names, script_info keys, and so on.


The use of strict mode, activated by placing "use strict"; at the top of the file, is recommended for all JS files to avoid bugs.

All properties and methods of the this object within Javascript files are recommended to have a name beginning with the _ or $ character unless they are intended to be an event handler (e.g. this.shipWillEnterWitchspace) or are a standard property such as this.name. This will ensure that future versions of Oolite do not provide an event handler with the name of a non-handler property.


The version entry of the requires.plist file, unless the OXP specifically requires a bug fix present in a minor release of Oolite is recommended to refer to a major release - 1.76, 1.77, etc. to avoid unnecessarily preventing use of the OXP.

Version 1.77.1

OXP packaging

There are two common methods of packaging OXPs currently in use: in the first, a ZIP file contains the .oxp folder and other loose files, and in the second, the ZIP file contains a folder, containing the .oxp folder and other loose files. These methods are recommended. All packaging arrangements other than those two are discouraged, including the use of compression algorithims other than ZIP. OXPers if possible should try to ensure that OS-specific files and folders (Thumbs.db, __MACOSX, etc.) are not included. It is recommended that the ZIP file has a name including both the OXP's name and the version number.

It is recommended that important documentation for the OXP be placed both within the .oxp folder and in the loose files next to it when packaging the OXP, for best compatibility with the range of operating systems Oolite runs on.


Worldscripts - and other Javascript files if practical - are recommended to have a this.version property with the OXP version as its value, to aid debugging using Latest.log.

Legacy scripting and other obsolete keys

The old "legacy scripting" methods are all considered obsolete. This includes:

  • any use of the script.plist file or worldscripts with a .plist extension
  • any use of the script_actions key in any plist
  • the use of the conditions key in equipment.plist
  • the use of the conditions, death_actions, launch_actions, setup_actions or spawn keys in shipdata.plist
  • the use of a conditions array as the value of has_shipyard in shipdata.plist.

This functionality is all possible to replicate in Javascript.

The following shipdata.plist keys are considered obsolete.

  • port_dimensions
  • port_radius
  • old-style subentity definitions

All Javascript properties and methods beginning with the word legacy are considered obsolete.

Scripting equipment availability

The TL:99 hack for making equipment temporarily unavailable is obsolete. A condition script is now the recommended approach.

No in-flight mission screens

The use of mission screens in flight is considered obsolete due to a number of bugs.

Random name string expansion

The use of the %R description expansion for purposes other than generating planet descriptions is discouraged. %N is recommended instead as it has better randomness.

Accessing custom interfaces

The use of GUI screen switching combinations to access functionality is discouraged. Instead, when docked at a station, the interfaces screen is recommended for player-initiated access to functionality. In flight, primable equipment is recommended for the same purpose.

No zero-polygon models

The use of zero-polygon models (including those with non-zero vertices and lines) is considered obsolete. Visual Effects are recommended if a non-colliding entity is required.

Planet textures

The use of lat-long maps for planet textures is discouraged. Cube maps are recommended.

Mission map markers

The use of the new object syntax for mission.markSystem is recommended to avoid conflicts. The numeric syntax is considered obsolete.

Weapon facings specification

The weapon_facings key in shipdata.plist is recommended for all NPC ships.

Missile explosions

The AI command dealEnergyDamageWithinDesiredRange is obsolete as it has bugs especially apparent at low frame rates. The JS method dealEnergyDamage is recommended.

Note: See dealEnergyDamageWithinDesiredRange is broken (2008) for more on this. OXPs which were updated included Missile Spoof and Extra Thargoids.


The OO_TANGENT_ATTR preprocessor definition should never be used in shaders (using it is incorrect, not merely discouraged).

Version 1.80

OXP Packaging

It is recommended that the compressed OXZ format be used for distribution of expansion packs. A ZIP file containing an OXP folder as in the previous standards may also be provided. If practical, the OXZ file should be placed at a location where direct HTTP download is possible, as this allows it to be added to Oolite's OXZ index for automatic download and installation. Dependencies and conflicts between OXZs should be specified in the manifest.plist file. While it is not required, it is recommended that expansion packs distributed in OXP folder format also include a manifest.plist file.


The manifest.plist file now contains the version number, and the this.version property of Javascript files will be automatically set from this. The recommendation in the 1.77.1 standards to include an explicit this.version property now no longer applies.

HUD Capabilities

All HUDs are recommended to include the new HUD selectors drawWaypoints:, drawPrimedEquipment: and drawASCTarget: as soon as possible. All HUDs are recommended to include at least one multi-function display.

The use of multi-function displays (usually together with primable equipment) is recommended for displaying persistent in-flight information to the player. Previous methods involving repeated printing of console messages are strongly discouraged.

AI language

The use of plist-based AIs for non-trivial AIs is discouraged. Javascript AIs are recommended. Use of the Priority AI library to write AIs, especially the standard conditions and behaviours it provides, is useful to make ships fit in with the core ships and to have future improvements to AI incorporated easily. Alternative AI controller libraries released as OXPs may also be used.

Ship roles

The roles used in ship OXPs should consider the documented advice especially for the roles with light, medium and heavy variants, to ensure that appropriately powerful ships are added at each level. The use of the 'escort', 'hunter' and 'pirate' roles will generally require adjustment.

For ships intended to fit in to standard Oolite roles, the use of the auto_weapons key is recommended. See here for more detail

The use of pirate_victim_roles.plist to specify ships as "trader-like" is obsolete. role_categories.plist provides the same functionality in a more flexible way and is recommended.

System population

The use of any method other than the system populator functions to add entities to a system is discouraged (for example, calling system.addShips during the witchspace exit world event handlers). Repopulation of the system is recommended to use the system repopulator functions, though other event handlers may still be used when appropriate. It is recommended that the deterministic flag is used for stations intended to be (semi-)permanent to allow the player to save the game at those places.

Shipset OXP structure

Shipset OXPs are recommended to use like_ships of the template entries, entering only those keys which have changed from the core details. The specification of the role key by shipset OXPs is discouraged.

Station allegiance specification

OXPs adding stations are recommended to set the new allegiance property to assist the AI. If this is not set a value will be calculated algorithmically.

Sound file format

Sound files are recommended to be encoded as single-channel (mono) audio at 44KHz, as this allows the positional sound features to be used most effectively. Music and potentially other non-positional sounds might remain as stereo files. Sound packs should consistently use either mono or stereo encodings, not a mixture of both.


The use of the OO_REDUCED_COMPLEXITY macro in shaders is obsolete as the Reduced Detail setting is now only applied in non-shader modes.

Version 1.82


The manifest description can now contain multiple lines, with the second and subsequent lines being visible by pressing 'i' within the manager. It is recommended that manifests be updated to add extra information here.

HUD Capabilities

All HUDs are recommended to use drawSurround: with a color attribute, rather than the hard-coded colours of drawYellowSurround: and drawGreenSurround:

Market settings

Market definitions have changed considerably in Oolite 1.82. OXPs wishing to be compatible with both 1.80 and 1.82 may specify both the old and new keys and plists without conflicts. OXPs are recommended to use the new keys. See Trade-goods.plist and the pages linked from it for more information.

Injectors and torus

Injector and torus speeds are no longer a fixed multiple of normal flight speed. player.ship.injectorsEngaged and player.ship.torusEngaged are recommended to detect enabling of these flight modes.

Removed commodity aliases

The following manifest commodity aliases were removed in Oolite 1.82: liquor, wines, liquorWines, gemStones, alienItems. OXPs that used these aliases must replace them with liquor_wines, gem_stones or alien_items.


  • BB Thread: OXP Development Best Practices (2012-17)