Lib Config 101

From Elite Wiki
Revision as of 11:18, 24 May 2026 by Phkb (talk | contribs) (Spelling correction)
IconLib.png
Config for AddOns (List of OXPs with settings)

This guide is designed to help you add Library Config into your OXP.

Lib Config is a powerful tool that can make it super easy for players to customise your OXP in the ways you want them too. If they open your OXP and fiddle with things you *don't* want them to, all bets are off!

There are 3 possible parts to Library Config integration.
1. Dataset
2. Interface code
3. Notify code

1. Dataset

The dataset required for Library Config is a dictionary with several distinct parts. Let's look at an example:

 this._myConfig = {
   Name: this.name,
   Display: "Debug Options",
   Alias: "My Super OXP",
   Alive: "_myConfig",
   Notify: "$generalChanges",
   Reset: false,
   Bool: {
     B0: { Name: "_debug", Def: false, Hide: false, Notify: "$debugFlagChanges", Desc: "Turn on debug messages" },
     Info: "0: Turn on/off debug messages sent to the log file",
     Notify: "$generalFlagChanges"
         }
   SInt: {
     S0: { Name: "_myValue", Def: 0.3, Min: 0, Max: 1, Float: true, Hide: false, Notify: "$myValueChanges", Desc: "My decimal value" },
     Info: "0: Special decimal value used for important calculations",
     Notify: "$generalValueChanges"
         }
   EInt: {
     E0: { Name: "_myBitmask", Def: 0, Min: 0, Max: 15, OneOf: false, OneOfZero: true, Hide: false, Notify: "$myBitmaskChanges", Desc: ["Value 1", "Value 2", "Value 3", "Value 4"] },
     Info: "0: Controls special settings",
     Notify: "$generalBitmaskChanges"
         }
 };
Config for AddOns (example: BGS flags settings)
Flags are On/Off options, Values give a numerical range. (Old Hyperspace is added by Tsoj's newest version of BGS)
Config for AddOns (example: BGS values settings)
Values (D is the default setting, R shows the range)

The first line this._myConfig is the name we are giving to the dataset. It can be pretty much any combination of letters and numbers. Something meaningful is usually preferred.

This is followed by an = sign, and then an opening curly brace {, which signals what follows should be considered a dictionary, that is, key/value pairs, separated by commas. There is a closing curly brace at the end with a semi-colon }; to mark the end of the dictionary.

Please note: key names are case sensitive. name doesn't equal Name. All the key values in a Lib Config dataset are Capitalised, so if you're getting errors when creating your dataset, check the key names for the correct format.

The first key/value pair is for Name. This is the worldScript name of where our dataset is being held. We could enter it as text, but the more reliable and easier to maintain method is to use this.name as the value.

Next is Display. This is the text that will be displayed in the "Settings" column in the Config display. This can be any text, but long values will be truncated.

Next is Alias. This is an optional value, and if not supplied the script name (ie what was entered into the Name key above) will be used. Alias allows us to put something more human-readable on the screen. This can be any text, but again, long values will be truncated.

Next is Alive. This is the name of your dataset, the same name we entered on the first line. The only difference is that you don't put this in front of it. It's just the name of your dataset on its own.

Next is Notify. This is the name of a function in your worldScript file that will be called whenever the user finishes making changes to your settings through Lib Config. This item is optional and is only used in specific circumstances. If you need to make other changes to various aspects of your OXP (for instance, changing the colour of something the player will see immediately), you would add a function and put the name of it here in Notify. Then in your function you could check the values that might have changed and perform any addition tasks those changes require.

Next is Reset. This is an optional boolean value. It will add a "Reset to default" menu option to your settings page, and is the reason why all the settings about to be described have a Def key. If the user selects the "Reset to default" option, Lib Config will set all your values back to their Def value.

We now get to the Bool, SInt and EInt sections. This is where we tell Lib Config what data we want it to interact with, and how to do that interaction. Each of these is another dictionary object (ie key/value pairs).

We'll start with the easy one first: Bool.

Bool Section

The Bool section deals with boolean values. ie. values that are either true or false. When you open your settings in Lib Config, this is the "Show Switches" menu item. The structure of the Bool dictionary is:

Bn: where "n" is a number between 0 and 8. For example B0, B1 etc. Each of these are another dictionary, and they each define one boolean value.

Info: A text entry that adds some descriptive text to your boolean values screen. Generally this has been used to provide additional help and instructions that might be otherwise difficult to enter on an individual line.

Notify: The name of a function to call when the user leaves the "Show Switches" screen.

Each of the Bn dictionaries has the following key/value pairs:

Name: This is the name of your variable, and an accurate path to get to it. In it's most simple form, this can be something like _debug. What this means is there needs to be a definition in your script file of this._debug = false;, usually above the point where you're defining your Lib Config data (not that it will matter, but it makes it easier to read as a human).

Where is can get complicated is if you have a dictionary object with all your custom values in it. For example:

 this._myData = {
   debug: false,
   myValue: 0.3,
   myBitmask: 0
 };

In this example, the "path" to the debug flag is this._myData.debug. When it comes to the enter in your config, you would leave off the this. and just enter _myData.debug.

Next we have Def. This is short for "default", and indicates what the default value for our flag is. For a boolean value, it can be either true or false.

Next is Hide. This is an optional key. This allows the value to be defined but not displayed to the user. This will only be used in very edge cases, so edge I'm not sure I can think of one!

Next is Notify. This is an optional key, and is the same as the overall settings Notify, in that it is the name of a function in your worldScript. The difference is that this function will be called every time the user changes the value.

Finally, we have Desc. This is the text that will appear beside the value, explaining what it does. You can put whatever text you like here, but the space is short and long entries will be truncated.

SInt Section

The SInt section deals with numerical data, both integers (or whole numbers) and decimal values. When you open your settings in Lib Config, this is the "Show Values" menu item. The structure is basically the same as the Bool section:

Sn: where "n" is a number between 0 and 8. For example, S0, S1 etc. Each of these is another dictionary, and they each define one numeric value.

Info: A text entry that adds some descriptive text to your values screen.

Notify: The name of a function to call when the user leaves the "Show Values" screen.

Each of the Sn dictionaries has the following key/value pairs:

Name: As with the boolean entries, this is the name of your variable, and all the same rules apply.

Next we have Def, which is the default value for this variable. This can be whatever you need it to be, but it makes sense for it to have the same value as whatever you use in your definition. For example, if you have this._myValue = 15.5; in your script file, it makes sense to have Def: 15.5 in your Lib Config entry for that variable.

Next we have Min. This is the minimum value your variable can have. Attempting to enter a value below this will fail and no value will be changed.

After this is Max. This is the maximum value your variable can have. Attempting to enter a value above this will fail and no value will be changed.

Next is Float. This is a boolean value indicating whether the variable is a decimal (ie with decimal points). This is an optional setting, and if omitted the default is "false", which means Lib Config will treat the value as an integer, and any decimals entered by the user will be stripped.

The last 3 entries are the same as for the Bool section. Hide will hide the entry on the display, Notify is a function that will be called whenever the user changes the value, and Desc is the short text description for the value, with long entries being truncated.

EInt Section

The EInt section is the least used section of Lib Config, largely because bitmasks are confusing. What are bitmasks, you ask? Well, in Oolite we do deal with bitmasks a little bit. Let me show you a small snippet from a random shipyard.plist file:

 weapon_facings = 3;

The weapon_facings value is a bitmask. The possible values (other than zero) start at 1 and go up by a factor of 2 for each additional value. In the example from shipyard.plist, the possible values are 1 = Forward weapon, 2 = Aft weapon, 4 = Port weapon, and 8 = Starboard. So a value of 3 would mean 1 (forward) + 2 (rear), meaning only front and rear laser mounts.

Think of it like this: Imagine a panel of switches like this:

 [XXXXXXXXXX]

Where "X" is a switch. Each of those switches can be turned on an off, like this:

 [X..XXX..X.]

Where "X" is on and "." is off. Now, we could set up ten different flag varibles, which would work, but gets cumbersome when there are a lot of flags to track. So instead we can use a bitmask:

         125
      136251
  1248624862
 [XXXXXXXXXX]

The numbers here are read vertically (1, 2, 4, 8, 16, 32, 64, 128, 256, 512).

Converting the switch settings above into a single value would be (1 + 8 + 16 + 32 + 256) = 313

Given the fiddly nature of bitmasks, they are only likely to be used in certain conditions, but they can be a handy way to combine a lot of boolean values into one.

When it comes to the EInt section, there is only 1 entry: E0. The other sections can have 9, but in this section there is only one.

Info: This is the same as for the other sections, a text entry that adds some descriptive text to the data entry screen.

Notify: The name of a function to call when the user leaves the "Show Flags" screen.

The E0 dictionary has the following key/value pairs:

Name: Same as the other section. This is the name of your variable, and all the same rules apply.

Next we have Def, which is the default value for this variable.

Next we have Min. This is the minimum value your variable can have. With a bitmask, this will either mean 0 or 1. If the value can have no flags set, the minimum value is 0. If there must be at least one flag set, the minimum value will be 1.

After this is Max. This is the maximum value your variable can have. With a bitmask, this will be either the sum of all the bits, or the value of the last bit. Which one it is will depend on how you are using your bitmask. If you're keeping track of multiple flags, then you are likely using a bitmask where multiple bits are set. If you're tracking something that can have only one state at a time, but there are a number of states it could be, then only one bit is being set. The maximum value can only be determined by understanding how you are using your bitmask value.

The next two keys would never be in the settings at the same time.

OneOf means only one bit can be set at a time, but one *must* be set. You cannot have a zero value. If you can only have one bit set at a time, but "no bits" is a valid possibility, then you would use OneOfZero. Both of these can be excluded if you can have any number of bits set.

The next 2 entries are the same as for the Bool and SInt sections. Hide will hide the entry on the display, and Notify is a function that will be called whenever the user changes the value.

Desc is slightly different to the other sections. Rather than being one piece of text, this is an array of text items. The array should be the same size as the number of bits in your bitmask. So, if you have 10 bits, there should be 10 entries in the array. The text entries will be shown beside the bit values on the screen.

So, that's our Lib Config dataset established. Next, let's have a look at the interface code.

2. Interface code

The hard stuff has largely been done now. To add our settings into Lib Config, we put the following code into the startUpComplete function of our worldScript.

 this.startUpComplete = function () {
   // register our settings, if Lib_Config is present
   if (worldScripts.Lib_Config) {
     worldScripts.Lib_Config._registerSet(this._myConfig);
   }
 }

If you don't need to be notified when changes are made, that's it! However, there is one more worldScript function we should add.

 this.playerWillSaveGame = function () {
   if (worldScripts.Lib_Config) {
     missionVariables.MyOXP_debug = this._debug;
     missionVariables.MyOXP_myValue = this._myValue;
     missionVariables.MyOXP_myBitmask = this._myBitmask;
   }
 }

If the player makes changes that need to be saved with the game, this is the spot to put it. Here, we are only saving the values if Lib Config is installed. If Lib Config is not present, the only way to change the values would be by editing the worldScript itself. If someone does that, they probably wouldn't want the values saved - they're making a global change, which probably shouldn't be overwritten by saved data.

If we're saving the data, we should also load it, so:

 this.startUp = function () {
   if (worldScripts.LibConfig) {
     if (missionVariables.MyOXP_debug) this._debug = missionVariables.MyOXP_debug;
     if (missionVariables.MyOXP_myValue this._myValue = parseFloat(missionVariables.MyOXP_myValue);
     if (missionVariables.MyOXP_myBitmask = this._myBitmask = parseInt(missionVariables.MyOXP_myBitmask);
   }
 }

3. Notify code

Adding the notify functions would only be required if you defined one in your dataset. What goes into them will be unique to your OXP. But for example:

 this.$debugFlagChanges = function() {
   log(this.name, "Debug flag is now set to " + this._debug);
 }

And that's it! Hopefully this guide has helped you unlock some of the potential in Library Config, and made the process of exposing internal settings a little bit easier.