Below is a list of all Reflex 3 scripts available. Look to the navigation bar on the left (or in the drop-down menu) to browse the list.

This script is not required, but is strongly recommended for every scene, even when they don't have any other Reflex scripts.

Please click here to learn more about the console.

If you're looking to detect the presence of people, trigger volumes present one of the easiest options. However, bump sensors have their uses, too. This can be particularly useful for detecting when projectiles hit something, for example.

Whereas trigger volumes and proximity sensors send out bang messages when someone (or something) enters or exits their spaces, bump sensors respond to potentially rapid rates of collisions with them. They cannot tell you when someone leaves. Instead, they simply tell you that collisions happen and potentially are ongoing. One result is that the output bang messages do not have the ":On" and ":Off" suffixes added to the names like those other sensors do.

This script watches what people say in public chat and triggers bang messages when it sees the text you want it to watch for. You can use it to exactly match whole messages or in "contains" mode to match any messages that happen to contain the desired text. You could, for example, respond to any text that contains the word "fart" by triggering a fart sound using an audio emitter.

One component can respond to multiple text options, expressed as a pipe-separated list. For example, "pen name | nom de plume | alias". Although you aren't required to, we recommend that you use spaces around the pipe (|) symbols like this to make it easier to read your settings. Those spaces will be ignored. However, spaces within each phrase (e.g., "pen name") are still used in matching.

This component is case-insensitive. If, for example, someone chats "MY SECRET ALIAS IS MOLE MAN", the "alias" word will match just fine. The UserMustChatPsv options can also be capitalized; it won't matter to the matching.

Note that this script is not oriented toward parsing commands that include with parameters (e.g., "volume 11") because Reflex is supposed to be about simple, binary behaviors. Technically, you could write a script that listens for bang messages from this component and then parse the message that is carried along with it, but it would probably be easier to just write a custom chat listener script.

This functions nearly identically to the proximity sensor except that it only detects hand controllers for users in VR mode.

The user does not need to pull the trigger, unlike with a properly configured trigger volume.

Keep in mind that this excludes people who are in Desktop mode. Consider offering them a keyboard shortcut (e.g., F7) as an alternative and making it only applicable if they are close to where the button is.

It's useful sometimes to allow visitors to use keyboard shortcuts to trigger actions. For example, you might want to have a user pressing F7 teleport them back to the spawn point. Or perhaps have F8 give them a hint in chat about what to do next based on where they currently are.

Sansar currently offers only a very limited set of keys you can detect visitors pressing. Here is a summary list:

W | A | S | D | F | Space | 1 - 9 | F1 - F12

For a full list of the current keys, see one of Sansar's own sample scripts that uses keyboard shortcuts.

You can express keys using Sansar's notation (e.g., "Key_F4") or using the more familiar shorthand (e.g., "F4").

Be aware that some of the keys are already used in existing keyboard shortcuts for Sansar. For example, F3 is used to toggle between first person and third person camera view. The script may detect this key-press, also, but it will not stop the built-in behavior. You should avoid trying to capture these existing keyboard shortcuts. And you should be aware that Sansar is in an early beta, so keyboard shortcuts will probably change over time. Similarly, the keys available will likely change over time.

Locks are typically fixed in place, though they can be moveable, too. You typically want your visitors to find and pick up dynamic key objects and place them near this lock. When someone does this, you may want to open a door, play a sound, etc. In the example of a door, you might wish to close the door when the key is taken away.

This lock-and-key concept relies on some awkward limits of the Sansar client right now. Desktop mode does enable users to pick up and drop or throw objects, but it is very limited. Even in VR mode, it can be challenging to precisely place objects. And the physics engine probably will not play nicely with attempts to slide keys into slots and other designs that require precise fits. Keep these things in mind when designing locks and keyes.

A lock can detect a key moving into range and also detect it moving back out of range. It can also detect when some other key object moves into range and trigger wrong-key bang messages. You might play a negative sound or emit some chat to let the visitor know it's the wrong key.

A lock can recognize more than one key as valid. A key can only have one name, so a lock can have a comma-separated list of valid key names (e.g., "Red, Green, Blue").

Also, you can have multiple copies of the same key (name). If two valid keys are placed in range of a lock, two "<Name>:On" bang messages will be sent.

Each lock will typically have one or more keys that fit. You can place them around a scene and then optionally configure them to return home once they are used.

A key can fit more than one lock, too, provided each of those locks uses the same lock-name as the key's FitsLockName setting.

A key is considered in the range of a lock if its own (relative) origin point is inside the imaginary sphere defined by the lock's NearPosition and WithinRadius values.

Most Reflex scripts do not emit script-to-script chat messages except when some important event happens. This is a rare exception. Each key in a scene sends out a "here I am" message once every UpdateSeconds. The locks watch for these messages to detect when right or wrong keys come into range. Keep this in mind when deciding how many keys to place in a scene and what to set UpdateSeconds to for each.

This is the quintessential OK/Cancel type dialog box. You have some sensor or logic component trigger it to display it to someone and they are forced to make a choice. This is a little intrusive, so use it with care. Be aware that this does partially black out their viewer and block the user from doing some things like chat.

You can also use this as a simple notification mechanism, too. If you leave one of the buttons' labels blank, that button won't be visible. Also, if you leave both blank, the red option-2 button will have "Close" as its label. Again, use this tactic sparingly. The chat window is generally a less intrusive way to give users nonessential notifications. See the chat emitter script, too.

You have control over the messaging, including what's on the two buttons. For the main message, try phrasing it as a concise question, possibly as a sentence fragment. For the buttons, be super concise and very clear about the positive and negative options. Here are some examples:

Teleport to my store?
No, thanks
Teleport
Delete this item?
Cancel
Delete
Settings have changed. Save now?
Cancel
Save
You've won a million dollars!
 
Yay!
You are likely to be eaten by a grue
Run
Hide
One day you're gonna wake up dead
Okay, mom
Whatever, mom

Like the trigger volume, this script is generally made to detect people entering and exiting a volume of space. Whereas the trigger volume is defined by a cuboid, this one is defined by an imaginary sphere centered at NearPosition. The PerPerson setting determines whether that position is absolute to the scene or relative to the dynamic object it is put into.

This sensor and the trigger volume script behave very similarly, but there are some key differences. The cuboid versus spherical volume mentioned above is one. Another is that trigger volumes can detect objects and limited hand controller interactions. One benefit of prox sensors is that there isn't a big, blue volume obscuring your view while editing a scene.

Another benefit is that there is no practical upper or lower limit on the size of a prox sensor. One very useful application is to detect when a person enters and exits the entire scene, which happens if you leave WithinRadius as zero. Similarly, if you switch BelowPosition to On, the volume then becomes all space below the elevation (Z value) of NearPosition.

This script is meant to be dropped into a Trigger Volume system object for use with it. One distinct benefit of this over a prox sensor is that you can see the volume represented as a translucent blue cuboid box while you are editing, so it's fairly easy to visualize.

It is important to point out is that if you are trying to detect people walking through the volume, you must make sure that the volume penetrates the ground they walk on. This is because an avatar's location is represented by a single point in space. That point is between their feet right on the ground. So if you make the mistake of placing the trigger volume slightly above where they will walk, they will literally walk under it and not be detected. But this also means you can put a large volume way down into the ground and only show the thin top of it poking above for detection. This can make it easier to see the rest of your workspace.

Linden Lab plans to eventually make it so users can jump. If you set up small trigger volumes, you may find users unwittingly jumping over them someday.

One other distinct benefit of a trigger volume is its ability to detect users interacting with things in VR mode with their "hands". Presently, a trigger volume will only recognize what can be described as a "punch" or "pinch". It cannot detect a hand merely passing through the volume. The user must either pull the trigger on that hand before moving the controller into the volume (punch) or must put the hand into the volume and then pull the trigger (pinch). Still, this means you can make things like wall switches using trigger volumes, provided you give the user a clear enough visual target to aim for. You may also need to give them explicit instructions, as this is a very new feature that users are not familiar with yet.

One interesting aspect of trigger volumes is that they behave like dynamic objects in that they can be moved. You could, for example, use a door script to move one between two locations or a rotator to swing it around in a circle as though on the end of a string.

This is a versatile way to add sounds and music to your scene, but there are a lot of things to consider. First, your best bet is to drop this into an Audio Emitter system object, although you can also put it into a dynamic or even static object from your inventory. One benefit of an audio emitter object is that you can see it while editing the scene, but it is invisible to visitors at runtime, so it's easy for you to visualize when creating. Another is that you can control the shape of the sound space by editing the Audio Emitter object's properties. (Don't select a sound or bother with its Loudness setting on the Audio Emitter; these will be ignored by this script.)

One of the most important reasons to favor using an Audio Emitter object with this script instead of another kind of object is that an Audio Emitter can move and the sound it emits can move with it. To do this, you must add an Audio Emitter object to some other dynamic object like a vehicle, a rock, a door, etc. Right click on that object in the "Scene Objects" list and choose "Add" and "Audio". Then you can click on that object to work on it. But also, you'll add the script to your dynamic object and, when it runs, it will find the Audio Emitter object.

In the most basic case, you can make an instant-on and forever-looping sound using this script using PlayImmediately = On and LoopPlay = On. That may sound roundabout, since you can also do this using an ordinary Audio Emitter with no script, but there is still a key benefit. As with all Reflex 3 scripts, you can use the Reflex console to adjust the loudness of your audio. And if you set PlayNamesCsv and StopNamesCsv, you can make it easy to stop and restart your sound. These can be very handy for disabling or turning down background music for special events, for example.

The LoudnessDb setting is one of the trickiest settings to get right among all Reflex script settings. And, frankly, among all Sansar audio challenges. One reason is that Sansar actually does a good job of audio leveling. If, for example, the volume of some sound is really high, Sansar will compensate by lowering the volume of all other sounds instead of blowing out your eardrums. This gives your ears the feeling that the sound is really loud, simply by contrast. However, it can also leave the scene designer very confused at times. But this really is where the Reflex console comes in very handy. This allows you to explore your scene's soundscape and interactively tinker with sound volumes. As long as you're writing down the LoudnessDb values you come up with along the way, you can go back into edit mode later and update your scene with the new values. Consider asking a friend to help by holding a light conversation with you while you tinker with loudness settings and asking their opinions of these values.

One interesting feature of this script is that it emits a bang message when the sound is done playing. This only works if you don't set it to loop, though. You could use this to open a door at the end of some speech, for example. Or to start another audio clip playing when one is done. You could even use this as a very simple sort of song playlist by having each song trigger the start of the next one as it finishes.

If you trigger the sound to play while it is already playing, the current playback will stop and the new one will immediately start.

This script is analogous to the audio emitter script. It allows your scene to "talk" to your visitors via chat messages. This has some unusual and interesting properties worth noting, however.

First, you can limit who sees your chat messages. In Sansar's current design, users cannot do this. Anyone who types in public chat will have their messages seen by everyone in the scene. This script, however, can send individual messages, one by one, to only those people in range (RelativePosition, NearPosition, WithinRadius). This can be useful in gameplay scenarios where multiple groups of players are at different stages along the way.

What's more, your ChatText setting can contain a few special template fields that are customized to each recipient. {FromUuid} and {FromName} represent whoever tripped the trigger volume or other sensor that triggered this script. And {ToUuid} and {ToName} represent you, the recipient of the chat message. You can also add "\n" to your text to insert a new-line into your text. Currently, you can't do this explicitly with text settings. You can also add "\b" to represent a backslash (\) character in the really unlikely situation that you need to represent "\n" as literal text (using "\bn") and not as a new-line character.

Most doors in the real world have a hinge on the left or right and we pull them out or or push them in to open and go through them. This script manages those and some other more unusual types of doors and door-like objects, like draw bridges and flip-up hatches. You can also use this in some special cases to swivel decorations or game objects into and out of place.

The key to properly defining a door lies in the HingeOffset and HingeRotation settings. Picture an imaginary straight line passing through the center of the hinge on a real door. If your door object's origin is already along that line, you can leave HingeOffset a zero vector. But let's say your door's origin is dead center of the object and your hinge will be on the left side (from your perspective). If the door is 1m wide, then your HingeOffset value should be somewhere near <-0.5, 0, 0>, but depending on its orientation, it could also be <0, -0.5, 0> or otherwise. HingeOffset is relative to the door's own coordinate system. If you physically rotate it in your scene, you may be confused about the X and Y directions for this. Consider using the Reflex console to interactively experiment with different values for HingeOffset until you figure it out.

The HingeRotation setting can be even trickier to figure out if it's anything out of the ordinary. This value relies on the standard right-hand rule. If you have a typical door, this will be <0, 0, ±90>. For a slightly more realistic feel, try using ±110° or some other non-90° angle. For a door that opens up or down, you'll use <±90, 0, 0> or <0, ±90, 0>, depending on the intrinsic orientation of the door within its own cordinate system.

The number of output bang messages can seem daunting at first, but they make a lot of sense when you realize how much control they give you over how a door might sound. In a trivial scenario, you could use the <Name>:StartOpening bang to start a long sound that includes the door unlatching, then creaking a bit, and then maybe stopping at the end. Then you might use the <Name>:StartClosing bang to start a similar sort of closing sound culminating in the final latching sound. However, the door's opening or closing could be interrupted. In that case, your sound would not line up with what the user is seeing. If, for example, the door starts closing and then someone steps into a trigger volume to start it opening again, the user would hear the rest of the closing sound, including the latching, even though the door is now opening. For more sophistication, consider using the <Name>:CancelOpening and <Name>:DoneOpening messages to stop the audio for an opening. Likewise for the closing sounds. This may still not be perfect, so it might actually make more sense to break your door's sounds up into smaller parts. Consider a buzz signalling that an automatic door is starting to close and triggered by either <Name>:StartOpening or <Name>:MidOpening and then a separate grinding-to-a-stop sound triggered by <Name>:DoneOpening. In any case, you have a lot of fine-grained options.

You could likewise use some of these bang messages to trigger turning on lights, emit chat messages or perform other actions.

Many of the extensive details for the hinged door script also apply to this one for doors that slide back and forth. Please consider reading it for context.

The most significant difference is that hinged doors have HingeOffset and HingeRotation settings, while sliding doors only have a SlideTrack vector to set.

This script can be used to create surprise behaviors like rock slides and flipping cars. With a rapid series of bangs and RelativeDirection = On and some LvPlusorMinus and AvPlusOrMinus values, you could even create the appearance of a group of rockets or birds taking off suddenly.

To a casual viewer, a nudged object will appear to be driven by an explosive force because it will immediately start moving without any time to accelerate.

The LvPlusOrMinus and AvPlusOrMinus vectors are optional but should not be overlooked. Keep them at zero if you want very precise control and exact(ish) repeatability of a behavior. But if you want some random variation in each repetition, consider bumping these up a little. This can be especially useful when you are nudging more than one thing at the same time and want them to seem natural.

Keep in mind that you probably want to reset the position of the things you nudge for visitors who come along after the one you just surprised. Here's where you'll want the return home script.

When people interact with loose objects in your scene, they are liable to scatter them around and leave the scene less usable for the next people to come along, so you want to have some sort of automatic cleanup. It could be sports equipment people play with, for example. Or rocks you kick up using the nudge script, for another.

The "home location" is determined 3 seconds after this script initializes. That gives your object some time to settle into its home position. The HomeRadius setting gives it a fudge factor in which to settle initially and upon return. So long as the object stays within that bubble, the AfterSecondsAway timer won't start running to auto-return it. Note that this feature is optional and is not on by default because AfterSecondsAway defaults to zero.

Chances are that you will simply want self-cleanup using AfterSecondsAway and possibly WhenBeyondRadius, but you can also explicitly trigger a return, too, via one of the TriggerNamesCsv options you set.

Although what this script does can be surprisingly simple to set up and understand in a basic case, it can get quite frustrating to fully grasp and apply in more complex cases.

Just about the simplest thing you can do is set up a slowly rotating turntable or floating, rotating object. If you don't touch any of the settings other than the Center and switch StartImmediately to On, you're all set with a starting point. You may want to change the RotationsPerSecond, as you might get dizzy with the 1-per-second default rate.

Try tinkering with the other vectors using the console at runtime. This will let you rapidly experiment with different behaviors.

The most mysterious setting is undoubtedly SpinDirection. Let's say you wanted to go from the default of counter-clockwise on the Z-axis to clockwise on the same. You might think that you could just tinker with the Z value of this vector, such as <0, 0, -90> versus <0, 0, 90>, but this won't change the direction of rotation at all. It's more like turning an old record player 90° on top of the table it's resting on. The record will still keep spinning the same direction. As described above, it's best to think of SpinDirection as a gimbal that a spinning top is inside of. To reverse the direction of spin, you would flip 180° the X or Y values, so <180, 0, 0>.

Not surprisingly, if you want the rotation to be vertical on the X axis or Y axis, as with a ferris wheel, you would go ±90° on either the X or Y values, such as with <90, 0, 0>. Again, try experimenting with different values via the Reflex console while visiting.

One interesting aspect of the spin direction is that this script will preserve the original orientation of the object at the start direction of the cycle. As it rotates, the object will maintain that orientation relative to the rotation direction. Most often this is intuitively what you would want, but if it's not, you'll need to tinker with the Tilt setting to correct for this.

One thing to note is that when one of the StopNamesCsv bang messages comes in and rotation stops, the object will stay where it was just before the stop. And when a StartNamesCsv bang comes in, it will start up at that same location, picking up where it left off. I originally had it reset to the original orientation, but in my testing, the sudden jerk of this reset seemed unnatural. And I couldn't think of many applications where a reset would make more sense than a continuation. I would have liked to have added a ResetOnStop boolean setting, but a script cannot currently have more than 10 settings and this setting was not as important as all the others. I had to make similar compromises with every Reflex script you see that has 10 settings.

Paired with a people sensor like the trigger volume sensor, this script enables teleportation of people to other parts of the same scene or to the spawn points of other scenes. Note that this will only work when the bang message carries the ID of a person to teleport with it. If, for example, you used a trigger volume configured to detect objects, it would not do anything when an object sends a bang message that this script listens for.

If you want to send someone to another experience or scene within your experience, you'll need to provide both the ToSceneOwner and ToSceneName settings. You can copy them directly out of the URL for the scene (e.g., " https://atlas.sansar.com/experiences/sansar-studios/zen-garden"). If you don't, it's assumed you mean to teleport someone within this scene.

If you do teleport someone to another scene, keep in mind you can't say where within that scene they will show up. They'll show up at one of the spawn points like anyone else going there. So don't bother with the RelativePosition or ToPosition settings in that case.

You can add a teleporter to a moving object and have its current position be the teleport destination, even. In that case, ToPosition is relative to the object's current position and orientation. This is handy for teleporting onto a moving vehicle, for instance.

In spirit, this is a classic boolean "and" gate. The idea there is that all inputs must be simultaneously on (or 1, true, etc.) for the gate to output an on signal. But Reflex's model complicates things to the point where more explanation is required. The most notable difference is that Reflex does not entail live voltages or otherwise continuous flows of information. Instead, Reflex is about sending signals only when things change. So this script has its own memory.

Picture a game where there are two buttons near a door and you must push both of them in turn to make the door open. So maybe you add two trigger volumes on the wall around your switches. You also set up toggles for each trigger volume so that each time you hit a button, it toggles that button on or off. You might use a sliding door script to move some model into place to indicate when each switch is on or off. You name your toggle switches associated with each door button "Toggle1" and "Toggle2". Those scripts are great because they already output bang messages like "Toggle1:On" and "Toggle1:Off", which is what this script requires. You set this script's InputNamesCsv setting to "Toggle1, Toggle2".

It's critical to distinguish this from most other Reflex scripts that ask you for lists of actual bang message names like "Toggle1:On". InputNamesCsv is not a list of bang names. It is instead a list of bang name prefixes like "Toggle1". This script will listen for those bang messages that begin with these prefixes and end with ":On" or ":Off" (case does not matter).

The InputNamesCsv setting is best thought of as a list of all the "and" inputs. That means every one of the inputs must be signaled as "Input name:On" before this script will switch from Off to On and output a "<Name>:On" bang. When any bang is received that is "Input name:Off" for any one of the inputs specified in InputNamesCsv, this script will switch from On to Off and output a "<Name>:Off" bang.

Note that this will only send out bang messages when a change of input would switch the output from Off to On or vice-versa. If an input would not change the output state, no bang message will be sent.

One practical consideration is that this script will not be aware of the state of other logic or sensor scripts before they send out their own signals. So a toggle that this script uses as an input might already be switched to On by default as the scene powers up, but this and gate will not be aware of that. In that case, you would need some way to ensure that that state information gets explicitly sent to this script, perhaps by having a random script set up for a delayed one-shot firing on startup. A better option would be to always expect the input values to be off by default to eliminate this complexity.

It is possible to bias some input values to On. Add to the DefaultOnsCsv list any input name that you want to be assumed to be On by default. Then it would be up to whatever provides the on/off bang messages to tell this that that input value is now Off. For example, you might have a way for a user to remove a lock key object from its lock, which would send out an ":Off" signal. That might be used as input to an and gate that then stops letting signals through.

It's complex enough to make sense of all the above when considering the case where PerPerson = Off. The per-person mode makes it even more complex. The idea here is that this script can be used to maintain state information about each person that visits your scene. (Technically, any object, too, but let's focus on people.) For example, you might want to require each visitor to go to 3 different locations in your scene before you'll let them use a teleporter to the next game level. You might set up proximity sensors for each of the three locations. Those already output "<Name>:On" and ":Off" bang messages. However, you wouldn't want the ":Off" messages, so you might use rebang scripts to only report the ":On" messages to your "and" script. (Make sure their names are something like "Rebang1:On" and not simply like "Rebang1"). Thus your "and" script will keep track of each user having visited each site. You could then use your teleporter script to teleport the person immediately once they have visited the last required location, regardless of which order they visited them in. Or you could add another input to your "and" script that responds to the user stepping on a trigger volume to start the transport process. Thus your InputNamesCsv might look like "Rebang1, Rebang2, Rebang3, TrigVol1".

If you have PerPerson = On and a visitor leaves the scene, they have a 5 minute window in which to return before this script forgets their current state of inputs. In the above example, they would have to visit all 3 locations again.

The key concept is that this script is a powerful way to enable your game to keep track of a combination of states for the whole scene or for each user.

One complication relates to mixing of per-person information with anonymous information. Consider a modified version of the above teleporter example in which the lights are flickering on and off, perhaps because the power in the game world is not reliable. The teleporter won't work without power, right? To make the lights flicker on and off, you might use a random script feeding a toggle script, which in turn feeds a sliding door script that moves a big light into and out of place, simulating a flicker. The toggle script might also feed your and gate above as yet another input. So your InputNamesCsv setting might now be "Rebang1, Rebang2, Rebang3, TrigVol1, Toggle1". In this case, Toggle1 is not passing along an agent (visitor) identity, so that seems to break the per-person model. Fortunately, this does still work. When an input bang message comes with an agent ID attached, the on/off input gets stored with the state for that person . If it does not come with an identifying ID, as the Toggle1 bang won't, it gets stored as shared-state information. When checking to see if a person's state has all the inputs in the On state, the and gate will consult both the per-person state's and the shared state's input values. So in our example, Rebang1, Rebang2, Rebang3, and TrigVol1 inputs' bang messages will carry identity information, so their on/off states will be associated with that visitor and Toggle1 input values will be shared by all visitors.

The ResetNamesCsv list gives you a chance to clear out state information person by person (if PerPerson = On) or clear all visitors' and shared states at once. If one of these bang messages carries the ID of a person and if PerPerson = On, only that visitor's state will be cleared. Note that resetting does not cause any bang messages to be output.

One way of thinking of this is as two rebang scripts ganged together to output two different bang messages. But those messages are going to be in the form of either "<Name>:On" or "<Name>:Off", thus making this one way to package outputs from other Reflex scripts that don't already fit the On/Off paradigm. This is largely meant to serve boolean logic scripts like and gate.

One special use for this is as an "inverter". Let's say you had a trigger volume named "TrigVol1". It will output "TrigVol1:On" and "TrigVol1:Off" bangs as people enter and exit its volume. So if you wanted to have the opposite, where On becomes Off and Off becomes On, you could wire up a booleanize script with OnNamesCsv = "TrigVol1:Off" and OffNamesCsv = "TrigVol1:On".

This is a pass-through script, meaning it will pass along the identity of people or objects and other optional arguments from the source bangs.

This is a basic count-up or count-down counter. You could use it to count how many visitors are currently in an area tracked by a proximity sensor by catching the output of that sensor (e.g., IncrementNamesCsv = "Prox1:On", DecrementNamesCsv = "Prox1:Off"). Or you could track how many visits (not unique people) that area by only incrementing.

The output for this numeric component is still bang messages. But those bang messages also carry numeric information, which can be used by other scripts. Moreover, you can tap into several different bang outputs. The "<Name>" one is a good default reflecting when the gradually changing value, all up to (but excluding) when it hits Limit. So if you want to respond to every value change, be sure to also capture the "<Name>:Limit" bang. The "<Name>:Up" and "<Name>:Down" bangs also get fired when a counter's value changes, but with an important difference: they will be fired when the limit is reached.

A note about values reported. The "<Name>" bang will never report a past-the-limit value because it will never be fired when the value is at or past Limit. However, the "<Name>:Limit" bang will report the value computed when the limit was reached or surpassed. If, for example, InitialValue = 0, IncrementBy = 3 and Limit = 5, the first call to increment will set the counter to 3 and the second will set it to 6, which is beyond the limit. Thus, "<Name>:Limit" will fire off and carry 6 as its value. However, internally, the value would either be clamped to 5 or reset to 0, depending on what ResetOnLimit is set to. The "<Name>:Up" and "<Name>:Down" bangs also report this computed value. As such, you should not consider the values reported by "<Name>:Limit", "<Name>:Up", and "<Name>:Down" to reflect the actual current value. Your application is likely to already know what Limit is set to, so you would decide how best to interpret the different bangs available.

Like some other Reflex scripts, this one can be per person. That is, each person (or object) can have its own counter or this script can be used as just one scene-wide counter. These two modes both have a lot of potential for game-play. For example, a per-person counter could be used to represent how much "life" a player has. The configuration, for example, might be like so:

Then you would want to listen for the "Health:Limit" bang to determine when the player has "died".

This can be used to schedule a future bang message to go out a fixed amount of time after another one is received. Generally, you want it to be a different bang name, but you technically can use the same one, should you want some sort of echoing.

One use of this script would be to have a delayed teleport after a person hits a trigger volume.

The RepeatTimes feature can have some interesting uses. For example, you could use it to trigger multiple repeats of a sound. Or you could add a nudge script to a rocket and use 9 repeats of the original launch bang to have it behave more like a rocket launch than just a one-shot explosion.

You wouldn't want to add more food to the dog's bowl every time it showed up, right? It makes sense sometimes to throttle repetition of triggered behaviors or even to limit it to a single repetition per session. This is one form of user state memory for implementing many game-play scenarios.

One example would be a greeting or advice you give in chat or audio to someone who walks over a trigger volume that you don't want to keep repeating if they trip it several times in rapid succession. You might set ResetSecondsAfterLast to 30 seconds. If it's for audio instructions, you probably want PerPerson to be Off. But if you want to send private chat, you would certainly want PerPerson to be On.

This script uses a specific concept of "session" that isn't the same as Sansar's. (This only applies when PerPerson is On). It is by agent ID. If you are logged into the same scene twice, it sees both of you as one person and thus one session. And if you go into My Looks, crash, or otherwise leave the scene, you have a 5 minute window to return before it forgets that you have tripped this script. If you return after that, it's like you were never here to begin with. Also, keep in mind that the scene may be unloaded and reloaded later, in which case this script forgets everybody.

It's easy to understand the idea of tracking the state for every individual person, but in truth this can also track the state of individual objects when PerPerson is On. If, for example, you had a dynamic football object, and a bump sensor that was reporting collisions with objects, the football would be treated like a person that just never logs out.

Although there are many settings that govern how this script works, it's handy to think of it as a combination of several distinct functions. First, it can be used to send out one bang message (same as the Name setting) on a random schedule. Let's say you chose a range from 0.1 to 3 seconds. Once the cycle starts, the script will choose an amount of time (e.g., 2.739 seconds) at random that falls between those bounds and can include exactly either of them.

The second function here is the ability to send out a bang message chosen at random from a fixed set of names on some schedule. If you set the time range so the min and max are exactly 5 seconds, for example, it would send out one of those randomly selected bangs roughly every 5 seconds. To this you can add the random schedule described above, of course.

Most other Reflex scripts naturally have one or more bang outputs derived ultimately from the single name of each script (e.g., "TrigVol1:On" and "TrigVol1:Off"). This script gives you the ability to specify more than one option by adding the extra options (after the name) via the AltBangNamesCsv setting. For example, you might name your script "Growl" and set AltBangNamesCsv to "Whisper, Purr, Yelp", bringing the total options to 4. With this you could, for example, randomly select from a set of different sounds to play via multiple audio emitter scripts.

This randomized emitter of bang messages typically gets used in applications that require an ongoing string of reactions like playing sounds or opening doors, but you can override that behavior through the StartImmediately, OneShot, StartNamesCsv, and StopNamesCsv settings.

Picture a simple raffle giveaway in which one random person is chosen to receive a teleport offer or a private chat message with a coupon code. Maybe it's triggered once every five minutes by a random script or every time someone enters an area. This script doesn't do the timing, but it does, upon request by some other script, select one person (avatar) and pass that information along. The bang message that goes out contains the identity of the selected avatar in the same way that, say, a trigger volume configured to detect people does, so that person's identity can be used downstream.

Note that every time a selection is requested, there will be a bang output. It will either bear the name of the script ("<Name>") or "<Name>:None" if nobody was selected. This enables you to get notice of the failure case, too. And you can require a certain minimum of people to be nearby before you'll select anyone from among them.

Like many other scripts, this one can be limited to a spherical space fixed at some absolute position or relative to the object the script is in. This allows you to select only from people inside that space and exclude everyone else in the scene from consideration.

This can be useful for distilling a bunch of different bang signals down to a single one. Or for renaming, which can be useful for making switchboard functionality in very complex scenes.

Picture a play/pause button on a video player. That's a toggle button. This logic script reproduces that on/off toggle behavior. Each time a triggering bang is received, the state switches to the opposite of its current state. When the state switches, an output bang is immediately sent with the new state indicated in the bang name (e.g., "Toggle1:On").

You can use this per person or as a single thing for the whole scene. A shared resource like a door is a good example of a per-scene toggle. A light bulb floating above each visitor's head is a good example of a per-person use of a toggle for switching each bulb on and off (e.g., by swapping out models).

The cool thing about per-person mode is that this script keeps track of state for every person (or object, if your input bangs reflect that) that is in your scene. If the person leaves or crashes, they have a 5-minute window to come back before this state gets cleared out and thus the "memory" for that person is lost.