Sunday, December 24, 2006

Wednesday, December 20, 2006

On the Technical Town Hall

Some excerpts from the Technical Town Hall transcript that I found particularly interesting or insightful, for whatever reason. Quotes are sometimes followed by my comments, when I have something to add. All emphasis in the quotes is mine.

Server scaling, other than the centralized services issues I just covered, is primarily a function texture prioritization/downloading, script processing, physical simulation, and interest list calculation.

The phrase interest list calculation gave me a fascinating little peek at how the servers prioritize what content (esp. animations, sounds, and textures) to keep ready-at-hand to feed to your viewer. It also explains why editing or hovering your mouse cursor over an unrezzed texture often makes it rez faster. And why textures you haven't accessed in a year take longer to rez than textures a dozen people see every day.

We had a serious bug through october and november that was crashing sims in the messaging code. That bug is now fixed, so sim crash rates should drop. As we find them we try to kill them.

Background: for several consecutive weeks in November, the sim where I host my Advanced Building class would crash 3-4 times within the 2-hour class session. On more than one occassion, I strongly considered retiring from teaching in SL, simply because of this issue.

I will say that we are trying to update our messaging system to more properly leverage existing standards rather than our hand-rolled one. … Doing this is, as you might imagine, a tremendous amount of work, because we have to start by taking message template out behind the shed and shooting it. Then, we need simulators and viewers to be able to discover what features they have, be able to fall back gracefully, etc etc.

I would ask folks to remember that when we undertake major changes, it is a little like trying to rebuild the engine of a car. While driving it. And changing to a hydrogen economy. Without hitting anyone, losing control, or breaking the car.

If they [libsecondlife developers] break the terms of service we treat them like any other resident, but just because they tinker does not make them criminals.

Speaking of hiring … to reinforce what Philip said, if you and a friend are somewhere other than the Bay Area, we still should talk. We are already a distributed company and I see no reason why we can’t become more of one.

Sunday, December 17, 2006

Rolling Your Own Menu

Jacek's secret herbs and spices

Have you ever wanted to gather all your favorite and most-used items from Second Life's main menus, and put them all in one place for easy access? Well, you can do exactly that by editing SL's XUI files!

For my own purposes, made a new sub-menu, Builder Tool, which lives under the Tools main menu. In it, I put lots of useful building tools and options that I took from various other menus. Now I can tear off one little menu, and have them close at hand while working! Yay!

I also added two new menu items, for options found in the Edit tool window: Stretch Both Sides and Stretch Textures! Because they are now menu entries instead of checkboxes in the Edit window, I can assign keyboard shortcut keys to toggle them! Double-Yay!

Rather than walk through every step of editing the XML, I'll just point out the important or new things. All the editing is done in menu_viewer.xml, the same file we editted to change the keyboard shortcuts before, but I also referred to floater_tools.xml, as described later in this post.

Creating a new menu is fairly easy: just make (or duplicate and modify) a <menu> block, being careful (of course) to close the block with a </menu> tag. Gathering items from other menus is a simple matter, just copy and pasting each desired <menu_item_*> block into the middle of your new menu block. From what I can tell, the positioning attributes (bottom, left, etc.) are ignored or overridden by SL, so you don't even have to worry about getting those numbers right.

Adding the two new menu items, Stretch Both Sides and Stretch Textures, was not much harder. But in fact, it is only possible because of the particular way that those two options, along with the Snap to Grid/Use Grid option, were implemented; I suspect that they were all once menu items in the past, or were intended to be so. Snap to Grid currently is a menu item in the Tools menu, and it was by examining the XML for the menu item and comparing it to the corresponding checkbox in the Edit window that I discovered that it was possible to do the same with the other two options.

The key is that all three of these options are manipulated by calling the ToggleControl function and passing the control name of the option. Both the menu and the checkbox refer to the SnapEnabled control name: in floater_tools.xml, the Use Grid checkbox has an attribute, control_name="SnapEnabled"; in menu_viewer.xml, the Snap to Grid item has two lines which mention SnapEnabled, once in an <on_click> tag, and once in an <on_check> tag.

Making the two new menu items was just a matter of looking up their control names (ScaleUniform and ScaleStretchTextures) in floater_tools.xml, and plugging them into copies of the Snap to Grid menu item definition in both lines (be sure to change the text labels to be descriptive of their new functions).

Doing a quick grep of the XML files, there are a handful of other miscellanious options which have control_names. This suggests to me that menus could be built to change these too. Some notable example uses are: (un)muting audio; the Copy Selection tool; toggling chat bubbles; toggling avatar names above their heads.

It may also be possible to change other options which are not simple on/off switches. For example, it just might be possible to make a menu item which changes all the render detail settings and draw distance to the minimum, for dealing with crowded areas.

Unfortunately, this dependence on knowing the option's control name means that this method does not allow us to add an "Edit Linked Parts" menu item—the checkbox in the Edit window does not refer to any control name. I still hope that it can be added somehow, but for now it's up to the Lindens.

Happy building!

Wednesday, December 06, 2006

My XUI Wishlist

There are specific things that I want to accomplish which drive me to poke my nose in SL's XML User Interface (XUI) definitions.

Here are the ones I have already accomplished:

  1. Customize some menu shortcuts.
  2. Rename "Hole Size" to "Thickness".
  3. Decripple Transparency.
Here are the things I want to accomplish, but are probably impossible through XUI-editing alone:
  1. Define keyboard shortcuts to toggle "Edit Linked Parts" and "Stretch Both Sides".
  2. Move the color and texture eyedroppers/pipettes from the Color/Texture Selection windows to the Toolbox's Texture panel, next to the swatches.
  3. Decripple the prim attributes.
  4. In particular, be able to edit the Profile Cut attribute for Box, Cylinder, and Prism.
I have already tried #2, performing a simple copyandpastectomy of the pipette button from the Color Selection window to the Texture panel, but the button was nonfunctional/disabled. I suspect that the Toolbox window does not have the proper function(s), or is not programmed to listen for clicks to that button. Likewise for #1: the button tag may not respond to shortcut attributes as the menu items did.

#3 and the more specific #4 appear to be impossible because the functionality involved in limiting, adjusting, and hiding various attributes based on prim type is programmed into the SL viewer, and is not part of the XML. To be able to coax the Profile Cut attribute to appear for Boxes, I would probably need access to SL's source code; of course, I do not have access to the source code, so this seems to be out of my hands.

Decrippling the UI

Ok, so I changed the Second Life XML User Interface files to change some text labels and names in the Toolbox (Edit window). This was just a simple matter of reading through the floater_tools.xml file and changing a few words here and there. No biggie. (No, I did not add a new prim type!—I just renamed "Sphere" to "Watermelon". It's much nicer, don't you think?)

But aside from the obvious comedic value, what can changing the UI do for us?

Here's a good one, the true poster child of useful UI changes: we can decripple the Texture panel's "Transparency" input form. Have you noticed that you can only make an object 90% transparent using the UI, but you can make it 100% transparent with a single function call in a script? Linden Lab crippled the UI, perhaps to prevent new Residents from making hundreds of totally invisible prims and forgetting where they put them.

Well, if you are capable enough to edit SL's UI definitions, you are experienced enough to toss aside that crutch! Please note that the same disclaimer as my earlier post also applies here—you are doing this at your own risk! Here's how: in floater_tools.xml, search for the string ColorTrans. That should take you to a <spinner> tag defining the spinner (a numeric entry form with up/down arrows on the side) that controls transparency. That tag has an attribute, max_val, which defines the highest number you are allowed to put in it. Change that number from 90 to 100. While you are at it, change the increment attribute to something more useful, like 5 or 10; now it will increase by that amount whenever you click the up/down arrows on the spinner (or use your mousewheel ← bonus pro tip for you!). The default value of 2 gives you a good degree of precision, at the expense of convenience. Don't forget that you can always just click on it and type in whatever number you want, when you need precision!

Now start (or restart) SL, and enjoy your newfound freedom!

Tuesday, December 05, 2006


(Write-up and useful changes to XUI tomorrow.)

Monday, December 04, 2006

Hacking XUI for Fun and Goodness

Today, I was writing up a huge post about custom keyboard shortcuts. I was covering all the bases: why keyboard shortcuts make everything happy and warm, the ways in which SL's shortcuts are poo, and how Linden Lab could and should implement custom keyboard shortcuts. During my research into this last aspect, I realized something:

I can do it myself.

In fact, I not only can do it, I have done it. As a proof of concept, I successfully remapped the Ctrl-Shift-M shortcut. It had previously been bound to View > Mini-Map; it is now, for my Viewer, bound to World > Force Sun > Midnight.

This is just the beginning.

For the curious, here's how I did it.

Second Life's user interface is (at this point in the time, but not so in the past) defined as XML located in the skins/xui/xyz/ directory (where xyz is the language code; for English readers like myself, it's en-us). The XML for the menu bar along the top of the viewer is in the menu_viewer.xml file.

The majority of this file are <menu_item_call> tags, one block for each menu item. One of the possible attributes for this tag is "shortcut". The values for the shortcut attribute are a pipe-separated list of modifiers followed by a key. For example, the "Ctrl-Shift-M" key combination is expressed as "control|shift|m".

Make a backup copy of menu_viewer.xml before you make any changes, in case you break something and need to revert. Then use a text editor (or, if you have one, a dedicated XML editor) to open the file. Find the entry for "Mini-Map", and cut out the part that says: shortcut="control|shift|m". Then find the entry for "Midnight", and paste it after name="Midnight" (but before the closing brace; and don't forget to put a space between between the quote after Midnight and the beginning of shortcut).

That's it. Start up SL, and if everything went as planned, the "World > Force Sun > Midnight" menu item will show a shortcut key combo next to it, and "View > Mini-Map" will not. You can press Ctrl-Shift-M to see for yourself that it now forces the sun to midnight.

Like I said earlier: This is just the beginning. There are dozens of other XML files in that same folder, defining such things as the layout of the edit window, the min and max values of number entry forms, and many, many other things which I intend to experiment with.

I will close with this disclaimer: I re-read the SL Terms of Service tonight, especially section 4.2, which covers accessing SL with "unauthorized" software (this is one of the sections that was amended after the recent CopyBot scare). And although I think that modifying the XML files accessed by the SL Viewer client is probably not a violation of the spirit of the TOS, should you choose to do it, you do so at your own risk.

It would be a mistake for Linden Lab to discipline anyone for trying to improve their own user experience without harming others; but it wouldn't be Linden Lab's first. Fair warning.

Thursday, November 23, 2006

Unheavenly Bodies

The sun and moon in Second Life are unrealistic and just plain ugly.

That's right, I said it. I went there. Ugly!

Figure A.

As I see it, there are three main problems with Second Life's sun and moon:
  1. Their reflections on water stretch unrealistically.
  2. They sometimes appear as dark or darker than the sky around them.
  3. Background stars are drawn in front of them.
Examine Figure A; the left half is raw, untouched snapshot of a near-sunset in SL at 300m; the right half is what I think it should look like. (NB: the bottom of the reflection is partially obscured by clouds.) Both problems 1 and 2 are in full force here.

Figure B.

Optics minilesson #1: In the real world, a reflection of the sun or moon on the water appears stretched because of small irregularities (i.e. ripples) on the surface of the water which change the angle at which light is reflected. You can see this in Figure B, a test image I rendered in Blender using raytraced reflections. The image shows a lit sphere resting on a perfectly reflective surface. On the left side, the mirror is completely smooth; note that no stretching occurs in the reflection. On the right side, however, the mirror has small ripples which affect the angle of reflection, causing the same type of stretching seen in the real world.

My graphics card is not powerful enough to enable fancy water, so I, like many Residents, simply see an upside down and yuckily stretched version of the sun or moon in the water. I know the programmer who did that meant well—he or she just wanted to make it look as if there were ripples distorting the reflection. But all it accomplished was making it look like the Grid is a concave Discworld.

Optics Minilesson #2: In the real world, the sun can never appear as dark or darker than the surrounding sky for the simple reason that the brightness of the sky is due to partial scattering of the light from the sun. Most of the light from the sun passes through the atmosphere without much scattering, which is why the sun appears to be a circle with definite edges, rather than a vague patch of brightness.

Figure C.

Optics Minilesson #3: The moon, too, will always appear at least as bright as the sky around it, never darker (as it does in the left half of Figure C). This is especially obvious on days when the moon is visible during the early morning or late afternoon; the unlit parts of the moon, which would appear black at night, appear the color of the sky.

Why does this occur, when mountains and skyscrapers do appear dark against the sky? Quite simply, because mountains and skyscrapers block the scattered light from the sky. The moon, because it is outside the atmosphere, does not block it.

Also note in Figure C the star appearing in front of the moon. That's just crazy.

Tuesday, November 21, 2006

Oi, clients.

This is not a rant. This is a cautionary tale.

I have done all my ranting about this issue in private conversation; ranting in public would do nothing to help it. I will not be naming names, and I ask that anyone familiar with the situation refrain from the temptation as well. I am not writing this to attack any individual, but as a general warning to others, and a reminder to my future self.

Over the past month, I have been working with an individual, "X", to thrash out the design for a large-scale building project. We went through several iterations of the design as I began to understand what X wanted. Finally, X was satisfied with the direction I was taking the design, and asked me to submit a formal bid—how long it would take to build, and how much I would charge to build it.

I mulled it over for a couple days, and sent my bid to X: estimates for what work I would be doing, how many hours each part of the work would take, when I would start construction, and when construction would be complete—along with my fee (regardless of how long it actually took to build). Given the number of hours of work estimated, I was charging about US $15/hour for construction, texture treatment, and scripting (my design allowed for the layout of the building to easily change with the client's needs).

It was, from my point of view, a fair offer. Given the scope of the project and the skills involved, I could have asked for much more than that. However, I am not a big-name well-established builder, so there is some amount of risk, from the client's viewpoint, that what I deliver would not meet the client's expectations. I took this risk into account in my fee, among many other risks on both sides. Confident that my offer was reasonable, I sent my bid to X.

To put it nicely, X was not prepared to pay what I asked, and rejected my bid.

To put it accurately, X snidely accused me of charging an excessive amount for my services and dismissed me without any further discussion.

X, it seems, would not pay more than a certain amount which, given the number of hours I had estimated as necessary, came out to less than US $3.50 per hour. Upon hearing this, I (trying to remain civil) asked X for verification of that rate, and asked if the number of hours I was estimating was, perhaps, more than would be necessary to achieve X's vision. X refused to discuss it.

Now, X had been a difficult client to work with during the design phase. X's "requirements" were vague, and in some cases contradictory or simply impossible given the realities of three-dimensional space. (On the other hand, if I were building for four-dimensional space, such pithy concerns as distance and volume could be ignored). I was warned by another builder who had worked with X. I had no reason to expect X to act rationally, but hope springs eternal.

The lessons I have learned (or had reinforced) are:

  1. Make sure the client knows what he/she wants before you begin, and can communicate it to you. Otherwise, you are trying to hit an unknown and possibly moving target, which is quite frustrating! It also increases the likelihood that the client will pull something new out of their hat halfway through the process.
  2. If you are designing a build in addition to constructing it, treat them as separate processes, and charge separately. Planning the design before you build is good on general principle, of course, and treating them as separate processes helps enforce that. On top of that, it ensures that you will be paid for the design work, even if the client changes his/her mind about hiring you for the building. I also recommend charging as-you-go for each revision of the design if possible, for the same reason.
  3. If the client is full of drama before you are working for them, they will probably be even more full of it while you are. If drama, headaches, and frustration are what you are searching for, this is good news. On the other hand, if you value your sanity, pass up that client.
  4. Contracts protect both sides. Write up contracts for every step of the way, outlining the expectations of both parties, and what should happen if those expectations are not met. Have the client sign/agree to each contract, then stick to it.

Sunday, November 12, 2006

Linden Lab to Instructors: kthxbye

Linden Lab recently announced that it would be ceasing the instructor subsidy program effective December 9—after that date, Linden Lab will no longer pay L$500 per class an Instructor teaches.

Apparently, this both upset and surprised a number of instructors! To them, this is the latest in a series of moves by Linden Lab to destroy everything we used to love about Second Life.

Me? I don't really care. I have never requested any subsidy payments for my teaching. I don't want hand-outs, and I'm not teaching as a favor to Linden Lab, so they can keep their money.

I take tips from students. At the end of (almost) every class, I mention that I do take tips, and that a contribution of any size is a good way to tell me that you appreciated the class—but that the class is free, and tips are entirely optional. I get paid iff my students think what I have taught them is worth paying me for.

On only one occasion have I received more in tips than I would have received as a subsidy payment; usually I receive about half. But I know I earned it.

There are two factors which, one might argue, make my situation unusual among instructors (and thus renders my opinion on this matter entirely invalid).

  1. I do not teach in SL as my means of survival. (I teach because I enjoy it, and to make a bit of spending money.)
  2. The material I teach is not geared towards newbies, but instead Residents who have been in-world for a while and wish to improve their skills for personal or commercial benefit. (Oldbies and professional builders are apparently more likely to have money on hand with which to tip someone who teaches them techniques to improve their building efficiency.)
"Of course you don't mind," writes an imaginary instructor. "You don't need the money, and besides, the way you teach is more profitable! I, on the other hand, have to teach a hundred newbies to put on their own pants just to make enough money to buy a pre-owned can of chicken broth!"

Yes, it's true: instructors who have been surviving on hand-outs from Linden Lab in return for teaching newbies the utter basics are getting the shaft. Tough break for you? My only advice is to adapt your business model. Find a business to sponsor your class. Start charging for admission. Teach something that people with money will pay you to teach.

Linden Lab is, in some ways, giving themselves and every Resident on the Grid the long-term shaft, too. Hordes of the unwashed masses are already trampling everything; now they will be unwashed, uneducated masses! Terrible, disgusting plebians whose purest motive in SL is to figure out how to attach a giant penis to their own forehead and find the nearest free sex community.

Boy, the Grid is going to /dev/null in a handbasket, I tell ya. It's enough to make me yearn for ye dayes of olde when a prim was a just a prim, grass textures were greener and never had to rez, and every Resident descended onto Help Island from the immaculate Skybox of knowledge and dedication.

Those were the days.

Monday, November 06, 2006

This is all.

(It's enough.)

Saturday, November 04, 2006

Chat Range

There is still one more part of Color Curves yet to be written, but it requires significant research and development into methods of algorithmically generating intermediary control points between the two blended colors, taking into account neighboring control points. (For the transition between two curves to be visually smooth, it must be continuous, which means that the end point and the control points on either side must be collinear, i.e. they are all in a straight line.)

But that is a post for another day. Today's post requires much less education in maths to understand. The topic: chat ranges!

Right now, avatars have two options for range when it comes to speaking: you can speak normally, in which case anyone (and anything) within 20m of you will hear you; or, you can shout, in which case the range is increased to 100m.

Scripted objects have one additional option, designed to reduce the noise in the chat channel: they can whisper, which carries for only 10m. (Avatars cannot whisper, only scripted objects.)

Being the person that I am, this limitation is dissatisfying to me. What if I want to have a conversation around a dinner table, without disturbing (or being overheard) by the group at the neighboring tables? Or what if I am teaching in a 60m-wide lecture hall, and I want even the students in the back to hear me—but I don't want to bother the people out in the lobby, who are 80m away?

Even if avatars had the whisper option made available to them, the granularity of three choices of range—10m, 20m, or 100m—is unsatisfactory. There are too many situations where something in between (or smaller) is needed.

In some situations, you can work around this with scripted objects. If you need a smaller range, you can attach an object to your avatar which listens for your chat on a hidden channel, and whispers it into chat for you (thus emulating a whisper option for avatars). If you need a range between 20m and 100m, you can set up scripted relay objects, like small intercomm systems which listen to chat in one place, broadcast it on a hidden channel, and then repeat any broadcasts it receives into chat. Both of these solutions are suboptimal.

"Alright, Jacek. Get to the point. Tell us your solution," you say? Oh rude and belligerent imaginary reader, I was just about to tell you!

The solution is this: on the chat bar, in lieu of the "Shout" button, we should have a numeric input box, into which we can type the desired range of our chat. This setting would remain in effect until the next time you changed it; a checkbox toggle in Preferences would determine whether the setting is saved across sessions of SL.

This renders the shout and whisper actions obsolete for the most part, but they do offer something useful which the proposed solution, as presented thus far, lacks: by appearing to other users as "Jacek Antonelli shouts: Yay! Candy!! \o/" or "Considerate Vendorbot whispers: Your purchase of 'Xcite! Interactive Torus Attachment' will be delivered soon.", they convey important information about the range of the chat, and who else can hear it.

It would be simple enough to automatically label chat as whisper, normal, or shout based on range (anything <=10m is whisper, anything >=50m is shout, for example). But we can do so much better—let's let the user define custom ranges and labels for their own chat!

This would be a new tab of the Preferences window. In it, you could define "rules" for determining what label chat will be given, based on range. An example rule might be something like this: >25m, <51m: "calls out". After defining that rule, anything I said with a range greater than 25m but less than 51m would appear like, "Jacek Antonelli calls out: CANNONBALL!! *splash*".

The other logical alternative would be for each user to define rules to label *incoming* chat based on range, rather than labelling their own *outgoing* chat for other people to see. I prefer the latter for its roleplay possibilities (you can easily establish a "personality" for your avatar based on how you label what you say), but the former would offer more uniformity in what each user sees (you won't have to figure out what the heck so-and-so meant when they "burbledummed" bad jokes at everybody in the room). For the best of both worlds, checkbox preferences for "accept chat labels from other users" and "apply custom labels to incoming chat" could be offered to let each user decide.

There is one more aspect of this feature proposal: remap the Ctrl-Enter keyboard command to send chat with a user-defined range. This way, users could decide whether Ctrl-Enter should send chat with a wide range (like the current Shout action does), a normal range, or a short range. Sending chat with Ctrl-Enter would not reset the range for other chat, so you could use it for those times when you want to send one or two lines of chat at a different range than the rest of your conversation. (For example, you are talking to your date across the dinner table, but you want to call out a song request with a normal chat range, then continue whispering sweet nothings.)

Sunday, October 29, 2006

Curves: Color (Part 2)

Attention: Maths ahead! Non-geeks may prefer to avoid the equations, and just look at the pretty colors instead.

Previously, on Jacek Writes: our hero introduced the topic of smoothly blending between two colors algorithmically.

Linear blend from red to blue.
Last time, I defined an equation for blending linearly between two color vectors a and b as time, t, increases from 0 to 1:

line(t, a, b) = a + t * (b - a)

After a little algebra, we can rewrite that function as:

line(t, a, b) = (1-t)(a) + bt

Linear blending looks just fine for blending between two colors, as demonstrated above. Starting from the left, we progress from red to blue, passing through magenta and purples. Looks pretty good, right?

Linear blend from red to blue to green.
The problem arises when we try to add a third color, blending from a to b, then from b to c. As you can see, there is a "spike" at the point where we reach pure blue. To use a spatial analogy, we are driving from point A to point B, then taking a hard right turn and going to point C; it's the spot that we take the turn that ruins the smoothness.

But there are other techniques besides linear blending, which can solve this discontinuity. The technique that I prefer (for its versatility) is Bézier curve blending.

For the uninitiated, Bézier curves are a beautiful and elegant mathematical technique for modelling smooth curves like those used in graphic and industrial design. They are closely related to NURBS (Non-Uniform Rational B-Splines) Surfaces, a modelling technique popular among computer animators for producing smooth, organic shapes. (Although, NURBS surfaces have somewhat fallen out of use in favor of other techniques like Catmull-Clark subdivision surfaces.)

Bézier curves have several properties which are important for our purposes: 1) they are smooth, 2) they are not difficult to compute, and 3) each curve can be defined through a small number of control points, or "knots".

Based on viewing the wonderful animated diagrams on Wikipedia, I set about reverse-engineering Bézier curves. (Sure, I could just find an equation on the web somewhere, but where's the fun in that?)

What I find so elegant about Bézier curves is that the equation can be a fractal, recursively defined. Using our linear blend function defined above, we can define a quadratic Bézier curve which passes through points a and c, with a control point b:

quad(t, a, b, c) = line( t, line(t, a, b), line(t, b, c) )

That may make a mathematician's lips quiver with joy at its simplicity and elegance (especially if you then use that function to define a cubic Bézier curve, as I will do next time), but it has certain redundancies when it comes to evaluating it with a computer (i.e. it takes more separate mathematical operations than necessary).

So, I got out my pencil and pad and expanded the equations by hand, combining terms and simplifying, then using that equation to write an equation for a cubic Bézier curve. In fact, I did so in four different ways (only two of which were novel in the fact that they contained algebra errors so foolish that they would embarrass an English major).

My final equation for a quadratic Bézier curve is as follows:

quad(t, a, b, c) = (1 - t)2(a) + (1 - t)(2bt) + ct2

Quadratic Bézier blend with red, blue, and green control points.
Using this equation to blend between three colors produces the image seen here. As you can see, it is definitely very smooth; it has solved the problem we saw with the linear blend, the spike when we reached blue and make a hard right towards green.

But there is a problem.

It never hits pure blue.

It gets close, there in the middle. We pass near blue. We are definitely in Blue County, Color-ado.

But we never actually see pure blue!!

Have Bézier curves failed our hero? Is this the end?!? Don't miss the shocking conclusion next time, Issue #1397: Crossed Controls & Cubic Curves --JA

Sunday, October 22, 2006

Curves: Color

I wrote a post about "section radius" recently, which involved drawing curves with a discreet number of anchor points. The application there was a more robust replacement for the Taper attribute of prims. Of course, the usefulness of using a curve instead of one or two numbers is not limited to Taper alonethere are innumerable other uses for them, completely aside from the Object attributes.

One of my backburner obsessions for the past few months has been color. (No surprise there, given that I'm currently enrolled in a color theory class, I suppose.) In particular and with regard to SL, two aspects have been on my mind. The first is using a base color as input to an algorithm to generate related colors (lighter tint, darker shade, blue-shifted, red-shifted, visual complement...). The second is blending between two colors in a smooth and visual appealing fashion.

This is where curves come in.

You see, colors can be represented in a computer program as multidimensional vectors, usually 3-vectors: the x component corresponds to the intensity of the red color channel, the y to the green, and the z to the blue. For example, [1.0, 0.0, 0.0] is pure red, [0.8, 0.5, 0.0] is an orangey color, [1.0, 1.0, 1.0] is pure white, and [0.0, 0.0, 0.0] is pure black.* (In additive color models, such as light, the presence of all colors is white. In subtractive color models, such as pigment or paint, the presence of all colors is black, at least theoretically; in practice, mixing all your paint colors together usually makes a grayish brown.)

* NB: for convenience, I am denoting vectors with square brackets, [ ], instead of the usual angled brackets, < >, which are also used to denote HTML tags, causing the silly Blogger software to interpret my vectors as malformed HTML code. Yes, I am too lazy to search-replace them with the symbol codes.

So suppose we want to blend between, say, [1.0, 0.0, 0.0] red and [0.0, 0.0, 1.0] blue. The simplest way to do this would be a straight linear blend. Since positions in space, like colors, can be represented as 3-vectors, a linear blend is equivalent to moving in a straight line from point A to point B.

We could write an algorithm thusly, with a being the starting color/point, b being the ending point, and t being a number between 0.0 and 1.0, representing our progress moving from a to b (e.g. t = 0.5 means we are exactly halfway between the two; t = 0.25 means we are ¼ of the total distance from a, and so ¾ of the distance from b):

line(t, a, b) = a + t * (b - a)
Here are some sample points using our algorithm to blend between red and blue:
line(0.00, [1,0,0], [0,0,1]) = [1.00, 0.00, 0.00]
line(0.25, [1,0,0], [0,0,1]) = [0.75, 0.00, 0.25]
line(0.50, [1,0,0], [0,0,1]) = [0.50, 0.00, 0.50]
line(0.75, [1,0,0], [0,0,1]) = [0.25, 0.00, 0.75]
line(1.00, [1,0,0], [0,0,1]) = [0.00, 0.00, 1.00]

To be ct'd in Issue #452: Pierre Bézier and Paul de Casteljau unite once more in... O What a Twisted Curve We Weave!! Don't miss it, gang!

Sunday, October 08, 2006

My Agenda

I didn't conciously realize this when I first started writing here, but my feature requests have a very specific agenda. To put it succinctly:

I want Second Life to be more like a high-level 3D modelling application.

My education is in 3D computer modelling and animation, and I have a good understanding of computer programming. Thus, my perspective on Second Life is from the angle of someone who uses high-level modelling and animating tools like Maya and Blender, and high-level programming languages like Ruby, Python, and LISP.

The tools offered in Second Life are technically inferior to just about everything I have used, but it has the definite advantages of being collaborative, interactive, and visible.

By collaborative, I mean that many people can use it and work on a single project at the same time, in the same working space. Rather than many people working separately on their individual parts, we can come together and build something together, watch each other build, and see how our work fits within the whole project.

By interactive, I mean that there is a great degree of communication between the user and the tool, and between the user and other users. You can see the changes you are making as you make them. And not only can you see them, but your partners can see them. This makes Second Life an excellent platform, again, for collaborative work, but also for education and error correction: rather than a teacher seeing only the finished product of a student's work, the teacher can see the student's process and suggest improvements to it.

By visible, I mean that the work exists in a "real" space where audiences can see it. Gallery spaces can be created and work arranged within that space for people to see. Multiple viewers can see it at once, discuss what they see and think about it, and interact with each other and with the artist. This has a definite advantage over a simple web page with several images ordered sequentially. It even has an advantage over a web forum where users can post work and comment on the work of others.

To bring all these points together: the high level 3D modelling applications that I use are missing something which Second Life has; and Second Life is missing something that the modelling applications have.

But there's more to the story than just that.

High-level 3D modelling applications have a lot of features which are not necessary or even useful in the context of Second Life, for reasons technical and otherwise. It is not my agenda to graft unneeded and pointless features onto Second Life. Doing so would waste resources which would be better used on more important things.

Second Life is a lot more than a distributed 3D modelling platform. It has social, commercial, educational, and recreational value, all of which are undeniably important parts of what make Second Life what it is. It is not my agenda to reduce or remove any of these facets of Second Life. They are the reason and purpose for the 3D modelling aspect to exist; without them, Second Life would be pointless.

And yet, just as tools without a purpose would be pointless, a purpose without the tools to fulfill it would be squanderage. The scenery of Second Life is a critical part of its social, commercial, education, and recreational value. It is toward the purpose of fulfilling the potential of Second Life that I propose features and changes. Every feature I suggest, I do so because the benefit towards fulfilling important values would be far greater than the cost of implementing the feature.

I want Second Life to be more like a high-level 3D modelling application...

...because that would facilitate the creation of new, interesting, beautiful, and useful things which would enrich Second Life.

Friday, September 29, 2006

Thursday, September 28, 2006

Linux Users Love Tofu Linden!

A cartoon penguin hugging a brick of tofu imprinted with the Second Life logo.
Yes, every Linux-using Resident of Second Life is now brimming over with love and affection for Tofu Linden, the Linux client developer for Linden Lab!

Today marks the first time the Linux client has had any sort of file upload/download capacity! Right now it's pretty rough around the edges, as there is still no file browser/picker, but it works! (Just rename the image to upload.tga and place it in your SecondLife/your_name/ folder, then use the upload menu item.) Tofu tells us that the file picker is in the works, which is also very nifty!

Since the last I posted about the Linux client, much progress has taken place, apparently due to the efforts of our hero, Tofu Linden! Audio playback was added August 29, including support for parcel audio streams, and Copy & Paste was added September 13—the Linux client is fast approaching the full feature set that the Windows and Mac users currently enjoy (plus, of course, the added "feature" of being able to log in to SL in Linux!).

I have found my own way to express my appreciation to Tofu: I created the adorable image above, featuring a penguin lovingly embracing a brick of tofu! (The image was created in Inkscape, by the way—a great piece of software if ever there was one!)

Action shot of the T-shirt.I then successfully uploaded the image, and a T-shirt featuring the image, to Second Life! Then I took a snapshot of me wearing the shirt (and standing in front of a waving flexi flag with the texture on it) and saved the snapshot to disk—you can see the proof here!

Since everybody should be able to show their love for Tofu Linden, I am giving out the shirt and textures* at my home/studio/gallery in Hallasan! (While you are there, say hi to Primmy!)

* A small word of caution, though: my gallery is in a Mature sim, and includes a few artistic nudes. You probably won't even see them if you go straight to those coordinates and don't poke around, but I thought I'd give you fair warning, in case you are logging in to SL while at work. In the Vatican. Where you share an office with his Holiness the Pope.

Friday, September 22, 2006

Section Radius

What I'm proposing here is fairly radical, in that it represents a very different method of building in Second Life. But, like everything I propose, it is not only possible, but feasible; I could devise the algorithm for it myself, with a bit of research as needed. This feature would require a more significant change to the data structure for prims than before, but the possibilities are astounding.

Throw away the Taper attribute for objects. It was great, but it will be made entirely obsolete by the feature I am proposing: section radii. Instead of describing the relative size of the beginning and end of the prim, as Taper does, Section Radius would describe the size of the prim at every point along its path.

NB: Every prim, with the exception of Sphere, can be represented as a two-dimensional shape such as a square or circle, which is extruded along a path to create a three-dimensional surface. For Box, Cylinder, and Prism, that path is a straight line into the third dimension; for Tube, Torus, and Ring, that path is a circle.

Take a look at my fancy diagram (to the right, click for a larger version). In (1), we are describing 5 different sections (solid lines), with another 4 values being interpolated between them (dotted lines). The gray line at the bottom represents the full span of the path from beginning to end.

In (2), we see a top-view of a cylinder with the sections that were defined in (1). Note that by smoothly interpolating between the defined sections, we can achieve a very smooth result without defining a large number of sections. In (3), we see a top-view of a torus with the same sections (or, at least, a passable representation of one; it's hand-drawn, not mathematically computed, so it may not be very accurate).

In the example, all the sections were equally spaced, but that need not be the case. Nor need there be a set number of sections. An arbitrary number of sections could be defined, with data storage increasing linearly with the number of sections defined (i.e. if we define twice as many sections, it takes twice as much space to store the data).

The advantage taper has is that it can be represented as two numbers between -1.0 and +1.0, one number for each axis X and Y. So, it doesn't take much bandwidth to transmit the Taper attribute of a prim. The disadvantage to taper is that its possibilities are decidedly limited: the shape's size can only be changed by a constant value as it is extruded along its path. It cannot, for example, start out small, become large in the middle, then small again at the end (making a surface resembling a lemon or American football).

With section radius, on the other hand, it would be possible to make such a shape, and a great many other shapes, with a single prim: vases, bullets, wavy french fries, bushy tails, barbells, and a great many non-PG items (which I will refrain from linking to). I haven't even started to mention all the possibilities with torus and kin!

There is, of course, a trade-off: section radius takes more information to store and transmit than taper. How much more?

One axis of taper requires, at most, a single floating point number (i.e. not an integer). If Linden Lab is clever, they don't even need that, because the granularity of each attribute is in the hundredths (I may be wrong, it may be thousandths), meaning there are only 200 (or 2000) possible values for one taper axis. That would take only 8 (or 11) bits to represent, versus a 32 bit float value.

Section radius, on the other hand, would require at least twice that, for every section defined. The more sections you define (i.e. the greater the detail in the section radius), the more data you have to store. I say "at least twice", because additional storage would be needed for storing the interpolation type (linear, smooth, step, and perhaps others). That might be stored once for the entire curve, or stored for each section. The latter would require more storage, but would be more flexible.

Section radius can, of course, be used to emulate the current Taper attribute (as well as the poorly-named Hole Size attributes for torus and kin, at no extra cost): one section each defined at the beginning and end, with linear interpolation between them. That's between four and six times as much data, for the same result.

When it's phrased like that, it seems like a bad idea. The same result, but a higher cost? No thanks!

But consider this: section radius would enable shapes which were impossible before. And if you were to try to approximate such a shape using existing building methods, it would require (n-1) separate prims, where n is the number of sections. Each prim, of course, has to store a great many redundant attributes (position, rotation, size, texture data, etc.) which would not be necessary for a single complex prim. And besides taking more storage space (not to mention parcel prim limit space), a many-prim solution would require a great deal of time to construct, and the results would be blocky and undesirable.

To put this in another light: section radius would enable complex and beautiful shapes to be made from a single prim, but would make creating a large number of simple shapes slightly less efficient.

It represents a shift from low-level, difficult-to-use tools to higher-level, easy-to-use tools. This is a shift that Second Life needs to make, in many areas, if it hopes to attract and retain the Doers and Makers that create the content of Second Life.

Saturday, September 16, 2006

Prim's Amazing Journey

Today, a joyful reunion marks the end of an amazing true story of struggle, perseverance, and hope.

Prim, a purebreed plywood cube and the adored pet of Jacek Antonelli, was returned to his owner today after being missing for nearly two weeks. "I had almost given up hope of ever seeing my dear Primmy again," says Antonelli. "I'm so glad he's back. My life just wasn't the same without him."

Jacek Antonelli looks on as Prim stretches out for a much-needed nap outside their home in Hallasan.
Jacek Antonelli looks on as Prim stretches out for a much-needed nap outside their home in Hallasan.
Prim went missing on September 4 after he bounced away from the cottage where he resided in Hallasan (located along the south-east coast of the Most-Southern Continent). "Prim needed some excercise, so I set him on physical and gave him a script to set his llTargetOmega," tells Antonelli. "But I forgot to put on his leash before I closed the edit window, and he bounced up into the air, right over the house! I was so surprised."

Jacek Antonelli searched for hours to find Prim, but he was nowhere to be found. When Prim hadn't been returned after several days, Antonelli feared the worst: "I thought he must have bounced into the ocean and drowned, or gotten trapped in a sex club and asphyxiated."

The route Prim may have taken from Hallasan (south) to Chamisak (north).
The route Prim may have taken from Hallasan (south) to Chamisak (north).

(Artist's recreation)
But today, Antonelli logged on to find some good news: Resident Artlan Doctorow found Prim on his parcel in the Chamisak region, over 5.5 kilometers from Antonelli's cottage. Said Antonelli, "I was so surprised! I have no idea how he got all the way to Chamisak by himself."

Asked for comment, Doctorow beamed, "I'm just glad to have helped reunite the two. No one shoud have to go through the fear of losing a pet, especially one that cute."

Now Prim, exhausted but seemingly no worse for wear, purrs contentedly as Antonelli strokes him. "I'm absolutely amazed at how he managed to keep going so long, especially with the grid restarting to frequently. I never imagined he would make it, but I'm so happy that he's back."

Antonelli has a plan to keep Prim safe and sound from now on: "I'm going to be extra-careful when dealing with physical objects. I'm giving Prim a script so I can track him wherever he goes, too. You know, just in case he gets loose again."

When asked to comment on his journey, Prim replied: "Hello, Avatar!"

Monday, September 11, 2006

Defining ourselves

Mera offered a thought stream which got me thinking about deriving identity in activity—the idea that you are what you do. If you center yourself around doing N, who would you be if you stopped doing N?

(I am reminded here of the crises of people who, after working their entire lives at the same job, reach retirement and are at a loss as to how they should spend their time. The job had become their identity.)

This struck a chord with me because I do tend to derive a lot of my identity from what I do. In both Lives, I keep myself perpetually buried in projects, so that I will always have some activity to define myself in relation to.

I create, so I am a creator.
I teach, so I am a teacher.
I do, so I am.

Assuming, of course, that it is undesirable to be left in a state of doubt about one's identity, one should endeavor to prevent and cure such a state. Defining oneself in relation to only one or two things is risky; interests come and go, and the anchor that holds today may not tomorrow. A less risky option (and the one I am prone to do) is to grab hold of as many activities as possible, so that each matters less. If one fails, the others are there as backup. But there is a danger to this too, that of spreading oneself too thin, so that there is no meaningful benefit in anything.

No matter how we define ourselves in relation to other things and activities, there is always the very real possibility that we will lose or shift away from them.

But what if we define ourselves not in relation to something else, but as being ourselves, no matter how we change?

I am myself.
I look a certain way, act a certain way, and enjoy certain things.
In the future, I will look another way, act another way, and enjoy other things.
I will be myself then, too.

(We'll see.)

Sunday, September 10, 2006

Build Window: Particles

The Build window should have a tab for controlling a prim's particle system.

That's simple enough, yeah? But I like to hear myself type, so I'll go into more detail.

Right now, the only way to activate on deactivate particle systems on a prim is through the use of a script which calls the llParticleSystem() function. That function takes a list of many pairs of parameters, each pair describing what is being defined (e.g. PSYS_PART_START_COLOR, i.e. particle starting color) and what that thing is being defined as (e.g. <1,0,0>, i.e. pure red). Constructing such a list is a tedious and frustrating task, but fortunately there are plenty of helpful scripts which can make it a bit more convenient. But even these helper scripts must call llParticleSystem() eventually, or there will be no particles.

You might think, based on the fact that a script is the only way to activate particles, that a prim must necessarily be scripted to have particles. This is not the case: the particle system is stored with the prim itself, not the script. Consider the fact that you can stop or even delete the script which activated the particles, and the particles will continue unabated.

To summarize, particle systems can exist without scripts, but there is currently no method aside from scripts to turn them on or off. As scripts are a tedious and ultimately unnecessary way of creating, changing, and deleting a particle system, it thus stands to reason that a more convenient method should be provided as a supplement to the scripted method. The Build window's Features tab (which currently houses the settings for flexible paths and light-emission) seems to be the natural place for this. But particles have a lot of settings, and the Features tab is already a bit crowded, so, at risk of over-complicating the user interface, I recommend branching the Features tab into sub-tabs, one of which would be dedicated to particle systems.

(In fact, particle systems have such a large number of settings that two or more tabs may have to be dedicated to particle systems. An obvious but imperfect division is between PSYS_PART_* and PSYS_SRC_* flags. A more natural but less clear-cut division is between settings which define the appearance of each particle, and those which define how they are emitted and behave as a system.)

So what would we see when we look at the Particle tab(s) of the Build window? It turns out that particle system settings are represented by a handful of distinct types of data, and the proper UI widgets to control each type are already used in other places in Second Life's interface, especially in the Build window itself:

bitfieldcheckboxesGeneral tab: permissions
optionradio buttons /
drop-down menu
General tab: for sale options /
General tab: When Left Clicked
floatnumeric controlObject tab: Revolutions
integernumeric controlObject tab: Hollow
vectormultiple numeric controlsObject tab: Position
colorcolor pickerTexture tab: Color
texturetexture pickerTexture tab: Texture
object/avatarobject pickerReport Abuse window

Some notes: in the script, colors are actually the vector data type, but it is non-intuitive to select a color the same way you set e.g. size in a graphical widget. Also, a script has the advantage in selecting a client asset texture by key, whereas the graphical widget can only select from inventory. And, the object picker in the Report Abuse window can only select the root prim of an object, which would be insufficient when targetting a child prim of an object.

In addition to all the particle system attributes, one more UI element would be needed: a checkbox for whether the particle system is currently active or not. But unchecking that box should not make in impossible to change the other settings, as happens with the flexi and light features (in fact, it should not do so in those cases either!). This might require a small change to the way particle systems work, as I am not certain if non-active particle systems are saved with prims. But even if the values for the attributes of a non-active particle system were stored only client side (so that if the client crashed, they would be lost), it would still be a useful feature.

I feel compelled here to anticipate several possible arguments against this feature:
  1. "Newbies and griefers will be making ugly and annoying particle systems left and right! At least now, you have to be able to script to abuse particle systems!"

    To this I have two responses. Firstly, newbies and griefers already make ugly and annoying particle systems left and right, because scripted smoke bombs etc. are already easily available. Secondly, I don't think that imagined fear of abuse is a legitimate reason to prevent progress in ease of legitimate use.

  2. "This change would put the makers of particle helper scripts out of business!"

    Adapt or perish. Should we have stuck with the telehub system, because point-to-point teleporting forced vehicle makers to change their business models? Perhaps we should get rid of the Object tab, and force all changes to a prim's shape be made through scripts, to increase demand in the prim-twisting script market?

    The fact is, scripts which control particle systems will still be useful; but they will have to go beyond the basics and have more complex behavior. Some examples include particle systems which gradually rotate through all the colors with time, or particle systems which detect nearby avatars, look up their favorite color in a database, and shoot particles of that color at them.

As I see it, there are plenty of reasons to add this feature and few reasons to reject this feature, little effort required to add it and much benefit from its addition. So get it done.

Sunday, September 03, 2006

Procedural Textures

This post appeared originally on the old blog. The original comments attached to the post are listed at the bottom. -J 09/03/06

Textures take a long time to download, even on the asset servers' good days. The fact is, they use a lot more storage space and bandwidth than the actual prims they cover. While moderately-sized textures will weight in at several kilobytes, a prim takes perhaps a hundred bytes (the exact figure does not matter at this point, only its relative magnitude). How can a three-dimensional object take less space to store than a two-dimensional image?

The trick is in how prims are created. Every single prim is parametric' or procedurally generated. Second Life has functions (i.e., procedures) which take certain parameters (e.g., size, twist, taper) and generate the three-dimensional mesh of, say, a torus based on those parameters. So you don't have to transfer the 3D mesh, just the parameters; the mesh can be constructed by any client locally.

Textures, on the other hand, store pixel data for the image. Of course, image compression is used, and varying levels of detail are generated (so you only have to transfer the lowest level of detail needed), but it still requires much more data than a prim.

But, just like it is possible to procedurally generate 3D primitives, it is possible to generate 2D images, i.e. procedural textures. Procedural textures are common in 3D computer animation as an easy and storage-inexpensive way of creating high-detail textures. Most animation packages come with a number of texture procedures, and although the complexity of the procedures varies, they all have something in common: one procedure can generate a (seemingly) unlimited number of similar (but not identical) textures, based on the procedure's parameters. In addition to the "standard" texture procedures which come with the program, many packages allow knowledgeable users to create their own procedures.

(To avoid confusion, I will use the terms "texture procedures" or "procedures" to indicate blocks of code which are executed to generate a texture, and "textures" to indicate collection of image data, either from an uploaded image or the saved result of a texture procedure.)

Consider a "wood-grain" texture procedure . Some of the parameters it might have are: wood color, grain color, ring density, ring uniformity (how similar in thickness each ring is), ring noise (how distorted the ring shape is), and so on. Based on these parameters, the procedure would generate a texture. If you used slightly different parameter settings, the procedure would generate a slightly different texture.

If I Ruled the Grid, there would be several standard texture procedures written in a simple 'shading' language (affecting surface color only; control over how light affects the surface would be excessive for Second Life). Eventually, custom procedures could be written by users and distributed through Second Life as objects.

Some examples of standard texture procedures would be:

  • multiple-octave Perlin noise (or similar)
  • wood grain
  • stone/marble
  • text
Standard texture procedures, which would be distributed with the client software, present a much simpler problem because everyone will already have the procedures on their computer. Custom procedures complicate the system, because they must be distributed across the net to other clients, but the IP rights of the creator must be respected. (Distributing the procedure code, even in compiled form, increases the risk of it being decompiled or reverse engineered.)

To allow the creators of texture procedures control over the use of their creations (making possible a market for procedures), special permission settings would be required, as detailed below. Unless otherwise noted, each setting can be enabled or disabled separately for creator, owner, group, everyone, etc.:
  • Modify: user can access and modify the procedure's source code.
  • Run: user can set parameters and execute the procedure.
  • Save: user can save the results of the procedure as a texture in his/her inventory.
    • Save Permissions: saved results will be created with these mod/copy/transfer permissions.
  • Download: user can download the compiled procedure to the client. If this is disabled, only cached server results can be seen.
  • Copy, Transfer: as with other types of object.

Obviously, some uses of custom texture procedures do not take advantage of the reduced bandwidth use of procedural textures; instead, they are used as a convenient way for the creator to generate many customized textures, which can then be used separately. The ability of texture procedures to create many textures with minimal human effort is no less useful than its bandwidth conservation.

Comments from the original post:
Akela Talamasca said...

Thank you for explaining the whole 'pocedural' thing... since the advent of Spore, there's been a lot of talk about 'procedurally generated animation' and the like, and I've never understood what it meant, and why it was able to provide suce small file sizes. Now I know. And knowing's half the battle. *GI Joooooeeeeeeee!*

8/31/2006 9:47 AM

Sunday, August 20, 2006

Ambiguous Object Chat

This post appeared originally on the old blog. The original comments attached to the post are listed at the bottom. -J 09/03/06

Consider the following LSL script:

llSay(0,"Hello, Avatar!");
llOwnerSay("Hello, Avatar!");
// edit: fixed erroneous argument in previous line. Thanks MP!
llInstantMessage(llGetOwner(),"Hello, Avatar!");
Drop that script into a prim and run it. Three lines of chat will appear for the owner:
Object: Hello, Avatar!
Object: Hello, Avatar!
Object: Hello, Avatar!
Three forms of chat available to scripted objects show up exactly the same! (The other two, shout and whisper, can be distinguished from all others.) But of these three forms of chat, only one can be heard by other people.

This issue comes up with scripted objects which use chat to report something to the owner. Sometimes these scripts use llSay when they should instead use llOwnerSay. (If your script does this, it is a naughty script that should be publicly flogged. I'm looking at you, "MultiGadget by Timeless Prototype"! For shame!) Being the considerate person that I am, I do not want to use an object which will spam everyone around me, but I cannot determine at a glance which method of communication the object is using.

So, If I Ruled the Grid, every form of visible object communication would be easily distinguishable from every other form, at a glance. The results of the script would show up as something like this:
Object: Hello, Avatar!
[Own] Object: Hello, Avatar!
[IM] Object: Hello, Avatar!
Not only would each form have different text boilerplate, but they would use different colors (which could be changed in your preferences, of course). The Grid would be a much less ambiguous place to live in, and that's a good thing.

Since I do not yet rule the Grid, I will point out for the benefit of my readers that you can tell if an object is spamming the general chat channel by using another object which has been scripted to repeat to you everything which is said on channel 0. Here is a script that should do the job (pending actual testing in SL):


listen( integer channel, string name, key id, string message )
llOwnerSay( name + " said: " + message );

To my knowledge, it remains impossible by any means (short of packet sniffing, which may or may not violate the Terms of Service) to tell the difference between llOwnerSay and sending an instant message to the owner.

Comments from the original post:
Timeless Prototype said...

The Multi Gadget advert can be disabled by its owner by saying 'cmd|advert|off'. That is to say it is the choice of the owner. Everything else is an IM or OwnerSay, except for the "key getter" feature which is deliberately a whisper because you might be getting keys for a friend to use.

I like your idea of prefixing what is said with [Own] or [IM]. Here's how that can be achieved by your LSL script:

myOwnerSay(string message)
string preserveName = llGetObjectName();
llSetObjectName("[Owner] " + preserveName);

8/21/2006 5:28 PM

Erbo Evans said...

I know I'll definitely turn that off on my copy of the MG...I just wonder if the setting "sticks" when the MG is detached and reattached (which is basically every time I change outfits). Perhaps I'll need to make a gesture that issues that command to the MG that I can use whenever needed.

8/24/2006 11:18 AM

Mera Pixel said...

You already know this, but llOwnerSay doesn't take a channel as the first example shows.

*waves to timeless*

8/25/2006 6:12 PM

Saturday, August 19, 2006

Missing Linux Client Features

There is an alpha (testing) version of the Second Life Client on Linux. And I appreciate it. I wouldn't be a part of Second Life if it had not been available. It has let me participate in a thriving community, build beautiful objects, and write useful scripts.

But it's missing some important features which put a damper on my creative ability:

  • Image, sound, and animation uploads from file.
  • Texture downloads.
  • Snapshot to disk or postcard. (Upload snapshot works fine.)
  • Text copy & paste.
  • Audio.
  • Streaming media playback.
The man behind the port is none other than Ryan C. Gordon a.k.a. Icculus a.k.a Icculus Linden, cross-platform porter extraordinaire. Last I heard of his ongoing SL work, he was working on switching out the FMod sound engine for OpenAL, which will eventually lead to audio playback for Residents running the Linux client alpha, as well as saving Linden Lab a bit of cash on library licensing fees.

That's great, but as a builder, designer, graphic artist and scripter, I would flag image uploads/downloads and text copy/paste as highest-priority items. But until we get them, there's always WINE to tide us over.

Comments from the original post:
Erbo Evans said...

I can't even use the Linux client because my video drivers for X aren't up to snuff...the Radeon accelerated driver seems to lock X hard, requiring a reset to regain control of the system. The VESA drivers work, but they're so slow I can see screen repaints even on a 2D desktop...

Oh well, that's what dual-boot is for. :-)

8/24/2006 11:20 AM

Friday, August 18, 2006

Object Clones

This post appeared originally on the old blog. The original comments attached to the post are listed at the bottom. -J 09/03/06

Suppose for a moment that you are a builder of detailed houses within Second Life. In a typical house, you might have ten window fixtures, eight decorative columns, four doors, and two statues in the garden. Each of these items is identical to the others of its type, and is constructed of, perhaps, ten prims each, with the exception of the statues which are 100 prims each.

You've just spent 420 prims of your parcel budget to make twenty-four objects, and we haven't even added furniture! That's 420 prims which must be saved to the sim, and 420 prims which must be sent to every Second Life client which wants to view your magnificent houses.

What a waste, when each item is exactly the same as the others of its type, with only a different position, rotation, and possibly scale!

With object clones, which I am herein proposing, you could build the exact same house, but the above-mentioned 420-prim figure would be reduced to a mere 130 prims.

At this point, some of you will think I have gone insane, but the clever among you will have deduced how this could be possible and are now bubbling over with glee at the prospect. For the benefit of those who don't yet see it, I will explain.

An "object clone" would be a special object which has no prims of its own; instead, it inherits prims from the original object. This means that instead of storing the details of ten window fixtures, you store the details of one window fixture, and then create nine clones, saying, "These nine objects are constructed exactly like the first one."

From a technical perspective, object clones are a simple form of lossless data compression. Rather than storing n identical sets of data, we store one set and n-1 additional references to that set. The compression rate becomes more dramatic as the number of duplicates increases. (I think object clones would constitute a type of dictionary coding, but I may be wrong on that.)

Because a clone only has to store a reference (the UUID of the original) and a transformation matrix (position, rotation, and scale), it takes considerably less data storage space than even a single prim (which must also store such things as texture information and prim parameters).

But, even if Linden Lab counted each reference as equivalent to one prim for the purposes of parcel limits, we could still reduce our example of 420 prims to 130 prims + 20 clones = 150 'prims'.

Clearly, this feature would be of incredible importance to builders of all types! Frankly, it is such a simple concept with such extraordinarily far-reaching benefit that I find it hard to believe that Linden Lab hasn't already thought to implement it.

I have in mind several extensions to this concept which would further revolutionize the way we build in Second Life, but this post is already lengthy, so I will save them for another day.

Comments from the original post:
Alexander Lapointe said...


Wow, what a wonderful idea! I'm not a regular builder at the moment, but even with the making of Trav Doll/Trav Hat this would have been useful and would have cut down the prims to 8 from 11, which isn't that big of a difference, but still....

Plus, it would be nice for owners of small parcels with low prim limits, *cough* *cough*, by allowing for the little extras that make home-owning wonderful. Or the possiblity of having a house and a skybox that one could use.

8/24/2006 8:48 PM

Thursday, August 17, 2006

Flexible prim scale adjustment

This post appeared originally on the old blog. The original comments attached to the post are listed at the bottom. -J 09/03/06

When it comes to flexible prims, size does matter. A small prim just won't bend as much as a larger prim with the same flex settings. So if you want your lop-eared pet rabbit's ears to lop just the right way, you may have to scale him up to 5 meters on a side!

If I ruled the Grid, flex would be independent of size. Depending on how Linden Lab has implemented flexible paths, this would likely involve subdividing the path into the same number of parts when it is big as when it is small—that is, a number of subdivisions per path, not per meter of the path's length.

Since flexible prims have already been implemented, and that change would "break" a huge number of existing objects (not to mention cause plenty of embarrassment for flexi-skirt users who go without the luxury of "glitch pants"), Linden Lab could instead add a new attribute to control the scale used for subdividing the path. The default setting would be equivalent to the current scale, so that existing flexible prims would not behave differently.

Comments from the original post:
Reina Quine said...

Go ahead and break 'em! Serves those hussies right for not wearing glitch pants!

8/17/2006 7:34 AM

Tuesday, August 15, 2006

Instructors Group Chatter

This post appeared originally on the old blog. The original comments attached to the post are listed at the bottom. -J 09/03/06

Yesterday evening before logging off, I was invited to the Instructors group. Today, I encountered my first example of chatter in the Instructor group IM channel. Someone couldn't figure out a scripting-related issue for his own project, and so decided to ask in the Instructors channel.

Do not do this. This is wrong.

The Instructors channel is for Instructors to discuss issues related to teaching in Second Life. It is not a scripting helpline, nor a basic building workshop, nor a gossip hub. There are other groups for all those things. Use them.

When I applied for the Instructors program, I was fully aware that there would be stupid chatter. I had heard my Instructor friends complaining about it, and seen forum threads like the one linked above. I knew exactly what I was getting into.

And I am going to fight it.

Our script-nescient friend got a few replies from other instructors. If it had ended there, or perhaps moved to a private IM session with someone who was willing to help him, I would have let it go. After a minute or so of back-and-forth petty chatter between two instructors, I (politely) suggested that they continue the conversation in private IM or another, more on-topic channel. They responded that I could just close the IM window if I didn't want to hear it. One even drew me a helpful ASCII diagram with an arrow pointing towards the Close button.

Charming, but they missed the point.

If you were to come to a Real-Life meeting of baked goods enthusiasts and start blathering about how much you love kittens, you would be asked to leave. Even if some of the people at the meeting also liked kittens, it is not the proper channel for discussion of the merits of our furry friends. The people there came to talk about baked goods. If they wanted to talk about kittens, they would have gone to a meeting of kittens enthusiasts. You would be wasting everybody's time, and hindering their ability to do what they came there to do.

There are a lot of helpful and knowledgeable people in the Instructors group. Indeed, Instructors, by their nature, tend to be helpful and knowledgeable people. If you have a question, chances are one of the many Instructors will be able and willing to answer it. But if you ask the Instructors group a question that is unrelated to the topic of teaching in Second Life, you are spitting on the proper purpose of the channel, and wasting the time of everyone who upholds that proper purpose.

But this site isn't called I Like to Whine Without Offering Solutions, it's called If I Ruled The Grid! Time for some proposed action.

  1. Linden Labs should decouple the Instructors group from the Instructor benefits. Some people want to teach without being constantly exposed to useless chatter.

  2. Linden Labs should clearly state the purpose of the Instructors group in the group charter, and deal with abuses of the group channel. Chatter is a serious drain of resources, and should result in a warning on the first offense, and removal from the group on the second offense.

  3. Instructors should refuse to answer off-topic questions asked in the group.

  4. If you do feel compelled to answer it, answer it in private IM with the invidual, then tell him not to ask in the group again. For the purposes of signalling to other Instructors that you are handling the question, it is acceptable to make a brief reply to the group first.
I can't say I expect either #1 or #2 to happen. Linden Labs has demonstrated that it is not concerned whether it alienates the dedicated individuals who shape the Grid and make our Second Lives enjoyable.

[Edit: Just as there is no "I" in team, there is no "S" in Linden Lab. Many thanks to Mera for pointing this out. -J 08/17/06]

Comments from the original post:
Mera Pixel said...

Wow. Come out of the corner swinging, why don't you. :) Instructors used to be, are at times are, the most quiet of the volunteer groups. It's been getting gradually worse lately.

And to be nit-picky, it's Linden Lab. :)

Congrats on the site...and thanks for the linkage, however incestual it may be.

8/16/2006 5:49 PM