You are currently browsing the monthly archive for February 2008.

You go for years waiting for a competitor to Second Life, and suddenly three come along at once.

Ok, that’s a bit of an exaggeration, if not to say completely misleading, but it does kind of sum up how I feel right at the moment. In the last few weeks some open-source versions of Second Life have emerged into the wild. They are still in early stages at the moment (think of them as alpha releases at best), but promise to develop very quickly into something very useable.

They also start to open up the possibility of a truly distributed 3D web (more on that later, but for me it is one of the most exciting aspects of these new developments).

First, a quick introduction to the applications in question, and how they relate to one another.

RealXtend

This one has the potential not just to outdo Second Life, but to knock it out of the ring altogether. At the moment the performance is worse than Second Life on a bad day, and a lot of features are missing or incomplete. It still manages to be breathtaking.

There is both a server and a viewer available. Let’s look at the viewer first, which is so similar to Second Life’s viewer that I’m not even going to bother with a screen shot. One significant point is that the viewer can be used for Second Life itself, and can also be used to connect to other servers/grids, such as the Open Life grid mentioned below.

However, RealXtend comes into its own when you use the ReadXtend server with it. You can download the server and run it on your own computer. Yes, your own local world — and yes, other people can connect to you, provided you tell them the correct IP address and port to use (no, this isn’t straight-forward — I told you this was early days yet).

Run the server, then launch the viewer to connect to it, and this is what you get:

RealXtend island

Let’s take a closer look, and let’s do a bit of creating. Ok, it’s just a simple block with a new texture, but at least it proves it works. Take a look at the surroundings, though, which come as default with the server. Very impressive.

RealXtend island

At the moment, there is no facility to change your own appearance, so you are stuck with the default avatar.

RealXtend default avatar

At least she is slightly more interesting than Second Life’s notorious ‘Ruth’!

OpenLife

As with RealXtend, OpenLife comes with both a viewer and a server (both downloadable for free, again as with RealXtend). They are also providing the ability to buy regions on the OpenLife grid, in a similar fashion to the Second Life model.

The viewer, once again, can be used to connect to the OpenLife grid, or to the main Second Life grid (I assume you could also use it to connect to a RealXtend server, but I haven’t tried this myself).

OpenSim

This is a third entrant in the list of open-source servers (there doesn’t seem to be a browser with this one, instead you use one of the existing browsers to connect). I haven’t investigated this one myself, not even to the extent of downloading it and trying it, but I intend to do so very soon.

Distributed 3D Web

Ok, so much for the programs themselves. There has been quite a buzz around them, and a lot of discussion, but I think that many people miss the point of what is going on here.

The most significant point is that it is possible to host a Second Life type of world on your own computer (you’ll need a decent connection!), and invite your friends to come and visit you, using a free downloadable browser. It looks as if many of the browsers will be cross-compatible, though I do see the scope for a new type of browser-war!

It will also be possible for companies to set up their own grids, and sell regions on it, somewhat like Second Life does at the moment, but instead of one central grid, there will be lots of them. The result will be very much akin to the world wide web, where companies host websites.

Avatars will be able to move between these worlds, taking their inventory with them — this is a crucial point (see the RealXtend website for a more detailed explanation), and makes this whole idea not only work, but actually useable and useful.

As I see it, the one thing missing is the equivalent of hyperlinks, to allow you to jump from one world to another. This would not be particularly difficult to implement — essentially you just restart the browser, pointing at a new location. It could be done in a manner similar to the existing teleport feature in Second Life. The trick is being able to find out where those other worlds are, as easily as you can find websites, a problem that has still to be fully addressed by the existing systems (but not, I think, a particularly knotty problem).

There are other issues that will cause existing Second Lifers problems, partly because of Second Life’s own peculiarities. For example, Second Life has an economy (a completely fake economy, of course, something which many people seem unable to grasp) — this is not going to transfer over to the 3D Web. How can it, when potentially everyone is running their own world, and has complete control over it. If you want to earn money, it will mean using a real-life economy, with real-life cash.

Security might also be an interesting issue, but possibly one that is more easily handled than in Second Life. If someone comes to your world, can they do anything they want, or do you have complete control over what they are allowed to do? I suspect that the latter is easily possible in theory, but has not actually been implemented in practice (the current emphasis has mainly been on recreating Second Life’s features).

Certainly, giving each independent world complete control over security opens the possibility of allowing functionality that has been excluded from Second Life purely because of the potential for abuse. I shall be interested to see how the security issues are tackled in these new worlds.

(On a personal note, I have one quibble. I am primarily a Mac-user these days, and all these browsers and servers are Windows-only.)

It’s a little too soon to declare “Second Life is dead. Long live the Open Web!” but I feel that it won’t be long. Maybe one or two years at the most.

Me, I can’t wait.

Links

RealXtend

OpenLife

OpenSim

Note: I’ve edited this post to remove the remarks about No Mod, No Copy, No Transfer and Mod, No Copy, No Transfer, when it was pointed out by a couple of commenters that these combinations are actually impossible.

I was originally going to write a brief article about the technical details of putting items up for sale, and I will still do that at some point, but as I was writing it I found that I had a lot to say about permissions. As permissions are something you have to give serious thought to if you want to sell things, I’ve decided to devote an entire post to it. I’ll assume that you already know how to set permissions (if you don’t, they are on the General tab of the Build dialog).

Permissions are a thorny subject, with wildly differing views. What I am going to do is to examine the ramifications of each option and (more importantly) of each combination of options. I’ll also give my own opinion on each of various options, but you should realise that there are plenty of merchants out there who will have quite different ideas. Be prepared to give the whole subject some very careful consideration!

First, let’s look at the individual permissions.

Mod means that the purchaser can freely change the object, using the Build tools. No Mod means that the purchaser cannot modify the object in any way other than simply moving or rotating it. They can’t scale it, they can’t change the textures, they can’t break it up (assuming it consists of more than one prim).

For most objects, No Mod is a sensible option. However, if you are selling clothing attachments (for example, hats), you might want to allow modification so that the purchaser can adjust the size of the object to fit their avatar (regrettably there is no way to restrict the types of modification that are allowed — it is all or nothing). In fact, some people might be reluctant to buy such items if they are not moddable.

Copy means that the purchaser can create multiple copies of the item (but only for themselves — they cannot pass these copies on to anyone else). This has some less than obvious effects. When a Copy object is rezzed, the original remains in the Inventory. If the owner deletes the rezzed object, they still have the original. If they mod the object (assuming it is moddable), the original is unchanged, and if they wish they can take a copy of the amended object back into their Inventory — they will then have two copies, both the original and the altered copy.

No Copy means that the purchaser cannot create multiple copies of the item. They will not be able to Copy and Paste the object within their Inventory (although they can move it around in the Inventory), and when they rez the object it will vanish from their Inventory.

Many merchants specify No Copy. Unfortunately, many purchasers (myself amongst them) are reluctant to buy No Copy items. The main reason is Second Life’s notorious flakiness. I have had experience myself of rezzing a No Copy object, seeing it vanish from my inventory, but failing to rez. If you are lucky, it might be returned eventually, sometimes to the Lost and Found folder. More often than not it is gone for good. Or rather, for bad.

The other reason for Copy applies to clothes. I have separate folders for each costume that I wear. In many cases these costumes are customised — I have built them by combining clothes from different merchants. Often I have an item that I want to use in more than one outfit, so I want to create copies in several different folders. From my point of view, it is a convenience for me — with No Copy items I would have to go to different folders in order to put together a specific costume. From the merchant’s point of view, I can only ever wear one copy at a time, so they are not losing out (and I’m not going to buy multiple copies just for convenience).

Nowadays I hardly ever buy clothing that is No Copy.

No Transfer means that the purchaser cannot give or sell the item to someone else. This is a very common option, but there is a catch when the purchaser wants to buy the item as a gift for someone else — this option stops them from doing that. A good solution is to create a special ‘gift’ version of the item, specifying Transfer and No Copy. With this option the purchaser can give the item to someone else, and it will be removed from the purchaser’s inventory. Of course, this goes against what I have said above about No Copy items, but there really isn’t a lot of choice in this case. You probably just need to be prepared to deal with the occasional loss of such gifts, when Second Life fails at the crucial moment of transfer!

But this is starting to get us into combinations of permissions, so let’s take a look at the other possible combinations, and what the implications are. I’ll begin with the probable no-nos:

Mod, Copy, Transfer, and the closely related No Mod, Copy, Transfer. Probably fatal, unless this is a freebie that you don’t mind being copied and given or sold on to any number of other people. For items that you want to make a profit out of, this is a very unlikely combination!

Ok, now for the more useful combinations.

No Mod, No Copy, Transfer. As I mentioned above, you can use this for items which are to be sold as gifts, but be prepared to deal with the occasional fall-out. Only use this combination if you are also selling a version with Copy and No Transfer options.

You could feasibly have Mod, No Copy, Transfer to allow moddable gifts (for the clothing attachments I’ve already mentioned). This is workable, but again be prepared to deal with problems. If the receiver of the gift mods it and breaks it, how generous are you going to be to them when they ask for a replacement?

No Mod, Copy, No Transfer. My favoured set of permissions, both for selling and for buying (except for clothing attachments, where I look for Mod as well).

Oh, while I’m at it, some merchants sell items with different permissions for different prices. Usually this means a No Copy version and a more expensive Copy version. Personally, I think this is a good compromise — I’m certainly prepared to pay a little more (but not too much!) for a Copy version, and I understand and empathise with the motives behind it.

Textures

When it comes to permissions, textures are an oddity. They are only usable by the purchaser if they come with full permissions – Mod, Copy, Transfer. This means that once you have sold the textures, the purchaser can do absolutely anything with them, including passing them on to other people. If you think about it, you can probably see why this is the case — if a texture is used on an object which is going to be sold, the texture has to be transferred along with the rest of the object. In a similar fashion, the texture has to have Copy, otherwise the purchaser could only make and sell one single item with that texture.

Does this mean there is no point in selling textures? Maybe. Personally, I have sold (and still sell) packages of textures, and make a good profit from them, in spite of my inability to restrict the usage of them. You might prefer not to take the risk.

You can, of course, accompany your textures with dire warnings about copyright, and threaten people with DCMAs. It might work, I’ve never tried it. It’s your call.

If you want to make textures your central product (and some people, such as Lauren Fox, seem to have done this successfully) you need to decide how much you are going to worry about people copying your work. If the answer is “a lot”, you might want to reconsider.

One final point. When you are selling your items, make sure that the permissions for them are clearly visible (either in a nearby advert, or on the box, if the items are boxed).

Brief, Opinionated Summary

  • Mod, Copy, Transfer – give-aways/freebies only!
  • Mod, Copy, No Transfer – good for clothing attachments
  • Mod, No Copy, Transfer – for moddable gifts
  • No Mod, Copy, Transfer – give-aways/freebies only!
  • No Mod, Copy, No Transfer – my favoured default
  • No Mod, No Copy, Transfer – for gift

In my previous article, I showed how to set up communication between different scripts in a set of linked prims. In this article I will explore this a little further, and show how to make it more flexible and easier to use.

First, we need a way of finding the link numbers of the prims in a set. Although it is possible to work this out manually, it is tedious and error-prone, and the more prims that are linked, the worse this becomes.

Let’s try an alternative. Give each of the prims a unique name (or at least unique within the link-set). This is probably a useful thing to do anyway.

Once this is done, you can set up variables for the prims that a script is interested in, and then locate the linked prims by name, using llGetLinkName function. Call this when the script is reset or the prim is rezzed.

Here’s a small example:

// This will hold the link number for the prim we
// want to send messages before.
integer LINK_TARGET = -1;
// A function to read the link numbers.
getLinks()
{
    integer i;
    // How many prims are linked?
    integer linkcount = llGetNumberOfPrims();
    // Reset our link target number, just to be
    // safe.
    LINK_TARGET = -1;
    // Work through the prims, looking for our
    // target.
    for (i = 1; i <= linkcount; ++i)
    {
        string str = llGetLinkName(i);
        if (str == "LINK_TARGET_NAME")
        {
            // Found it. Store the link number.
            LINK_TARGET = i;
        }
        // We can obviously extend this to
        // look for and record the link
        // numbers of other prims.
    }
    // If we didn't find our target, report this
    // to the owner.
    if (LINK_TARGET == -1)
    {
        llOwnerSay("Could not find LINK_TARGET_NAME");
    }
}
default
{
    state_entry()
    {
        getLinks();
    }
    on_rez(integer param)
    {
        getLinks();
    }
    touch_start(integer count)
    {
        // Make sure we actually found our target
        // prim.
        if (LINK_TARGET != -1)
        {
            // Send the message to it.
            llMessageLinked(LINK_TARGET, 0, "MESSAGE", NULL_KEY);
        }
    }
}

The only thing to be careful about here is that if you change the link order (by unlinking and re-linking your prims in a different order), you have to make sure that all the scripts are reset.

One convenient way of doing this is to include a RESET command which is sent from the root prim to all the other prims. When they receive this command, they should call llResetScript() to reset themselves:

link_message(integer sender, integer cmd, string param, string id)
{
    // Assume we have defined CMD_RESET somewhere.
    if (cmd == CMD_RESET)
    {
        llResetScript();
    }
}

Now, how about passing different types of parameters, other than simple strings? If you only want to pass a single value, a straight-forward typecast is all that is required. For example, suppose we want to have a message that tells another prim to move to a specific position. To do this, we want to send a vector. We can do this like this:

llMessageLinked(TARGET, CMD_MOVE, (string)<128.0,128.0,128.0>, NULL_KEY);

The receiving prim can convert this back into a vector in a similar way:

link_message(integer sender, integer cmd, string param, string id)
{
    if (cmd == CMD_MOVE)
    {
        vector pos = (vector)param;
        llSetPos(pos);
    }
}

(Of course, I am assuming you have set up a CMD_MOVE variable in both scripts, with the same value in each. It would also be sensible to provide some kind of error-trapping, in case the parameter string does not actually hold a vector. If it doesn’t, you will end up with a vector of .)

What about passing more than one parameter between the scripts? The main trick here is for the sending script to pack the parameters into a string, and then the receiving script uses llParseString2List() to extract the result.

In this example, I am separating the parameters with a semi-colon. Here is the sender’s code:

llMessageLinked(TARGET, CMD_MOVE, "<1.0,1.0,1.0>;Move!", NULL_KEY);

The receiver needs to unpack this, like so:

link_message(integer sender, integer cmd, string params, key id)
{
    if (cmd == CMD_MOVE)
    {
        list parameters = llParseString2List(params, [";"], [""]);
        vector moveBy = (vector)llList2String(parameters, 0);
        string command = llList2String(parameters, 1);
        // Do something with the results
        // ...
    }
}

Note that when extracting the vector, I am extracting the parameter from the list as a string, and then typecasting it to a vector, because the parameter is stored as a string in the list (llParseString2List will extract the contents as string), and llList2Vector will not perform a typecast itself.

By combining the getLinks() function and the ability to pass multiple parameters, you can construct a flexible and fairly robust system for passing information between linked prims.

A final caveat: don’t overdo this. Every script takes up resources. If you have an object with a large number of scripts all communicating with one another you can seriously contribute to lag. If you find yourself doing this, it is worth rethinking how your object is working, and whether there is a simpler way of doing things.