Adam Frisby

MRM: Making Scripting Simpler and Faster

with 2 comments

I mentioned previously the introduction of MRM Scripting into OpenSim. You can go read my early introduction into it – since then, I have committed the code into the OpenSim trunk and been improving it a bit, it’s enablable today. As a quick recap – it’s C# (or any .NET language) with a World API that is both simpler, more logical and more powerful than LSL/OSSL.

The first, most obvious, question is why not LSL? The shortest answer is, it’s bad. Linden Lab made a lot of mistakes in LSL – particularly around the destination intended audience. LSL was designed for very simple functionality, and this is evidenced in a number of places; such as lack of library support, minimal memory limits, an API which is internally inconsistent, lack of communication between script instances, etc. One of the reasons for this was Linden Lab envisiged LSL as being tiny little bits of functionality that you added together – so one object would have lots of scripts each doing tiny little things. How it turned out however is just like any other scripting language – people wanted a single script doing all the functionality, and were forced into doing things badly in order to get them working with the concieved limits.

That’s the first big complaint – the API is designed for something its not used for. To a programmer, writing in LSL can be a serious chore.

The second big complaint is that it is designed (not on purpose) to waste serious amounts of programming cycles on simple tasks.

Consider the following task: You want a list of every avatar within the region.

Under LSL your script looks something like the following:

Let’s go through this an examine how that gets processed by the simulator.

Entrypoint.

  • Examine every entity in the SceneGraph of type AGENT
  • Put every agent into a seperate list containing the agent and it’s position.
  • Calculate the distance between the host object position and every agent in the simulator. If less than 96m, remove from list. (note: distance calculations are expensive computationally as they involve running a Square Root, this needs to be done for every agent in the region)
  • Sort the list. (note: Sorting is also somewhat expensive)
  • Save the top 16 items in the sorted list.
  • Trigger the VM to schedule a SENSOR event, with the above list

Notice this isnt exactly efficient – it also has the downside that it wont show any agents outside of the 96m range, even if they are in the region. If you wanted to scan the entire region confidently you would need several hundred copies of the script.

This is an event fired by the VM, the results from the previous query are returned here – notice how difficult this makes programming. You cannot request data within a function, you need to break the function up into several components, at the very least one to gather the data, one to process it. If you have multiple requests going on, the assembly process is even more difficult, since you cannot request two sensors at once – you need to wait for the first to return results before firing the second.

Iterate through each potential value, nothing particularly inefficient here, however foreach syntax is nicer.

This forms another badly designed section of LSL – we have two calls here, llSay and llDetectedName – say is fine, it’s not perfect, but there’s nothing wrong with it. llDetected*() however on the other hand is badly designed. First it’s not consistent or type checked – not every llDetected function is availible in every event. There is no error handling – if an object has a empty blank name, it returns the same result as if you passed an invalid parameter as i. The other major issue is it requires making a function call to fish out the member of the list – the data is not stored ready to go in an array or object. (LSL lacks both arrays and objects)

If we count all the lines ‘doing something’ with the sensor, we have 7 lines of code to achieve the above simple task. We also have the VM doing walks of it’s entire scenegraph, calculating distances, generating lists then sorting them, etc. The act of calculating the sensor is going to be more complicated than processing the results. How can we do better?

Well the similar code in an MRM looks like this:

We have three lines ‘doing something’, to examine them in the same methodology as above:

This collects the list of World.Avatars from the SceneGraph – the most complex interaction here is just examining objects on the SceneGraph to see if they are agents, however we do not need to calculate their distance unnessecarily, we have no limits on only being able to return 16 at a time, the object that is returned contains all the availible properties of the avatar – not just the select few exposed to a llDetected*() function.

This prints the result out onto the OpenSim console – eventually that will look like Host.Object.Say(av.Name), however right now the API still needs work in terms of method calls from Objects. Right now we use the same ILog provider as OpenSim, however eventually we’ll see about moving that into a specialised console for script outputs.

For those interested in experimenting with MRM, it is still early days – however hopefully as the above points out, it could potentially be a very significant step forward from where we are today with LSL/OSSL. The language design is cleaner and simpler – and it is a degree more logical. If you compare the full LSL example to the MRM one – the MRM one has all the logic in a single place, both simpler and shorter. The LSL one jumps logic between events and does lots of limiting things unnessecarily. With MRM we also have a lot more potential that the C# language brings us – such as libraries and extensibility, arrays, objects and more.

2 Vote

Feedback

If you found this post useful and want me to write more on this topic, please use the vote button to the left or leave me a comment below.

Written by Adam Frisby

April 4th, 2009 at 5:20 am

Posted in OpenSim

Tagged with , ,

2 Responses to 'MRM: Making Scripting Simpler and Faster'

Subscribe to comments with RSS or TrackBack to 'MRM: Making Scripting Simpler and Faster'.

  1. One nit: while calculating a distance requires taking a square route, doing a distance *comparison* doesn’t. Checking if a bunch of points are within 96m of you doesn’t have to involve any square roots at all; you can just compare the sum of the squares of the axial distances to 96 squared. I don’t know if SL does this internally in the implementation of sensors, but if it doesn’t it should… :)

    Dale Innis

    9 Apr 09 at 12:20 am

  2. Yeah that is true – I moved our check from Util.GetDistance(x,y) in OpenSim to Util.IsLessThan(amount,x,y). The remainder is however a fairly expensive and unnessecary process.

    Adam Frisby

    9 Apr 09 at 6:02 am

Leave a Reply

 

You need to log in to vote

The blog owner requires users to be logged in to be able to vote for this post.

Alternatively, if you do not have an account yet you can create one here.

Powered by Vote It Up