Showing posts with label OpenSim. Show all posts
Showing posts with label OpenSim. Show all posts

Friday, December 5, 2008

OpenSim in Visual Studio on Win64

Note! Article applies to developers using Visual Studio on 64-bit Windows.

Visual Studio is a great tool. Most developers who can use it should.

Currently OpenSim has some problems with 64-bit mode. This is because we have some native .dll's and .so's such as:
  • SQlite
  • ODE
  • OpenJpeg
  • + more

SQLite you can do without by choosing MySQL or similar. But the rest is a bit more difficult.
See http://www.adamfrisby.com/blog/2008/08/running-opensim-under-a-64-bit-environment/ for more info.

To solve this problem we have a file named "OpenSim.32BitLaunch.exe" which is compiled with CPU target set to 32-bit. This in term loads OpenSim.exe as a standard module and executes it.

But this is only from command line. If you want all the glory of debugging that Visual Studio provides then this workaround will work:

  1. Download the OpenSim source as usual, run prebuild as usual.
  2. Open OpenSim.sln in Visual Studio.
  3. Right click solution and choose Add->Existing Project...
  4. Browse to "OpenSim\Tools\OpenSim.32BitLaunch" and add the project "OpenSim.32BitLaunch".
  5. Right click project called "OpenSim.32BitLaunch" and choose "Set as StartUp Project".

And OpenSim will run from Visual Studio on 64-bit Windows...

Tuesday, March 4, 2008

OpenSim tackles high load

3Di have provided us with some new fancy features being added to OpenSim over the next few days.

Region splitting
Allows multiple physical computers to cooperate on maintaining one region. This is good for scenarios where you would want a large amount of people in the same region (think large events). OpenSim has already proven the potential of holding well over a hundred users, and this patch increases that number many times.

Dynamic load balancing
Monitors the load (often related to number of users) a region is exposed to and can realtime move the region to a computer with less load (while it's running!). More efficient use of computer resources means we save electricity. No more empty regions occupying an idle server. So this is a green patch! :)

Monday, February 25, 2008

Objectifying LSL

A few months ago we decided to make a distinction between SL's LSL2 and our own LSL implementation. This mainly because we were planning to add new features to the language. But also to make people understand that the compatibility may not be 100% - at least not for some time into the future. One thing is implementing all ll-commands. Another is to get them all right. So we decided to call our language OSSL (OpenSim Scripting Language.)

Yesterday OSSL took a new turn. In addition to LSL2's straight forward function calls and our own similar os-calls I want to provide a modular aproach.

So now OSSL has a new object "Prim" that can be used in the following ways:
Prim.Position.x += 10;
Prim.Rotation.x += 45;
Prim.Text = "This text floats on top of a prim!";

I'm planning to implement more functions. Especially looking forward to getting for example the particle-system into objectified managed code.

Later down the road people can use Visual Studio to write scripts for OpenSim. If they include some OSSL.dll they will get the benefits of managed code and writing scripts should be a breeze.

So, here is a sample script:
//c#

double x = 0;
double y = 0;

public
void default_event_state_entry()
{
llSetTimerEvent(0.1);
}

public void default_event_timer() {
x += 0.2;
y += 0.1;

Prim.Position.x = System.Math.Sin(x) * 10 + 100;
Prim.Position.y = System.Math.Cos(y) * 10 + 100;
}

Monday, February 11, 2008

New common framework

I have moved most of the code from OpenSim.Region.ScriptEngine.DotNetEngine to OpenSim.Region.ScriptEngine.Common.

Right now we have only one ScriptEngine, and its purpose is to emulate a Second Life script engine by executing scripts put into prims. But in the future I expect different kinds of script engines such as controllers that manipulate in-world game rules or objects from a .dll that has nothing to do with prim scripts.

Therefore I moved parts of DotNetEngine into Common so that Common is an execution framework.

DotNetEngine now does LSL->C# convert and compile. But does not do anything else. It simply hands the compiled .dll back to Common when its done. Then Common does the actual execution of script.

To quote http://opensimulator.org/wiki/OpenSim.Region.ScriptEngine.Common

What do I get for free?
1. Loading/unloading of scripts are queued and executed in sequence. Only one load/unload at the time.

2. What script belongs to what object is automatically taken care of. You just need to provide the scripts classes - nothing else.

3. OpenSim events are translated and given to you as LSL events. Your script functions are executed automatically, no need to hook up to events or anything.If you want to implement your own event handlers, feel free to do so. Look in "OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.EventManager.cs" how its done. Your own events can run together with LSL events without any problem.

4. Whenever an event is executed, the execution is queued. Only one event per script is ever executed simultaneous. But multithreading is used to run multiple scripts in parallel.

5. Errors during script execution is automatically handled and relayed to users in-world.

6. You get all LSL commands in an easy to use object, no need to keep track of scene or objects to execute functions. Running an LSL command from your script engine is as easy as running it from inside any LSL-script.

7. Long LSL-commands that returns with an event is also handled.

ScriptEngine with many regions per server

I have added a whole lot of detailed config options in OpenSim.ini.example that can be used to control DotNetEngine. Many of these are specific to Common, some are specific to DotNetEngine.

You can now control a lot of detailed stuff that you usually wouldn't care about. The reason why these options are there now is because 1) Common will be sharing resources across different script engines (so we can support large amounts of script engines) and 2) who knows what you will be using OpenSim for.

One of the most important new features is the capability of Common to share maintenance, load/unload and execution threads accross instances (read: regions). Today a new instance of ScriptEngine is created for each region. And with 3-4 threads per ScriptEngine ... I guess this is a severe limit to large scale use of OpenSim.

Note! The thread sharing is currently disabled due to some bugs that needs fixing.

ScriptServer

ScriptServer is "almost done". Meaning it is capable of doing everything except communicating from a script to OpenSim. For this I need to abstract the layer between llFunction() and the actual implementation. Which already is in part done.
However ScriptServer has not been a priority lately.

For those who dont know the difference: ScriptEngine is a .dll that OpenSim uses to run scripts. ScriptServer is 1) a ScriptEngine .dll, but instead of executing scripts it remotely communicated with a 2) ScriptServer that uses the same ScriptEngine .dll's as OpenSim to execute scripts.
The advantage of this is that the script execution can happen on a remote machine (or same machine if you want) outside of OpenSim.exe.

Sunday, October 14, 2007

Script engine implementation

I just wrote this contribution to AWG: http://wiki.secondlife.com/wiki/Tedds_stand-alone_script_engine

It explains how and why on my opinions on the future script engine implementation.

Monday, October 1, 2007

A peek on new architecture



This is where my planning is at now.
It was very complex, and after redrawing it a few times I neded up at this.
Still not 100%, but getting there...

Thursday, September 27, 2007

Major rewrite number 2

I have been doing some thinking on the ScriptEngine. Actually a whole lot of thinking, and planning. Lots of alien squid-like drawings in my notebook.

Trying to run through the process: Idea, required elements, architecture and finally simplification.

The idea is simply: Moving ScriptEngine to a separate daemon, independent from the region.
This has several big advantages and of course some drawbacks.
  • Script does not need to be moved between regions when object it is inside does.
  • Scripts can run on separate servers and even clusters of servers, offloading the main region server.
  • Script source (and binary) can be secured by running it from a trusted server. Even makes it possible with script rental. You can run your own ScriptEngine.
  • We can add the option to move script between regions as usual to avoid network lag on time-critical scripts.
  • It is easier to write alternative ScriptEngines, developers are not restricted to .Net.
  • ScriptEngines can be more complex and allow bigger and more complex scripts than the region would by default.
  • Regions can be more secure as they do not have to execute scripts locally.

Disadvantage:

  • Each region may have to speak to many different scriptengines.
  • Network latency will affect script performance.
  • Script reliability is much lower.
  • Various problems related to authentication.

Of course all the work done with implementing LSL commands so far will survive. That is independent of this rewrite.

I'll be back with more as it unfolds.

Friday, September 14, 2007

Pure C# support

ScriptEngine supports both LSL and C# within the same script. Mainly this means that you can write LSL, but when you want you can use C# code. For example instead of using llToLower(mystring) you can use mystring.ToLower(), instead of llStringLength(mystring) you can use mystring.Length().

But to make sure that we support pure C# code, I've added support for forcing the compiler to not use LSL preprocessor. This means skipping directly to compile without going through LSL to C# converter.

Any script that starts with the 4 letters "//C#" or //c#" will be compiled as C# directly. This ensures that we have 100% C# support.

There are a few rules you need to follow. Mainly:

  • Any LSL event needs to be renamed to <STATE>_event_<EVENTNAME>.
    For example "start_entry()" in default state will be "public void default_event_state_entry()"
  • LSL events needs to be public, of course.
  • Script needs to start with "//C#" without the quotes and without space in front of it. These 4 characters needs to be the first thing inside the script!
  • You still have to use ll-commands for stuff that native C# doesn't support. But don't worry - the ll-commands are just the name, you are actually writing in C#. ;)

If you put a LSL script into an object in OpenSim, the C# code of that script will be debug-logged to the "bin\ScriptEngine\"-folder. So if you have any trouble, just write up a LSL code, put it into an object and you have a working C# script that does the same thing.

Untested example:

//C#

namespace SecondLife
{

   public class Script : OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass
   {

      public Script() { }

      // Your script goes here!
      int touch_count = 0;
      int tick_count = 0;
      int objnum = 1;

      public void default_event_state_entry()
      {
         llSay(0,
"Hello, Avatar! Starting timer...");
         llSetTimerEvent(10);
      }

      public void default_event_touch_start(int total_number)
      {
         touch_count++;
         llSay(0,
"Object was touched. Touch count: " + touch_count);
      }

      public void default_event_timer()
      {
         tick_count++;
         llSay(0,
"Timer count: " + tick_count);
      }
   }
}

Sunday, August 26, 2007

Small stresstest

114 scripts loaded. 1 script per AppDomain. Most scripts are alone inside a prim, except the big box over there that has something like 10 scripts in it (it is bigger so I could fit more scripts into it).







My computer is a 2,8GHz Prescott with 2GB RAM and Windows Vista Ultimate.
60 of the scripts run the timer event every 1 second. 50 run it every 5 seconds.



Basically this tells us that ScriptEngine uses a bit too much memory. This is expected. CPU usage while running 114 events every x seconds is almost nothing.


Increase from 38MB to 76MB RAM when creating objects and scripts, so ~10MB for 25 scripts+objects.


The scripts don't do much work right now, but if they did the speed would still be high as they are compiled to CPU native code.



Results after running for 9 hours

OpenSim did not crash or eat any more CPU or memory over time. However the Second Life viewer did crash, so I had to log in again... Funny ;)

Saturday, August 25, 2007

So where are we now?

[Updated Monday 13:45 GMT+1]
[Updated Wednesday 21:45 GMT+1]
[Updated Saturday 22:45 GMT+1]

As always its important with a summary for those who don't want to read techie details.

Here is current status of LSL script support:
+ We have LSL script support.
+ We can run hundreds of scripts simlutaneously, probably not thousands (needs testing). We have confirmed 50 simultaneous scripts without any sign of trouble.
+ We can utilize multicore CPU's for running scripts.
+ We can to some degree unload scripts to free up memory. (if we use 1 AppDomain per script)
+ Events from server are put into a queue, so server threads are released imediately.
+ Some llFunctions are implemented.
+ ScriptEngine is more or less ready to bind individual scripts to individual prims.
+ We have implemented touch_start event when someone touches a prim.
+ We have implemented llSetTimerEvent.
+ Script compile errors are displayed in-world.
+ We can put scripts into prims.

- Can not run too many scripts that contain infinite loops or sleeps to long.
- No memory/CPU sharing/limitation/throttling on scripts.
- Almost no security implemented on scripts.
- Can not move script between regions.
- Missing 300+ llFunctions.
- Missing most events.





There is room for making scripts run 2-5 times faster, if not more. And same in memory usage. This is because of the development process.
"Get it working, remove bugs, make it fast."


There is much data related to each script. I suspect if we load too many scripts the working set (WSClock) will be too high. Meaning there is too much data to process, so the CPU and memory will be more occupied with looking at what to do than actually doing it.

Introduction of a new class

Some LL-commands takes longer to return. These often return with a event. For example llSetTimerEvent(10) will return a timer() event every 10 seconds. llHttpRequest() will return when it receives answer from HTTP-server.

To handle these types of requests a new class has been added as a subclass of ScriptEngine. The class is named LSLLongCmdHandler.cs. This class will contain handlers for adding/removing requests. Adding when script executes a command, removing when command is not complete yet but script is being moved to another region or otherwise removed.

The class has a dedicated thread that will be working the different services, for example async HTTP requests and queueing of timer events at the correct intervals.
LSL_BuiltIn_Commands.cs accesses this class through ScriptEngine.


Example from LSL_BuiltIn_Commands.cs:

public void llSetTimerEvent(double sec)
{
// Setting timer repeat
m_ScriptEngine.myLSLLongCmdHandler.SetTimerEvent(m_localID, m_itemID, sec);
}

Sunday, August 19, 2007

Speed

I've added support for multithreading execution of script events. Only one object will be processed at the time. This will benefit from MultiCore CPU's. Though it makes each call more expensive because we have to keep track of mutexed objects.

Also added caching of event binding (function call) so we only use Reflection on first execution of a given event within a given state.

Changed sleep time of inactive threads from 200ms to 50ms, so they are more responsive.

AppDomains

.Net does not allow unloading of assemblies. If you want to unload an assembly you have to unload the whole AppDomain.

I've created AppDomainManager that handles creating AppDomain, finding a free AppDomain, loading scripts into it, and unloading AppDomains with no active scripts in them.

Its purpose is to create AppDomains and put X number of scripts into each of them. Later when we get microthreading support we will add a feature to move scripts between AppDomains, so if one or more AppDomains has only a few active scripts we can move these to a fresh AppDomain and unload the old one.

With the introduction of AppDomain there came a few changes to the source. Because of how communication between AppDomains (mainly between scripts AppDomain and the main AppDomain) works there has been made some changes.

First of all a new assembly called OpenSim.Region.ScriptEngine.Common.dll has been introduced. It contains interface for scripts and some common code for all AppDomains to execute events inside scripts.

Secondly the LSL BuiltIns (llFunctions) has been moved to a separate file (LSL_BuiltIn_Commands.cs) and are no longer part of the LSL_BaseClass.cs.

Also OpenSim.Region.ScriptEngine.Common.LSL_Types that contains custom Vector and Rotation objects is now used throughout DotNetEngine/Compiler.

Each AppDomain has only 2 references, OpenSim.Region.ScriptEngine.Common.dll and OpenSim.Region.ScriptEngine.DotNetEngine.dll.

Friday, August 17, 2007

llSay implemented

Picture of llSay() implemented.


Tuesday, August 14, 2007

llFunction interface/empty prototypes

Charles Krinkle has helped in adding interface and necessary empty prototype implementations of base class for the compiled script.

Almost all functions has been implemented (they contain no code yet though). This helps me test the compiler on all kinds of scripts without getting errors.

Thanks dude! :)

New status after Monday (and a milestone)

ScriptEngine has now been implemented!

We have a default script that is placed in all objects. We have a "touch_start" event. And we have llSay() with output to server console.

Once inventory is working we can bind user made scripts to user made objects. So now we can start implementing all 350+ builtin ll-functions.

We will be able to test the functions in-world as they are being implemented. Just modify the script "Default.lsl" under "bin\ScriptEngines\" folder to use the new command you are implementing.

There may still be problems compiling some scripts. Please let me know about these problems so I can fix them!
Next step for me is to implement error handling around ScriptEngine.