Randomly generating terrains

… aka “When the Creator misplaces a parenthesis”. :)

So my first attempt to write a program to generate random but pleasing landforms for my Sim on a Stick did not go quite as expected.

When the Creator God misplaces a paren...

Bit spikey, for instance.

But then I found a misplaced parenthesis! And things got better.

Ah, much better

I think I am liking the algorithm…

Landforms from the RNG

For the curious, here is the basic (recursive, self-similar) routine, in everyone’s favorite language: Python. (Squished down to fit in the weblog here, not guaranteed to compile as-is.)

def fill_in_terrain(t,lowx,lowy,maxx,maxy):
   ''' Takes the input terrain, where the low-by-max '''
   ''' corners are already filled in, and fills in '''
   ''' everything inside those corners, by the '''
   ''' Magic of Recursion. '''
   if maxx-lowx<2: return t
   if maxy-lowy<2: return t
   xmid = int((lowx+maxx)/2)    
   ymid = int((lowy+maxy)/2)
   hscale = (maxx - lowx) * HSCALE
   # first the corners
   if t[lowx][ymid] is None:
     t[lowx][ymid] = (t[lowx][lowy] + t[lowx][maxy]) / 2 
       + hscale - math.floor(2*hscale*random.random())
   if t[maxx][ymid] is None:
     t[maxx][ymid] = (t[maxx][lowy] + t[maxx][maxy]) / 2 
       + hscale - math.floor(2*hscale*random.random())
   if t[xmid][lowy] is None:
     t[xmid][lowy] = (t[lowx][lowy] + t[maxx][lowy]) / 2 
       + hscale - math.floor(2*hscale*random.random())
   if t[xmid][maxy] is None:
     t[xmid][maxy] = (t[lowx][maxy] + t[maxx][maxy]) / 2 
       + hscale - math.floor(2*hscale*random.random())
   # then the center
   if t[xmid][ymid] is None:
     t[xmid][ymid] = (t[lowx][ymid]+t[maxx][ymid]
                     + t[xmid][lowy]+[xmid][maxy])/4 
                     + hscale - math.floor(2*hscale*random.random())
   # and recurse on the four quadrants
   t = fill_in_terrain(t,lowx,lowy,xmid,ymid)
   t = fill_in_terrain(t,lowx,ymid,xmid,maxy)
   t = fill_in_terrain(t,xmid,lowy,maxx,ymid)
   t = fill_in_terrain(t,xmid,ymid,maxx,maxy)
   return t

def get_terrain(x,y):
   ''' returns an [x][y] array of floats representing a terrain; '''
   ''' range unpredictable '''
   ''' x and y ought to be powers of two, for best results.  '''
   ''' oh, and equal I suppose '''
   answer = [ [None for a in range(y+1)] for b in range(x+1) ]
   answer[0][0] = 0
   answer[x][0] = 0
   answer[0][y] = 0
   answer[x][y] = 0
   answer = fill_in_terrain(answer,0,0,x,y)
   return answer

Fun that all these pretty hills and things come out of that little bit of (also pretty) code…

Breeding like prims

So yet another thing about having one’s own private virtual world is that one can do all sorts of fun but dangerous stuff that one wouldn’t do in anyone else’s.

The main fun-but-dangerous thing, naturally, being the creation of uncontrolled replicators.

(Carefully controlled replicators are safe even for, say, Second Life; and of course SL has the Grey Goo Fence, which is good for the Grid but can be annoying for Residents.)

The other day in my local OpenSim-on-a-stick I made a little physical sphere that randomly moves around. It promptly took off into the open water ‘way off the side of the sim (into space that, strictly speaking, doesn’t exist).

So then I made a tall green wall, and put the randomly-moving ball inside the wall, and that was better.

Then I taught the ball to make copies of itself, and also to randomly delete itself. I set the probability of replicating just barely above the probability of self-deletion, knowing from my days as an Anti-Virus Guru that this should lead to an (initially) slow population increase.

Then I got bored, watching the number of balls inside the wall go from one to two to three, back to two, back to three, to four, back to one…

So I cranked up the probability of replication a bit. And then of course the phone rang and I had to open a different window to do something, and when I went back to the viewer:

Runaway 1

Oh, dear.

Well, no problem, I thought; the sim was running kind of slow, but I could just cam up, select everything nearby, deselect the wall, and hit Delete.

And that worked great, except that in the few seconds between my selecting everything and hitting Delete, another few dozen balls had spawned, and they weren’t selected or deleted, and then a couple seconds after that the sim was running so slowly that deleting stuff wasn’t really working anymore.

And then I noticed…

Runaway 2

a potential crisis! If the balls were to start spawning outside the wall, it seemed not unlikely I would have to restore the sim from the last OAR file I took or something.

On closer investigation there were at least three balls that had apparently escaped the wall:

Runaway 3

but when I went to examine (and hopefully quickly Delete them), it turned out none of them actually existed as far as the sim was concerned, the viewer was just confused as a result of all the physics and lag going on. So that was good.

I thought I would log out and then log back in as the AV with Estate powers (Simona Stick, rather than Test User). I noticed that over on the Opensim console, things were not entirely happy:

Runaway 4

It look a long time to settle down again when I tried to log out, and at this point I started to panic a bit. In the time it would take me to log in as the estate owner and try to turn off scripts or whatever, would the sim have become utterly unusable? So instead I did a shutdown on the Opensim console. This resulted in lots more red messages for quite awhile…

Runaway 5

but eventually it did shut down.

Okay, smartypants, so now what? Well, it turns out that Opensim in Sim on a Stick happens to use a MySQL database to store everything in, and that due to the Day Job I have some knowledge of MySQL, and the database tables that Opensim uses are at least somewhat documented.

So once I’d figured out the MySQL username and password that SOAS had installed, I logged into the MySQL console, and viola:

mysql> select count(*) from prims;
+----------+
| count(*) |
+----------+
| 1482 |
+----------+
1 row in set (0.00 sec)

So we have fourteen hundred and eighty-two prims. Fortunately all of the self-reproducing ones have the same name, and each rezzed prim (as far as I can tell) corresponds to one or more records in just three different tables.

First we delete the shape-records for the prims (Opensim could save considerable space in the database by compressing out duplicates here, one would think):

mysql> delete from primshapes where UUID in (select UUID from prims where name="moving and reproducing ball");
Query OK, 1294 rows affected (0.05 sec)

So it looks like we have about 1294 replicators

Then, we destroy the contents (prim inventories) of all of them:

mysql> delete from primitems where primID in (select UUID from prims where name="moving and reproducing ball");
Query OK, 2385 rows affected (0.14 sec)

And that more or less makes sense; each replicator typically contains a script and a copy of itself, so we’d expect to have roughly twice as many contents as we have replicating prims. 2385 is somewhat less then twice 1294, but that’s because of that “roughly” in the last sentence, which I will not go into in detail.

And finally, we remove the little beggars themselves:

mysql> delete from prims where name="moving and reproducing ball";
Query OK, 1294 rows affected (0.05 sec)

Another reassuring 1294.

Now we would expect to have 1482-1294 prims left, and:

mysql> select count(*) from prims;
+----------+
| count(*) |
+----------+
| 188 |
+----------+

(counting on fingers) that adds up!

Crossing our fingers and venturing back into the world as Test User, we find:

Runaway 6

The wall (and everything else) undamaged, but the nasty replicators gone! And sim performance back to normal. So huzzah!

Disclaimer: I have no idea whether the steps above are actually the right way to remove a bunch of nasty things from an OpenSim instance, and for all I know they have left the database in some incoherent state that will cause it to die horribly tomorrow. If your Opensim world is valuable to you, take frequent backups and don’t go messing with the database directly in MySQL because of something you saw in a weblog once. Also, in retrospect, it probably would have been cleverer to use MySQL just to turn off scripting for the estate, and then gone in and cleaned up normally inworld. But hindsight is a penny earned!

Gypsy Sunflower

Gypsy Sunflower

(Original bigger size)

I do love my skybox. And sorting inventory!

Details:

Outfit: VreMode Gypsy Sunflower in Peach* from VreMode;
Skin: Snowfall Deep Black from Mango, Mango;
Hat an’ Hair: Cloche Ponytail from La Boheme;
Monocle: the Automatic Viewing Lens, from VAUGHAN’s House of Curiosities;
Hazard-Symbol eyes: almost certainly Grim Bros.;
Skybox, as always, from the bargain basement at KOSH;
Elegant bookcase-loft from S&S Clockworks.

I can haz fashionblogging? :D

* ObDisclaimer: I’m in the VreMode model group, so I get stuff early sometimes so I can take pictures of it an’ all for using on ads and boxcovers and stuff. But I am not paid to post. :) This particular outfit may not be actually available yet, or anymore, or whatever.

Sim-on-a-Stick and Kitely: they both work!

After I described my uber-l33t bat file hax0ring the other day, Ener Hax emself commented that the latest Sim on a Stick would detect 32 vs 64 bit and do the right thing All By Itself, and also had a more recent version of OpenSim, and a thing to let you choose three different styles of world layout, and so on.

So I tried it! In particular, I exported what I had built so far (i.e. the increasingly awesome house, pictured here being built still in the older OpenSim I think:

Test User builds a house!

) to an OAR file on my laptop’s hard drive, using the actual Opensim documentation, imported it to the sim next door on my USB key just to make sure it worked (matter duplication!), saved Test User’s (tiny) inventory to an IAR, shut down that little OpenSim, installed the latest one from Sim On A Stick (they both fit onto the USB key with room to spare), developed even more l33t Opensim skills by finding out Test User’s UUID on the old one, creating a Test User with the same UUID on the new one, imported the OAR and IAR, and poof!

Test User was ready to start building again in the new moderner and unhacked-by-me virtual universe:

Interior Design in a USB key

And that was extremely cool.

After building a little more there I thought the next ossum thing to do would be to put this little house-in-a-world onto the public Web somewhere were other people could (potentially) also get to it.

Kitely was the obvious choice, so I looked at various other things first. :) If you are a company wanting to pay a small (by company standards) monthly fee for a virtual server in the cloud, there are lots of people eager to take your money. But if you are an individual wanting really not very much at all for hopefully more or less nothing, the choices are more limited as it turns out.

So Kitely it was! First I went back into the local USB-key world and put a crate in the yard and put all of Test User’s inventory items into it and made a new OAR (since Kitely I think will let you upload an OAR but not an IAR). Then I joined Kitely on the Free plan (by logging into Twitter and telling it to tell them that I was me, which is cool and/or scary), created my one free world, uploaded the OAR, and logged in…

kitely_001

Is that Test User’s house we see in the distance?

kitely_002

Hurrah, it is! (Including the inventory-crate in the yard, and the various textures harvested from the Innertubes, and their accompanying baggage of moral and legal copyright questions!)

Let’s go inside and check out the details.

kitely_003

Everything seems to have come over just fine, including the genuine Dale Innis art on the wall there, with the subtle band of color on the black horizontal piece, that moves slowly from one side to the other, changing hue as it goes. (And the amusing 70’s-style orgy picture in the background.)

Back out to the yard, and the crate of inventory items, and here is Kitely Dale with my favorite custom OpenSim eyes and hair, and Eloh Elliot skin, and home-made “n00b” tee shirt, ready to take on the world! (At least as long as the free two hours lasts, after which I will have to consider buying some Minutes a la carte.)

kitely_005

Fifteen minutes later, there is a nice wall around the yard:

kitely_006

and the universe is threatening to fork. I tried to export it, with the modifications, from Kitely as a new OAR, but apparently I don’t have enough Kitely Credits for that. And my patience for figuring out virtual currencies and stuff had apparently run out, because I went off to write in my weblog here rather than finding out about Kitely Credits and continuing on that path tonight.

Pretty neat, eh? Maybe sometime I will throw a party there! If I can figure out how the Minutes and Kitely Credits required would work an’ all…

World in my Pocket (USB Windows 64-bit version)

So I stumbled across the ‘Sim on a Stick’ idea for the Nth time (that one is Tateru Nino’s; see also SimOnAStick dot com from the adorably pink iliveisl entity, and NWN’s recent coverage), and this time I thought I’d try it.

Tateru’s ZIP file doesn’t actually work under 64-bit Windows, which is what the fancy laptop here runs, but it almost does. The symptom is that after the opensim console says “APPLICATION” you get a popup about opensim.exe being evil, like so:

and then a big Java-or-something traceback about a bad image and an invalid format and similar geeky stuff shows up in the console and it acts as though you’d typed “shutdown”:

I poked around a little, and found the fix here. Basically you just have to run opensim.32bitlaunch.exe instead of opensim.exe (this runs the 32-bit opensim; actually running a 64-bit opensim would be more work, especially since at least one important component, ODE, doesn’t seem to have a 64-bit build that I can find).

So what I did, concretely:

  • Open the usb-opensim folder on the USB key in Explorer,
  • Copy and paste the “opensim” thing, so there are two now,
  • Rename to new one to “opensim64”
  • Rightclick on it and Edit
  • Find where it says “opensim.exe”,
  • Change that to “opensim.32bitlaunch.exe”,
  • Save and exit,
  • Now run your world just as Tateru says, except:
  • Where she says to run opensim.bat, run opensim64.bat.

And that’s all! Mere moments later (and after not being able to figure out how or if it’s possible to tell Firestorm to point at anything besides SL, and being glad I still had an Imprudence around), I was duckwalking around, uploading some great old Eloh Elliot skins and my “noob” tee shirt, and making some brand-new prims on my very own laptop!

That is the comely and talented Test User, wearing capris from the small clothing collection that comes in the ZIP file, the abovementioned skin and tee shirt, and the ever-popular New Hair and New Eyes, admiring the First Three Prims Ever Created In This Particular Universe.

Which is really quite cool, in its own way…