packaging

Xanadu software packages


The _xanadu-package script is a suitable wrapper for all applications and data destined for use in the user memory portion of a Companion or ATOS/CX main controller. This is appropriate for nearly all types of custom software, including:

  • Most sideloaded LSL applications
  • Arabesque and LSLisp code
  • Personas
  • Vox filters and dictionary data
  • Removable package signatures (a part of software packages; see below)
  • Web folder directives

Noteworthy exceptions include:

  • Devices (these should be used directly without any sort of wrapper)
  • Device firmware (these require a different wrapper; see below)
  • Voice schemes (these must be manually placed in the speaker prim)
  • Chat tone markers (these can be specified by UUID within a persona, or manually placed in the speaker prim and referenced by name)
  • _warp-system replacements (these can be manually installed in the controller's root prim or the CSU)
  • Static menu assets (these need to be installed with a system installer or manually in the root prim)
  • Replacements for core animations (manually installed in the root prim)
  • Key OS add-on modules that need high-frequency i/o with system libraries, like TESI and ATOS/E (these use special system installers)

building a Xanadu software package


To create a software package, put the _xanadu-package script into a prim created by you, called the package disk. During installation or updating, this disk will be transferred from the package server to the controller, and then rezzed by the controller. You are encouraged to make the package prim resemble some kind of physical media such as a CD-ROM or cassette tape. Official system packages are currently distributed on prims that look like NeXT optical discs. If your package has fewer than five scripts, it should be viable to set the object to Temporary, guaranteeing it does not linger unduly in case of a failed installation.

Package objects must be named according to the syntax <name>_<version>, e.g. instructor_1.0. If you wish to include a word separator in a package name, do so using a hyphen, e.g. esamir-personas_2.0.

A typical package will also contain:

  • The package info file. This is a notecard named <name>_<version>_info, e.g. instructor_1.0_info. This is a human-readable read-me file describing what the package contains, who created it, change log information, etc. Two copies of the info file are needed: one included inside the package, and one uploaded onto the installation server along with the package. Info files need both the copy and transfer permissions enabled to be properly usable.
  • The package manifest file. This is a notecard named ~<name>_<version>, e.g. ~instructor_1.0. The contents should be a list of the files that the package installed, separated by blank lines, for example:

    instructor-core
    i_example-data-for-instructor
    instructor_1.0_info
    ~instructor_1.0

    When the package is removed or updated, the controller will read through the manifest file and delete each inventory item from user memory that it names. Any files not named will be left behind. If the manifest file is absent, the OS will not be able to remove it at all. Manifest files should be distributed with both copy and transfer permissions enabled.
  • The payload. These are your actual files, the ones you want to be usable on the recipient's controller. If you are distributing onto the controllers of others from a server you own, scripts need only copy permissions; if you are distributing via someone else's server (such as the public xnebula:0 server in Eisa) then scripts need copy/transfer permissions. Notecards cannot be read reliably without copy/transfer permissions and should be distributed as such.

version number standard


Although version numbers may superficially resemble decimal fractions, they are actually a distinct numbering system with an infinite* radix. For example, the decimal "3.10" comes before "3.9", but the version number "3.10" comes after "3.9". When the package manager compares such numbers to decide which version is newer, it uses this convention, evaluating each segment (separated by periods) from left to right until it finds a mismatch. 6.0.0.0.9999999 is therefore smaller than 6.0.0.1.0.

Missing segments are treated as zero, so 1 is equal to 1.0.0.0.

This design allows for negative numbers to be used on a per-segment basis: 6.-1 is lower than 6.0, but higher than 5.999999. Official NS packages sometimes use negatives to indicate pre-release versions. For legibility, these are usually substituted according to the following table:

stringmeaningvalue
rcrelease candidate.-1.
bbeta or build.-2.
aalpha.-3.
mmilestone.-4.


Thus, 8.0m999 comes before 8.0a1. Note also that 8.0rc999 ( = 8.0.-1.999) comes before 8.0.

* Each segment is limited to the range of a signed 32-bit integer for implementation reasons.

distributing a Xanadu software package


  1. Ensure that the package prim itself is set to have the same permissions as your payload. This normally means copy/transfer, though you may be able to get away with copy-only in certain contexts, such as manually-distributed packages for paid software.
  2. If the package is intended to be acquired automatically (and is free), drop the package and its matching info notecard into the package server. Up-to-date package servers, including diagnostics beds, will automatically detect and delete packages with matching names but inferior version numbers.
  3. If the package is not intended to be acquired automatically (because you wish to charge a fee for it), then provide it to your customers with a readme explaining how to install it using the cache method:
    1. Drop your controller on the ground.
    2. Place the package into the controller.
    3. Pick the controller back up.
    4. Unpack the cached package with @xanadu unpack <name>

Full-permissions payloads: Contributing open-source packages to the community can be a valuable teaching resource for enabling other developers to learn how to code devices and applications for NS ecosystems. It is also very useful to be able to modify data files, e.g. customizing mantras and dictionaries. But be aware that once you distribute a full-perm inventory item with your name on it as a creator, that type of inventory item can no longer be reliably assumed to be untampered. This is why NS doesn't rely upon "trusted creator" device filtration, as it is trivial to circumvent, although it is part of the OS and device update authentication process.

creating a Xanadu device firmware package


This feature is still currently in development.

preparing a device for distribution


Devices using the light bus must update this channel when worn by a new avatar, and usually also send 'add' commands over the light bus to trigger connections into the controller. For minimal redundant code execution, try:

string device_name = "widget";
integer channel_lights;
key robot;

default {
  changed(integer w) {
  if(w & CHANGED_OWNER)
    llResetScript();
  }

  state_entry() {
  llListen(channel_lights = 105 - (integer)("0x" + llGetSubString(robot = llGetOwner(), 29, 35)), "", "", "");
  if(llGetAttached())
      llRegionSayTo(robot, channel_lights, "add " + device_name);
  }

  on_rez(integer n) {
  if(llGetOwner() == robot && llGetAttached())
      llRegionSayTo(robot, channel_lights, "add " + device_name);
  }
}


marketing your NS-compatible work


See the third-party products policy page on NSIS.