Gortax Logo

Gortax Robots GX-MOTOR script

Overview

 

The GX-MOTOR is a generic script for animating objects into the virtual world Inworldz. It is a very powerful script, intended to allow builders to create objects with complex behaviors otherwise very hard to script (some functions were never implemented in SL or in Inworldz):

-Moving prims relative to the root prim, or relative to other prims in order to make complex movements (ex: an arm)

-Moving the object itself, without physics. Although it can be used in physical objects too, with some cautions.

-Defining these sequences of movements in notecards, which are loaded when starting.

-Work in coordination with other scripts within the same object, or emit or receive commands between objects.

 

GX-MOTOR V1 Crafted into Inworldz 2017

Gortax Robots (TM) and (C) Yichard Muni 2017

YichTrains Elven Works (TM) and (C) Yichard Muni 2017

In this page

Overview

     You are an end user

     You are a creator or builder

     Editing the data notecards

     warnings

Bases for programming the GX-MOTOR

     The config notecard (general params for the script)

     General information on how sequences are organized

     Names, indentations, comments

     The GX-SEQstart: command (sequence start)

     The GX-SEQend: command (sequence end)

     Time frames (time sequencer of elementary movements)

Programmming movements: the GX-MOVE commands

     GX-MOVEset: instant movement

     GX-MOVElin: continuous movement

     Rotation formats

     The relto command (compounding movements)

     reltoparams

     virtual prims

     Animating the object with the VirtualRoot prim.

Programming other commands

     Text messages

     Playing sounds

     Sim crossing, warping and Position test

     Error messages

Sending and receiving linked messages

     Sending linked messages from the GX-MOTOR script

     Statute requests and reports

Sending and receiving messages with other objects

 

You are an end user

The script is copy, no mod no trans.

This makes that you need to buy the script only once.

Updates will be free for V2, and free or just a supplement cost for others.

When you buy (or create yourself) an object which uses the script, you just need to drop the script in, from your inventory. This copies the script. The creator already placed the notecards with the programming and settings.

The script has a build-in automatic menu allowing to start any of the sequences in the notecards. But the GX-MOTOR can also be part of a more complex system, with other scripts controlling it. Example: a physical horse, using a moped script base, and GX-MOTOR for animating legs after the different gaits.

You are a creator or builder

The basic idea of this GX-MOTOR script is to allow any creator to animate his creations with it, without need to understand complicated scripting or juggle with quaternions. I did all this for you!

This makes that it will often be included in cooperative works, with sharing sales. This is possible between trusting partners, but the idea was to allow everybody to do this, including persons I don't know. For this reason, the cooperation will happen differently:

-You creator buy the script as it is, copy, no mod, no trans. This allows you to create your data notecards, and set them with the permissions you want.

-You give or sell your object with the data notecards, but without the script, while clearly warning the customer that the GX-MOTOR script is NOT included.

-Your customer needs to buy the script, unless he already has it in his inventory. He necessarily has it in the inventory, as the script cannot be purchased inside an object.

Given the amount of work and expertise it represents, I could not just give away this script. So it is not a freebie, even if I wanted to have it at a price affordable to all (given that you buy it once for many objects).

But what mattered more was to keep it into Inworldz (or possible successors). The reason is that I do not want unknown persons, possibly hostile to Inworldz, just appropriate my work and say it is theirs. This would, even unintentionally, harm my work in Inworldz. So the GX-MOTOR script is not editable (no mod).

Edition of data notecards

Although the basic of data notecards is simple, the quantity of lines and numbers can become confusing, and the very small font will quickly break your eyes. So it is advisable to have your master document in a text editor, such as Notepad++. Generic text editors like Open Office work too, but they sometimes alter characters like hyphens or quotes. Then the best solution is to use a spreadsheet, even if you only have basic knowledge of them, like using cell references for repeating values or making simple formulas. Use colored cells to make your work more clear. Save a copy in CSV format with semicolon as separator and no quotes. The GX-MOTOR can use this straight away, although in production it is recommended to systematically remove repeating semicolons with Notepad++.

Warnings

This script is a powerful tool. As such it can be dangerous. Some commands can:

-Break you object. For this reason it is advised to start programming with a small «reset» sequence, using GX-FRAMEset: commands in order to easily replace all the prims in a right position.

-Send your object into unexpected or very far places, if you try to move the root prim. For this reason , it is advised to have a GX-FRAMEtest: in order to be able to recover your object, or simply to sit on it. And in any case save your data notecards in inventory, because if your object is lost they will be lost too.

-Create lag. This script is a legit yet intensive use of the scripting engine. So having many such scripts running sequences simultaneously will end up causing problems. No tests were done on this regard, but in short the created script lag is expected to be in proportion of the number of animated prims in the whole sim (including root prims and VirtualRoot prims). Virtual prims create lag too, although less. The script also creates Internet traffic, in the same proportion. But it does not lower the fps. Sharing the load (number of prims or objects) between several GX-MOTOR should not increase script lag.

Bases for programming the GX-MOTOR

The config notecard

The GX-MOTOR-config notecard allows you to set general parameters to configure the GX-MOTOR script.

group=only

If group=any, everybody can control the script. If group=only, only members of the same group the object belongs to (group must be active). if group=none, nobody can control the script (ensure that automation can do).

 

SendEmailTo=myname@mydomain

Send an email when a failure occurs, as when a position test detects a sim offline. Make it a null string to disable the sending.

 

DialogChannel=1001

Used for the dialog box. Possible values: -2147483647 to 2147483647. 0 is local chat. -1 disables dialog box

DialogTimeout=60

Seconds. Must be positive, if not 30s is the default value.

 

AutomationChannel=-1

Must be different of Dialog Channel!! The sequencer will send and receive automation message on this channel. Possible values: -2147483647 to 2147483647. 0 is local chat. -1 disables automation (This saves lag if it is not used).

 

RetryDelay=30

(not implemented in V1). Minutes. In case if a sim crossing fails (sim offline), will try to continue the sequence after this time. This time is usually enough when there is a rolling restart. If there is no value specified, the script will just stop the sequence.

 

Verbosity=2

This controls the quantity of warnings and error messages you will get.

-1 shuts down any text message, including GX-SAY: (not recommended, use this only for roleplay or similar situations)

0 lets GX-SAY but nothing else (recommended in production)

1 allows GX-SAY and fatal errors.

2 allows GX-SAY, fatal errors and plain warnings

3 allows all messages, including functional acknowledging

 

StatuteVerbosity=22

This is actually two parametres, each with one digit. First digit is for the verbosity of Linked message spontaneous statute reports, second is for the verbosity of automation messages.

0: no spontaneous reports, only reply to statute request.

1: spontaneous reports only when physics statute changes.

2: at end of sequence or when a sequence ends looping.

3: at each looping turn and each end of sequence.

Default value is 22, to avoid creating a riddle for beginner users. However it is highly recommended to reduce verbosity to only what you need.

 

TimeQuantum=0.1

Elemental time between two interpolation steps (the viewer interpolates between the steps, making a continuous movement). Smaller is more accurate (0.05 minimum), larger is less laggy. Use larger TimeQuantum for slow movements, or if the steps are not too visible. For instance TimeQuantum=0.1 can do the seconds hand of a watch.

General information on sequences

The script and its notecards must be placed in the same prim.

The script and its notecards can be placed in any prim. However if you distribute objects to random users, it is recommended to have them all in the root prim, so that an inexperienced final user will still add the script in the right place.

Data notecards contain the data coding for the various movements that the GX-MO-motor script will execute.

A data notecard is named «GX-MOTOR-data xxx» where xxx is at your convenience. Final blank is mandatory in version V1.

There can be one or several sequences in a data notecard, and one or several data notecards.

The data is organized in SEQUENCES, indivisible series of movements which can be started using menu or automation. They run until their end, or until commanded otherwise.

A sequence is enclosed between a GX-SEQstart: and a GX-SEQend: command.

Each sequence is divided in one or several FRAMES. Each frame lasts a specified time. It executes a segments of line or an arc of circle, or their combination. There also are instantaneous frames.

Each frame can contain zero, one or several GX-MOVE commands, one for each prim to animate.

Frames can also contain special commands to tell text, start sounds, send automation messages, etc.

Here is an example of a simple sequence:

GX-SEQstart: ; test sequence ; timemultiplier: ; 1 ; scalemultiplier: ; 1 ; overridephysics ; version: ; 1.0

GX-FRAMEset: ; frame1 // My first sequence

    GX-MOVEset: ; RootPrim ; moveto: ; <200,100,25> ; <0,0,0> ; 0° // set a defined position in the sim

GX-FRAMEtime: ; Frame2 ; 5 ;1;

    GX-MOVElin: ; RootPrim ; startat: ; <200,100,25> ; <0.0,0.0,1.0> ; 0° ; moveby: ; <20.0,0.0,0.0> ; <0.0,0.0,1.0> ; 0°

    GX-SAYsay: ; 0 ; Hello Inworldz

GX-SEQend:

The object will start from the point <200, 100, 25>, and will move to <220, 100, 25> in 5 seconds, while accelerating from zero. Upon arrival the object will say «Hello Inworldz».

Names, indentations, comments:

-Prims are always identified after their name, save the root prim which is ALWAYS called «RootPrim». No need for prim number.

-Among the prims mentioned in your sequence, none must share the same name. If two prims have the same name, only one at random will respond to the commands, and probably not always the same.

-Names and texts are any valid notecard characters (ascii 256), including blanks, but obviously without the semicolon. No need for quotes.

-Values are separated with semicolons. It is indispensable to always set the semicolons between values!!

-Text beyond // is ignored. You can use this for comments.

-Blank lines or lines starting with // are ignored. You can use them for comments. Yet it is better to avoid them in production.

-Indentations are here for clarity. The script do not see them.

-Leading and trailing blanks are ignored.

 

The GX-SEQstart: command

GX-SEQstart: ; test sequence ; timemultiplier: ; 1 ; scalemultiplier: ; 1 ; overridephysics ; version: ; 1.0

This start a sequence, which is a succession of movements executed at the specified speed.

The first field, mandatory, is the command name, GX-SEQstart: ;

The second field, mandatory, is the name of the sequence, as it will appear in the command menu, or in automation messages. Any notecard character allowed (ascii 256) save of course the semicolon.

The other fields or group of fields are optional, and they do not need to appear in any defined order.

Time multiplier. These two fields timemultiplier: ; 1 ; can provide an overall scaling of the speed of the whole sequence. Default value is 1. Null or negative values are assumed to be 1.

The scale multiplier.These two fields scalemultiplier: ; 1 ; can provide an overall scaling of the movements size. Default value is 1. Null or negative values are assumed to be 1. This works well if for instance you resize a house: the movement of a sliding door must be resized by the same factor. But this does not work well if you specify absolute positions of the object in the sim, as in this case the movement will be resized relative to the 0,0,0 point.

Overriding physics. (not implemented in version V1). The GX-MOTOR script animates objects without using physics. It can as well animates prims in a physical object, like horse legs in a physical horse. However attempting to move the physical object itself can give unpredictable results. This is still needed, for instance a physical train may need the GX-MOTOR to be animated on a turntable. In this case, adding the field overridephysics: ; allows to manage the situation: the sequence will force the object non-physical, execute, and then restore the previous physical statute. In more complex cases, this command may clash with a physics controller. Then you can use an automation message instead.

The GX-SEQend: command

GX-SEQend: ; Next sequence

This marks the end of a sequence, and stops any execution.

The first field, mandatory, is the command name, GX-SEQend: ;

The second field, optional, is the name of the next sequence. If a sequence name is specified here, the ending sequence will continue using this new sequence. This sequence name must be one of the sequences defined in the data notecards. If you specify the same name as the running sequence, it will loop continuously. If nothing valid is specified, the sequence stops.

Time frames

A frame defines an indivisible segment of time. One sequence can contain one or several frames. There are several types of frames, and whichever is implemented depends on the version:

 

GX-FRAMEset

GX-FRAMEset: ; name

The GX-FRAMEset: is implemented starting in version V1. It is instantaneous (as much as a script can be). The commands it contains will be executed instantaneously: starting a sound, saying a message, moving to a place, etc. Commands involving a progressive movement are not allowed here.

GX-FRAMEtime:

GX-FRAMEtime: ; name ; duration ; acceleration factor

The GX-FRAMEtime: is implemented starting in version V1.

The second field, mandatory, is the frame name. Any notecard character allowed (ascii 256) save of course the semicolon. This is the name which will appear in error messages.

The third field, mandatory, is the duration of the frame, the time it will take to complete. This time will be rounded up to the next number of TimeQuantum (see the config notecard).

The fourth field acceleration factor If zero (or absent), the frame will be executed at a constant speed. Set to 1, it will accelerate starting from zero. Set to -1, it will brake until zero. There is a catch here, as the average speed of the movement will be half of expected. So that you need to multiply the duration by 2. Fractional values are possible too, for partial acceleration or braking. In this case the duration will have to be multiplied by 2/(2-acceleration factor) if acceleration factor is positive, or 2/(2+acceleration factor) if acceleration factor is negative. Excess values of acceleration factor are clamped to 1 or -1. Default value is zero.

In a general way, we cannot define simultaneously distance, speed and time, since they are related. So if you want to achieve a desired speed, you will have to calculate times as a function of the distance, especially for accelerations. This is where using a spreadsheet is useful.

An empty span style="color:#9900ff;">GX-FRAMEtime: will act as a plain delay.

Fast movements. In a GX-FRAMEtime:, if you set the duration to zero, the frame will not be instantaneous. Instead, it will last one TimeQuantum of time. This is by design, as it allows you to use TimeQuantum as a base scale factor. This can be used for very fast movements, or on the contrary for slow ones. For instance if you animate the hands of a clock, then setting TimeQuantum to one second will show the seconds hand moving in a realistic way. In more of saving lag.

If you really want a zero duration, use GX-FRAMEset: instead. But a succession of these will show the prims moving to the last specified position, making the succession useless.

Movements: the GX-MOVE commands

A FRAME can contain zero, one or several commands. Each command is on a single line in the notecard (despite there may be line feed here)

There are several types of GX-MOVE commands, and whichever is implemented depends on the version:

GX-MOVEset:

    GX-MOVEset: ; PrimName ; moveto: ; <0,0,0> ; <0,1,0> ; 0° ;

GX-MOVEset: is implemented starting in version V1. It can be used only into a GX-FRAMEset:

PrimName is the name of the prim to move. Any notecard character is allowed (ascii 256) save of course the semicolon. You do not need to bother with prim numbers, as in any case the GX-MOTOR calculates them. Important, the root prim must not be addressed by its name (this would give odd results in some cases) but by the generic name RootPrim. Among the prims mentioned in your sequence, none must share the same name. If two prims have the same name, only one at random will respond to the commands, and probably not always the same.

moveto: tells the prim the coordinates where to go. For a linked prim, it is the local coordinates in the linkset. For the root prim, it is the sims coordinates.

The first parameter of moveto is the position where to go. It is a LSL vector, the one that you can get from the build window, and copy paste in your sequence.

The second and third parameters of moveto: are the rotation, which is explained further.

GX-MOVElin:

    GX-MOVElin: ; PrimName ; startat: ; <0,0,0> ; <1,0,0> ; 0° ; moveby: ; <0,0,0> ; <1,0,0> ; -45° ;

GX-MOVElin: is implemented starting in version V1. It can be used only into a GX-FRAMEtime:

PrimName is the name of the prim to move. Any notecard character allowed (ascii 256) save of course the semicolon. You do not need to bother with prim numbers, as in any case the GX-MOTOR calculates them. Important, the root prim must not be addressed by its name (this would give odd results in some cases) but by the generic name RootPrim. You must take care that, among the prims mentioned in your sequence, none must share the same name. Should this happen, the script would address one of the two at random, and even not always the same.

moveby: tells the prim how much to move. It is a displacement. For a linked prim, it is in the local coordinates in the linkset. For the root prim, it is in the sims coordinates.

The first parameter of moveby: is the displacement vector. It is a LSL vector, the one that you can get from the build window, and copy paste in your sequence.

The second and third parameters are the CHANGE in the rotation, which is explained further.

startat: tells the prim where it must start. For a linked prim, it is the local coordinates in the linkset. For the root prim, it is the sims coordinates.

The first parameter of startat: is the position vector, the place where you want the prim to start from. It is a LSL vector, the one that you can get from the build window, and copy paste in your sequence.

The second and third parameters are the CHANGE in the rotation, which is explained further.

It should be noted that startat: is mandatory in the version V1 (otherwise the movement starts form <0,0,0>). This is awkward, as it much complicates the notecard (and needs a spreadsheet to calculate each startat: from the previous displacements). One of the most important feature planned for the V2 will be the ability for the script to sense the start position, so that you need to indicate only the displacement. Normally ascending compatibility should happen.

Rotation formats

There are four rotation formats, which can be used everywhere, and mix in the same sequence:

Euler: <0,0,90> ; Euler ; This one has three angles in degrees, in a vector. It is the vector you get in the build window, and you can copy-paste here.

Quaternion: <0,0,1,1> ; Quaternion ; This is the quaternion format, as it is used natively by the LSL scripts.

Axis Angle, degrees: <0,0,1> ; 90° ; The vector «Axis» is the direction the axis of rotation is pointing. For instance if a car turns on a flat ground, axis is upward, that is <0,0,1>. Note that it is different of the Euler vector, as each value is maximum 1 or -1.

Axis Angle, radians: <0,0,1> ; 1.570795 ;

The axis angle format is the internal format of the GX-MOTOR script, for the following reason: imagine you move the hands of a clock. From Noon to 3, it is perfect. But for Noon to 9, the hand moves counter-clockwise! The Axis Angle format corrects this, as it allows to specify a larger angle than 180°, here 270°: the hand moves from Noon to 9, clockwise. We even can go as far as specifying several turns in a single frame. The maximum speed is when we reach 180° in a single TimeQuantum, which usually makes 1800° per second, 5 turns per second, or 31.4 radians per second. This works only for moveby:, though. Moveto: and startat: are still limited at 180°.

relto command

This is the most powerful command, which allows you to set the movement of a prim A relative to a prim B. Think at animating a horse leg: the leg rotates relative to the hip, while the foreleg moves and rotates relative to the knee, thus compounding the two movements. Example:

GX-FRAMEtime: ; frameName ; 2.0 ;

    GX-MOVElin: ; Thigh ; moveby: ; <0,0,0> ; <0,25,0> ; Euler

    GX-MOVElin: ; Foreleg ; moveby: ; <0,0,0> ; <0,-50,0> ; Euler ; relto: ; Thigh

This will realistically fold a leg, rotating the Foreleg of -25°.

The difficulty yet is how to set the rotation center. For the Foreleg, it can be deported to the knee, if this foreleg is a mesh, and you add some extra very small triangles in such a way that the center of the prim is at the knee. This is similar to the trick of using slice to get a prim door to rotate around its hinge. This can work in some cases, but not all. For the general case, you need the following:

reltoparams:

GX-FRAMEtime: ; frameName ; 2.0 ;

    GX-MOVElin: ; Thigh ; moveby: ; <0,0,0> ; <0,25,0> ; Euler

    GX-MOVElin: ; Foreleg ; moveby: ; <0,0,0> ; <0,-50,0> ; Euler ; relto: ; Thigh ; reltoparams: ; <0,-0.5,0> ; <0,0,1> ; 0°

We still have the position vector and a supplementary rotation for the reltoparams. What the script will do with them is as follows:

-The rotation center for Foreleg is now the position of Thigh, but moved to the knee, by the reltoparams: vector (into a referential borne by Thigh, which rotates with it).

-If you specify a rotation for Foreleg, this Foreleg will not rotate around its center, but around the previously defined knee. Like a door formed of a single prim, without slice, yet rotating around a hinge which is not its own center.

Virtual prims

Now what happens if you remove the Thigh prim above? The Foreleg still moves the same way. The GX-MO script will simply issue a warning as that it considers the prim Thigh as a «virtual prim».

This is useful when you want a complex movement for a prim, without intermediate prims. Example: a flower opens its petals. Each petal rotates around an axis, which is itself moving. But this axis does not exist in real, so it needs to be virtual.

But there is more.

Animating the object with the VirtualRoot prim.

VirtualRoot always is a virtual prim (Do not use this name for a prim of your own, it will just confuse the script). It has a precise use: serve as a rotation center when you animate the object itself. CAUTION: while usually RootPrim has its position in the sim, in this case the position of RootPrim is relative to VirtualRoot, like another prim. It is the later which has its position in the sim!

See:

GX-SEQstart: ; roottest ; timemultiplier: ; 1 ; scalemultiplier: ; 1 ; notoverridephysics ; version: ; 1.0

GX-FRAMEtime: ;Frame 1; 2 ;0; // move eastward

    GX-MOVElin: ; RootPrim ; startat: ;<120,100,21>; <0,0,1> ; 0° ; moveby: ;<20,0,0>; <0,0,1> ; 0°

GX-FRAMEtime: ;Frame 2; 4 ;0; // turn from east to south

    GX-MOVElin: ; VirtualRoot ; startat: ;<140,120,21>; <0,0,1> ; 0° ;

    GX-MOVElin: ; RootPrim ; startat: ;<0,-20,0>; <0,0,1> ; 0° ; moveby: ; <0,0,0> ; <0,0,1> ;90° ; relto: ; VirtualRoot ;

GX-SEQend:;

The first frame moves the object from <120,100,21> to <140,100,21>

The second makes it draw a circle of 20m radius, centered in <140,120,21>

Also note that there are several ways to achieve the same functioning:

GX-SEQstart: ; roottest2 ; timemultiplier: ; 1 ; scalemultiplier: ; 1 ; notoverridephysics ; version: ; 1.0

GX-FRAMEtime: ;Frame 1; 2 ;0; // move eastward

    GX-MOVElin: ; RootPrim ; startat: ;<120,100,2001>; <0,0,1> ; 0° ; moveby: ;<20,0,0>; <0,0,1> ; 0°

GX-FRAMEtime: ;Frame 2; 4 ;0; // turn from east to south

    GX-MOVElin: ; VirtualRoot ; startat: ;<140,120,2001>; <0,0,1> ; 0° ; moveby: ; <0,0,0> ; <0,0,1> ;90°

    GX-MOVElin: ; RootPrim ; startat: ;<0,0,0>; <0,0,1> ; 0° ; moveby: ; <0,0,0> ; <0,0,1> ;-90° ; relto: ; VirtualRoot ; reltoparams: ; <0,-20,0> ; <0,0,1> ; 0°;

GX-SEQend:;

This one works differently, by rotating the VirtualRoot with moveby:. But it also has an interesting feature: rotating the RootPrim in the opposite direction (also with moveby:) makes the object always point toward the same direction! As a Ferris wheel pod which keeps straight up despite rotation. This works because it uses a vector reltoparams: instead of startat:. The tip of the reltoparams: vector rotates, carrying the object. Then the object itself counter-rotates around the tip of this vector.

Other commands

The commands described here allow for the GX-MO script to play sounds, read texts, or send error messages.

Text messages

A     GX-SAY commands says a text in local chat. Can also be used to send messages to objects.

    GX-SAYwhisper: ; Channel; text to whisper

    GX-SAYsay: ; Channel; text to say ;

    GX-SAYshout: ; Channel; text to shout ;

    //GX-SAYInstantMessage: is not implemented, because of the 2 seconds delay. Use a relay script

    GX-SAYowner: ; Channel; text to the owner ;

    GX-SAYregion: ; Channel; text to region ; (cannot be channel zero)

channel is the channel you want to speak in. Zero channel is the local chat.

The texts must contain NO SEMICOLONS. If you really need any, replace them with ↕ (ascii 18), they will appear as semicolons. If ever you need a ↕, then type two. Setting Verbosity to -1 in the config notecard shuts down even the text messages.

Playing sounds

A     GX-SOUND command allows to play a single sound at a time (for several, use a linked message to a sound player)

    GX-SOUNDplay: ; SoundName; volume

This plays a sound once. The sound names must contain NO SEMICOLONS. You may need to have it last the same time as the GX-FRAME it is in. volume is a number between 0 (muted) and 1 (max) (only starting with V2). You can also specify for instance -1dB, it will result in an attenuation of 1dB. Values in dB are more intuitive. Positive values of volume will not increase the volume beyond 0dB. However the syntax allows them for future uses. You also have:

    GX-SOUNDloop: ; SoundName; volume // start a sound loop

    GX-SOUNDstop: ; SoundName; volume

    GX-SOUNDvolume: ; SoundName; volume // changes the volume

    GX-SOUNDpreload: ; SoundName // will be in version V2

Note that a prim can play only one sound at a time. If you need several, you can make the GX-MOTOR send a linked message to a relay script in another prim. A working relay script is delivered within the GX-MOTOR box.

Sim crossing, warping and Position test

The GX-MOTOR can move objects through sim borders without special restriction.

Further, the GX-MOVEset: command uses the LSL function llSetRegionPos(), which makes the ancient «warping» technique obsolete: you can move instantly anywhere within a sim. llSetRegionPos() can also cross a sim border, but with a restriction however: only 10m of trajectory within the target sim. (which makes less than 10m from the border, if this trajectory is oblique).

This still allows for «warping» from sim to sim, with a series of GX-MOVEset:, and cross considerable distances nearby instantly.

However this exposes to problems if one of the sims is offline, or if one of the crossings fails. For this reason, GX-FRAMEtest: will be implemented in V2, to check if the crossing really occurred. The result of this test can be used to send an email, or to warn a controller script which may decide another course of action. But given the quantity of possible options, probably a separate «hyperdrive» script is preferable, for teleporting objects in sims away.

Error messages

The script can say various error messages, warnings, or simple info (like which GX-FRAME is playing).

You will get more or less such messages with the parameter Verbosity in the config notecard. Zero is recommended in production.

Linked messages

Linked messages allow for scripts to communicate with other scripts in an object. The GX-MOTOR script can send and receive some. This allows it to act as a time sequencer to start other scripts. It can receive messages to start sequences, or overriding running sequences. It can receive statute requests, and send statute reports.

Please note that this is still experimental in version V1. Simple messages work, but more complex ones were not extensively tested.

Sending linked messages from the GX-MOTOR script

A GX-LINKED: command allows to send linked messages to other scripts, within the prim or in other prims:

    GX-LINKED: ; PrimName ; Integer ; Text ; UUID

The conventions for these four values are the ones used in linked message.

PrimName can be any existing prim name (without semicolons, but it can also be one of the following TEXTS:

-RootPrim or LINK_ROOT sends the message to the root prim (and any script within)

-LINK_SET sends to all prims

-LINK_ALL_OTHERS ends to all other prims

-LINK_ALL_CHILDREN sends to all children prims, (everything but the root)

-LINK_THIS sends to script within the same prim

Note that these are texts, not the LSL constants. Writing the integer values will not work.

Although it is possible to place the GX-MOTOR script in any prim, it is recommended to have it in the root prim, especially if a customer has to add it to the object.

A simple full perms relay script to receive such messages is provided with the main script.

Controlling the GX-MOTOR script

The GX-MO script can also receive linked messages. Especially linked messages can start or stop sequences. For this precise purpose, the sender script must contain the LSL code:

    llMessageLinked( linkNumber, StopStyle , "MySequence" , "GX-MOTOR" ) ;

The conventions for these four values are the ones used in linked messages. See the LSL documentation on llMessageLinked on how to send messages from a script.

LinkNumber is the prim number where the GX-MOTOR is. NOTE that it is the prim NUMBER (not the name) or one of the special values: LINK_SET LINK_ALL_OTHERS LINK_ALL_CHILDREN LINK_THIS. Since this value is an integer, the prim name cannot be passed, and the sender script must manage itself to get the prim numbers on the fly, especially if the object may be modified. This is one of the reasons why the GX-MOTOR is better in the root prim.

This linked message will start MySequence. If this field is blank, then the running sequence is just stopped.

StopStyle is a number which controls which action will be performed:

StopStyle = 1 soft stop (default value), waits for the end of the sequence or of the loop turn, and starts MySequence if one is specified.

StopStyle = 2 mild stop, stops the running sequence at the end of the current frame, and starts MySequence if one is specified.

StopStyle = 3 hard stop, stops the running sequence at once, and starts MySequence if one is specified.

Be careful that 2 or 3 may leave your object broken in a random state. So that the starting sequence may need some GX-MOVEset: to reset the object or the prims in a defined position. If you just want to stop the running sequence without starting another, then start a short reset sequence with just some of GX-MOVEset:.

Statute requests and reports

This is more experimental in version V1. This means that exact syntax may be modified in V2.

Statute request

A controller script may need to know the current state of the GX-MOTOR, for a variety of reasons. For instance many vehicles become physical when a driver sits. However, when the vehicle is controlled by a sequence running in the GX-MO script, it must not be made physical at this moment, or this will result in an erratic behavior. To avoid this, the sit routine needs to know what the GX-MO motor script is currently doing, with a statute request. It is made with the following LSL code:

    llMessageLinked(linkNumber, 0 , "" , "GX-MOTOR?" ) ;

This is a statute request, specified by the «?» . It does not perform any action.

If you do not like the reply (see further) you can force the GX-MOTOR script with one of the commands above.

LinkNumber is the prim number where the GX-MOTOR is. NOTE that it is the prim NUMBER (not the name) or one of the special values: LINK_SET LINK_ALL_OTHERS LINK_ALL_CHILDREN LINK_THIS. Since this value is an integer, the prim name cannot be passed, and the sender script must manage itself to get the prim numbers on the fly, especially if the object may be modified. This is one of the reasons why the GX-MOTOR is better in the root prim.

Statute report

To receive the reply to your statute request, your script must contain the following LSL code:

    link_message ( integer SenderPrimNumber, integer OverridingPhysics, string message, key ID ){

        if (ID == “GX-MOTOR=”) {

            // your test on SenderPrimNumber, not shown

            list StatuteValues = llParseStringKeepNulls( message, [","] , [""] ) ;

            string GX-MOTOR-STATE = llList2String(LinkedValues, 0) ;

            string EndingSequence = llList2String(LinkedValues, 1) ;

            string StartingSequence = llList2String(LinkedValues, 2) ; // blank if none

            //Your LSL code here for interpreting these values

        }

    }

ID is the text: «GX-MOTOR=». The «=» sign tells it is a statute report.

SenderPrimNumber is the prim number where the GX-MOTOR is. NOTE that it is the prim NUMBER (not the name) or one of the special values: LINK_SET LINK_ALL_OTHERS LINK_ALL_CHILDREN LINK_THIS. Since this value is an integer, the prim name cannot be passed, and the sender script must manage itself to get the prim numbers on the fly, especially if the object may be modified. This is one of the reasons why the GX-MOTOR is better in the root prim.

OverridingPhysics = 0 tells that the GX-MO script is not overriding the physical statute

OverridingPhysics = 1 tells that the GX-MO script is currently overriding the physical statute. You must avoid to change it at this moment, for instance is a driver is sitting.

GX-MOTOR-STATE describes the internal state of the GX-MO script:

«loading» is when the GX-MOTOR script is resetting and loading data

«ready» is when the GX-MOTOR script is not active

«busy» is when the GX-MOTOR script is playing a sequence

«looping» is when the GX-MOTOR script is re-playing a sequence in a loop.

EndingSequence is the sequence actually running

StartingSequence is the sequence waiting for starting after EndingSequence, if any.

Spontaneous statute report

Whenever the GX-MOTOR script receives a statute request, it replies at once.

But it can send spontaneous reports in different occasions:

-when it changes the physics statute of the object

-at the end of a sequence or loop

-at the end of each loop turn.

The number of messages is set with the variable StatuteVerbosity in the GX-MOTOR-config notecard.

 

Messages with other objects

V2 will have a better system, and this syntax will probably NOT work in V2, since it is too vague and allow anybody to control the GX-MOTOR.

Waiting for this, there is a hack for the V1. You can start a sequence with the following LSL:

default{

    state_entry(){

    }

    touch_start( integer num_detected ){

        // This event is triggered when somebody touches the prim (whenever it is linked or not)

        // There can be other ways to start the following message sending code, with other events,

        // in a function, as a result of a calculus, etc.

        // MESSAGE SENDING CODE

        llSay(0,"touched");

        string SequenceName= "MySequence";

        llRegionSay(DialogChannel,SequenceName);

        // END of MESSAGE SENDING CODE

    }

}

A working full perm command script is delivered within the GX-MOTOR box.

DialogChannel is defined in the Config notecard. For the hack explained here, DialogTimeout must be set to a very high value, in order to look permanent. For instance DialogTimeout=1000000000