Quickstart: from nothing to logged in
This chapter takes you from an empty machine to your own Paracosm world: the OpenSimulator 0.9.3.0 server with our seven source patches and the WorldBridge region module, logged into with the Firestorm-Paracosm viewer, and an AI connected through the MCP server. It is written for Windows; Linux notes are given where the scripts support it.
Every command below is run from the root of the Paracosm source folder unless it says otherwise. The examples put
the source in C:/paracosm and the built server in C:/paracosm-server; use any folders you like, but the server
must be built OUTSIDE the source folder.
Related chapters: config.md (every setting), backup.md, packaging.md, operations.md (running and restarting), worldbridge.md (the control API).
1. Prerequisites
| what | version used for the reference build | needed for |
|---|---|---|
| Windows 11 x64 (or Linux x64, see the notes) | Windows 11 Pro 10.0.22631 | everything |
| .NET 8 SDK | 8.0.422 (any .NET 8 SDK; it includes the runtime) | building and running the server |
| Python | 3.12.10 (3.8 or later; the server scripts use the standard library only) | the build, config, run and backup scripts; the MCP server |
| OpenSimulator source | opensim-0.9.3.0-source.zip, SHA-256 44811934c289195420ec82a5d448e6ee28b6cfa6094e1a8e6882e489c0967ab7 |
the server build |
| SQLite (Windows only) | the official sqlite3.dll 3.47.0 x64 |
the server build (fetched for you with --fetch-sqlite3) |
| A viewer | Firestorm-Paracosm 7.2.5.1 (portable zip) or any OpenSim-capable viewer | logging in |
On Windows, winget install Microsoft.DotNet.SDK.8 and winget install Python.Python.3.12 install the first two.
On Linux, install your distribution's .NET 8 SDK package and Python 3. Check with dotnet --list-sdks (an 8.x
line) and python --version (python3 on most Linux systems).
Install the Python packages with python -m pip install -r requirements.txt (psutil, numpy, Pillow, scipy). psutil lets tools/run_server.py find THIS install's OpenSim process exactly, without PowerShell or pgrep,
and read each process's working directory, so it can always tell this install's OpenSim from a second server
(without it, on Windows, it relies on bin/opensim.pid).
The viewer's helper bridge for an AI (section 10) needs pip install llbase.
Not needed: Mono, Visual Studio, git (unless you clone), NuGet packages.
2. Get the source
Clone the Paracosm repository or unpack a Paracosm source release into C:/paracosm. Then put the pristine
OpenSimulator source zip in that folder:
cd C:/paracosm
powershell -Command "Invoke-WebRequest http://opensimulator.org/dist/opensim-0.9.3.0-source.zip -OutFile opensim-0.9.3.0-source.zip"
(Linux: curl -O http://opensimulator.org/dist/opensim-0.9.3.0-source.zip.) The build checks the zip's SHA-256
and refuses any other file. *.zip is git-ignored, so the zip never enters the repository.
3. Make your .env
All secrets and per-install values live in one file, .env, in the source root. It is git-ignored and never
shipped. Start from the template:
copy .env.example .env (Linux: cp .env.example .env)
Then edit .env. These keys MUST change:
| key | set it to |
|---|---|
PARACOSM_BIN |
the server's bin/ folder: <build output>/bin, here C:/paracosm-server/bin |
PARACOSM_ESTATE_OWNER_FIRST, _LAST |
the estate owner's name: two single words (the first start creates this account) |
PARACOSM_ESTATE_OWNER_PASSWORD |
a real password (never leave it change-me or empty) |
PARACOSM_RESIDENT_FIRST, _LAST, _PASSWORD |
the AI resident's own avatar. The template makes it the estate owner (the same name); if you keep that, the password must equal the estate owner's |
These may stay as they are for a first run on one machine: the grid and region names, PARACOSM_PORT=9000,
PARACOSM_EXTERNAL_HOST=127.0.0.1, PARACOSM_REGION_SIZE=256, WORLDBRIDGE_ALLOW_CONSOLE=false,
WORLDBRIDGE_FILE_ROOTS=worldbridge-files, the empty REST console keys (an empty PARACOSM_CONSOLE_USER keeps the
REST console closed), and WORLDBRIDGE_TOKEN_FILE, commented out (tools/wb.py then reads
<PARACOSM_BIN>/WorldBridge.token, where WorldBridge writes it).
config.md explains every key.
Decide the region size now if you want a var region (section 11): it is simplest to set before the first start.
4. Build the server
python build/build_server.py ../paracosm-server --fetch-sqlite3
This one command verifies the zip, extracts it into ../paracosm-server, applies the seven patches in
opensim-patches/ (checking every patched file against opensim-patches/patched-files.sha256), runs OpenSim's
Prebuild, compiles OpenSim in Release, installs the official sqlite3.dll (Windows), builds WorldBridge against
the fresh bin/ and copies WorldBridge.dll in, writes the config from your .env (section 5), and records
every input and output hash in ../paracosm-server/paracosm-build.json. It takes a few minutes and ends with
[build] DONE (exit code 0) or [build] FAILED: <reason> (exit code 1).
| option | does |
|---|---|
--fetch-sqlite3 |
download the official SQLite 3.47.0 zip and take sqlite3.dll from it (hash-checked) |
--sqlite3-dll PATH / --sqlite3-zip PATH |
the same DLL from a file you already have (offline) |
--no-sqlite3 |
skip the DLL (on Windows the region then cannot open its databases) |
--sqlite3-sha256 HEX |
accept a different SQLite release on purpose |
--zip PATH |
the OpenSim zip, if it is not in the source root |
--env PATH |
a different env file (default: .env in the source root) |
--clean |
delete the output folder first (without it the build refuses a non-empty folder) |
--low-priority |
run dotnet at idle priority (use it when a region already runs on this machine) |
--dotnet PATH |
a dotnet other than the one on PATH |
The runnable server is C:/paracosm-server/bin. The rest of C:/paracosm-server is the patched source tree it
was built from. build/README.md describes each step and how to check the result by hand.
Linux: the script handles Linux (the per-OS System.Drawing.Common.dll, executable bits, no sqlite3.dll step)
but has not been run there yet, and which native SQLite library a .NET 8 OpenSim loads on Linux is not verified.
5. Generate the config
The build writes the config for you (its step 9) when .env exists. It runs:
python tools/make_config.py C:/paracosm-server/bin --env .env
which writes, into bin/:
| file | made from |
|---|---|
OpenSim.ini |
upstream's OpenSim.ini.example with config/paracosm.ini merged in |
config-include/StandaloneCommon.ini |
upstream's example with config/StandaloneCommon-overlay.ini merged in |
config-include/FlotsamCache.ini, config-include/osslEnable.ini |
upstream's examples, unchanged |
Regions/Regions.ini |
config/Regions.ini.template, with a new region UUID made once |
make_config.py keeps any of these that already exist. After you change .env, run it again with --force: it
writes a .bak of each file it replaces and keeps the region's UUID. If it prints
WARNING: not set in the environment/.env, a key the templates need is missing from .env.
bin/OpenSim.ini now holds the estate owner's password and the REST console password in clear text. Treat it like
.env.
6. First start
python tools/run_server.py start
It starts dotnet OpenSim.dll -inifile OpenSim.ini -console=rest in the background from PARACOSM_BIN, writes the
process id to bin/opensim.pid and the process's own output to bin/opensim-console.out.log, and returns.
OpenSim's log is bin/OpenSim.log; watch it:
powershell -Command "Get-Content C:/paracosm-server/bin/OpenSim.log -Tail 40 -Wait" (Linux: tail -f .../OpenSim.log)
On the first start, with no prompt:
- OpenSim creates the estate from
PARACOSM_ESTATE_NAMEand the estate owner's account fromPARACOSM_ESTATE_OWNER_*. The lineEstate <name> has no owner set.is part of this step, not an error. - WorldBridge finds no token and generates one:
[WorldBridge] generated a new token in <bin>/WorldBridge.token. This file is the full-access (gaia) key to the control channel. Keep it private. - WorldBridge opens its channel:
[WorldBridge] control channel listening on http://127.0.0.1:9002/. - It creates the
worldbridge-filesfolder beside OpenSim (the only place WorldBridge requests may read or write files, see config.md).
Check it:
python tools/run_server.py status running: [<pid>]
python tools/wb.py state the region's name, size, avatar and object counts
tools/wb.py reads the token from WORLDBRIDGE_TOKEN_FILE (default <PARACOSM_BIN>/WorldBridge.token). A 401 means the file it read is not the one
WorldBridge wrote (check the path in .env).
Other ways to run it:
- In a terminal, with OpenSim's own interactive console:
cd C:/paracosm-server/binthendotnet OpenSim.dll. Stop it withshutdownat theRegion (...)prompt. Never run this whilerun_server.pyalso runs one: two processes on one set of SQLite files corrupt them (operations.md #7). - As a service that restarts OpenSim when it exits:
python tools/run_server.py supervise(see run/README.md for a Windows scheduled task, andrun/paracosm.servicefor systemd on Linux).
To stop it: python tools/run_server.py stop. It asks WorldBridge's console op for a clean shutdown and waits
up to 90 s for OpenSim to exit. While WORLDBRIDGE_ALLOW_CONSOLE is false that op is refused: stop then has
WorldBridge write the scene to the database (save_world), sends SIGTERM on Linux, and waits 10 s. Whatever is
still running after the wait is forced: taskkill /F /T on Windows (a detached, window-less OpenSim cannot be
stopped any other way), SIGKILL elsewhere. stop only touches an OpenSim running from this install's bin/,
never a second server elsewhere on the machine, and exits 1 if the process survives even the force.
If the log says [WorldBridge] failed to start HTTP listener on 127.0.0.1:9002 -- Access is denied, Windows is
refusing the HTTP reservation for a non-administrator. From an administrator prompt,
netsh http add urlacl url=http://127.0.0.1:9002/ user=<your user> reserves it. (Whether a non-elevated install
needs this has not been tested.)
7. Get the viewer
Either:
- The portable zip (Windows x64): unzip
Firestorm-Paracosm-7.2.5.1-win64-portable.zipanywhere and runFirestorm-Paracosm/FirestormOS-Paracosm.exe. Nothing is installed. Its settings live in%APPDATA%/ParacosmViewer_x64and its cache in%LOCALAPPDATA%/ParacosmViewer_x64, never shared with a stock Firestorm. To make the zip yourself, see packaging.md. - Build it from the Firestorm source and our ten patches: viewer.md and packaging.md.
- Any OpenSim-capable viewer, a stock Firestorm OpenSim build included. You lose only what the Paracosm build
adds: no requests to third parties by default, the double confirmation before a Second Life login, voice off,
and the LEAP camera and snapshot operations the AI's
viewer_*tools need.
8. First login
- Start the viewer. On the login screen choose the grid
localhost:9000(its login URI ishttp://localhost:9000). In the Paracosm build it is the only grid besides the two Second Life grids, and the default. - Username: the estate owner's
First Lastfrom.env. Password:PARACOSM_ESTATE_OWNER_PASSWORD. - Log in. You arrive on the default region.
With a viewer that lacks the localhost:9000 entry, add the grid once: Preferences, OpenSim, Grid Manager, add
the login URI http://127.0.0.1:9000/, then select it. (Do not rely on a --loginuri command-line switch with
Firestorm: see viewer.md section 4.)
If the login fails with "could not connect", the region may still be starting: wait for the WorldBridge line in
OpenSim.log and try again.
9. More accounts
The estate owner is the only account at first, and everything WorldBridge builds is owned by it. Give each person their own account:
-
WorldBridge
create_account(needs the gaia token, whichtools/wb.pyreads from the token file):python tools/wb.py create_account first=Ann last=Example password=<password> [email protected]It creates the account, sets the password, creates the inventory and sets home to the middle of the default region, as the console's
create userdoes.lastdefaults toResident;emaildefaults to<first>@paracosm.local. The password travels in the JSON body, which WorldBridge's audit log masks; your shell history still keeps it. -
The OpenSim console:
create user <first> <last> <password> <email>, then press Enter at theUser ID (enter for random)andModel nameprompts. The console is there when OpenSim runs in a terminal (section 6). A server started byrun_server.pyhas only the REST console: setPARACOSM_CONSOLE_USERand a strongPARACOSM_CONSOLE_PASSin.env, runpython tools/make_config.py C:/paracosm-server/bin --force, restart, and connect with OpenSim's console client frombin/:dotnet OpenSim.ConsoleClient.dll -host 127.0.0.1 -port 9001 -user <user> -pass <password>. Do not sendcreate userthrough WorldBridge'sconsoleop: its prompts wait for an answer, and its audit log does not mask acreate userpassword.
To let other accounts edit what WorldBridge built, share the builds through a group (sharing-and-inventory.md).
To change a password later: console reset user password <first> <last> <new password>, then update .env.
10. Connect an AI through the MCP server
mcp/worldbridge_mcp.py is a standard-library-only MCP server (stdio, JSON-RPC 2.0) with 26 tools: 21 world_*
tools that call WorldBridge (among them world_call, which passes any WorldBridge command through) and 5
viewer_* tools that drive the AI's own viewer. It must run on the same machine as OpenSim: WorldBridge listens on
loopback only.
Add it to your MCP client's configuration (the mcpServers shape is used by Claude Desktop and Claude Code's
.mcp.json):
{
"mcpServers": {
"worldbridge": {
"command": "python",
"args": ["C:/paracosm/mcp/worldbridge_mcp.py"],
"env": {
"WORLDBRIDGE_URL": "http://127.0.0.1:9002",
"WORLDBRIDGE_TOKEN_FILE": "C:/paracosm-server/bin/WorldBridge.token"
}
}
}
}
-
The MCP server does not read
.env: give itWORLDBRIDGE_TOKEN_FILE(orWORLDBRIDGE_TOKEN) in its ownenv. -
It reads the token once, when it starts. Start OpenSim once before you start the AI client, so the token file exists; restart the client if the token changes.
-
The token file's token is full access. For less, set a role token in
.env(WORLDBRIDGE_OBSERVER_TOKENorWORLDBRIDGE_BUILDER_TOKEN, 16 characters or more), runpython tools/make_config.py <bin> --force, restart OpenSim, and give the MCP that token asWORLDBRIDGE_TOKEN. See config.md. -
A quick test without a client (it lists the tools; no server needed):
cmd: echo {"jsonrpc":"2.0","id":1,"method":"tools/list"} | python mcp/worldbridge_mcp.py bash: echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python3 mcp/worldbridge_mcp.py
The viewer_* tools also need the AI's own viewer running with the helper bridge: tools/run_viewer.py launches
it (logged in as PARACOSM_RESIDENT_*) with tools/leap_bridge.py attached, which needs pip install llbase.
Give the MCP VIEWER_TOKEN equal to .env's PARACOSM_VIEWER_TOKEN. run_viewer.py defaults to a development
build under C:/fs; for the portable viewer set PARACOSM_VIEWER_EXE to its FirestormOS-Paracosm.exe and
PARACOSM_VIEWER_DATA to its folder. It is Windows-only and logs in only to a loopback login URI. See
viewer.md.
11. A var region (2x2 or 3x3)
One region can be bigger than 256 m: set PARACOSM_REGION_SIZE in .env to 512 (a 2x2 var region) or 768
(3x3). make_config.py writes it as SizeX and SizeY in Regions/Regions.ini. OpenSim requires a multiple of
256 and a square region. The region covers SIZE/256 grid cells in each direction from
PARACOSM_REGION_LOCATION, so a neighbouring region must sit at least that many cells away. WorldBridge reads the
real size for every default and clamp (worldbridge/VAR-REGIONS.md).
Set it before the first start. For an existing region, change .env, run make_config.py <bin> --force (the
region UUID is kept) and restart; resizing a region that already has terrain and objects has not been tested.
A var region has not yet been tested live; a 256 region is the tested path.
12. LAN and remote access
By default the world is reachable from this machine only (PARACOSM_EXTERNAL_HOST=127.0.0.1). For other machines:
- Set
PARACOSM_EXTERNAL_HOSTto an address every viewer can reach: the server's LAN IP or DNS name, or its public name for the internet. It becomes[Const] BaseHostname(the login and service URLs) and the region'sExternalHostName(where viewers send their UDP traffic). - Set
PARACOSM_LOGIN_URI=http://<that host>:9000(read bytools/run_viewer.pyand the test bot; it does not configure the server). python tools/make_config.py C:/paracosm-server/bin --force, then restart the server.- Open port 9000 for TCP (login, capabilities) and UDP (the region) in the server's firewall, and forward both for
internet access. Each viewer adds the grid
http://<host>:9000/in its Grid Manager.
| port | what | expose? |
|---|---|---|
| 9000 TCP and UDP | the simulator: login, capabilities, region traffic | yes, to the viewers that should reach it |
| 9001 TCP | OpenSim's REST console (plain HTTP on all interfaces; it refuses every session while PARACOSM_CONSOLE_USER is empty) |
never; firewall it |
| 9002 TCP | WorldBridge (loopback only, full control of the world) | never; do not tunnel or proxy it |
| 9004 TCP | the viewer's LEAP helper bridge (loopback only) | never |
Keep the AI and its MCP server on the server machine. WorldBridge has no TLS, and it refuses a non-loopback
BindAddress by design. tools/run_viewer.py refuses a non-loopback login URI, so on a LAN the
people log in with the viewer directly.
What crosses the network in clear, TLS for the login (OpenSim's own HTTPS listener or a reverse proxy), and the firewall in more detail: tls.md.
13. Next
- Load a world from an OAR, or restore a backup: backup.md and tools/RESTORE.md.
- Build things: worldbridge.md, then the craft chapters in README.md.
- Run and restart safely: operations.md.