Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

2 Beginner Questions

Hamaar Tyne
Registered User
Join date: 17 Jun 2005
Posts: 23
06-22-2005 09:19
Hello, I'm pretty new to sl, so please excuse me for any lack of common knowledge or other beginner mistakes.

I've been reading the lsl wiki and am just starting to play around with scripting. I had two questions.

1) What is the best way to have an object do multiple things on command. The most obviously way I see is to have the object listen on a channel for diffrent chat commands. But the wiki mentions that listening causes lag, so I wonder, is there a different way to communicate with an object giving it multiple commands.

Just as an example say you had a sphere as an object and wanted it to have some particles appear when you say "glow" , or have it fly in a circle when you say "dance". Is there a better way to feed commands to the sphere then chatting?

2) Multiple scripts in an object. I guess my question is, what happens with multiple scripts in an object? If you had a script that said something on a touch event, and had 3 copies of the script, and touched the object, would there be 3 chat messages?

The reason I ask is prompted from another thread talking about a dance machine and how it has one script handling multple copies of the dancing script. But the question arises of having one object handling permissions from multple people. Since one script can only remember the last person who got permissions from it, it does make sense to use multiple scripts in an object.

How do multiple scripts in an object work then? Does it pretend the scripts are all mashed together in the same file or do they run concurently? Can you call other scripts from within the object? Is the solution to have only one script in the object have the default state, and have it call script_1, script_2 ect as people activate it?

I'm sorry if these are basic questions, but I couldn't find the answers in the wiki so far. Right now I have no clue what I want to do in game so it's making it hard for me to figure out what I want to script, and learning something without an objective is hard :)

Well anyway, thank you for reading and thank you in advance for any answers :)

Hamaar
Barbarra Blair
Short Person
Join date: 18 Apr 2004
Posts: 588
06-22-2005 09:47
If you stay off channel 0, I don't notice too much lag with listens; remember to remove your listens, tho.

I don't know about the multiple script thingee. hmm.
_____________________
--Obvious Lady
Jon Marlin
Builder, Coder, RL & SL
Join date: 10 Mar 2005
Posts: 297
06-22-2005 11:32
Multiple scripts in an object all run independently and concurrently. You can communicate between scripts in an object using the llMessageLinked function to send, and the link_message event to receive.

http://secondlife.com/badgeo/wakka.php?wakka=llMessageLinked
http://secondlife.com/badgeo/wakka.php?wakka=link_message

- Jon
Hamaar Tyne
Registered User
Join date: 17 Jun 2005
Posts: 23
06-22-2005 12:09
Ah thank you both for answering. So when you have an object there is no other way besides having it monitor another channel. The only way to keep the listen event down would be to say touch it first to start it listening on your channel, then touch it again to have the listen stop. Is a script sitting in an idol state waiting for a touch command less resource intenstive then a script listening on a non 0 channel?

In the case of multiple scripts, you would fire off a linked message to yourself, which would trigger everyone's event at the same time. Then, you just check the message so one script would say "hey thats me, i'll do something" while the other guys just drop it and do nothing. Is that the idea behind it?

Again, thank you both for your quick answers.

Hamaar
Lit Noir
Arrant Knave
Join date: 3 Jan 2004
Posts: 260
06-22-2005 12:22
Well, I can't really speak to the dance machine example with multiple animation requests, but I can take a crack at the other questions.

A few notes on "listens":
Yeah, they cause lag, but so does most everything. Also a good idea to have commands issued from any chat channel but the public one (0). I remember reading way back that the benefit of this MIGHT be much less than what one would assume, but, good practice anyway.

Never use more listens than necessary. The listen event is flexible enough so that you could have multiple listens in a script searching for specific commands. The idea is to use the listen event as it's own filter rather than using custom logic in the listen event. General rule, don't do this. Filter the channel, filter the av if it makes sense (only owners can change for example), but don't use multiple listens to filter text. I don't think you were going down this path, but just making sure, I just rememebr I was tempted to try that myself once.

Still, lots of folks REALLY hate listens, the red-headed stepchild of user interfaces it seems. For some things it makes sense though, but there can be alternatives. Touch is fine for a toggle, but not much else... unless you use touch to activate the llDialog command, this will create a listen (that can and should be removed after the dialog is done thru your script). Dialogs are great when there are only specific commands that are known ahead of time, not so good (though doable in a way) for things where a command might be any text the av can think of (think hovering title scripts).

If you decide to segment out your project into multiple scripts for different functions, it would likely be wise to add another script just to listen for commands and send link messages when you want the "functionality" scripts to do their job. Better than putting a listen handler in every script, though that would work, just unecessary. As for touch events, if an object (or linked set of objects) is touched, all touch events will fire in the prims (unless you code the prim to not pass touch events, it's in the wiki).

As for multiple scripts, let's see...

As Jon said they run concurrently, with arguments passed through the MessageLinked function. The function doesn't really call the other script, it just tells it to start running. It is not like an in-script function where the calling script will wait for the called script to finish (you can get around that, but probably not advisable).

Hope this makes sense, and is not just stating the obvious.
Lit Noir
Arrant Knave
Join date: 3 Jan 2004
Posts: 260
06-22-2005 12:27
D'oh, took too long with my response, looks like you got it.

But as for the touch to activate listen and then touch to deactivate, you could just have touch to activate the listen then start a timer to automatically kill the listen handler after some amount of time. I think this would work.

Also, touch events are better (processor wise) than listens. Think of listens as the script pulling info constantly, while touchs have to be pushed and just keep their heads (and resources) down until provoked.
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
06-22-2005 12:36
From: Hamaar Tyne
1) What is the best way to have an object do multiple things on command. The most obviously way I see is to have the object listen on a channel for diffrent chat commands. But the wiki mentions that listening causes lag, so I wonder, is there a different way to communicate with an object giving it multiple commands.

Just as an example say you had a sphere as an object and wanted it to have some particles appear when you say "glow" , or have it fly in a circle when you say "dance". Is there a better way to feed commands to the sphere then chatting?
Depending on the actual object and what it is doing, there are a few good ways to avoid listens.

The most obvious way is to only start listening when someone touches the object, and stop listening once they give a command or a timeout period has elapsed. For example:

CODE

float LISTEN_TIMEOUT = 15.0; // seconds to wait for a command
integer LISTEN_CHANNEL = 3; // channel to listen for commands
integer OWNER_ONLY = FALSE; // only listen for owner

vector COLOR_RED = <1,0,0>;
vector COLOR_WHITE = <1,1,1>;

integer listen_id; // id returned from llListen()

// Here we start or stop listening. TRUE starts, FALSE stops.
set_active(integer active) {
if ( active ) {
// In case an old listen is still active, try to remove it.
llListenRemove( listen_id );

// Listen for the person who clicked us.
listen_id = llListen( LISTEN_CHANNEL, "", llDetectedKey(0), "");

// Change color to show we are listening
llSetColor( COLOR_RED, ALL_SIDES );

// Set up a timer
llSetTimerEvent( LISTEN_TIMEOUT );

// Timer events are VERY unreliable, so we use this to double check
llResetTime();
} else {
// remove the listen
llListenRemove(listen_id);

// remove our timer
llSetTimerEvent(0.0);

// Change color to show we are done listening.
llSetColor( COLOR_WHITE, ALL_SIDES );
}
}

default {
touch_start(integer num) {
// If we will only listen to the owner, make sure it's them.
if ( OWNER_ONLY && ( llDetectedKey(0) != llGetOwner() ) )
return;

set_active(TRUE);

}

listen(integer channel, string name, key id, string msg) {
string msg_lower = llToLower(msg); // don't worry about CaSe

if ( msg_lower == "glow" ) {
// do stuff here
} else if ( msg_lower == "dance" ) {
// do stuff here
} else {
// If no commands match, we return here. That way, if we get
// past this point, we know a command DID match, and we can
// tear down the listen.
return;
}

set_active(FALSE);

}

timer() {
// timer events are unreliable (though, so is llGetTime()...),
// so we double check if LISTEN_TIMEOUT seconds have passed
// since we called llResetTime()
float cur_time = llGetTime();
if ( cur_time < LISTEN_TIMEOUT ) {
// Change the timer to however many seconds we have left to wait
llSetTimerEvent( LISTEN_TIMEOUT - cur_time );
return;
}

// If we get here, LISTEN_TIMEOUT seconds have really passed.
set_active(FALSE);
}
}

Another option could be seperate prims as buttons for each command you want to implement. You can use llDetectedLinkNumber() and llGetLinkName() to make this just as easy as listens, and still only one script. Just name the individual prims after their function; for example, name your glow button "glow", and then link it. I think this is easier both to implement and use, but it is not always practical.

CODE

integer OWNER_ONLY = FALSE; // only respond to owner

default {
touch_start(integer num) {
string cmd;

// If we will only respond to the owner, make sure it's them.
if ( OWNER_ONLY && ( llDetectedKey(0) != llGetOwner() ) )
return;

cmd = llToLower( llGetLinkName( llDetectedLinkNumber(0) ) );

if ( cmd == "glow" ) {
// do stuff here
} else if ( cmd == "dance" ) {
// do stuff here
}
}
}


edit: I fixed a few silly mistakes so they will compile.

From: Hamaar Tyne
Is a script sitting in an idol state waiting for a touch command less resource intenstive then a script listening on a non 0 channel?
I think that listens are "active" and constantly scan the sim chat buffer, whereas touch events are passive.
Hamaar Tyne
Registered User
Join date: 17 Jun 2005
Posts: 23
06-22-2005 13:42
Wow, thank you all for the detailed replies. The framework for the scripts are excelent (ha as far as a newb can tell :) ) and it definatly helps showing some of the finer points of scripting practices (unrelyable timers ect...).

I wish i had some ideas for what I wanted to script :) I think I am going to start with the "listening ball" as I get my feet wet with the language and make lots of "toys" as I try things out.

Thanks again everyone :)

Hamaar
Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
06-22-2005 18:36
Like every one else, I beleve in resources managment, and only use listens when they are nesisary, and then only on channels other then 0.

Another thing you can do is use triggers. They can't remove the use of listens, but they can bind actions to keys, or as filtered to serch for specific triggered in genreal chat.