Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

A life for beginers

Olympia Rebus
Muse of Chaos
Join date: 22 Feb 2004
Posts: 1,831
06-13-2005 08:54
I want to learn how to do this myself, but my scripting skills are mediocre. For example, I can get my fish (actually cubes at this point) to find and look at each other, but attempts to get them to "school" result in ugly head-butting brawls that end up flying off world.
To clarify, I want to learn (or teach myself) how to do this. I'm not demanding everyone to fork over their high-end ai scripts to me for free. That would be unfair to the creators and of limited use to me learning anything
I've learned much from the LSL wiki and from tinkering with existing scripts, but I have trouble integrating what I've learned into practical, functioning scripts, particularly with any artificial intelligence simulation. How do I bridge this gap? Are there any excercises, tutorials or challenges to get me up to speed? Any wimped down, no-frills scripts for ai beginers? Overlooked LSL concepts vital to this area? Dos and Don't lists that apply here?

Any ideas and help would be appreciated.
Thanks
_____________________
Surina Skallagrimson
Queen of Amazon Nations
Join date: 19 Jun 2003
Posts: 941
06-13-2005 09:44
Welcome to AI for dummys ;)

Which part are you having problems with Olympia? LSL or the AI concepts? or both?


As far as starting out with AI critter movement, you need to learn to walk before you flock.. hehehe

First off, use a single critter (your box) and try pushing it around with a few llApplyImpulse() commands, Have yourself as its target so it constantly tries to come to you.
The conceptual code would go something like this...


llSensorRepeat(your target params here)


sensor(num_objects)
vTarget = llGetDetectedPos(0) // gives you the position of the closest target seen by sensor
vMypos = llGetPos() // gives your critters current position.
vDesiredHeading = vTarget - vMypos // the heading from critter to target
vImpulse = llVecNorm(vDesiredHeading) // reduces the 'size' of the heading vector to a standard unit. ie, removes distance info, but retains direction.
llApplyImpluse(vImpulse, fStrength, 0)


Everytime SensorRepeat finds you it triggers the sensor event. The sensor event looks to see where you are, checks where the critter currently is.. subtracts your position from its own position to give a heading and distance towards you.. then 'normalises' this heading to a unit vector giving only the direction, then applies this as an impulse to the critter which should give it a bump towards you.

This is about as simple as it gets. Learn the commands used here (check the Wiki for correctness...) and you should be able to build on it.

Remember, if you have several critters all looking for each other you have to add a repulsion impulse to keep them from forming one big blob... Make the size of the repulsion impulse 1/distance so as they get closer together, the repulsion force increases untill it balances the attraction force.. You will need to experiment to find precise values that work well for your critters.


Edit to add:- If this is too simple just shout and we'll move on to more complex stuff... Where do you want to start?
_____________________
--------------------------------------------------------
Surina Skallagrimson
Queen of Amazon Nation
Rizal Sports Mentor

--------------------------------------------------------
Philip Linden: "we are not in the game business."
Adam Savage: "I reject your reality and substitue my own."
Olympia Rebus
Muse of Chaos
Join date: 22 Feb 2004
Posts: 1,831
06-13-2005 09:52
Thanks! Just the stuff I was looking for.
I'll play with this and see what happens...

From: Surina Skallagrimson
Welcome to AI for dummys ;)

Which part are you having problems with Olympia? LSL or the AI concepts? or both?


As far as starting out with AI critter movement, you need to learn to walk before you flock.. hehehe

First off, use a single critter (your box) and try pushing it around with a few llApplyImpulse() commands, Have yourself as its target so it constantly tries to come to you.
The conceptual code would go something like this...


llSensorRepeat(your target params here)


sensor(num_objects)
vTarget = llGetDetectedPos(0) // gives you the position of the closest target seen by sensor
vMypos = llGetPos() // gives your critters current position.
vDesiredHeading = vTarget - vMypos // the heading from critter to target
vImpulse = llVecNorm(vDesiredHeading) // reduces the 'size' of the heading vector to a standard unit. ie, removes distance info, but retains direction.
llApplyImpluse(vImpulse, fStrength, 0)


Everytime SensorRepeat finds you it triggers the sensor event. The sensor event looks to see where you are, checks where the critter currently is.. subtracts your position from its own position to give a heading and distance towards you.. then 'normalises' this heading to a unit vector giving only the direction, then applies this as an impulse to the critter which should give it a bump towards you.

This is about as simple as it gets. Learn the commands used here (check the Wiki for correctness...) and you should be able to build on it.

Remember, if you have several critters all looking for each other you have to add a repulsion impulse to keep them from forming one big blob... Make the size of the repulsion impulse 1/distance so as they get closer together, the repulsion force increases untill it balances the attraction force.. You will need to experiment to find precise values that work well for your critters.


Edit to add:- If this is too simple just shout and we'll move on to more complex stuff... Where do you want to start?

I think this is a good start. Thanks again!
_____________________
Surina Skallagrimson
Queen of Amazon Nations
Join date: 19 Jun 2003
Posts: 941
06-13-2005 10:46
I should add that while the llVecNorm part above is not important for this specific example, all you need is direction which is given by vTarget - vMypos, it is important for future use where you are adding several impulses together to get combined behaviours.

With each impulse direction starting out as a standard unit length it is easy to add 'weight' to certain behaviours and take away from others.
_____________________
--------------------------------------------------------
Surina Skallagrimson
Queen of Amazon Nation
Rizal Sports Mentor

--------------------------------------------------------
Philip Linden: "we are not in the game business."
Adam Savage: "I reject your reality and substitue my own."
Moopf Murray
Moopfmerising
Join date: 7 Jan 2004
Posts: 2,448
06-13-2005 12:44
Olympia,

I've just started messing around with a few objects in the last couple of days, getting used to physics and getting them to move around independantly. One thing I've found really useful (as my vector maths is beyond abysmal - I really need to read up on this :D ) is adding in a touch toggle so if an object is getting out of control I can touch it to turn off physics etc. and touch it to turn them on again. Just a little hint as it's saved me trying to find them again :) But then that might have more to do with my lack of brain on vectors!

If I can be of any help just give me a shout. Although don't be expecting too much quality in that help ;)
_____________________
Rhysling Greenacre
Registered User
Join date: 15 Nov 2003
Posts: 132
06-13-2005 16:25
you could also add a listen event so when someone says "stop" you could disable physics
Olympia Rebus
Muse of Chaos
Join date: 22 Feb 2004
Posts: 1,831
06-13-2005 19:26
Good ideas, Moopf and Rhysling.
Much better than my physics-enabled "playpen" that was supposed to contain wayward blocks. They busted out like a bats outta hell. :D
From: Moopf Murray
Olympia,

I've just started messing around with a few objects in the last couple of days, getting used to physics and getting them to move around independantly. One thing I've found really useful (as my vector maths is beyond abysmal - I really need to read up on this :D ) is adding in a touch toggle so if an object is getting out of control I can touch it to turn off physics etc. and touch it to turn them on again. Just a little hint as it's saved me trying to find them again :) But then that might have more to do with my lack of brain on vectors!

If I can be of any help just give me a shout. Although don't be expecting too much quality in that help ;)


From: Rhysling Greenacre
you could also add a listen event so when someone says "stop" you could disable physics
_____________________
Zak Escher
Builder and Scripter
Join date: 3 Aug 2003
Posts: 181
06-14-2005 03:43
Don't forget that with experimental scripted objects, you can use:

llSetStatus(STATUS_SANDBOX, TRUE);

This will prevent the scripted object from moving more than 20m away from you.

llSetStatus(STATUS_SANDBOX, FALSE);

turns sandbox mode off.
_____________________
Zak Escher
Unity Shapes
http://slurl.com/secondlife/Hatteras%20Island/125/46/31
http://unityshapes.blogspot.com/
See what I have for sale at SLExchange
Moopf Murray
Moopfmerising
Join date: 7 Jan 2004
Posts: 2,448
06-14-2005 03:49
From: Zak Escher
Don't forget that with experimental scripted objects, you can use:

llSetStatus(STATUS_SANDBOX, TRUE);

This will prevent the scripted object from moving more than 20m away from you.

llSetStatus(STATUS_SANDBOX, FALSE);

turns sandbox mode off.


Zak, I was looking at that yesterday (didn't even realise the option was there until I looked at the Wiki for llSetStatus http://secondlife.com/badgeo/wakka.php?wakka=llSetStatus).

I've not tried it yet because looking at the Wiki it will only allow the object to travel 10m maximum from it's start point (not from the owner from what I understand), which is a really tight constraint. I may have a play with it later though to see if the Wiki is right on that.
_____________________
Shining Seraph
Registered User
Join date: 19 Jan 2005
Posts: 2
06-16-2005 14:59
ALife has fascinated me for a while now. Surina's fish finally motivated me to tamper with it myself. Using the code above as a starting point I now have a little blob that diligently follows me around my plot.
I have noticed a strange behavior and was wondering if any of you know why this was happening. Sometimes is will follow me, and other times it will vastly over shoot and end up orbiting my like a small oddly shaped planet for 5-10 minutes.
I'm sure it will work itself out as I fine tune things but any road signs to the right direction would be helpful.
Surina Skallagrimson
Queen of Amazon Nations
Join date: 19 Jun 2003
Posts: 941
06-16-2005 22:46
What you're seeing there Shining is the behaviour defined by the code snippet. It is purely an 'attraction' behaviour which will work like gravity, as opposed to 'seek'.

Just as satelites stay in orbit despite (because of) gravity, your object will orbit you as the constant force directly towards you will give the same effect. No account has been taken of the current velocity of your object.

For 'seek' you need to take your objects current velocity into account by adding it to its current position.

vector vMyPos = llGetPos() + llGetVel()

Use this in the orriginal snippet.


This is fine as long as the target is stationary, the next stage being 'pursue' which makes allowance for target movement. You should know what is coming by now.... yes, you add the velocity of the target to it's position to guess where it will be next...

vTarget = llGetDetectedPos(0) + llGetDetectedVel()

Obviously this relies on constant movement by the target and changes of speed or heading will fool it. However each iteration will re-evaluate the sceen and apply corrections.


There are more complex algorythms for persuit but they're beyond the scope of 'AI for Dummys'
_____________________
--------------------------------------------------------
Surina Skallagrimson
Queen of Amazon Nation
Rizal Sports Mentor

--------------------------------------------------------
Philip Linden: "we are not in the game business."
Adam Savage: "I reject your reality and substitue my own."
Surina Skallagrimson
Queen of Amazon Nations
Join date: 19 Jun 2003
Posts: 941
06-16-2005 23:55
The completed code snippet for 'persuit' should look something like this...

CODE


llSensorRepeat(your target params here)


sensor(num_objects)
vTarget = llGetDetectedPos(0) + llGetDetectedVel() // gives you the FUTURE position of the closest target seen by sensor
vMypos = llGetPos() + llGetVel()// gives your critters FUTURE position.
vDesiredHeading = vTarget - vMypos // the heading from critter to target
vImpulse = llVecNorm(vDesiredHeading) // reduces the 'size' of the heading vector to a standard unit. ie, removes distance info, but retains direction.
llApplyImpluse(vImpulse * fStrength, 0) // multiply vImpulse by fStrength to set the strength of the push...




Note: Seek or Persuit are good when you need one object to chase or catch another, For swarming or flocking simple attraction is good enough as you're after overall effect, not accuracy on the part of an individual object.
_____________________
--------------------------------------------------------
Surina Skallagrimson
Queen of Amazon Nation
Rizal Sports Mentor

--------------------------------------------------------
Philip Linden: "we are not in the game business."
Adam Savage: "I reject your reality and substitue my own."
Shining Seraph
Registered User
Join date: 19 Jan 2005
Posts: 2
06-17-2005 08:21
Thank you very much Surina. I'll be sure to try this out when I get on tonight.
Moopf Murray
Moopfmerising
Join date: 7 Jan 2004
Posts: 2,448
06-17-2005 08:44
Well I've been having fun today :) I've been reading the article that Surina posted a link to on the Techniques thread (/191/28/49765/1.html) and, following the principles of separation, cohesion and alignment highlighted on that I now have an object I can copy and see the effects of these different methods in action on a group. I've put a listener in each one which enables me to change the weightings etc. for separation, cohesion and alignment en-mass with simple commands on a channel to see how the different weightings change the flocking of the objects. All good fun :) The listens wouldn't be needed eventually, of course, but it does enable me to interactively play with the weightings and see the effects (I can also change field of vision etc. as well).

I'm encountering one problem that I'm currently scratching my head over though. For some reason I'm finding the the objects tend to go higher than I would expect, and I'm sure that's got something to do with not normalising in a place where I shoud be (but as I've said before vector maths is not my forte).

I'm also encountering frustration with the sensor facility in SL. I've read conflicting information on whether the 'type' you're searching for in a sensor can by OR'd or whether ORing them actually means that the sensor will only pick up all that match both - the Wiki has a note pointing to the second one, whilst I've read other threads that point to the first (the Wiki also seems to suggest only two flags can be ORd for the type, but I've seen examples with more than two). The reason I'd like this is that, for the purposes of testing I'd like to keep the objects generally near me and add a weighting to how far an object is away from me, how determined it will be to come back to me.

Anyway I'm going to carry on tweaking.
_____________________
Trep Cosmo
Registered User
Join date: 3 Mar 2005
Posts: 101
06-17-2005 12:30
From: someone
I'm also encountering frustration with the sensor facility in SL. I've read conflicting information on whether the 'type' you're searching for in a sensor can by OR'd or whether ORing them actually means that the sensor will only pick up all that match both - the Wiki has a note pointing to the second one, whilst I've read other threads that point to the first (the Wiki also seems to suggest only two flags can be ORd for the type, but I've seen examples with more than two). The reason I'd like this is that, for the purposes of testing I'd like to keep the objects generally near me and add a weighting to how far an object is away from me, how determined it will be to come back to me.


I've found that doing ACTIVE | PASSIVE works out alright. It lets me make stationary boids to kind of anchor the swarm in place while I'm working on other code.
Moopf Murray
Moopfmerising
Join date: 7 Jan 2004
Posts: 2,448
06-17-2005 12:37
From: Trep Cosmo
I've found that doing ACTIVE | PASSIVE works out alright. It lets me make stationary boids to kind of anchor the swarm in place while I'm working on other code.


Yes, that's what I did in the end to help keep the little so-and-so's from running away which I play with settings. Because I can change all the weights though chat, I can just up the weighting for this "attractor" object really high to force them all to come back if their other settings are making them hyperactive.

Once I'm happy that it's a reliable test-bed I think I'll put it out for anybody else to use (open source etc.). I'll try and comment it and put lots of instructions with it as well - it may help get some people started and allow them to play with and start to understand the different settings - there's nothing like interaction for working out what the implications of things are.
_____________________
Olympia Rebus
Muse of Chaos
Join date: 22 Feb 2004
Posts: 1,831
06-22-2005 08:42
From: Surina Skallagrimson

Remember, if you have several critters all looking for each other you have to add a repulsion impulse to keep them from forming one big blob... Make the size of the repulsion impulse 1/distance so as they get closer together, the repulsion force increases untill it balances the attraction force.. You will need to experiment to find precise values that work well for your critters.

(emphasis added)

Thanks again for your suggestions.
I'm doing pretty well, but have some trouble with the repulsion part.
My current script has fStrength = 1/distance but that seems to knock my blocks in different directions. Is this just a matter of adjusting the numbers? 0r am I off track?
_____________________
Surina Skallagrimson
Queen of Amazon Nations
Join date: 19 Jun 2003
Posts: 941
06-23-2005 01:56
You're doing it right Olympia, to take the easiest example with just 2 critters, the repulsion direction and attraction direction will be directly opposite. So with an attraction strength of 1 and a distance of 1 the repulsion (1/1) will balance out and there would be no movement.

at 2 meters distance you still have a fixed attraction of 1, but your repulsion strength is now only 1/2 giving an overall attraction of 0.5 likewise at 3m distance a=1 r=1/3 total=0.66

At closer than 1m, (say 0.75) a=1 r=1/0.75 total = -0.33 (pushes away)

You can adjust the balance distance with either the attraction strength or the repulsion.

With more than 2 critters the attraction point should be the average position of all visible critters, this could be the center of the shoal if your critter can see all of them but does not have to be if your critters visibility is limited. Just add together all the detectedPos and divide by number...
The repulsion should be calculated from either the nearest critter, or at most the nearest few, to prevent collision.

Do a few test calculations in your head (or on paper) to find out what impulse strengths you're using so you can weight them to balance out accordingly.

Finally, add in a multiplier for mass, fMass = llGetMass(). This will ensure that you're not trying to push around a big object with tiny impulses or worse, a tiny object with big impulses...
_____________________
--------------------------------------------------------
Surina Skallagrimson
Queen of Amazon Nation
Rizal Sports Mentor

--------------------------------------------------------
Philip Linden: "we are not in the game business."
Adam Savage: "I reject your reality and substitue my own."
Olympia Rebus
Muse of Chaos
Join date: 22 Feb 2004
Posts: 1,831
06-24-2005 20:59
Thanks for your help Surina, Moopf and Zak.
I've been playing with this all week (still at 2 "critters" for now)
Below is my current script (don't laugh)

Biggest current issue:
My "repluse" setup tends to send fish flying far apart instead of nulling the forward movement. Turning down the force to .1 (as in current script) slows this down, but makes them stare at each other and glide sideways.

Is this still a matter of getting the settings right? Or am I doing something wrong?
Thanks in advance, I owe you big time :)

CODE
default
{
on_rez(integer start_param)

{
llResetScript();
}
//on_rez(integer start_param)


touch_start (integer total_number)
{



llSetStatus(STATUS_ROTATE_Z, FALSE);
llSetStatus(STATUS_SANDBOX,FALSE);
llSetStatus(STATUS_PHYSICS, TRUE);
llSay (0,"I will look for fish NOW");
//look for objects named "fish"
llSensorRepeat("fish","",SCRIPTED,20,PI,3);
}

sensor(integer total_number)
{
llSay (0,"I sense " +(string)total_number +"!");
llSetBuoyancy (.99);

float fMass = llGetMass();
llSay (0,"My mass is " + (string)fMass);

// determine where (closest) detected fish is heading
vector vTarget = llDetectedPos(0) + llDetectedVel(0);

//determine where this fish is heading
vector vMypos = llGetPos() + llGetVel();

float fDist = llVecDist(vTarget,vMypos);

float fRepulse = 1/fDist;

//Determine direction & distance between where both are heading
vector vDesiredHeading = vTarget - vMypos;



//vector vImpulse is the direction (without distance) fish needs to point to get to other fish
vector vImpulse = llVecNorm(vDesiredHeading);


llLookAt (vTarget, 1,1);


//llSay (0, "frepulse is " + (string)fRepulse);
llApplyImpulse(((vImpulse * fMass )+(((vImpulse * fMass) * -1)*fRepulse)*.1), TRUE);




}
no_sensor()
{
llSay(0,"Where did they go?");
}
}
_____________________
Trep Cosmo
Registered User
Join date: 3 Mar 2005
Posts: 101
06-25-2005 14:58
I'd just like to take this opportunity to point out the llOwnerSay(); function. I noticed the other day Themiskyra was getting a little noisy. Please tell all your friends about this nice function LL has provided us with.
Surina Skallagrimson
Queen of Amazon Nations
Join date: 19 Jun 2003
Posts: 941
06-25-2005 18:45
You have...
llApplyImpulse(((vImpulse * fMass )+(((vImpulse * fMass) * -1)*fRepulse)*.1), TRUE);


try this

vector vRepulse = vImpulse / fDist;
llApplyImpulse((vImpulse - vRepulse) * fMass, TRUE);
_____________________
--------------------------------------------------------
Surina Skallagrimson
Queen of Amazon Nation
Rizal Sports Mentor

--------------------------------------------------------
Philip Linden: "we are not in the game business."
Adam Savage: "I reject your reality and substitue my own."
Olympia Rebus
Muse of Chaos
Join date: 22 Feb 2004
Posts: 1,831
06-26-2005 12:52
Thanks, Surina & Trep.
:D
_____________________
paulie Femto
Into the dark
Join date: 13 Sep 2003
Posts: 1,098
The fish are great!
06-26-2005 20:54
Great stuff! I had fun playin with the fishies! I blocked their food supply (only temporarily!) to see how theyd behave. I tried to get em to follow me. What fun! Are the cyberfish predators? I didnt see any predator / prey interaction, but the lil fishies seemed to be keepin far away from the cyberfish. Have the fishies "learned" to keep away?

I wasnt sure if fishies were "dying" or "spawning" as I watched. I saw some "poofs." Was that life and death? Maybe new fishies could start small and "grow." Wouldnt that be great! To see baby fishies swimmin with the bigger ones! Maybe dead fishies could float to the top. lol. The live fishies could eat the dead ones. Heh.

Are you plannin to sell or give away schools of these? Id love to have a school of em.

Keep up the great work.
_____________________
REUTERS on SL: "Thirty-five thousand people wearing their psyches on the outside and all the attendant unfettered freakishness that brings."
Zak Escher
Builder and Scripter
Join date: 3 Aug 2003
Posts: 181
06-27-2005 03:40
I created the cyberfish to try out a swarming script posted on the scrpting library forum. They do not have any scripted interaction with Surina's fish. However, I have noticed Surina's fish semingly interacting with them. I don't know if it is coincidence or part of her script.
_____________________
Zak Escher
Unity Shapes
http://slurl.com/secondlife/Hatteras%20Island/125/46/31
http://unityshapes.blogspot.com/
See what I have for sale at SLExchange
Surina Skallagrimson
Queen of Amazon Nations
Join date: 19 Jun 2003
Posts: 941
06-27-2005 05:37
I've not writen anything into the scipts in the fish that would make them interact with the cyberfish.

However the fish have done lots of things in the past that I've not specifically scripted them to do... <snd>Twilight Zone</snd>


Death is indicated by a small particle explosion, new borns sink to the bottom while their scripts are loaded from their 'Mother'.
_____________________
--------------------------------------------------------
Surina Skallagrimson
Queen of Amazon Nation
Rizal Sports Mentor

--------------------------------------------------------
Philip Linden: "we are not in the game business."
Adam Savage: "I reject your reality and substitue my own."
1 2