Rez smart, save space, be lazy: Modularization

•January 19, 2012 • Leave a Comment

Big things. Second Life hates them.

So it falls upon us, the LSL life-givers of the grid, to make it easier to deploy, move, and rotate our multi-segmented structures.

Thomas Conover built this Platform Rezzer tool, which demonstrates the same principle of simple modular deployment.

But this is half of the lesson plan. I also want to make moving and rotating these giant builds easier.

Fun fact: the content of this post and the scripts within have been completely overhauled and rewritten three times to date. >=/
But it’s done, I can’t complain.

SO, you are now faced with another script pair for this lesson, and we’re going to have to be able to distinguish between them while explaining the logical flow.

We have >modular.core, and >modular.segment.


Development Stage 1: Co-ordinating our efforts

First off, let’s take a look at the global vars we will use:


This build will operate via chat commands by the owner through channel cmdchannel. Commands such as ‘compile’ and ‘deploy’.
Line 1, datachannel is the line of communication between the core and all other segments.
While segmentlist will contain the names of all segments to be affected.


Here, we have 2 vectors, whereibelong and howiamsupposedtobe, which will represent this segment object’s position and rotation (in Euler values) in relation to the core object.
Line 2, corename is important, for we use a sensor which locates the core to do our operations.
And you already know about datachan.

With these, we have the basis of coordinating one core and many segments together.
The following lines explain the process.

It all begins when the Owner says “compile“.

Remember that the core name is important.

Speaking “compile” forwards the command to the segments, who do most of the work.


It is here that the corename is recorded for the following sensor search:

In this search, we figure out the core‘s position and rotation (again, in Euler), from which we subtract the segment object’s position and rotation. This will give us the difference, which will ensure that however the core is oriented, the segments will align again properly.
Now, if all this 3D mathmaticing intimidates you, there’s a great reading (albeit pretty long) on rotations in Second Life, and the difficulties and solutions.
>http://eowyn.bigpondhosting.com/SecondLife/SecondLife_WindMill_1.html

Long, long, long, long story short in a few pointers:
-Rotation +/- another rotation must be done with two rotations converted to Euler (http://wiki.secondlife.com/wiki/LlRot2Euler)
And when you convert to Euler, don’t forget to use RAD_TO_DEG.
ex: (euler)Rot1 + (euler)Rot2 = (euler)RotNew
-When calculating a position in relation an object, we must not forget to multiply that pos vector by the rotation (not as a Euler val, but as rotation) of the core object, in order to align its placement correctly. *This is will appear in the next stage when we deal with placement
ex: CorePos – (MyPosOffset * CoreRot)

This actually concludes the first piece of logic. The core merely issues commands to the multiple segments involved, which all retain their own personal positions and rotations relative to the core object. The core also stores the names of these segments, for when after compiling has been completed, you may Take Copies of each segment and place them inside the core for quick deployment and positioning (what I like to call Build Blooming).


Development Stage 2: Places, everyone!!

This is the fun part; watching everything reposition itself when the core is moved or rotated.

We begin with 2 possible initiators of the “reorient” command. Unfortunately, there’s no way in LSL (perhaps only of which I know) to merge handlers for an object having been moved and/or rotated into one, so we’ll have to make due (though it is a little unsightly).


The timer event weighs the last recorded changed rotation, lastrot which is declared globally, and the current rotation, to see if there was a change. And if there was, go ahead and reorient.
The moving_end event is a straightforward LSL event triggered by, you guessed it, moving the object.


A line in the listener sends the script into state orientmode when the proper command is heard.

Once again, the sensor is key to working with wherever the core has been moved. Again, we detect its pos and rot, and apply the offsets saved; whereibelong and howiamsupposedtobe to get our new placements.
This is where NewPos = CorePos – (MyPosOffset * CoreRot) comes into play.


Development Stage 3: Destroy & Deploy

When you’re sure all segments have been injected with the seg scripts, that compilation works flawlessly, and everything is where it needs to be, you are free to Take or Take Copy of each segment and place it into the core for Rezzing.

Scripting this part is easy peasy by now. Just a looped llRezObject sequence through our list of names stored in core.

Command: “deploy” in the cmdchannel

For each name in our segment list, poop it out. Wait half a second, then order everyone into position.


Huzzah!!

Now I’m modularizing freaking everything.

*Current known bugs
-the moved_end event does not always fire for some raisin
-the core must be at an angle of <0,0,0>, or will skew all placement
-segments originally placed at certain angles are also prone to skewing
*To-be-updated list
-intelligent interaction between multiple cores (subcores)
-chained rotation for subcores

Let’s make a HUD – pt.2 – Fun with essentials

•October 11, 2011 • Leave a Comment

Time to Level Up our Toolkit.

Here we go!!

Let’s start with renaming+shortening some global variables we’re going to be using often in the course of this HUD’s existence.

You should also note that the listen event is now split into 2 sections, the mode-changer section, where a command should change the behaviour of clicking the Mother prim of the HUD; and object rezzer section, where a command will spawn a tool when needed.

Now we can start. >:]


Quick-Access Necessities

Too often do I see people who are forced to spawn a platform on the ground (or any kind of upward-facing surface), simply because it’s the only way to get something out of inventory — and who then have to sit on it and send it up into the sky using manual coordinate entry.
The task of describing that entire process in a sentence alone was more of a hassle than I dare accept.

Why not…

un-complicate the entire procedure by flying freely up to any particular point in a vast and empty sky, type in a short command, and press Stop Flying as you land on the platform directly at your feet?

In the name of Great Logic, let’s learn to do that.

If you have a platform you already like to use, go ahead and toss it into the AggroHUD content section.
Me, I use a plain old flattened box, which I call “platfrm”.

I also use a short walled alternative for when I’m playing with physical stuff I don’t want to fall out of my little playground. Name: “sandbx”.

Here’s the simple rez call required to make floating girders possible:
/13 plat = rez platfrm
/13 sand = rez sandbx

Now, building castles in the sky doesn’t have to be the logistical nightmare it imposed us these last few millennia.


Weaseling your way out of anything

Equally necessary for an acolyte of havoc is the ability to get out of havoc.

If you’re being knocked around by hooligans shelling you with prop launchers (ie: see Lesson 1), or are being attacked by a rogue Goku with a sim-shaking Spirit Bomb, or got hit by the classic “noobRape Gun”; there is no time to waste in getting a defense set up.

I like to use… No Muthaf&(*ing Clip.


/13 noclip = rez npv

Trip out your enemies and laugh in the face of their uberpush lazors.
Startle even the most elite ninjas with mad silence.
Doors? What the hell are those?
Weasel out of anything while riding an NPV (Non Physical Vehicle).

Now, how an NPV works is simply by making a prim (it doesn’t matter what kind) rideable, that is, give it a SitTarget, turn it phantom, and give it movement control overrides with control event handling.
Oh yeah, also make it invisible.

I use an open-source NPV for the npv object, originally made by one very generous and very talented Crooked Shim, who also puts his scripts up for free sharing.

Credit to this part of the lesson, and the HUD, goes to him. I’m just deploying his work.


Omniscience

If you use Phoenix Viewer and/or (I think) Firestorm Viewer, you may go ahead and add my Phx Radar bridge script right into the HUD.
Check out the lesson on the radar’s script if you’re just tuning in.


The Final Must-Have…

Childishness.
  

I’ll go over the mechanics of the balls some other time.
For now, just make a small sphere and give it the both the swarm bounce script and the killscript (to save you the pain of cleaning up after yourself).
Insert the ball into the HUD contents.

To briefly go over the play-by-play in calling these things out:


/13 ball
sets the mode to spawn balls by the multitude.


On touching our Mother button of the HUD, balls will be birthed continuously for as long as we hold down the click.
But the balls need to know where to be spawned. I use my own position, and spread it out with randomized floats.


Variety is the spice of life. So I like to randomize the ball colours too, just as they spawn. First a value is decided, then the ball is rezzed, then transmit its RBG value via a random channel associated to that one ball (for each one).

Alright, let’s recap.

Mix all following ingredients together:

Plus AggroHUD lesson 2,
to get a grand total of:

Target in range. Avatar located: locking coordinates… Engage. Engage.

•September 26, 2011 • Leave a Comment

You. *points*

It’s time to start talking about targeting systems.

A good targeter script is like a fine broth. Quite simply, it is among a chef’s best of friends. Starting with this basic ingredient, you’re open to a great landscape of cooking possibilities. In this same respect, knowing who you want to engage and where they are becomes a great asset in whatever technowizardry with which you occupy yourself (in this case, SL programming).

In this article, I will be taking you through a few different ways to pick someone out of a crowd. What you do with them is up to you.


MK.I – Minimalist

In this simple version that I like to use for speedy picks, a single sensor pulse is sent out to farm up a list of avatar names and keys.

Pros: simple as hell, fast selection, reliable.
Cons: the use of llSensor means that we rely on a scan range around a single point in the map to sniff for avatars.

Breakdown:
This targeter will scan the area within the desired range, gather a list of avatars, and index them. This means that the closest person, say Denzel Washington, will be index 1, and then Wesley Snipes, who is just behind him, will be 2, and so on…

targeterMKI: 1-Denzel Washington
targeterMKI: 2-Wesley Snipes
targeterMKI: 3-Joe Rogan

Now, making our target selection is easy. Speak into the chat channel, whichever you choose to use, the index of your target.

example: /19 2

will select Wesley.


Global vars we’ll need


Touch to start having fun >:]


Now let’s build the list of targets, and display them with their indices.


The number spoken into channel 19 is stacked against our list of target keys.
Ref lookup: llList2Key(list src, integer index) 


MK.II – The Command Centre

This model, like the Minimalist version, uses a sensor to gather the list of potential targets.

Pros: fool-proof, looks professional
Cons: I’ll think of some later.


New variable: list of target names.


Listener channel has been changed to -19. We will not be speaking to it manually anymore.


Compilation is done with keys and names.


The list will now display in a buttoned dialog box.


Our listener hears the name instead of the index, so this name’s position in the names list is what we use to weigh against our list of keys.
Ref lookup: llListFindList(list src, list find)


MK.III – The Seer

This time around, we’ll make use of the Phoenix Radar bridge of a previous post, instead of a sensor. This allows for targeting of anyone anywhere (in the sim), as opposed to whoever is near the object wherever it spawns.

To understand this script fully, please refer back to the post on the radar bridge itself.

Pros: range no longer an issue, easy selection, distance between is shown
Cons: slightly complex in nature, took a long-ass time to learn, may be prone to special case bugs if unhandled

There was actually little that needed to be added to the bridge script to make it a targeting system:


A new global list containing the names of our keys.


A dialog box containing these names for selection.


And finally, a listener to the channel -19.


Where to go from there

Is your call beyond this point.

Research Project 1: Phoenix Viewer Radar feed

•September 10, 2011 • 2 Comments

I like to know what I’m walking into as often as I can.
So a radar that lists me all avatars in a region, along with their distance from me is a great way of discreetly keeping an eye on what I can’t always see; from people trying to be sneaky to those teleporting up/down&across the map.

But the obstacle in the face of accomplishing this in LSL is a formidable one;
scanners only work in spheres.
A)  To scan an entire sim, we would need to deploy multiple drones that spread out and zoom up and down the map to give us updates, which is resource-expensive.
B)  llSensor/llSensorRepeat can already be rather heavy in processing demand, especially for wider radii and fast repeat succession.
C) All in all, a good radar system is hard to make low in lag. There is just a lot going on in trying to see the whole sim’s activity.

Well, take a gander at this \/

The concept of Phoenix Viewer’s radar feed is actually really simple.
Getting it, however, without any walkthroughs and very little documentation on tapping into the radar, took some time and mistake-making to understand.
But there are three key components to this bridge:
1) Opening ears to the feed
2) Organizing the feed into workable values
3) Creating/updating the avatar list

*note* read before moving onhttp://wiki.phoenixviewer.com/doku.php?id=avatar_list_radar
and pay heed to the section near the bottom of the page marked Options Tab about Announcing Keys to HUD.

So, we begin with easy-peasy-lemon-squeezy piece #1:

llListen(-777777777,”",”",”"); 

Phoenix Viewer uses a system of 3 pieces of information stuffed together and separated by commas, which is broadcasted anytime an avatar leaves or enters the sim. You will know which is the case by the second value separated by commas, an integer indicator which is 0 for an exit notification, and 1 or greater for an entry. The third segment will be our one or more keys, also separated by commas. The first value in the feed, however, is still a complete mystery to me.

So we might see something like:

This raw stream is of little use as is. We’re compiling keys, so that we can extract the names and distance from our avatar.

Ideally, we want to take

7256,4,b2d574b8-b293-4d0d-xxxx-a236367523fb,8277ec64-d8e1-4e23-xxxx-52bcdba0e33b,30db3442-0d5d-40e2-xxxx-d345279bec23,77f43037-6edb-44ae-xxxx-816f7b48333c

and compile it into a list like so:

7256
4
b2d574b8-b293-4d0d-xxxx-a236367523fb
8277ec64-d8e1-4e23-xxxx-52bcdba0e33b
30db3442-0d5d-40e2-xxxx-d345279bec23
77f43037-6edb-44ae-xxxx-816f7b48333c

This, too, is a one-liner of code to accomplish.
Ref lookup: llParseString2List(string src, list separators, list spacers); 

7256 means… I dunno.
4, being a positive number, tells us that we have 4 keys to add to the list.
Then we have the keys themselves.

If we were to see:

27338,0,8277ec64-d8e1-4e23-xxxx-52bcdba0e33b

It would mean that our buddy #2 has left, thus to remove this key from the Is Present list.

On occasion, we cannot wait for a person to exit/enter the sim to get an update, for we may have just entered ourselves. llTriggerSound the UUID: 76c78607-93f9-f55a-5238-e19b1a181389 to force a refresh of the feed.
(Currently, there is a bug in the functioning of the sound-triggered update. See http://jira.phoenixviewer.com/browse/PHOE-1023 for info)
*Update* bug resolved!* llTriggerSound of the key above works again.
But mind you, it is TriggerSound, not PlaySound. I’m not sure of the reason why, but I had to learn it the hard way. May have something to do with the fact of one making the sound attached to the object, and the other not.
Ref lookup: llTriggerSound(string sound, float vol); 
Ref lookup: llPlaySound(string sound, float vol); 

Let’s Bridge already!

Alright, I’ve talked enough. Get the Phx Radar Bridge script and follow along.


The very focal point of this script. The sacred list.


No need to re-explain, but this is where it all begins.


When a string of radar feed comes in, it is split into a flag and our keys [I simply extract the int flag and slice off all but the keys].


For each key we hear in the feed, we want to check for its existence in the noob list already, to avoid overlap or removing things that don’t exist, and casually avoiding catastrophe.


In laymans terms, it says that we’ll only add a key to the list if our flag is a positive number, if the key is not already in the list, and the key is not our own.
To remove, the flag will be 0, and the key should already be in the list, and its index, the value of nubFound, is positive.


Now, we get into displaying our list of unsuspecting suckers.
Two things are retrieved using the key: the name and the world position, which is used in determining the distance between the both of you.
Meanwhile, a multi-lined string is compiled as we go, and this shall be the display engine.

But wait, there’s more!!

Included in the package are a few Deluxe features.


Sim crossing refreshing.


Live updates on distance changes.

And by the end of it all, we find ourselves with something like this

Graffiti with words

•August 23, 2011 • Leave a Comment

[CURRENTLY UNDERGOING UPDATES]

 

Vandalism.

We all know what it is. The world of second life is no different from the first one, where the classic saying rings true: “any freedom has the potential to be abused”. The total freedom of creation inherent to the metaverse means that there is very little you can’t create, which as a result allows for lots of very strange and fascinating exploits. Vandalism comes in many forms, colours, intensities, and capacities for maliciousness. This one, however, is pretty benign by comparison. Well, at least in this version. >:]

The main itch I wanted to scratch when coming up with this idea was the tragic impermanence of words in the world. If you want to post some kind of message or incoherent series of letters, you are pretty much forced to do so by uploading a texture with the printed text, which is intolerable for two reasons:
1) it costs 10L$ per upload, and
2) there is no capability for dynamic text changing whatsoever.

I don’t even need to tell you how much individual, non-free, static, manual uploads suck and blow at the same time.

And so, I unleash upon the world…
the power of words!!


(version 0.5)

*Note: While the script is being shared, you will have to make your letters and characters yourself (which was the most tedious part of the whole process of inventing this), or for now until I release the char pack. In case you do wish to make your own letters (in whatever font you like), there are a few schemes to follow:

-Each letter, symbol, or general ASCII or even Unicode character you plan to use needs to have a sphere within it, made to be the root prim.
-Each root sphere must be at the same rotation in relation to the the orientation of the letter/char object’s face side.
-Each root must contain this character script.
-Name the object the char it represents (ie: & char object is named &)

The base object which will spew out prim text contains the typewriter script.

At the molecular level, this script is ludicrously simple:
Our typewriter thing will contain its single char-named objects, shaped like their letters (a, b, c, 1, “,”, &, etc…).
The script reads input text from our notecard, and reads one character at a time.
The typewriter vomits a char object, having the same name as the raw char itself.
Script moves its theoretical cursor over to plop down its next char in the text.

Pretty simple, yes? Indeed!

Just not so much when we get into dynamic text centering, and breaking up the lines when the string gets too long.

 But let’s get started.

Public distribution version: It accepts a notecard called “In>”, and spews its contents. Some of the code I use to give it a slightly more playfully nefarious purpose is omitted for obvious reasons. >;D

So, let’s start with initializing some variables.

startup vars
The first lines look pretty self-explanatory. In line 2, the charspace variable controls how much space is provided for a letter, by moving the cursor when ready to print the next one. This variable is subject to change based on your own build.
Line 3, printcursor, is going to be the vector position equivalent of our cursor; where to place a letter.
Line 4, InLn, is the line of the notecard currently being read.
Line 5, query, is the key of the notecard itself. Obviously necessary.


Before anything is done, we run the init function, which clears any characters (Ln8), resets our Notecard Line to 0 (Ln9), finds our key (Ln10), and opens a listener for owner commands (Ln11).
Ref lookup: llGetNotecardLine(string name, integer line) 

beginread
The next thing that happens after we init() is we begin to read the notecard, starting with InLn (which is 0 at the moment).
We have our character string, the first line, and now we pass it to the println function to be typed out (Ln67). Increase our line reader index (Ln68), and do it again (once printing is finished, duh) (Ln69).

printing part 1
First off, knowing the text line’s length is important. If it gets too long, then the cursor will go out so far that llRezObject just won’t work. llRezObject has to rez object within a certain vicinity of the rezzing object. It’s just how it rolls.
In line 15, our printcursor vector decides it’s going to be 2 meters above the center of the writer obj.
Then we convert our string to all lower case letters (because adding upper case would mean doubling the work, in my case).
Ref lookup: llToLower(string src) 

Let’s skip the segment of dynamic line-breaking for now and just continue with the printing process. We’ll get back to dealing with long lines of text.


So to make the most of this limited space we have with an object spawning letters, we’re going to use a centered alignment. Halving the string length and multiplying it by the space-per-char, you get exactly that.
Now, for each char, extract it from the string (Ln42), check to skip spaces and special chars not yet in the inventory (Ln43), rez (Ln44), and shift that cursor over 1 (45).
Ref lookup: llGetSubString(string src, integer start, integer end)
Ref lookup: llGetInventoryType(string name)

That covers the logical flow. But we still gotta account for a thick paragraph of unbroken text.

Contingency Plan Alpha

Now, the number I use as max chars per line is 30, but it is dependent on the size of the char and the cursor space size, so it is also bound to be different for whatever you make.

contingency segment1
The variable mult will be the number of line segments we get when we get the ceiling of our whole line length divided by the max char per line. With this, we can use simple centering again.
Ref lookup: llCeil(float var) 


Look familiar? Yep. Except, notice the last two lines here. Ln30 deletes the segment just printed from the whole of the string line, then we shorten the string length value len by 30 (Ln31).
Next.
Ref lookup: llGetInventoryType(string name)
Ref lookup: llDeleteSubString(string txt, integer start, integer end)


This line handles the enjambment by appending a dash (-) to the 31st character (Ln33), calling a new line (Ln34), and resetting our cursor (Ln35) in readying for the next segment.

Alright, that’s everything. </anti_climactic_ending>

Let’s make a HUD – pt.1

•August 22, 2011 • 1 Comment

In the heat of battle, some gadgets need to be deployed quickly. None of that digging through inventory crap.

So for a while now, I’ve been using a simple HUD (Heads Up Display) I made for exactly this purpose – to whip things out of my bag of tricks without letting a wizard dueling moment go to waste.

So this will be the first post in an informative series of lessons on building  a simple battle HUD.

Its name? Let’s go with AggroHUD. >:]


AggroHUD – The Beginning.

Aggro is a jargon word in WoW, probably originally derived from the English words “aggravation” or “aggression”, and used since at least the 1960s in British slang. In MMORPGs, such as WoW, aggro denotes the aggressive interests of a monster/NPC.

Some examples are “We’ve got aggro!” and “Go aggro that monster”.

-http://www.wowwiki.com/Aggro

Yep.
One would think it should be a good idea to write out some formal disclaimer segment notifying you that I am releasing toys of mayhem and annoyance, sure to be abused, for the sake of education only – but it’s not like doing so would have changed your mind if you were intending on doing so anyway. I’m not that talented a writer.

So without further horn-tooting, let’s do the deed.

Pushing; shoving; it happens. Push back, with a barrage of blocks.
Messes. They can teach the overly-neat an important lesson. Make big messes with a barrage of blocks.

This, my friends, is lesson 1.


Start with two cups of fresh, pure evil

Step 1: physically make the HUD.
I use 2 prims, one in which I press to do things, and which will listen for commands and what not (which we shall call Mom) – and the other, which I press to quickly clear any objects I make with the killscript inside (which we shall call Dad). Dad has this infanticide script contained in him.

Step 2: gather your ingredients.
Make a cube. Scale it up a little bit. Insert the deathscript. Now multiply this cube so that it forms a 2x3x4 brick of blocks. Ah-ah! Don’t link them!
Select all of them, and without releasing a single one so that it they don’t drop, set them all to physical. Now ‘take’ them as a group of single prims. Name it something. I call it dissed.

Step 3: let’s cook!
Inseminate Mom with the birthing script.


The Chef’s Science

initializ0rs
Initializers; a flag called mode which will control the functions, and what results from touching the Mom button; and the channel which we use to change the mode via keywords.


In this first installment, we have one function so far, and this listener is pointless. Regardless, it is important as we’re going to use it plenty. It is the main segment which will be updated in every subsequent installment.
Typing /13 blox  will set our mode to fire the barrage.

brap brap!
To rez and fire off our toy, we need 3 properties: our avatar’s position in world coordinates, the velocity (which is also apparently the direction), and a rotation to apply to the rezed object upon creation.
Line 9 computes our position, in addition to an offset which is also affected by the avatar’s rotation/look direction.
Line 10 figures out the direction to shoot, while multiplying it by the speed at which you want to shoot it to create a velocity value.
Line 11 is the orientation of our block of boxes. This is subject to change from what is shown depending on how you oriented your brick during creation.
Ref lookup: llRot2Fwd(rotation rot)
Ref lookup: llEuler2Rot(vector vec) 


Delicious.

Miscellaneous Magnificent Magnum Opuses

•April 2, 2011 • 2 Comments

Today’s post is not about anything I’ve made, but some seriously breathtaking innovations done by others with/for Second Life.

We all know how Youtube is great for insomnia, so I was browsing and absorbing for hours last night, learning about a couple of technologies which have blown my mind right out of its jar.

Raytracing

If you, like me until 20 hours ago, have no idea what Raytracing is, it is basically the simulating of real life light vectors. Light, which travels in a straight line rays, bounces off of objects and either illuminates or colours the surrounding environment in any given hue. Ray tracing in computer logic is based off this concept of light reflections in straight line vectors for the purpose of determining the reflective, illuminative, and light absorbent properties of an entire scene of objects on the fly. It is to be the advent of a new age in environmental advancements.

Intel Labs is doing some flabbergasting research on this technology. Check out some excellent informational vids on their work and how it works here and here.

This Second Life raytracer is no less astounding. It uses prims to take a screenshot of prims, then a canvas also made of prims to display the captured image.
I know what you’re thinking. Wat. @__________@
Hats off to Mr. Foxular. Hell of an invention.

Parallax Shading

This confounds me beyond words.
I’ve dabbled in heightmaps in one of my game programming classes, but not enough to understand any of this. But according to the Valve dev community, it is apparently doable with some ease.
But wait there’s moar, as if your jaw wasn’t open wide enough already.
*note* Both the Shader and the Ghost videos, are inventions of one incredibly innovative Nexii Malthus, and were shot while using the Vertical Life (otherwise known as Combat Cubed) client for SL, which is built with a Script API not included in SL’s Viewer 2 which is needed to run them [I think]. VL/C3 itself is also partly [or wholly] a brainchild of Nexii.
You earn yourself a wholehearted golf clap, sir.

Ghosting

Using the API available only in VL/C3, this incredibly fascinating technology enables the user to draw an object across surfaces with apparent telekinesis (mouse positions across surfaces). This is an insanely fascinating challenge I will perhaps have to give a go at reverse engineering sometime.

Also check out Tool.Path to show this API in further use.

Realtime Full-Body Motion Streaming


Holy flapcrackers.

Seek and ______

•March 31, 2011 • Leave a Comment

At this posting rate, it will take me forever to document even the majority of my inventions while new projects keep writing themselves.
So with still much else to cover, this article will be explaining one of several different methods of picking and seeking in on an avatar. A mantracker, if you will. Hacked together and formatted specially for this tutorial.


The Briefing

I’ll be drawing inspiration from my previous post on the Dungeon of Psychological Torture, from which the main chunk of logic pertaining to listing, choosing, and engaging targets will be taken. But mind the differences in the changes which will be made, as a few sequential strides in upgrading the tracker have been taken. Compulsive optimizing, baby.
For one, instead of using repeaters, which was always far more taxing a process than it needed to be, we will simply spawn a single drone which will be given its target in the form of a key transmitted through a random chat channel, then displace itself across the region’s map in short, quick bursts until its position is identical to that of its target’s.

*note* I have seen monstrously fast ways of moving a prim across the map, but have never actually managed to figure that out yet. Plus, it’s fun to watch the chase! I’ve seen some advanced teleporters which will send you [while seated] anywhere around 1000 meters in an instant, used in a few of the sandboxes I frequent.
One of the gadgets from a toolbelt HUD made by one of my favourite scripters in the game, a talented Thomas Conover, who builds some of the highest grade tools I’ve ever seen in Second Life, has also demonstrated this magical and esoteric technique of hypermove.

But back to the manhunt.


Mission Begins

This build will be in the form of 2 scripted objects, one which goes inside the other for deployment: a seeker drone inside a radar object. You have all the freedom to pack a little surprise into the drone to dish out on arrival to its destination. I use the same cage seen in DoPT, but I encourage any branch-off hack you the reader may imagine can be of use in your crusade.

The Radar Console
http://pastebin.com/Ya34g4EG
A simple, 40 line script which scans for all avatars in x range (I use 100 for now), displays a dialog box with a list of these avatar names to choose from, for upon making a selection, the seeker drone is rezzed and fed the key of our selected avatar.

Step 1: Radar object is touched (by owner)

Step 2: Scan for avis in range

*Note* For the Dialog selection to be heard, remember to declare a listener to keep tabs on channel x (which ever you choose, I use 2012 here). Even I forget to do this sometimes.
So what you’re seeing here is the list pair, tgtnames and tgtkeys being instantiated as blanks on every Sensor run, a for loop running through each detected actor, saving the avatar’s name and UUID key [excluding those of the owner], and then the displaying of these names in the dialog if the number of avatars detected is at least 1.

Step 3: Select target

llDialog(…) uses the listen event to communicate a selection. Thus, we draw the index at which our target is from the list of names, and pull the corresponding key from the keys list. From there, engagement.

Step 4: Spawn drone, feed target data

Random range channel communication is your friend. Once that channel is decided, we rez our drone, take a tiny llSleep(…) nap in case of lag or delay of the drone creation, then a simple llSay(…) command to speak out the key. That makes up the radar.

The Tracker Drone
http://pastebin.com/YduGQi7V
When a scripted object is spawned, it is spawned with an integer parameter given by its birthgiving scripted object, and this integer is accessible in the on_rez(integer param) event. So when the drone comes to life, it is given the start parameter of random int in range of -50000 to -60000, which is the channel in which it must listen. The drone takes a key, and figures out its position. It then sets forth in a straight path towards the target. Once arrived… That, I leave to you.

Step 1: Birth and learning

Straightforward. No need for any formatting or validation with the incoming message, so we can just parse it as is.

Step 2: OMW!

This function repeats the movement process of small burps until arrived, and closes with a final check on target’s updated position since beginning of move.

Step 3: Finale – Gotcha, sucker.

What I do to make sure that this drone stays on the target  even while they’re moving, so that the surprise is not missed. This is done by figuring out the maximum distance you can accept them to be from the drone before it deploys its surprise. For me, it is no more than 0.9 meters, which is actually so close that a running target will be continuously chased until they slow to a walk or stop altogether. And the whole process comes to its conclusion once this post-move sniff sensor determines the target is within the acceptable distance gap.

Justice in Chaos!

Hacking up something sinister

•December 19, 2010 • Leave a Comment

The other day, I was browsing through some of the free scripts I found in my first weeks in SecondLife and found this one pretty cool one, called an Iris door, by Cera Murakami.
Here, have a gander:
http://bdhtrn.pastebin.com/Zitq5KbH

The purpose of this script is to apply it on a torus of any dimensions, and clicking it toggles the size of its hole that it is either a completely impassive, circular block, or merely the outer rim of said block.

It’s a refreshing variation to all the generic door scripts out there.

But holy rampaging disclaimers Batman! Way to make me WANT to rehaul the code, and the first lines to go would be the comments telling me not to delete these comments. Dissed. >=]

However, at this point, I still needed to find a purpose for editing someone else’s script other than for being colossally fatter than necessary.
While messing around with the shape and parameters, expanding the torus so that it now had some girth, I noticed that an avatar standing inside the iris while its open will be devoured by it when it is closed. Escape is not possible.

I had found what I was searching for — it was time to start hacking up something sinister.


Fast-Forward about an hour

and the script ended up evolving from a door to a boobytrap. At this point, I forgot what I initially planned on doing, which was skim the code down for cleanliness, and maybe toss in a functionality boost or two. In the end, I had 5 lines MORE than when we started. But not a single one of those was a comment.
http://bdhtrn.pastebin.com/7Yy9aGCQ

The fat block of global vars at the top is comprised of:
-Flag for deployment mode (standby or trap set off)
-A bunch of torus parameters laid out for easy altering
-Original position and rotations of the trap when set
-UUID Key of the poor sucker who fell for it

Like any boobytrap, it needs to be set.


is where the torus morphs its shape.

And so it begins.

Our starting position and rotation are noted, and the trap is set up.

So when the Sensor picks someone up within its 0.5meter scan radius

The flag is raised, the trapped avatar is recorded, we kill the trap radius scan, send the mancapsule flying upward, then set another scanner to keep dibs on whether or not the victim is still caught in the trap. If the victim does manage to escape (managed to put more than 5 meters of distance between them), the capsule will self-destruct.

For compassion’s sake, there is also the chance for the victim to disarm the trap themselves by touching the cage. But this is not an obvious solution.

When this happens, the torus opens up again, and returns to its original position and rotation as recorded upon init, releasing the avatar and readying itself for a repeat performance.

The finished product: 
Note: It’s hard to trap things without bait, so you’ll notice I tossed in a little message which reads “Step inside for Free L$”.

Moving on up in the tutorial game

•December 17, 2010 • Leave a Comment

I remember Humph once mentioned in class how video demonstrations are beyond a great way to expand on the things you explain, add a little professionalism to a tutorial post, and as well as capturing the reader’s eye/attention with a break from the sea of text.

Like coders, blog readers are lazy. Skimming over posts is a globally common practice, and the average browsing reader will usually spend 5 to 30 seconds (a minute if they’re feeling generous) over a post they haven’t actually intended on reading in full, perhaps even less if it’s nothing but words. So to put something visual, like an image or video, plays a key role in giving the reader the gist of the post in an instant. From there, they decide whether or not it’s worth reading.

So I got my hands on Fraps, an in-game recording client, and set up a youtube account exclusively for my SecondLife contraptions whose basic explanations don’t do them justice.

You can find the videos I’ve shot so far within some of my now updated older posts: the holodoor, coin flip, and freakish eyeball.
I’m aiming to make a habit of this, so expect more as we go along.

 
Follow

Get every new post delivered to your Inbox.