Extensible & Maintainable Opensimulator Config

Opensimulator Logo - Extensible & Maintainable Opensimulator Config
Opensimulator Logo

Extensible & Maintainable Opensimulator Config is a guide to creating an Opensimulator configuration that is both extensible and maintainable. Unfortunately, the default setup isn’t well configured for this.

Anyone who prefers a video to reading should scroll to the bottom.

Full Guide

Problems With The default Configuration and File Structure for Extensible & Maintainable Opensimulator Config

Upgrading the Opensimulator Version

Opensimulator delivery is a single compressed tar or zip file(Duarte 4/2/20202). Therefore, copying files from multiple folders is necessary using the default structure. Then replace the bin folder entirely and finally copy the original files’ contents back into the new versions.

Moving all the INI configuration files outside the bin folder fixes the upgrade issues. Fortunately, both Robust and Opensimulator have command-line arguments for specifying the location of their INI files(Duarte 22/6/21). 

Opensimulator developers expect users to modify some of the INI files but not all. Unfortunately, moving files inside the “config-include” folder outside the “bin” folder requires editing both types of INI files.

Creating Backups

Opensimulators default configuration and file structure do not lend themselves well to backing up a minimal amount of data. Similarly to the upgrade issue, having configuration files inside the “bin” folder causes problems. Additionally, the asset cache gets generated in a subfolder of “bin”.  Fortunately, it is possible to move the location of the asset cache elsewhere. Similarly, the bakes Robust uses should not form part of a backup and need moving. Differently, script states do need backing up. Some of the inworld items which only store data in the script state will break if these are not present. Most notable among these are breedable systems and scripted rez systems.

Logging Issues

Some operators may wish to backup logs while others may not. However likely, most will not want to lose logs during an upgrade. Log locations change with a combination of INI files and startup params(Duarte 22/6/21, Configuring Opensimulator).

Script State

Script state files store variables that inworld scripts use. Most of the time, these are similar to cache. However, unlike proper cache, some items require script state files to be present to continue working after a region restart. The same is true if restoring things that are made this way from a backup. The popular method of backing up regions in Opensimulator is OAR files. Unfortunately, OAR files do not keep the script state. Consequently, to move a land area from one server to another requires a combination of Database data, script state files and configuration files. Additionally, this means each region needs a separate folder for its script state files.

Multiple instances of Robust and Opensimulator

Seperating Robust Services Into Multiple Instances

Using multiple instances of Robust is only necessary for load balancing. However, expanding a grid pre-configured with multiple robust models is considerably easier than separating them later.  Creating a separate instance at the point load balancing is necessary for the assets will likely require moving tables with millions of rows from one database to another.

Simulator Instances (OpenSim.exe)

Opensimulator supports a maximum of 16 regions in a single instance. Unfortunately, this is not enough for anything other than the smallest of Grids.  Additionally, when a simulator has multiple regions, its thread pool is shared among all the regions on that Simulator. Consequently, performance on modern multi-core servers substantially improves when each Simulator has a single region. It is frequently more cost-effective to run fewer, more powerful servers than many less powerful systems. Consequently, a configuration capable of supporting multiple instances on the same machine is desirable.

Further considerations – Extensible & Maintainable Opensimulator Config

Databases

Robust

Using multiple instances of Robust is complicated, especially if the database is also separate. Furthermore, grids that use Hyper-Grid have fewer options than closed environments since most public Opensimulator grids enable Hypergrid; the app’s configuration focuses on this. However, it is still possible and desirable to separate the asset database. Consequently, it is desirable to have a design that will use two databases, even on a single server.

Simuators

It is possible to use a single database for all regions on a  server regardless of how many instances of Opensimulator run them. However, it then becomes considerably more complicated to move a region from one server to another. If the items on the region use the Script state, it becomes almost impossible to do.  Consequently, it is desirable to have a single database for a single simulator that in turn runs a single region.  Using this approach also helps to avoid excessive database growth when moving regions between servers. 

Standalone vs Grid Mode

Unless there is a certainty that the grid will never grow beyond the capacity of a single simulator, there is little benefit to using a “stand-alone” configuration.   A stand along format uses fewer ports and processes. However, the memory requirements and overall processing power are similar to those of Grid configuration. In addition, many new Opensimulator grids start with small budges and no existing user base.  Running multiple servers adds unnecessary cost and complication. Having a single server configuration that uses Robust gives the flexibility to extend to numerous servers later.

Restarting A Single Region

A long-standing problem in the  Opensimulator code means restarting a region requires being restarted. If a simulator has multiple regions and a single region requires a restart, either all must reset, or the one with an issue must wait. Consequently, this adds further weight to the necessity of having a single region per Simulator. In addition, a simulator needs to shut down rather than terminate.

Region Loading

During startup, Opensimulator will load all INI files inside the folder specified for regions. While this is helpful for multiple regions on a single simulator, it is a problem when running numerous simulator instances. Therefore each instance needs a separate folder for the region configuration files, even if it only contains one INI file.

Multiplexers

Most commercial Linux servers use a command-line interface.  Subsequently, to run multiple processes simultaneously, they must either run as a service or inside a multiplexer. Multiplexers allow CLI control of the running process, whereas simply running them as a service does not. However, it is also desirable to have Opensimulator services startup when a server comes online.   Therefore, the best option is to create a service that loads each Robust and Simulator instance into a multiplexer.

Additionally, multiplexers allow instructions to pass from the console or scripts into the multiplexer window. Ergo it is possible to achieve this programmatically using BASH scripts started by SystemD.  Finally, the length of time a shutdown takes frequently exceeds the maximum time allowed during a system shutdown event. Therefore, multiplexing is necessary to avoid data loss and maintain console control of Opensimulator while running.

Avoiding File Duplication

To run multiple Opensimulator instances and the default file structure, keeping numerous copies of the bin folder is necessary.  Additionally, Opensimulators “bin” folder substantially increases in size after running. Consequently, it is desirable to maintain a single copy rather than multiple.

Setting Duplication, Set once where possible

While changing some settings on a per instances basis is necessary, many of them can share settings.  For example, every instance of Robust And Opensimulator will have the same login URL and gatekeeper address. Additionally, most of the Robust instances are likely to share the same domain name. However, each Robust model will have a separate port.  Similar patterns exist in the simulators configurations.

Manipulating the INI files.

Firstly, Opensimulators INI files allow the inclusion of settings from other INI files. Secondly, it applies a hierarchy. Additionally, it is possible to create variables known as Consts directly in the INI files.   However, it is impossible to use those variables as part of the path to an included INI file.  Despite this, the combination of include statements and constant declaration allows an almost programable configuration without any third-party software.

File And Folder Stucture Changes – Extensible & Maintainable Opensimulator Config

Original Structure

├── bin
│   ├── addon-modules
│   ├── assets
│   ├── config-include
│   │   ├── FlotsamCache.ini
│   │   ├── GridCommon.ini
│   │   ├── GridHypergrid.ini
│   │   ├── Grid.ini
│   │   ├── osslDefaultEnable.ini
│   │   ├── osslEnable.ini
│   │   ├── StandaloneCommon.ini
│   │   ├── StandaloneHypergrid.ini
│   │   ├── Standalone.ini
│   │   └── storage
│   │       └── SQLiteStandalone.ini
│   ├── data
│   ├── Estates
│   ├── inventory
│   ├── lib
│   ├── lib32
│   ├── lib64
│   ├── Library
│   ├── openmetaverse_data
│   ├── OpenSim.ini
│   ├── opensim.sh
│   ├── Regions
│   │   └── Regions.ini
│   ├── Robust32.exe.config
│   ├── Robust32.vshost.exe.config
│   ├── Robust.exe
│   ├── Robust.exe.config
│   ├── Robust.HG.ini
│   └── Robust.ini
└── ThirdPartyLicenses

New Structure – Extensible & Maintainable Opensimulator Config

├── OpenSim
│   ├── Bin
│   │   ├── addin-db-002
│   │   ├── addon-modules
│   │   ├── assets
│   │   ├── config-include
│   │   ├── data
│   │   ├── Estates
│   │   ├── inventory
│   │   ├── j2kDecodeCache
│   │   ├── lib
│   │   ├── lib32
│   │   ├── lib64
│   │   ├── Library
│   │   └── openmetaverse_data
│   ├── Data
│   │   ├── addins-registry
│   │   ├── fsassets
│   │   │   ├── data
│   │   │   ├── Main
│   │   │   └── tmp
│   │   ├── MapTiles
│   │   │   └── 00000000-0000-0000-0000-000000000000
│   │   ├── MySql
│   │   ├── Oars
│   │   ├── ScriptState
│   │   │   ├── Simulator00
│   │   │   └── Simulator01
│   │   └── www
│   ├── Logs
│   ├── Scripts
│   └── Settings
│       ├── OpenSimConstants.ini
│       ├── OpenSimLogs.config
│       ├── Robust
│       │   ├── RobustDefaults.HG.ini
│       │   ├── Robust.HG.Asset.ini
│       │   ├── Robust.HG.GridUser.ini
│       │   ├── Robust.HG.Main.ini
│       │   └── Robust.HG.Map.ini
│       └── Simulators
│           ├── FlotsamCache.ini
│           ├── GridCommon.ini
│           ├── GridHyperGrid.ini
│           ├── OpenSimLogs.config
│           ├── osslEnable.ini
│           ├── Simulator00
│           │   ├── Regions
│           │   │   └── Regions.ini
│           │   └── Simulator.ini
│           └── SimulatorDefaults.ini
├── OpenSimCache
│   ├── assetcache
│   ├── bakes
│   └── DataSnapShot
│       ├── Simulator00
│       └── Simulator01

While it is unnecessary to back up the “Bin” folder, it allows quick and straightforward restores in a full server restore.

Inside the OpenSim folder, there is Bin, Data, Logs, Scripts and Settings. The Data folder and subfolders contain items likely to be wanted in a full restore. Next, there are folders for Script state, which once automatically populated, contain subfolders for each Simulator. Finally, the settings folder has subfolders for Robust and Simulators, then subfolders for defaults and each instance.

Prepwork – Creating the databases

Before getting into the details of the configuration it’s necessary to create the databases. This was left out of the previous guide on setting up the server because it depends on the configuration. Usually, Robust services and Simulator services will be on different servers but they do not need to be. Additionally, the number of Simulators per server will vary depending on the specification of the server. By this point, I am assuming you know how to get into the settings for your chosen database. Create two databases for Robust, granting permissions to the user for the robust databases. Then create one database per simulator. In this example, the same machine is used for both Robust and Simulator services. Finally, two Simulators are in use.

Example Using Mysql: remember to change the names ‘robustadmin’ and ‘simulatoradmin’ to the user names set for them previously.

sudo mysql
CREATE DATABASE RobustMain;
CREATE DATABASE RobustAsset;
GRANT ALL PRIVILEGES ON RobustMain.* TO 'robustadmin'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON RobustAsset.* TO 'robustadmin'@'localhost' WITH GRANT OPTION;
CREATE DATABASE Simulator00;
CREATE DATABASE Simulator01;
GRANT ALL PRIVILEGES ON Simulator00.* TO 'simulatoradmin'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON Simulator01.* TO 'simulatoradmin'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit

Creating The New Configuration – Extensible & Maintainable Opensimulator Config

Combining Startup Parms With INI file configuration

Both Robust and Opensim have launch params that specify the location of the INI file console and logging configuration file.  Additionally, it is possible to pass configuration parameters into the log config from this point.

-inifile=
-logconfig=
-console=local

Setting the first INI files for Simulator Instances

First Opensim.ini File

When an instance starts, the configuration files to read are specified. Then, any settings specific to that instance get set and includes additional locations from other files. In addition, all paths use local path statements. Consequently, it is easy to set and change programmatically without breaking the rest of the configuration.

E.g. For a simulator00 in the structure above, the INI file is located at

~/OpenSim/Settings/Simulators/Simulator00

It contains the following

[Const]
    Include-Const = "../Settings/Simulators/Defaults/OpenSim.ini"
    SimulatorNumber = "00"

[Startup]
    meshing = ubODEMeshmerizer
    physics = ubODE
    DefaultScriptEngine = "YEngine"

[Permissions]
    region_manager_is_god = false
    region_owner_is_god = false

[Network]
    http_listener_port = 9000
    
[RemoteAdmin]
    port = 10000
    access_password = "**RemoteAdminPassword**"
    
[Economy]
    ;economymodule = Gloebit

[Chat]
    ;whisper_distance = 50
    ;say_distance = 100
    ;shout_distance = 400

[XEngine]
    Enabled = false
     
[YEngine]
    Enabled = true

At the top of the file in the Const section

[Const]
    Include-Const = "../Settings/Simulators/Defaults/OpenSim.ini"
    SimulatorNumber = "00"

The first line includes different settings from another file called Opensim.ini located in the default settings folder.

~/Opensim/Settings/Simulators/Defaults/OpenSim.ini

The second line sets the Simulator number used in the settings included from the other Opensim.ini file (explained in detail later).

The rest of the settings are likely to change on a per simulator basis. However, pay close attention to

[Network]
    http_listener_port = 9000
    
[RemoteAdmin]
    port = 10000
    access_password = "**RemoteAdminPassword**"

In these sections, the port numbers must be different for each Simulator. It is also helpful to set regular intervals for port numbers. For example

  • Simulator00 Netorkwork Port: 9000
  • Simulator00 Remote Admin Port :10000
  • Simulator00 Netorkwork Port: 9010
  • Simulator00 Remote Admin Port :10010
  • Simulator00 Netorkwork Port: 9020
  • Simulator00 Remote Admin Port :10020

Setting up port numbers in this way allows scripts to automatically generate the values quickly. Readers that plan to use the example scripts found later in this guide should stick to precisely this configuration. Additionally, changing the remote admin password for each Simulator increases security.

Setting up the INI file in the Defaults Folder

File located at

~/OpenSim/Settings/Simulators/Defaults

Containing

[Const]
    Include-OpenSimConstants = "../Settings/OpenSimConstants.ini"
    LslExternal = "**ReverseDnsOfRegionServer**"
    DatabaseUserName = "**SimulatorDatabaseUserName**"
    DatabaseUserPassword = "**SimulatorDatabaseUserNamePassword**"
    DatabaseNamePrefix = "**Simulator**"
    Simulator = "${Const|DatabaseNamePrefix}${Const|SimulatorNumber}"

[Startup]
    ConsoleHistoryFileEnabled = true
    ConsoleHistoryFileLines = 500
    save_crashes = true
    crash_dir = "crashes"
    allow_regionless = true
    MaxPrimUndos = 20
    NonPhysicalPrimMin = 0.001
    NonPhysicalPrimMax = 4096
    PhysicalPrimMin = 0.01
    PhysicalPrimMax = 64
    AllowScriptCrossing = true
    TrustBinaries = false
    CombineContiguousRegions = false
    InworldRestartShutsDown = true
    MinimumTimeBeforePersistenceConsidered = 60
    MaximumTimeBeforePersistenceConsidered = 600
    physical_prim = true
    emailmodule = DefaultEmailModule
    SpawnPointRouting = closest
    TelehubAllowLandmark = false
    
[Terrain]
    SendTerrainUpdatesByViewDistance = true

[Map]
    MapImageModule = "MapImageModule"
    MaptileRefresh = 604800
    TextureOnMapTile = true
    DrawPrimOnMapTile = true
    TexturePrims = true
    TexturePrimSize = 48
    RenderMeshes = true;
    
[SMTP]
    enabled = false
    internal_object_host = lsl.opensim.local
    host_domain_header_from = ""
    email_pause_time = 5
    email_max_size = 4096
    SMTP_SERVER_HOSTNAME = ""
    SMTP_SERVER_PORT = 
    SMTP_SERVER_LOGIN = ""
    SMTP_SERVER_PASSWORD = ""

[Network]
    ExternalHostNameForLSL = ${Const|LslExternal}
    shard = "OpenSim"
    
[ClientStack.LindenUDP]
    
[ClientStack.LindenCaps]
    Cap_GetTexture = "localhost"
    Cap_GetMesh = "localhost"
    Cap_AvatarPickerSearch = "localhost"
    Cap_GetDisplayNames = "localhost"
    
[Messaging]
    OfflineMessageModule = "Offline Message Module V2"
    OfflineMessageURL = ${Const|BaseURL}:${Const|PrivatePort}
    StorageProvider = OpenSim.Data.MySQL.dll
    ForwardOfflineGroupMessages = true

[BulletSim]
    AvatarToAvatarCollisionsByDefault = true
    UseSeparatePhysicsThread = true
    TerrainImplementation = 0

[ODEPhysicsSettings]
    mesh_sculpted_prim = true
    use_NINJA_physics_joints = true

[RemoteAdmin]
    enabled = true
    access_ip_addresses = 127.0.0.1
    create_region_enable_voice = true
    create_region_public = true
    enabled_methods = all  

[Wind]
    enabled = true
    wind_update_rate = 150
    wind_plugin = ConfigurableWind
    avg_strength = 20.0
    avg_direction = 1.0
    var_strength = 5.0
    var_direction = 30.0
    rate_change = 1.0
    strength = 1.0

[LightShare]
    enable_windlight = true

[Materials]
     enable_materials = true
     MaxMaterialsPerTransaction = 100

[DataSnapshot]
    index_sims = true
    data_exposure = minimum
    gridname = "${Const|GridShortName}"
    default_snapshot_period = 1200

[Economy]
    SellEnabled = true
    PriceUpload = 0
    PriceGroupCreate = 0
    
[YEngine]
    ScriptStackSize = 512
    ScriptHeapSize = 512
    UseSourceHashCode = true
    MinTimerInterval = 0.01

[XEngine]
    MinThreads = 2
    MaxThreads = 100
    IdleTimeout = 300
    Priority = "BelowNormal"
    MaxScriptEventQueue = 100
    ThreadStackSize = 262144
	MinTimerInterval = 0.01
    DefaultCompileLanguage = "lsl"
    AllowedCompilers = "lsl,cs,vb"
    EventLimit = 300
    ScriptDelayFactor = 1.0
    ScriptDistanceLimitFactor = 1.0
    NotecardLineReadCharsMax = 255
    SensorMaxRange = 99
    SensorMaxResults = 200
    DisableUndergroundMovement = false

[OSSL]
    Include-osslEnable = "../Settings/Simulators/Defaults/osslEnable.ini"  
    
[Groups]
    Enabled = true
    LevelGroupCreate = 0
    Module = "Groups Module V2"
    StorageProvider = OpenSim.Data.MySQL.dll
    ServicesConnectorModule = "Groups HG Service Connector"
    LocalService = remote
    GroupsServerURI = "${Const|BaseURL}:${Const|PrivatePort}"
    MessagingEnabled = true
    MessagingModule = "Groups Messaging Module V2"
    NoticesEnabled = true
    MessageOnlineUsersOnly = true

[InterestManagement]
    UpdatePrioritizationScheme = BestAvatarResponsiveness


[MediaOnAPrim]
    Enabled = true;

[NPC]
    Enabled = true

[Terrain]
    InitialTerrain = "pinhead-island"

[UserProfiles]
    ProfileServiceURL = "${Const|BaseURL}:${Const|PublicPort}"

[XBakes]
    URL =  "${Const|BaseURL}:${Const|PrivatePort}"

[AutoBackupModule]
AutoBackupModuleEnabled = true
AutoBackup = true
AutoBackupInterval = 7200
AutoBackupBusyCheck = true
AutoBackupThreshold = 5
AutoBackupSkipAssets = true
AutoBackupKeepFilesForDays = 14
AutoBackupNaming = Time
AutoBackupDir = "../Data/Oars"

[Architecture]
    Include-Architecture = "../Settings/Simulators/Defaults/GridHypergrid.ini"

Again it is necessary to focus on the first section in the INI file

[Const]
    Include-OpenSimConstants = "../Settings/OpenSimConstants.ini"
    LslExternal = "**ReverseDnsOfRegionServer**"
    DatabaseUserName = "**SimulatorDatabaseUserName**"
    DatabaseUserPassword = "**SimulatorDatabaseUserNamePassword**"
    DatabaseNamePrefix = "**Simulator**"
    Simulator = "${Const|DatabaseNamePrefix}${Const|SimulatorNumber}"

Similarly to the previous file, the first line includes more settings from another file called “OpenSimConstants.ini”. This file does not exist in the standard Opensimulator configuration and will need making entirely. Full details on this file will come later.

The same happens at the very bottom.

[Architecture]
    Include-Architecture = "../Settings/Simulators/Defaults/GridHypergrid.ini"

All the settings to the right of an equal sign enclosed in double asterisks require substituting with values specific to this server. Therefore:

  1. Reverse DNS is found in the details provided by the server host. If one is not given it’s possible to use Nginx or Apache for the same purpose but its outside the scope of this article.
  2. Database user name is the name of the user which has access to simulator databases
  3. Database user name password is the passord assigned to the database user above

Earlier in the article, it was explained why having one database per Simulator is desirable. Similarly to the Simulator and port numbers, matching database names with Simulator names and numbers makes sense. Additionally, this approach allows scripts to simply match Simulator numbers, port numbers and Database names.

The simulator prefix is then part of the name, which comes before its number. Readers using unmodified versions of the scripts found later in this article should use “Simulator” here. However, it could be any name. The final line combines the prefix name with the Simulator number.

Resultingly if the Prefix is “Simulator” and the Simulator number is “00”, then the database name is “Simulator00”.

3rd and 4th Level Simulator Configuration Files.

OpensimConstants.ini

This file contains values that are always consistent for the entire grid. They are used in the Robust configuration, which follows too. It is located at.

~/OpenSim/Settings/OpenSimConstants.ini

And contains.

 [Const]
    SystemUsersPathWindows = "C:\Users"
    SystemUsersPathLinux = "/home"
    SystemUserName = "sara"
    FolderSeperatorCharLinux = "/"
    FolderSeperatorCharWindows = "\"
    FolderSeperatorChar = "${Const|FolderSeperatorCharLinux}"
    TempFolderLinux = "/tmp/"
    TempFolderWindows = "${Const|SystemUsersPathWindows}\${Const|SystemUserName}\Local\Temp\"
    TempFolder = "${Const|TempFolderLinux}"
    
    SystemUsersPath = "${Const|SystemUsersPathLinux}${Const|FolderSeperatorChar}"
    
    BaseFolderPath = "${Const|SystemUsersPath}${Const|SystemUserName}${Const|FolderSeperatorChar}"

    GridName = "**Full Grid Name**"
    GridShortName = "**ShortGridName**"
    BaseURL = "http://**LoginServerUrl/IpAddress**"
    AssetURL = "${Const|BaseURL}"
    MapURL = "${Const|BaseURL}"
    InventoryURL = "${Const|BaseURL}"
    PublicPort = "8002"
    PrivatePort = "8003"
    AssetPort = "8004"
    GridUserPort = "8005"
    InventoryPort = "${Const|PrivatePort}"
    MapPort = "8007"
    DatabaseSource = "localhost"
    DatabaseSslMode = "None"
    DatabaseOldGuids = "true"

MainFolderName = "OpenSim"
    CacheFolderName = "OpenSimCache"
    BinFolderName = "Bin"
    DataFolderName = "Data"
    LogsFolderName = "Logs"
    ScriptsFolderName = "Scripts"
    SettingsFolderName = "Settings"
    ScriptStateFolderName = "ScriptState"
    AssetCacheFolderName = "assetcache"
    SnapShotFolderName = "DataSnapShot"
    BakesFolderName = "bakes"
    AddinRegistryFolderName = "addins-registry"
    FsAssetsFolderName = "fsassets"
    MapTileFolderName = "MapTiles"
    OarFolderName = "Oars"
    RobustSettingsFolderName = "Robust"
    SimulatorSettingsFolderName = "Simulators"

    MainPath = "${Const|BaseFolderPath}${Const|MainFolderName}${Const|FolderSeperatorChar}"
    CachePath = "${Const|BaseFolderPath}${Const|CacheFolderName}${Const|FolderSeperatorChar}"

    ;Main Folder Sub Directories
   BinPath = "${Const|MainPath}${Const|BinFolderName}${Const|FolderSeperatorChar}"
   DataPath = "${Const|MainPath}${Const|DataFolderName}${Const|FolderSeperatorChar}"
   LogsPath = "${Const|MainPath}${Const|LogsFolderName}${Const|FolderSeperatorChar}"
   ScriptsPath = "${Const|MainPath}${Const|ScriptsFolderName}${Const|FolderSeperatorChar}"
   SettingsPath = "${Const|MainPath}${Const|SettingsFolderName}$Const|FolderSeperatorChar}"
   
   ;Cache Folder sub directories
   AssetCachePath = "${Const|CachePath}${Const|AssetCacheFolderName}${Const|FolderSeperatorChar}"
   SnapShotPath = "${Const|CachePath}${Const|SnapShotFolderName}${Const|FolderSeperatorChar}"
   BakesPath = "${Const|CachePath}${Const|BakesFolderName}${Const|FolderSeperatorChar}"

   ;Data Folder sub directories
   AddinRegisryPath = "${Const|DataPath}${Const|AddinRegistryFolderName}${Const|FolderSeperatorChar}"
   FsAssetsPath = "${Const|DataPath}${Const|FsAssetsFolderName}${Const|FolderSeperatorChar}"
   MapTilePath = "${Const|DataPath}${Const|MapTileFolderName}${Const|FolderSeperatorChar}"
   OarPath = "${Const|DataPath}${Const|OarFolderName}${Const|FolderSeperatorChar}"
   ScriptStatePath = "${Const|DataPath}${Const|ScriptStateFolderName}${Const|FolderSeperatorChar}"

   ;Settings Folder sub directories
   RobustSettingsPath = "${Const|SettingsPath}${Const|RobustSettingsFolderName}${Const|FolderSeperatorChar}"
   SimulatorSettingsPath = "${Const|SettingsPath}${Const|SimulatorSettingsFolderName}${Const|FolderSeperatorChar}"

Items inside double asterisks need changing to match the grid being configured. The port numbers can vary; however, each listening port must be unique. Inventory Port and Inventory URL currently use the BASE URL. It is left this way because grids that do not enable Hyper-Grid have greater scope to separate Robust services. This shows the potential for further separation.

GridHypergrid.ini

This file is one of the ones the Opensimulator development team suggest users do not edit. However, it is necessary to edit it when moving the contents of the “config-include” outside the “bin” directory. Only one small change is essential, so copy the file from an original download and then edit one section. It may be necessary to repeat this set when upgrading Opensimulator.

Change the “Includes” section to match the example below.

[Includes]
    Include-DatabaseService = "../Settings/Simulators/Defaults/GridCommon.ini"
OsslEnable.ini

This file is unmodified and can be copied from an original download. It needs placing in the Simulator defaults folder.

~/OpenSim/Settings/Simulators/Defaults
FlotsamCache.ini

This file is almost the same as the original; again, it needs to be put in the Simulator defaults folder containing the following.

[AssetCache]
    CacheDirectory = ../../OpenSimCache/assetcache
    LogLevel = 0
    HitRateDisplay = 100
    MemoryCacheEnabled = true
    UpdateFileTimeOnCacheHit = false
    NegativeCacheEnabled = true
    NegativeCacheTimeout = 120
    NegativeCacheSliding = false
    FileCacheEnabled = true
    MemoryCacheTimeout = .016 
    FileCacheTimeout = 48
    FileCleanupTimer = 0.0

Only the first line is different, so it matches the new folder structure.

GridCommon.ini

This file is considerably different from the original. In most cases, it is possible to copy-paste the contents that follow. However, if the database in use is not a MySQL database, update the top section “DatabaseService”. The changes either make the configuration work with the new file structure or use the new constants defined in other files.

[DatabaseService]
    StorageProvider = "OpenSim.Data.MySQL.dll"
    ConnectionString = "Data Source=${Const|DatabaseSource};Database=${Const|Simulator};User ID=${Const|DatabaseUserName};Password=${Const|DatabaseUserPassword};SslMode=${Const|DatabaseSslMode};"
    
[Hypergrid]
    HomeURI = "${Const|BaseURL}:${Const|PublicPort}"
    GatekeeperURI = "${Const|BaseURL}:${Const|PublicPort}"

[Modules]
    AssetCaching = "FlotsamAssetCache"
    Include-FlotsamCache = "../Settings/Simulators/Defaults/FlotsamCache.ini"

[AssetService]
    DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll"
    AssetLoaderArgs = "assets/AssetSets.xml"
    AssetServerURI = "${Const|AssetURL}:${Const|AssetPort}"
    
[InventoryService]
    InventoryServerURI = "${Const|InventoryURL}:${Const|InventoryPort}"

[GridInfo]
    GridInfoURI = "${Const|BaseURL}:${Const|PublicPort}"

[GridService]
    GridServerURI = "${Const|BaseURL}:${Const|PrivatePort}"
    AllowHypergridMapSearch = true
    MapTileDirectory = "../Data/MapTiles"
    Gatekeeper="${Const|BaseURL}:${Const|PublicPort}"

[EstateDataStore]
    LocalServiceModule = "OpenSim.Services.Connectors.dll:EstateDataRemoteConnector"

[EstateService]
    EstateServerURI = "${Const|BaseURL}:${Const|PrivatePort}"

[Messaging]
    Gatekeeper = "${Const|BaseURL}:${Const|PublicPort}"

[AvatarService]
    AvatarServerURI = "${Const|BaseURL}:${Const|PrivatePort}"

[AgentPreferencesService]
    AgentPreferencesServerURI = "${Const|BaseURL}:${Const|PrivatePort}"

[PresenceService]
    PresenceServerURI = "${Const|BaseURL}:${Const|PrivatePort}"

[UserAccountService]
    UserAccountServerURI = "${Const|BaseURL}:${Const|PrivatePort}"

[GridUserService]
    GridUserServerURI = "${Const|BaseURL}:${Const|GridUserPort}"

[AuthenticationService]
    AuthenticationServerURI = "${Const|BaseURL}:${Const|PrivatePort}"

[FriendsService]
    FriendsServerURI = "${Const|BaseURL}:${Const|PrivatePort}"

[HGInventoryAccessModule]
    HomeURI = "${Const|BaseURL}:${Const|PublicPort}"
    Gatekeeper = "${Const|BaseURL}:${Const|PublicPort}"
    OutboundPermission = True
    RestrictInventoryAccessAbroad = True

[HGAssetService]
    HomeURI = "${Const|BaseURL}:${Const|PublicPort}"

[HGFriendsModule]
    LevelHGFriends = 0;

[UserAgentService]
    UserAgentServerURI = "${Const|BaseURL}:${Const|PublicPort}"

[MapImageService]
    MapImageServerURI = "${Const|MapURL}:${Const|MapPort}"

[AuthorizationService]
  ; If you have regions with access restrictions
    ; specify them here using the convention
    ; Region_<Region_Name> = <flags>
    ; Valid flags are:
    ; DisallowForeigners -- HG visitors not allowed
    ; DisallowResidents -- only Admins and Managers allowed
    ; Example:
    ; Region_Test_1 = "DisallowForeigners"

GridCommon.ini needs to be put in the Simulator defaults folder.

~/OpenSim/Settings/Simulators/Defaults

Robust Instances

Robust in this article is split into four instances. They are Main, GridUser, Map and Asset. Additionally, the Asset instance uses its own database. Precisely like the Simulators, each model is launched from the same Robust.exe, only the parameters used at startup change. Again, it uses a series of Include statements that build up like a tree to generate the entire configuration.

There are five configuration files in

~/OpenSim/Settings/Robust
  • Robust.HG.Asset.ini
  • Robust.HG.GridUser.ini
  • Robust.HG.Main.ini
  • Robust.HG.Map.ini
  • RobustDefaults.HG.ini

The first four in the list contain “include” statements, which point to RobsutDefaults.Hg.ini, which in turn includes

~/Opensim/Settings/OpenSimConstants.ini

This file is the same one in the simulators example above.

RobustDefaults.HG.ini

[Const]
    Include-OpenSimConstants = "../Settings/OpenSimConstants.ini"
    DatabaseUserName = "**RobustDatabaseUserName**"
    DatabaseUserPassword = "**RobustDatabaseUserPassword**"
    DatabaseRobustMain = "**Robust Main Database Name**"
    DatabaseRobustAsset = "**Robust Asset Database Name**"
    DatabaseRobustGridUser = "${Const|DatabaseRobustMain}"

[Startup]
    RegistryLocation = ".../Data/Robust/addins-registry"
    ConfigDirectory = "robust-include"
    ConsoleHistoryFileEnabled = true 
    ConsoleHistoryFileLines = 2000
    NoVerifyCertChain = true
    NoVerifyCertHostname = true 

[ServiceList]

[Network]
    AllowllHTTPRequestIn = false

[Hypergrid]
    HomeURI = "${Const|BaseURL}:${Const|PublicPort}"
    GatekeeperURI = "${Const|BaseURL}:${Const|PublicPort}"

[DatabaseService]
    StorageProvider = "OpenSim.Data.MySQL.dll"

[GridInfoService]
    login = ${Const|BaseURL}:${Const|PublicPort}/
    gridname = "**Grid Name**"
    gridnick = "**Grid Short Name**"
    welcome = ${Const|BaseURL}
    economy = ${Const|BaseURL}
    about = ${Const|BaseURL}
    register = ${Const|BaseURL}/Register
    help = ${Const|BaseURL}/Contact
    password = ${Const|BaseURL}/Account
    gatekeeper = ${Const|BaseURL}:${Const|PublicPort}/
    uas = ${Const|BaseURL}:${Const|PublicPort}/
    GridStatus = ${Const|BaseURL}:${Const|PublicPort}/GridStatus
    GridStatusRSS = ${Const|BaseURL}:${Const|PublicPort}/GridStatusRSS

[LoginService]
    LocalServiceModule = "OpenSim.Services.LLLoginService.dll:LLLoginService"
    UserAccountService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
    GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService"
    AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
    InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService"
    AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
    PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
    GridService = "OpenSim.Services.GridService.dll:GridService"
    SimulationService ="OpenSim.Services.Connectors.dll:SimulationServiceConnector"
    LibraryService = "OpenSim.Services.Connectors.dll:LibraryServiceConnector"
    FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService"
    MinLoginLevel = 0
    UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService"
    HGInventoryServicePlugin = "[email protected]:HGSuitcaseInventoryService"
    Currency = "$G"
    ClassifiedFee = 0
    WelcomeMessage = "Welcome to **Grid Name** Grid"
    AllowRemoteSetLoginLevel = "false"
    MapTileURL = "${Const|MapURL}:${Const|MapPort}/";
    SearchURL = "";
    DestinationGuide = ""
    AvatarPicker = "${Const|BaseURL}/avatars"
    SRV_HomeURI = "${Const|BaseURL}:${Const|PublicPort}"
    SRV_InventoryServerURI = "${Const|BaseURL}:${Const|PublicPort}"
    SRV_AssetServerURI = "${Const|AssetURL}:${Const|AssetPort}"
    SRV_ProfileServerURI = "${Const|BaseURL}:${Const|PublicPort}"
    SRV_FriendsServerURI = "${Const|BaseURL}:${Const|PublicPort}"
    SRV_IMServerURI = "${Const|BaseURL}:${Const|PublicPort}"
    SRV_GroupsServerURI = "${Const|BaseURL}:${Const|PublicPort}"
    DSTZone = "America/Los_Angeles;Pacific Standard Time"

Firstly pay attention to the “Const” section at the top.

[Const]
    Include-OpenSimConstants = "../Settings/OpenSimConstants.ini"
    DatabaseUserName = "**RobustDatabaseUserName**"
    DatabaseUserPassword = "**RobustDatabaseUserPassword**"
    DatabaseRobustMain = "**Robust Main Database Name**"
    DatabaseRobustAsset = "**Robust Asset Database Name**"
    DatabaseRobustGridUser = "${Const|DatabaseRobustMain}"

The first line includes the constants that remain the same grid wide. Next, the second and third lines set the database user name and password for the Robust databases. After that, the fourth and fifth lines set the name for the two databases. One for Assets and the other for all other robust data. Finally, the last line is left as an example of how another database could theoretically be separated. However, this is not currently possible with grids that enable Hyper-Grid. It may be possible for closed grids.

Everywhere there is a value inside double asterisks, it needs substituting for the importance of the grid.

Secondly, look at the “GridInfoService” where it may be necessary to change the welcome message(depending on how the grid name is worded or language preference).

[GridInfoService]
    WelcomeMessage = "Welcome to the ${Const|GridName} Grid"

Finally, if the database engine is not MySQL, update it appropriately in the “DatabaseService” section.

Robust.HG.Main.ini

[Const]
    Include-RobustDefaults = "../Settings/Robust/RobustDefaults.HG.ini"
    
[Startup]
    PIDFile = "/tmp/RobustMain.pid"
    ConsoleHistoryFile = "../Logs/RobustMainConsoleHistory.txt"

[ServiceList]
    InventoryInConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:XInventoryInConnector"
    GridServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:GridServiceConnector"
    GridInfoServerInConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:GridInfoServerInConnector"
    AuthenticationServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector"
    OpenIdServerConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:OpenIdServerConnector"
    AvatarServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:AvatarServiceConnector"
    LLLoginServiceInConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector"
    PresenceServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:PresenceServiceConnector"
    UserAccountServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:UserAccountServiceConnector"
    AgentPreferencesServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:AgentPreferencesServiceConnector"
    FriendsServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:FriendsServiceConnector"
    OfflineIMServiceConnector = "${Const|PrivatePort}/OpenSim.Addons.OfflineIM.dll:OfflineIMServiceRobustConnector"
    GroupsServiceConnector = "${Const|PrivatePort}/OpenSim.Addons.Groups.dll:GroupsServiceRobustConnector"
    BakedTextureService = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:XBakesConnector"
    UserProfilesServiceConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:UserProfilesConnector"
    EstateDataService = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:EstateDataRobustConnector"
    MuteListConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:MuteListServiceConnector"
    GatekeeperServiceInConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector"
    UserAgentServerConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:UserAgentServerConnector"
    HeloServiceInConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:HeloServiceInConnector"
    HGFriendsServerConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:HGFriendsServerConnector"
    InstantMessageServerConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:InstantMessageServerConnector"
    HGInventoryServiceConnector = "HGInventoryService@${Const|PublicPort}/OpenSim.Server.Handlers.dll:XInventoryInConnector"
    HGAssetServiceConnector = "HGAssetService@${Const|PublicPort}/OpenSim.Server.Handlers.dll:AssetServiceConnector"
    HGGroupsServiceConnector = "${Const|PublicPort}/OpenSim.Addons.Groups.dll:HGGroupsServiceRobustConnector"

[Network]
    port = ${Const|PrivatePort}
    ConsoleUser = **Test**
    ConsolePass = **secret**
    ConsolePort = 15000

[DatabaseService]
    ConnectionString = "Data Source=${Const|DatabaseSource};Database=${Const|DatabaseRobustMain};SslMode=${Const|DatabaseSslMode};User ID=${Const|DatabaseUserName};Password=${Const|DatabaseUserPassword};Old Guids=${Const|DatabaseOldGuids};"

[AssetService]
    AssetServerURI = "${Const|AssetURL}:${Const|AssetPort}"
    BaseDirectory = "../Data/Robust/fsassets/Main/data"
    SpoolDirectory = "../Data/Robust/fsassets/Main/tmp"
    
[InventoryService]
    LocalServiceModule = "OpenSim.Services.InventoryService.dll:XInventoryService"
    AllowDelete = true

[GridService]
    LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
    AssetService = "OpenSim.Services.Connectors.dll:AssetServicesConnector"
    MapTileDirectory = "../Data/MapTiles"
    Region_TestBeta = "DefaultRegion, DefaultHGRegion, Persistent"
    Region_TestBeta2 = "FallbackRegion"
    HypergridLinker = true
    ExportSupported = true
    
[AuthenticationService]
    LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
    AllowSetPassword = true

[OpenIdService]
    AuthenticationServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
    UserAccountServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService"

[UserAccountService]
    LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService"
    AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
    PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
    GridService = "OpenSim.Services.GridService.dll:GridService"
    InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService"
    AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
    GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService"
    CreateDefaultAvatarEntries = true
    AllowCreateUser = true
    AllowSetAccount = true

[GridUserService]
    LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService"

[AgentPreferencesService]
    LocalServiceModule = "OpenSim.Services.UserAccountService.dll:AgentPreferencesService"

[PresenceService]
    LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService"

[AvatarService]
    LocalServiceModule = "OpenSim.Services.AvatarService.dll:AvatarService"

[FriendsService]
    LocalServiceModule = "OpenSim.Services.FriendsService.dll:FriendsService"

[EstateService]
    LocalServiceModule = "OpenSim.Services.EstateService.dll:EstateDataService"

[LibraryService]
    LibraryServerURI = "${Const|BaseURL}:${Const|InventoryPort}"
    LibraryName = "OpenSim Library"
    DefaultLibrary = "./inventory/Libraries.xml"

[MapImageService]
    LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
    TilesStoragePath = "../Data/Robust/maptiles"

[GatekeeperService]
    LocalServiceModule = "OpenSim.Services.HypergridService.dll:GatekeeperService"
    UserAccountService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
    UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService"
    PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
    GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService"
    GridService = "OpenSim.Services.GridService.dll:GridService"
    AuthenticationService = "OpenSim.Services.Connectors.dll:AuthenticationServicesConnector"
    SimulationService ="OpenSim.Services.Connectors.dll:SimulationServiceConnector"
    AllowTeleportsToAnyRegion = true

[UserAgentService]
    LocalServiceModule = "OpenSim.Services.HypergridService.dll:UserAgentService"
    GridUserService     = "OpenSim.Services.UserAccountService.dll:GridUserService"
    GridService         = "OpenSim.Services.GridService.dll:GridService"
    GatekeeperService   = "OpenSim.Services.HypergridService.dll:GatekeeperService"
    PresenceService     = "OpenSim.Services.PresenceService.dll:PresenceService"
    FriendsService      = "OpenSim.Services.FriendsService.dll:FriendsService"
    UserAccountService  = "OpenSim.Services.UserAccountService.dll:UserAccountService"

[HGInventoryService]
    LocalServiceModule    = "OpenSim.Services.HypergridService.dll:HGSuitcaseInventoryService"
    UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
    AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
    AuthType = None

[HGAssetService]
    LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGFSAssetService"
    UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
    AuthType = None

[HGFriendsService]
    LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGFriendsService"
    UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService"
    FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService"
    UserAccountService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
    GridService = "OpenSim.Services.GridService.dll:GridService"
    PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"

[HGInstantMessageService]
    LocalServiceModule  = "OpenSim.Services.HypergridService.dll:HGInstantMessageService"
    GridService         = "OpenSim.Services.GridService.dll:GridService"
    PresenceService     = "OpenSim.Services.PresenceService.dll:PresenceService"
    UserAgentService    = "OpenSim.Services.HypergridService.dll:UserAgentService"
    InGatekeeper = True

[Messaging]
    OfflineIMService = "OpenSim.Addons.OfflineIM.dll:OfflineIMService"

[Groups]
    OfflineIMService = "OpenSim.Addons.OfflineIM.dll:OfflineIMService"
    UserAccountService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
    MaxAgentGroups = 42

[UserProfilesService]
    LocalServiceModule = "OpenSim.Services.UserProfilesService.dll:UserProfilesService"
    Enabled = true
    UserAccountService = OpenSim.Services.UserAccountService.dll:UserAccountService
    AuthenticationServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"

[BakedTextureService]
    LocalServiceModule = "OpenSim.Server.Handlers.dll:XBakes"
    BaseDirectory = "../../OpenSimCache/Robust/bakes"

[MuteListService]
	LocalServiceModule = "OpenSim.Services.MuteListService.dll:MuteListService"

Pay attention to the “Network” section.

[Network]
    port = ${Const|PrivatePort}
    ConsoleUser = **Test**
    ConsolePass = **secret**
    ConsolePort = 15000

The lines where values are inside double asterisks need substituting for real value. Additionally, consider changing the console port number.

Robust.Hg.GridUser.ini

[Const]
    Include-RobustDefaults = "../Settings/Robust/RobustDefaults.HG.ini"
    
[Startup]
    Include-Startup = "../Settings/Robust/Robust.HG.ini"
    PIDFile = "/tmp/RobustGridUser.pid"
    ConsoleHistoryFile = "../Logs/RobustGridUserConsoleHistory.txt"

[ServiceList]
    GridUserServiceConnector = "${Const|GridUserPort}/OpenSim.Server.Handlers.dll:GridUserServiceConnector"
    HeloServiceInConnector = "${Const|GridUserPort}/OpenSim.Server.Handlers.dll:HeloServiceInConnector"
    
[Network]
    port = ${Const|GridUserPort}   

[DatabaseService]
    ConnectionString = "Data Source=${Const|DatabaseSource};Database=${Const|DatabaseRobustGridUser};SslMode=${Const|DatabaseSslMode};User ID=${Const|DatabaseUserName};Password=${Const|DatabaseUserPassword};Old Guids=${Const|DatabaseOldGuids};"

[GridUserService]
    LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService"

Robust.HG.Asset.ini

The asset service uses its own database as well as being its own instance. Consequently, it is possible to move the asset service to a different server. However, doing so will require adjusting the URL/IP address for it.

[Const]
    Include-RobustDefaults = "../Settings/Robust/RobustDefaults.HG.ini"
    
[Startup]
    Include-Startup = "../Settings/Robust/Robust.HG.ini"
    PIDFile = "/tmp/RobustAsset.pid"
    ConsoleHistoryFile = "../Logs/RobustAssetConsoleHistory.txt"

[ServiceList]
    AssetServiceConnector = "${Const|AssetPort}/OpenSim.Server.Handlers.dll:AssetServiceConnector"
    HeloServiceInConnector = "${Const|AssetPort}/OpenSim.Server.Handlers.dll:HeloServiceInConnector"
    
[Network]
    Include-Network = "../Settings/Robust/Robust.HG.ini"
    port = "${Const|AssetPort}"

[DatabaseService]
    Include-DatabaseService = "../Settings/Robust/Robust.HG.ini"
    ConnectionString = "Data Source=${Const|DatabaseSource};Database=${Const|DatabaseRobustAsset};SslMode=${Const|DatabaseSslMode};User ID=${Const|DatabaseUserName};Password=${Const|DatabaseUserPassword};Old Guids=${Const|DatabaseOldGuids};"

[AssetService]
    LocalServiceModule = "OpenSim.Services.FSAssetService.dll:FSAssetConnector"
    BaseDirectory = "../Data/Robust/fsassets/data"
    SpoolDirectory = "../Data/Robust/fsassets/tmp"
    FallbackService = "OpenSim.Services.AssetService.dll:AssetService";
    DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll"
    AssetLoaderArgs = "./assets/AssetSets.xml"
    AllowRemoteDelete = true
    AllowRemoteDeleteAllTypes = false

[LoginService]    
    SRV_AssetServerURI = "${Const|BaseURL}:${Const|AssetPort}"
    HeloServiceInConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:HeloServiceInConnector"

Robust.HG.Map.ini

[Const]
    Include-RobustDefaults = "../Settings/Robust/RobustDefaults.HG.ini"
    
[Startup]
    PIDFile = "/tmp/RobustMap.pid"
    ConsoleHistoryFile = "../Logs/RobustMapConsoleHistory.txt"

[ServiceList]
    MapAddServiceConnector = "${Const|MapPort}/OpenSim.Server.Handlers.dll:MapAddServiceConnector"
    MapGetServiceConnector = "${Const|MapPort}/OpenSim.Server.Handlers.dll:MapGetServiceConnector"
    HeloServiceInConnector = "${Const|MapPort}/OpenSim.Server.Handlers.dll:HeloServiceInConnector"

[Network]
    port = "${Const|MapPort}"
    
[LoginService]
    MapTileURL = "${Const|MapUrl}:${Const|MapPort}/";
    
[MapImageService]
    LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
    TilesStoragePath = "../Data/MapTiles"
    GridService = "OpenSim.Services.Connectors.dll:GridService"

The map service can conceivably move to a different server entirely, just like the Assets. However, it relies on access to the MapTiles folder. Therefore it would mean either moving that folder to a separate shared network location or giving one server direct access to the files on another server.

Logging – Extensible & Maintainable Opensimulator Config

Logging uses a single configuration file for everything. When either a Robust or Simulator instance starts, the parameters are pass in at launch. So the logging config file is.

~/OpenSim/Settings/OpenSimLogs.config

Containing

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>
  <runtime>
    <loadFromRemoteSources enabled="true" />
  </runtime>
  <appSettings>
  </appSettings>
  
  <log4net>
    <appender name="Console" type="OpenSim.Framework.Console.OpenSimAppender, OpenSim.Framework.Console">
      <filter type="log4net.Filter.LoggerMatchFilter">
        <loggerToMatch value="special"/>
        <acceptOnMatch value="false"/>
      </filter>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{HH:mm:ss} - %message" />
        <!-- console log with milliseconds.  Useful for debugging -->
<!--        <conversionPattern value="%date{HH:mm:ss.fff} - %message" /> -->
      </layout>
    </appender>

<!-- If you want automatic log-rolling then use RollingFileAppender instead of FileAppender:
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="log/OpenSim.log" />
      <rollingStyle value="Date" />
      <datePattern value="'.'yyyy-MM-dd"/>
      ...
-->

    <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
      <file type="log4net.Util.PatternString" value="${LogPath}${LogFile}" />
      <appendToFile value="true" />
      <filter type="log4net.Filter.LoggerMatchFilter">
        <loggerToMatch value="special"/>
        <acceptOnMatch value="false"/>
      </filter>
      <layout type="log4net.Layout.PatternLayout">
        <!-- <conversionPattern value="%date %-5level (%thread) - %logger %message%newline" /> -->
        <conversionPattern value="%date %-5level %message%newline" />
      </layout>
    </appender>

    <appender name="StatsLogFileAppender" type="log4net.Appender.FileAppender">
      <file value="OpenSimStats.log"/>
      <appendToFile value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date - %message%newline" />
      </layout>
    </appender>

    <root>
      <level value="DEBUG" />
      <appender-ref ref="Console" />
      <appender-ref ref="LogFileAppender" />
    </root>

    <!-- Independently control logging level for per region module loading -->
    <logger name="OpenSim.ApplicationPlugins.RegionModulesController.RegionModulesControllerPlugin">
      <level value="INFO"/>
    </logger>

    <!-- used for stats recording -->
    <logger name="special.StatsLogger">
      <appender-ref ref="StatsLogFileAppender"/>
    </logger>

  </log4net>
</configuration>

This file is almost identical to the “.conf” files in an original download’s “bin” folder. Only slight changes are made to use parameter passing.

Starting Robust and Simulators – Extensible & Maintainable Opensimulator Config

Starting Robust and Simulators manually is still possible; however, it is much more convenient to do this with a script. Creating scripts to start, stop and detect crashes is in a later article. Below are examples for starting one Robust and one Simulator instance.

Robust

The example below starts RobustMain.

cd ~/OpenSim/Bin/
export LogFile=~/OpenSim/Logs/RobustMain.log
ulimit -s 1048576
export TERM=xterm
mono --server Robust.exe -inifile=../Settings/Robust/Robust.HG.Main.ini -console=local -logconfig=../Settings/OpenSimLogs.config

Simulators

Below is an example to start Simulator00.

cd ~/OpenSim/Bin/
export LogFile=~/OpenSim/Logs/Simulator00.log
ulimit -s 1048576
export TERM=xterm
mono --server OpenSim.exe -inifile=../Settings/Simulators/Simulator00/OpenSim.ini -console=local -logconfig=../Settings/OpenSimLogs.config

This article replaces all previous Opensimulator configuration examples posted, including.

Video Version

Related Post

13 thoughts on “Extensible & Maintainable Opensimulator Config

  1. Is there a problem to separate the robust.inventory.ini as in other manuals you developed?

    Thans you

      1. thank you, i was just really curious, i really liked your blog work, i’m seeing if i can do something just a little different, saving each region in a different db, for that i’ll have to create opensim.ini files with different .

        I think:

        region01
        region02
        region03

        and also create a separate HGgrid linked to the gridcommon for the database, still studying how to assemble the structure in the best way.

        1. My config works with a single region, on a single simulator with a single database. Yes, you need one INI file per simulator instance. However many of those settings can be shared. As for your hypergrid database it’s not currently possible. You can only separate all the robust services with a closed grid. Maybe even then not all of them, although without hypergrid every one I have tried has worked.

  2. Hello,

    I have a strange error in my grid, it doesn’t load the map from my server, but the second life map, can you tell me if you’ve seen this before?

    in advance thank you for your attention

    DEX

Leave a Reply

Your email address will not be published. Required fields are marked *