Always treat both 0 and 1 as root prim
Tapple Gao
In 1-prim objects, root prim has link number 0. In other prims, root prim has link number 1 (
=LINK_ROOT
). This behavior should change:- It's a pain to make scripts work with both types of objects
- Link numbers are so closeto already using 1-based indexing, like everything else in SLua has been already changed to. This change would complete that transition
For functions that accept a link number:
- 0and1should both be treated equally as the root prim number, regardless of prim count
- This change should be made in SLua at least, but possibly in LSL and Mono as well. (it's probably easier to change both)
- I can't think of a reason this would break existing LSL content, as it only makes the functions do something useful where they previously did nothing (Suzanna thought of a theoretical reason it could break code below)
For functions that return a link number:
- In LSL, they must be left alone, as this check is somewhat common to test for 1-prim vs multi-prim: if (llGetLinkNumber())
- In SLua, they should be changed to always return 1 (=LINK_ROOT). This makes them more consistent, and SLua has no backwards compatibility concerns yet (This is the main reason this proposal is in SLua-Alpha and not Scripting Bugs)
These functions accept link numbers, and return a prim property:
- ll.AvatarOnLinkSitTarget
- ll.GetLinkKey
- ll.GetLinkMedia
- ll.GetLinkName
- ll.GetLinkNumberOfSides
- ll.GetLinkPrimitiveParams
- ll.GetLinkSitFlags
- ll.GetObjectLinkKey
- ll.IsLinkGLTFMaterial
These functions accept link numbers, and modify them:
- ll.BreakLink
- ll.ClearLinkMedia
- ll.LinkAdjustSoundVolume
- ll.LinkParticleSystem
- ll.LinkPlaySound
- ll.LinkSetSoundQueueing
- ll.LinkSetSoundRadius
- ll.LinkSitTarget
- ll.LinkSetSoundRadius
- ll.MessageLinked
- ll.SetLinkAlpha
- ll.SetLinkCamera
- ll.SetLinkColor
- ll.SetLinkGLTFOverrides
- ll.SetLinkMedia
- ll.SetLinkPrimitiveParams
- ll.SetLinkPrimitiveParams({PRIM_LINK_TARGET})
- ll.SetLinkPrimitiveParamsFast
- ll.SetLinkPrimitiveParamsFast({PRIM_LINK_TARGET})
- ll.SetLinkRenderMaterial
- ll.SetLinkSitFlags
- ll.SetLinkTexture
- ll.SetLinkTextureAnim
- ll.SetPrimitiveParams({PRIM_LINK_TARGET})
- ll.SitOnLink
These functions return a link number:
- LLEvents.link_message
- ll.CastRay
- ll.DetectedLinkNumber
- DetectedEvent.getLinkNumber
- ll.GetLinkNumber
- ll.GetObjectDetails({OBJECT_LINK_NUMBER})
Log In
Tapple Gao
We tried making the smallest Lua code (by compiled size) to iterate over all valid link numbers. Here's the ones I thought were the most interesting:
Smallest bytecode, by Suzanna:
local numPrims = ll.GetNumberOfPrims()
local isUnlinked = numPrims == 1 and 0
for primId = isUnlinked or 1, isUnlinked or numPrims do
print(primId, ll.GetLinkName(primId))
end
print(ll.GetUsedMemory() - 2267) -- > 157
Smallest readable bytecode, by Kristy:
local numPrims = ll.GetNumberOfPrims()
local startPrim = 1
if numPrims == 1 then
numPrims = 0
startPrim = 0
end
for primId = startPrim, numPrims do
print(primId, ll.GetLinkName(primId))
end
print(ll.GetUsedMemory() - 2267) -- > 162
Smallest reusable iterator, by Tapple and Suzanna:
local function allPrims()
local numPrims = ll.GetNumberOfPrims()
local isUnlinked = numPrims == 1 and 0
return function(last, i)
if i < last then return i + 1 end
end, isUnlinked or numPrims, isUnlinked and -1 or 0
end
for primId in allPrims() do
print(primId, ll.GetLinkName(primId))
end
print(ll.GetUsedMemory() - 2267) -- > 312
Tapple Gao
If this bug were fixed, these could just be:
for primId = 1, ll.GetNumberOfPrims() do
print(primId, ll.GetLinkName(primId))
end
print(ll.GetUsedMemory() - 2267) -- > 128
Journey Bunny
integer rootLinkNum = !!llGetLinkNumber();
Now rootLinkNum is correct number.
SuzannaLinn Resident
Journey Bunny
In SLua:
local rootLinkNum = if ll.GetLinkNumber() == 0 then 0 else 1
Tapple Gao
SuzannaLinn Resident the smallest Lua code (by text size) to get the root prim I can think of is
local rootLinkNum = math.sign(ll.GetLinkNumber())
Suzanna's is smaller by bytecode size (72 bytes vs 79)
SuzannaLinn Resident
I like the idea.
I would do it only in SLua in the
ll
library (1-based LL functions).I would leave untouched the
llcompat
library (0-based LL functions) and LSL.Probably there are things like this in LSL...
-- orange box that turns blue when someone sits
local function setColor()
llcompat.SetLinkColor(0, vector(1, 0.5, 0), ALL_SIDES)
llcompat.SetLinkColor(1, vector(0, 0.5, 1), ALL_SIDES)
end
LLEvents:on("changed", function(change)
if bit32.btest(change, CHANGED_LINK) then
setColor()
end
end)
setColor()
Lou Netizen
Modifying functions that return a link number to always return LINK_ROOT in single-prim objects will break a good deal of existing scripting. Testing if a link number is zero is a very common way to test if a script is in a single-prim object.
Tapple Gao
Lou Netizen Added a note to only consider doing that in SLua