The nbsConfig Build Notecard Format (BNF) is a format used for "build" notecards in products that use nbsConfig. This notecard format is similar to INI files and TOML with some tweaks for optimizing parsing into the enLSD linkset data format used by the En LSL Framework.
This document is formatted as a syntactical reference to help with debugging configuration notecard problems. If you are attempting to configure a product that uses nbsConfig, you should first refer to the comments in the notecard and the product's user manual to understand the configuration values that the product uses; the examples below are only a definition of the nbsConfig specification and aren't necessary unless you are running into errors when loading an nbsConfig build notecard.
nbsConfig uses "build" notecards to define configuration parameters that are editable by the end-user and need to be persisted across script resets. Typically, this notecard is any notecard in a prim's inventory (or, for some products, the root prim's inventory) that includes the word "build" in the notecard's name. In some cases, the product may use a different naming scheme, or may have multiple notecards; see the product's user manual for details.
When you edit a build notecard, a script in that object - typically a "config" script - automatically parses the notecard and loads its data into the object's linkset data using the enLSD library. A special category of enLSD-formatted linkset data pairs is reserved for nbsConfig use. When the notecard is loaded, or in certain other circumstances like unlinking the prim, all previous build values are erased and the notecard's data replaces it. This allows scripts to rapidly read build configuration data from the linkset data store instead of needing to parse through the notecard every time to find it.
Some products that use nbsConfig also have "remote" configuration values that are edited via Web Setup; see the product's user manual for more information on this configuration method.
Each line of an nbsConfig build notecard must be one of the following line types:
A comment line always starts with the #
character:
# This is a comment.
# This is also a comment (leading whitespace is ignored).
#### This, too, is a comment (only the first # character is read; everything else is ignored).
Comment lines are completely ignored when parsed.
Unlike INI and TOML files, nbsConfig does not support inline comments, since they are more complex to parse:
key = "value" # This is NOT a valid comment and will result in an error; the entire line will be ignored!
Most lines in build notecards are key-value pairs, separated by a =
character:
key1 = "value1"
key2 = "value2"
key3 = "value3"
Since nbsConfig build notecards use the enLSD library, which uses lists instead of strings as key-value names for flexibility, keys can also contain multiple elements separated by the .
character. If you need to include a .
character as part of the key itself, wrap the element in quotes:
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["category", "subcategory"], "value")
category.subcategory = "value"
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["domain.tld"], "value")
"domain.tld" = "value"
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["websites", "northbridgesys.com"], "value")
websites."northbridgesys.com" = "value"
There is no internal check for duplicate keys, even when using sections (see below) - the lowest line in the notecard will always take priority:
same_key = "this value will be overwritten"
same_key = "this value will also be overwritten"
same_key = "this value will be the ultimate value written to the key"
The =
character is a special character and can never be used in a key, even if quoted (although it can be used in a value):
# The following lines are NOT valid and will throw an error:
invalid=key = "value"
"also=invalid=key" = "value"
# The following line is valid:
value_equals_one = "value=1"
Whitespace is ignored in keys unless inside a quoted element, and is trimmed from the start and end of a value unless quoted:
# All of these are equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["category", "subcategory"], "value")
category.subcategory = "value"
category . subcategory = "value"
"category"."subcategory"="value"
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, [" leading_space"], " value")
" leading_space" = " value"
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["internal space"], "value")
"internal space" = "value"
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["internal space"], "value"), but isn't recommended
internal space = "value"
# All of these are equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["Hello, Avatar!"], "Touched.")
"Hello, Avatar!" = "Touched."
"Hello, Avatar!" = "Touched."
"Hello, Avatar!"="Touched."
Values can be of any LSL type, since everything is stored in linkset data as a string anyway:
example_string = "Hello World!"
example_key = "968262b6-d22f-482f-9dfb-ceb5bf9ad405"
example_integer = 5
example_float = 3.14159
example_vector = <0.0, 0.0, 180.0>
example_rotation = <0.0, 0.0, 0.0, 0.0>
Lists as values are supported; they must start and end with [
and ]
characters. Note that these lists are converted internally to enList string-lists for storage, so they can accept any characters or values inside them, except quotes due to how nbsConfig parses the line:
example_list = ["a", 1, "b", 2, "c", 3]
# Whitespace is ignored between elements, so these lists will also result in the same values:
example_list = ["a" , 1 , "b" , 2, "c" , 3]
example_list = ["a",1,"b",2,"c",3]
Boolean values are supported; they must be unquoted values that start with t
, f
, y
, or n
(case-insensitive) and will be converted into "1" or "0" for storage:
# These are all internally converted to "1", although you probably shouldn't do some of these:
truthy = 1
truthy = true
truthy = t
truthy = TRUE!!!!!
truthy = the squirterrrrrrrrrrrrrrrrrrrrrrrrrrrrr
truthy = yes
truthy = y
truthy = Yeag
truthy = yeah, nah, yeah mate
# These are all internally converted to "0", though, again, use your judgement here:
falsey = 0
falsey = false
falsey = f
falsey = F minus minus
falsey = franklin delano loafing, our nation's laziest president
falsey = no
falsey = n
falsey = Nope
falsey = nah, yeah, nah mate
# This is left as "true":
true_string = "true"
# This is left as "no":
no_string = "no"
Strings must be surrounded in quotes, since the parser will check unquoted values as potential booleans and/or strip whitespace unexpectedly, but unquoted strings will not throw an error:
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["unquoted_string"], "Hello World!"), but do not do this:
unquoted_string = Hello World!
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["unquoted_whitespace_string"], "This string should have 8 spaces in front of it."), so do not do this:
unquoted_whitespace_string = This string should have 8 spaces in front of it.
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["unquoted_key"], "968262b6-d22f-482f-9dfb-ceb5bf9ad405"), but do not do this:
unquoted_key = 968262b6-d22f-482f-9dfb-ceb5bf9ad405
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["unquoted_key_starting_with_f"], "0") as a "falsey" boolean, so do not do this:
unquoted_key_starting_with_f = ff9f95f6-32e9-4a19-9243-94d62caa4061
Constants like PI, ZERO_VECTOR, ZERO_ROTATION, etc. are not supported and will result in the literal string being written instead (there are simply too many of them to check for!):
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["constant_zero_vector"], "ZERO_VECTOR")
constant_zero_vector = ZERO_VECTOR
The "
character is a special character and, except for quoted values, can never be used inside a string:
# The following lines are NOT valid and will throw an error:
invalid = "Bob says, "This won't work.""
invalid = "This won't work, even with \"escaped quotes\", since the parser can't understand those."
invalid = Even though strings can be unquoted, "this" still won't work.
A section header is a special line that starts with a [
and ends with a ]
(whitespace is ignored). When a section header is used, all keys thereafter will have the section header prepended to them.
This can be used for categories, like so:
[products]
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["products", "Product A"], "b9d1b510-6b1a-4826-adb4-e19c4c7edacc")
"Product A" = "b9d1b510-6b1a-4826-adb4-e19c4c7edacc"
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["products", "Product B"], "431f8d9d-8a87-425f-aa8e-7d9aa4185c36")
"Product B" = "431f8d9d-8a87-425f-aa8e-7d9aa4185c36"
Section headers, like keys, can also contain multiple elements separated by .
characters, and those elements may contain quoted and unquoted elements:
[websites."My Favorites"]
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["websites", "My Favorites", "northbridgesys.com", "homepage"], "https://northbridgesys.com")
"northbridgesys.com".homepage = "https://northbridgesys.com"
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["websites", "My Favorites", "ntbigroup.com", "homepage"], "https://ntbigroup.com")
"ntbigroup.com".homepage = "https://ntbigroup.com"
Section headers don't stack; each section header resets which section is being used:
[category_a]
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["category_a", "key"], "value_a")
key = "value_a"
[category_b]
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["category_b", "key"], "value_b")
key = "value_b"
[category_b.subcategory]
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["category_b", "subcategory", "key"], "value_b_sub")
key = "value_b_sub"
If, for whatever reason, you need to clear the active section header, use []
, although it's recommended to just put the non-section key-pairs above any section header lines:
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["no_category"], "value") assuming there are no section headers above this line in the notecard
no_category = "value"
[category]
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["category", "key"], "value")
key = "value"
[]
# Equivalent to nbsConfig_Write(NBSCONFIG_BUILD, ["key"], "value")
key = "value"
There are some other key differences between nbsConfig BNF and INI/TOML files:
key
, Key
, and KEY
are all different key-value pairs.;
character is not supported as a comment symbol, unlike some INI dialects.\
are not supported and will be read in directly.'
character is not supported as a quote character.[category]
followed by [.subcategory]
resulting in a ["category", "subcategory"]
section) is not supported.5_349_221
), octal (0o755
), or binary (0b11010110
), since the LSL interpreter does not support this.[fruit]
followed by apple = "red"
followed by [fruit.apple]
followed by texture = "smooth"
is permitted, though not recommended for clarity.