IRegionModule

Introduction
Region modules are .net/mono DLLs. During initialization of the simulator, the OpenSim bin directory (bin/) and the scriptengines (bin/ScriptEngines) directory are scanned for DLLs, in an attempt to load region modules stored there.

Region modules execute within the heart of the simulator and have access to all its facilties. Typically, region modules register for a number of events, e.g. chat messages, user logins, texture transfers, and take what ever steps are appropriate for the purposes of the module.

There are two types of region module.


 * Non-shared modules where a separate module is created for each region/scene
 * Shared region modules, where a single module is shared between all regions/scenes running on the same simulator.

Region Modules require a few basic things:
 * The Base Interface
 * Some callbacks for OpenSim events

This page now addresses the new region module mechanism, which has been in place since at least 0.6.9. But for an older version of this page that references the older IRegionModule mechanisms, please see http://opensimulator.org/index.php?title=IRegionModule&oldid=13166

Example
Let's start off with the most basic region module possible. Below is a region module that does nothing more than log the events that it receives. Technically, it could be made a little simple by printing messages directly to the console rather than OpenSim's logging infrastructure but it's better to have it nicely integrated.

You can also find this example in OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs in OpenSim's source distribution from 0.7.1 onwards (not yet released). There's also a bare bones shared module example there.

In the source tree, the [Extension... attribute line is commented. You can uncomment this, rebuild OpenSim and start it to see the module in action.

The Base Interfaces
Now let's discussion the components of the example above. Region modules must implement INonSharedRegionModule or ISharedRegionModule as appropriate - the example above implements INonSharedRegionModule. However, both these interfaces extend IRegionBase, defined as follows.

INonSharedRegionModule itself contains no methods, being defined simply as

ISharedRegionModule has one additional method.

Enabling the module
Creating the module code itself isn't quite enough to enable it. To do that, we need to make it visible to OpenSim's module mechanism (which is currently Mono.Addins).

This is done by adding an Extension attribute to the class, for example.

The important part here is the "Path" section - this is how OpenSim retrieves modules from Mono.Addins. The Id can be anything meaningful to the module.

Integrating with OpenSim
NOTE: This section is now very out of date - NEEDS WORK!

Accessible Objects
Note: these are internal interfaces, and will change in the future, probably for the better. We expect these to stabilize over time, but for now this point in time snapshot is probably helpful.

In the AddRegion routine you get access to the scene object for the region, from here you can spider down into the scene and get access to many other objects of interest.


 * scene.GetEntities - returns a list of all the Entities in the environment. This will be a combined list of SceneObjectGroups (prim sets) and ScenePresences (avatars).
 * scene.GetAvatars - get only the avatars in the scene (very handy for sending messages to clients)
 * scene.EventManager - this is the object from which you can register callbacks for scene events. Some examples provided in a little bit
 * scene.RegionInfo - properties about the region

Registering for Events
Taking the SunModule as an example we can see the following code:

In Initialise: Pretty simple, we just got the EventManager and registered the SunUpdate method as a callback for the OnFrame event. OnFrame is triggered every time there is a render frame in opensim, which is about 20 times per second. If you are firing on the OnFrame event you need to do something small, or punt most of the time, as you'll negatively impact the performance of the system otherwise.

Now, for that function...

SunUpdate takes no parameter (some events may require them). It only fires every 1000th frame by default (m_frame_mod = 1000 in this module), so it doesn't take too many cycles.

In order for the sun position to change for the clients, they need to be told that it changes. This is done by getting a list of all the Avatars from the scene, then sending the Sun Position to each of them in turn. It is important to check to see if the avatar is a ChildAgent, otherwise you will generate zombies in opensim world.

Where to go from here

 * Getting Started with Region Modules -- the Hello World of OpenSim application development. Rather old by now but still worth a look.
 * http://bluewallvirtual.com/node/14 - More shared region module example code by Bluewall.
 * Development discussion of the current region module mechanism
 * Read the source for existing opensim core modules. These are in the OpenSim.Region.CoreModules and OpenSim.Region.OptionalModules projects.  Looking through this code is an extremely good way to find out what region modules can do and how they can do it.
 * Read the source code for the EventManager class in the OpenSim.Region.Framework.Scenes project. These list the many events that exist.  Some modules may also export their own events (e.g. OnInventoryArchiveSaved in the InventoryArchiverModule at OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/).
 * Help write some examples here. OpenSim grows with your contributions.