OpenSim Tech Basics : My God, it's full of modules! May 8, 2008Posted by justincc in opensim, opensim-dev, opensim-tech-basics, secondlife.
Hello folks. Today I thought that I’d write about the modular nature of OpenSim. Modularity is of great importance to OpenSim since its goal is not explicitly to provide a complete Second Life service implementation. While the current Second Life protocol does provide a handy trellis up which OpenSim can grow (a little bit like POSIX did for Linux – though in this case the existing “standard” is both evolving and not very well documented), the guiding philosophy is to make OpenSim a platform for 3D environments in general, as stated on our front page. We hope that OpenSim will ultimately be useable as a base for many systems, covering the range from standalone 3D applications (such as data centre monitoring) to different types of virtual world grids. By changing or extending the OpenSim kernel using various modules and plugins, different metaverse systems and programs will hopefully be able to use the same base platform for different viewers, protocols and region features.
Thus, modularity is a crucial part of the OpenSim system. By a “module”, I mean a class or a set of classes (within a .NET dll) which can easily be integrated with OpenSim in order to either provide different types of core functionality, or provide extensions to the existing codebase. If one doesn’t count alternative grid service implementations, all the modules which I know to currently exist come bundled with OpenSim (such as the experimental SVN module which allows you to periodically backup your region to a subversion control system, and the dynamic texture module which uses .NET libraries to create a texture on the fly using draw commands). However, over time the real power of the system will come in allowing other people or organizations to write their own module code to make OpenSim do pretty much anything they want.
Since this is a tech article, I want to go on a brief tour of the modular system as it exists today. I’m going to cover three of the major types of module in OpenSim – database plugins, application plugins and region modules. We’ll take a look at each of these in turn.
OpenSim Database Plugins
These are the plugins which provide an interface between OpenSim and the database system that it’s using to store data. In an OpenSim distribution, these are found in the OpenSim.Data.* namespaces (such as OpenSim.Data.MySQL and OpenSim.Data.SQLite). Each of these namespaces is populated with classes which implement the storage interfaces for the various OpenSim services. So, for instance, OpenSim.Data.SQLite.SQLiteInventoryStore is a class which implements IInventoryData, translating calls to methods such as IInventoryData.GetInventoryFolders() to the necessary SQLite SQL commands required to retrieve the folder data).
This means that anybody can come along and implement the necessary interfaces to make OpenSim use another database. This was done with MSSQL, which also sits in our build tree. However, the problem that we currently have is that a database module writer ends up implementing lots of custom code in order to talk to the backend system – it’s much easier currently to copy, paste and adapt than it is to extract common module code. Getting the code right for the foibles of each individual database is difficult, and means that unless someone is actively maintaining a plugin, it easily falls into disrepair (as has in fact happened for some of the MSSQL plugins).
Luckily, there are various ways to tackle this. Core committer Neas Bade (sdague) is currently working on the production of a set of NHibernate plugins, following preliminary work by developers such as Impalah. NHibernate can handle all the necessary work in persisting our objects to the database. Moreover, it means that in the future, OpenSim should be able to use all the databases which NHibernate supports, which is much larger than the set we could ever hope to reliably maintain. So much of what I’ve just told you should one day become obsolete, unless you want to use a database which NHibernate doesn’t support :-)
OpenSim Application Plugins
These are plugins which act over the whole OpenSim server rather than just for a single region. Application plugins implement the IApplicationPlugin interface which provides just two methods – Initialise(), which passes in a reference to OpenSimMain by which the application plugin can get the information it needs, and Close(). Application plugins are found and instantiated using the Mono.Addins system (which also works under Microsoft’s .NET implementation).
There are a couple of examples of application plugins in the OpenSim build tree. One of these is the Remote Admin plugin, which allows certain OpenSim functions (such as shutdown and region creation) to be controlled by XML RPC calls rather than from the console.
OpenSim Region Modules
These are modules which operate at the region level (hence the name!). As mentioned earlier, these cover both fairly core functionality (such as the Chat module which is needed to allow anybody to say anything!) and extension functionality (such as the SVN backup and dynamic texture modules). The modules are currently a little scattered about the OpenSim tree (though there is now the beginnings of a categorization in OpenSim.Region.Environment.Modules), but they all implement the IRegionModule interface – a simple interface whose most important function is to pass in scene data when the module is initialized.
Apart from this initialization, region modules generally get and send information in one of two ways – either by registering for scene events (which is often done by modules that extend existing functionality and don’t need to pass back any data), or by registering a module using an explicit interface which the core code can later call. An example of the latter is the Permissions module, which registers itself with an IScenePermissions interface. This interfaces contains methods such as CanRezObject() that the scene can invoke when it wants to know whether object rezzing is permitted for a given entity.
You can find others examples of region modules by looking through the OpenSim code tree. There is also some documentation on the OpenSim wiki, though this does need to be updated.
We’ve covered three of the major types of OpenSim modular functionality. In addition, though, there are also other types of modularity (such as the ability to substitute alternative scripting engines) that I haven’t gone through here.
At the moment, the module system in OpenSim is pretty immature. For instance, it’s questionable as to why we’re using different systems for application plugins and region modules. There’s also currently no proper way of turning modules on and off, something which needs to be addressed. But even so, if anyone does get interested in changing or extending a part of OpenSim that can’t be done in the current module system, please do let us know. I am, as I’m sure are other core developers, very interested in providing the interfaces and architecture needed to accomodate further modularity.
Oh, and if you do write any modules, please feel free to list them on our related software page!