Create A Flying Pet: Session 1
In this session we are going to look at how our scripts are going to use link mesages to talk to eah other
We will be developing a system that can be reused and expanded
Thats quite a long section, but will cover the majority of the functions we will need
Then a look at the design of the brain script, we will start simply with the bare basics, and will expand it later
Once we have talked about the design, time to start putting all the bits together to form the script
So Link messages are used for communicating between scripts in the same object. The scripts themselves can be in diferent prims.
In this project, we are going to use link messages to allow the brain script to tell the movement script where to go. And to let the movement script tell the brain that it has reached the destination.
To send a linkmessage, you use the link message function. This sends the data fields num, str and id to other scripts, triggering the link message event. Which scripts, or more correctly, which prim the message gets sent to, depends on Linknum
Lets think about what sort of things we want to send via a link message. Well we know we need several of them. We are going to want to send a vector, possibly a float, in fact quite a variety of data types. We also want to be able to send different information in the same data format. Sometimes our float is going to represent the speed, sometimes a range.
Most messages are going to be for a specific script, but that might not always be the case.
Design 1
So this is one way we could set up the scripts and link messages. We could put each script in a separate prim and use Linknum to direct the linkmessage to the correct script. Apart from not being very flexible, it does require you to have one prim per script. Plus unless each script only ever has one input message, we still need a way of telling the messages apart.
Design 2 is better. By setting Linknum to LINK_SET, every linkmesage is sent to every script, no matter which prim it is in. Most of the time, all your scripts are going to be in the root prim, sometimes its useful to put scripts in separate prims. Here we are using the variable num to store the message type. So a move message could be num = 1, a stop message num = 0 etc etc
However, using num as the message type does have a problem. If you try and use someone elses scripts in your pet as well, you may get a conflict over messages. YOu use 1 to represent a move message. The third party script might be using 1 as the turn off message. You could get some very strange behaviour if this happens.
For that reason, this project is going to use design 3.In design 3, linknum is set to LINK_SET to allow all messages to be sent to all scripts. Num is being used to represent a company ID. I always use 150. If you do this, using a different number, then your scripts will co-exist with mine and everyone else using the system. It does leave us with the problem of how to identify the message type though. But we can deal with that and the problem of wanting to send several bits of data at the same time. In fact we are going to put them all the the string variable.
A quick browse through the wiki brought up this method of compacting several different data items into one string, just what we need
Silde 15:
What this does is set up a list containg all the information we want to send. Here we are sending a message type ("MOVE") a speed, (could be a float), a target, vecotr, and a TRUE/FALSE indicator.
Each of the data items is put into a list, and then we use the function llDumpList2String(). This function converts each element in the list into a string, and concatonates them all together, separating the data items with, in this case, a "-=-" string.
At the bottom you can see the string this example produces.
Once we have a string containing all the data items, we can send it with llMessageLinked.
Slide 16:
So once we have packed all the data items into a string and send it using the link message function, we need to receive it at the other end, and unpack the data.
The event that is triggered by a link message, is Link_message
When it is triggered, four variables are set.
sender_num contains the link number of the prim that the originating script is in. We wont be using this in this example. After that, we have num, str and id, and these contain the information that we sent in the link message
Slide 17:
And here is how we unpack the data. Note this code is not the actual code we are going to be using, its just an example
The first thing we need to do is to check that this message is actually for this script, it might be a message for something else. So we have a if statement to see if num is equal to the chosen channel number, 150 in this case
So now we know that the message contains information in the expected format, we can exract the data from the string
llParseStringKeepNulls() does this. You feed in the string, tell it what the separators string is, and it returns a list containing a string for each data item.
Note here that we have lost the data type. Every thing is now a string representation of the orginal data item. You can preserve the data format as well, but we dont need it for this example.
Once we have our list of data, we can check the first item in the list. If it is equal to "MOVE" we know that it is a movement order and can extract the data to the appropriate place.
In this example we had speed in the second list item , target in the third etc.
Note that each data item has to be typecast into its correct format.
Slide 18:
Here we have the basic structure of our brain code.
At its simplest level, we only need 2 events, state_entry and link_message
State_entry is going to pick somewhere to move to and then tell the movement script to go there.
Link message is going to wait for the movement script to tell it that it has got to the target, and if so send it off somewhere else
There are two user defined functions in this script that we are going to write.
So lets look at state_entry in detail. The first line calls a user defined function called select_new_position(). This function is going to return a vector which is the objects next location, all the code to choose a vaild target is going to be in here.
Once it has that vector, it passes it to another function called move_to_positition. And move_to_position is going to encode the apporpriate data into a string and send out a link message
In the link message event.
We are going to check that the link message is the right channel number, and then look at the first item in the data list.
If it is equal to ATPOS, it knows the object has reached its new position, so like state_entry, it chooses a ne target and sends the link message
Slide 19: Select_new_position
We are going to start simple with this function, but will need to return to it at a later data.
This function is going to decide where your pet moves to next. Changing how this function works will have a big impact on the behaviour of your pet.
In this example this function is going to return a random location , based on the pets current position. But you could replace it with something returning the location of the next landmark in the inventory.
OK, so there's a global variable at the top. move_range is going to be the maximum distance away from the current position that the new target can be.
So if the object is at <20,20,20>, the new target will be no more than <20,20,20> plus or minus the target_range.
So to do that, we are going to calculate an offset from the objects current postion, how far left/right, up/down etc it should move.
after declaring the vector offset, we can then set each of the three components in turn. For x and y, we are going to use llFrand to select a random number between 0 and twice the move_range and then subtract the move_range. The result is a number between -move_range and move_range.
I'm treating z slightly differently here, and will do so in the movement script as well. The reason is to improve the "look" or "behaviour" of the pet. THink about birds, aircraft etc, they tend to move move in the x and y plane than up and down.
To simulate this behaviour, the maximum z offset is going to be half that of the x and y.
The upshot is that we end up with a box twice the move_range long and wide, and move_range high. With the object in the center of the box, its going to move to somewhere in that box.
But our movement script is going to ned a global location, in sim terms. To get that, we add the offset to the objects current position and return that value.going back to slide 18, you can see we are going to take that new targe vector and feed it into
Slide 20: move_to_position function
This function takes the new target vector as a parameter.
You can see I've declared a couple of new global variables at the top, speed and target range.
Speed is fairly obvious target_range less so. This is how near the object should get to the target before it decides its reached it. I'll explain more about this during the movement script section.
Both these variables your going to want to adjust, and possibly change depending on what your pet is doing
The function itself should be familiar by now. We load up the variables that we need, including a message type of "MOVE" into a list. And then send the whole out in a link message
Slide 21
Homework:
Write a Brain script
Here is our overall layout
Three global variables at the start.
Two user defined functions, select_new_pos and move_to_position
Then the states themselves
state_entry is going to pick a new target and then tell the movement script to go there
link_mesage is going to wait for a "reached current target" message and then pick somewhere to go to, and then send the link mesage
I've also added an on_rez, which is going to do the same an state_entry. This is to stop the situation where you have your pet in the top left of a sim, put it in your inventory and move to the bottom right. As the script will run from its previous position, the pet will march off towards the top left of the SiM!
the on_rez event will ensure that when the pet is rezzed, it immediatly picks a target close to its current position.
I'm going to give you a script called "test harness". A test harness can be used to test scripts, where you are missing of the whole system. In this case we dont have a movement script yet. The test harness is going to pretend to be the movement script. It will listen for the correct link message and tell you what it has received. If it receives a correct MOVE order, it will wait a few seconds and then send an ATPOS link message to tell your brain script that it has reached the target.
This script is in the box along with a few others.
Playing with physical objects can be a pain. Always take plenty of copies of your work and use the utility scripts to try and kill any that try and escape.
Back To The Create A Flying Pet Home Page
Back To The Script Library
Comments (0)
You don't have permission to comment on this page.