Wednesday, September 1, 2010

Second Life Game Tile Testing


I've been messing around with game tile systems again using second life. Looking at the rudiments of a table top game like checkers, chess or even something as complex as monopoly. Trying to figure out how to develop something that doesn't use physics, but uses a tile based movement system.

I started by building a blank table top and adding a piece to it. Right now, the piece simply moves from corner to corner when someone clicks on the table. Under the hood there is a lot more going on than you might first think.



This is the code in the init script in the table.

default
{
state_entry()
{

//list bb = llGetBoundingBox(llGetKey()); // get my bounding box
vector sz = llList2Vector(llGetPrimitiveParams([PRIM_SIZE]),0);
llMessageLinked(LINK_ALL_OTHERS,1,(string)sz,NULL_KEY);
}

touch_start(integer total_number)
{
//llSay(0, "Touched.");
llSay(1024,"move");
}
}

You might as why did I comment out llGetBoundingBox. The reason is it works great when the table is by itself, but once the piece is on the table, the piece's location is included in the bounding box. This makes the box larger than expected.

So, the script get's the actual prim size from the table top and passes it to all the other linked objects (in this case the "disc" using a linked message. The identifier of the message is the number "1" which in this case means "table size", and the size (vector) is passed as a string.


You can also see that when the table is touched, it says "move" on channel 1024 which you can guess that the "disc" is listening for. Why not use llMessageLinked for both communications? We'll I should, but the "move" message was added early on and I started using linked messages later and have to get back to change to use llMessageLinked.


This is the code for the disc

vector mysize;
vector mysizediv2;
vector tablesize;
vector min;
vector max;
integer posMinOrMax;

default
{
state_entry()
{
//list bb = llGetBoundingBox(llGetLinkKey(1)); // get the bounding box of the table
//max = llList2Vector(bb, 1); // max corner
//min = llList2Vector(bb, 0); // min corner
//min = >min.x,min.y,max.z<;

//llWhisper(0,(string)min+" "+(string)max);

posMinOrMax = 0;

llListen(1024,"",llGetLinkKey(1),"move");
}


listen( integer channel, string name, key id, string message )
{
if (channel==1024)
{
if (posMinOrMax==0)
{
llSetPos(max);
//llWhisper( 0, "max" );
}
else
{
llSetPos(min);
//llWhisper( 0, "min" );
}
posMinOrMax = 1 - posMinOrMax;

}
}

link_message(integer sender_num, integer num, string str, key id)
{
if (num==1)
{
mysize = llList2Vector(llGetPrimitiveParams([PRIM_SIZE]),0);
mysizediv2 = mysize / 2;
mysizediv2.z = 0.0;

tablesize = (vector) str;
llWhisper(0,"got size = "+(string)tablesize);
vector sz = tablesize / 2;
min = >-sz.x,-sz.y,sz.z*2< + mysizediv2;
max = >sz.x,sz.y,sz.z*2< - mysizediv2;

}
}
}

You can see that early on I calculated the min and max positions based on the bounding box which I have already said is wrong. On the listen channel when I hear "move" I toggle the position between the min and max. That should be pretty straight forward.


The interesting stuff is in the link_message function. I first get the size of the "disc" using the llGetPrimitiveParams call. All positioning is done from the center of the object, so if I use the absolute min and max sizes of the table then the disc will hang off the edge. I divide the size by two because that is how far I have to inset the position from the table's min and max.

I then convert the table size vector from the string that was passed on the link message back to a vector and calculate the min and max positions using the inset of half the disc size. The min adds half the disc size and the max subtracts. The other thing is that the table's origin is at the center, and positioning the disc has to take that into account. So the min is the table position (center) subtracting half the size of the table. The max is the table position (center) and adding half the table size.

Wednesday, August 25, 2010


I had a discussion with another developer about the moonphase virtual sculpture. They mentioned a technique that might improve bandwidth usage by using llSetTextureAnim instead of setting the offset of the texture directly. The idea being that llSetTextureAnim would be running on the actual client which doesn't require any bandwidth, while llOffsetTexture is run on the server and all the clients viewing that object need to receive a message that the object change.

So I did some testing with llSetTextureAnim and I couldn't get the same results. When you use ROTATE in llSetTextureAnim then you can't specify the texture offset, only which portion of the texture you want to use. It seems like it is used to have a tiled texture where each section of the tile can be used as an individual tile. In my case, I used a half transparent texture and am rotating that around the sphere. Using llSetTextureAnim I don't see a way to get the same effect. I'm a little slow most of the time so I may be missing something. Here is a screen shot of using
default
{ state_entry()
{
llSetTextureAnim(ANIM_ON | LOOP | SMOOTH | ROTATE,ALL_SIDES, 1,1, 0, TWO_PI, TWO_PI/360);
}
}



I also tried using a non-ROTATE texture animation which only cause the texture to turn on and off when the "tile" reached the non-transparent section.

I really like the idea of reducing bandwidth by having the texture changes run on each client, but don't see a way to get this to work for this sculpture. llSetTextureAnim is definitely a good tool for the tool belt and I'll have to consider some sort of sculpture using a tiled texture. That would mean that each client would see something different on their machine so there couldn't be a discussion about the "current" look of the sculpture between two people, but I'm not sure that's a real problem.

Wednesday, August 18, 2010

Sensor land detection

I recently moved lands and my new neighbor asked if I could turn of my sensor that greeted visitors. I guess it was going off when people were visiting their land.

I first detected the location of the Agent who tripped the sensor. Then get the land owner key at that location. It's hard to tell what that key is so I wrote code to print that out if the sensor detected me, then went into my neighbor's land. Then took that number and hard coded it into the welcome message. Now the sensor will only greet someone if they are on a different land than my neighbors.

sensor( integer number_detected )
{
integer i;
for( i = 0; i < detpos =" llDetectedPos(" k =" llGetLandOwnerAt(detpos);" k ="="" k = "+(string)k); // } //} if ( (llDetectedKey( i ) != llGetOwner()) && (k != ">

Tuesday, August 17, 2010

Moon Phase Second Life Sculpture

I've been working on an art gallery for an internal company sim and also building a couple of small sculptures for it as well. I built this one in the internal sim, then recreated it and improved it in SecondLife. It is a number of concentric rotating half-spheres that also change color.


"moon phase"
Virtual Second Life Sculpture

Monday, August 16, 2010

Beyond Facebook - designing outside the box

Beyond Facebook. - Design Outside The Box.

This is a great presentation on a huge transition that is happening in the game industry and gives a peak on how you can use psychological gaming techniques in everyday interfaces to improve the user experience. The presenter is Jesse Schnell from Carnegie Mellon University. I played this for my class last semester and recently watched it again. There is definitely a lot of good information in here.

Wednesday, August 11, 2010

lsl - Giving a notecard


I was wading back into the Second Life waters after volunteering to help build an art gallery for a group at work. I was also working on a couple of sculptures.

One of the things I wanted to add was to have my object give a notecard to someone who clicked on it.

This was simple.
First. Create a new notecard in your inventory.
Drag it into the content of the object you want to give that notecard.
Let's say it's called "Light Hand Sculpture - notecard"

Add this script and it will give the notecard to someone who clicks on your object.

default
{
state_entry()
{
}
touch_start(integer total_number)
{
llGiveInventory(llDetectedKey(0), "Light Hand Sculpture - notecard");

}
}


Here is the sculpture I was working on. It is on a private sim so I can't give you a link to see it. Sorry.


"Light Hand"

Tuesday, August 10, 2010

Traded land

The land I was using had all the land around it purchased by one person who was trying to create a cohesive sim. I was the last hold out and not because I was being stubborn, I just haven't logged on for a long time because I've been focused on XNA. I agreed to trade the land for something comparable. It turned out this was pretty simple for her to find and I traded my land.

New location: