Skip to content

OpenSim gotchas

lickx edited this page Feb 12, 2026 · 30 revisions

All script engines

Scripts can reset in some occasions

  1. Teleport to a hypergrid region that doesn't have a fix for mantis 8366 implemented. All your attached scripts will stop working. Now teleport home again, or cross/teleport to another region within that foreign grid. All scripts will have reset. You now lost all your collar settings!
  2. Teleport to a region with scripts disabled. Now teleport to a region with scripts enabled. You now lost all your collar settings!

Over the years we tried various solutions to recover this situation:

  1. Offer a 'Save Card' button in the settings menu. This uses osMakeNotecard() which many regions do not allow. If the region still uses the obsolete XEngine, due to the osMakeNotecard being used in a try {} catch (which is YEngine only), the settings script will fail to run entirely. Unfortunately, this solution also has to store Owners in the card, which is never recommended.
  2. Store the most important data (owners!) as texture data (uuid, offsets, scale), and the rest in the settings notecard. This made the code needlessly complicated and bloated.
  3. Our current solution is to backup all settings in linkset data. This is only supported from OpenSim 0.9.3 onwards, with a critical bug fixed in OpenSim 0.9.3.1 (which hasn't even been released yet). As a fallback (when linkset data lost its data from teleporting to a region running OpenSim older than 0.9.3) it tries to recover from the settings notecard, which can still be saved manually.

But what OpenSim core really needs to do, is fix mantis 8366.

Never edit/compile scripts in worn attachments when on the hypergrid

Either do that in your home grid, OR first rez the object out and then edit/compile the script(s) inside. If you don't do this, the script asset will be missing!

Never modify a worn attachment when on the hypergrid

The changes made won't stick when:

  • You log out while on the HG
  • You re-attach the attachment while on the HG
  • You detach, then give away or rez the attachment while on the HG.

It will revert back to the state before you started changing it. This also goes for inventory inside the object! Always first rez the object out on the floor before starting modifications. Then take it back to inventory and then you can wear it.

If you did edit something worn while on the HG, make sure to afterwards teleport to your home grid. Then re-attach, relog, or log out cleanly for the changes to stick.

OSSL functions

There are some interesting ossl functions but most can't be used in attachments because the threatlevel exceeds the default threatlevel of OpenSim (VeryLow).

Replace a string within a string

SecondLife: llDumpList2String(llParseStringKeepNulls((sSource = "") + sSource, [sSearch], []), sReplace);
OpenSim: osReplaceString(sSource, sSearch, sReplace, -1, 0);
Since january 2023 llReplaceSubString landed in OpenSim git; use osReplaceString to remain backwards compatible with older versions of OpenSim

Non initialized keys are not NULL_KEY

They are "" instead (an empty string). Always initialise keys with NULL_KEY or another valid UUID!

llTarget, at_target(), not_at_target() (fixed in OpenSim >= 0.9.2.1)

When used in more than one script in the same object, triggers at_target and not_at_target in all scripts that have such events. LSL wiki states this should be limited to the script where the llMoveToTarget is used in. We work around this by explicitly checking for the handle and setting it to 0 when unused. Affects: oc_leash, oc_pet, oc_couples.

llSameGroup() can fail

llSameGroup() as used by the authorizer for group based access, can fail on unpatched vanilla OpenSim. This is due to attachments not set to group when changing your active group. Mantis 9052, with patch

Probably XEngine specific (TODO test on YEngine!):

Vector not <0,0,0>

SecondLife: if (vMyVector)
OpenSim: if (vMyVector != ZERO_VECTOR)

Is a key:

SecondLife: if ((key)sMyString)
OpenSim: if (osIsUUID(sMyString))

Key not 00000000-0000-0000-0000-000000000000:

SecondLife: if (kMyKey)
OpenSim: if (kMyKey != NULL_KEY)

List has elements:

SecondLife: if (lMyList) or if (lMyList!=[])
OpenSim: if (llGetListLength(lMyList) > 0)

List is empty:

SecondLife: if (lMyList==[])
OpenSim: if (llGetListLength(lMyList) == 0)

String is not empty:

SecondLife: if (mystr)
OpenSim: if (mystr!="")

llMinEventDelay(float delay)

Either works somewhat at times > 0.5 or doesn't work reliably at all. Best to comment out this function.

XEngine specific

Note XEngine can no longer be be used by simulators starting with OpenSim 0.9.3

Don't redeclare variables within scope:

integer i = 3;
for ( ; ; ) {
    integer i = 4; // throws error in OpenSim
}

More than one negate expression:

SecondLife: if (~Expr1 && ~Expr2)
OpenSim: if ((~Expr1) && (~Expr2))

llSleep(float delay)

Will cause a lock on the sim's main thread, causing lag. Avoid this as much as possible by using the timer instead.

Timers (XEngine)

Timers < 0.5 such as used by llSetTimerEvent() are not reliable.

CHANGED_OWNER never fires

Work around that by checking g_kWearer against llGetOwner()

Choking on not using nested brackets

Example:

if (a)
    DoSomething();
else
    if (b)
        DoThis();   // xengine will choke around here
    else
        DoThat();

Use brackets explicitly even if it encloses just one line:

if (a) {
    DoSomething();
} else {
    if (b) {
        DoThis();
    } else {
        DoThat();
    }
}

OSSL functions can throw a permission error, making the script not run (XEngine only)

When a used OSSL function is not enabled, it can throw a script error and make the script not run. With YEngine we can use try() {} catch() {} and the script keeps running.

Clone this wiki locally