No description
Find a file
2026-08-04 14:09:17 +02:00
src added janusxml jml insertion admin-field + iframe<>parent urlsync now works! 2026-08-04 14:09:17 +02:00
.env various bugfixes + clouddrive update 2026-08-03 19:19:07 +02:00
.gitignore 🔧 master: work in progress [might break] 2026-07-31 20:03:24 +02:00
default.nix 1st commit 2026-05-15 13:22:33 +02:00
README.md various bugfixes + clouddrive update 2026-08-03 19:19:07 +02:00
run.sh optimized scanner 2026-08-02 14:00:56 +02:00
shell.nix 🔧 master: work in progress [might break] 2026-07-31 20:03:24 +02:00

XRForge is a tiny, powerful tool to interconnect XR experiences.

An open, seamless XR web built from simple URLs and directories, without gatekeepers.


XRForge transforms standard local or remote file directories into interconnected 3D spaces.
Users can seamlessly "surf" the spatial web, turning everyday directories into 3D portals.

    ┌───────────────────────────────────┐   ┌──────────────────────────────────────────┐
    │           local disk              │   │          Surf via 3D portals             │
    ├───────────────────────────────────┤   └──────────────────────────────────────────┘
    │                                   │
    │  /myverse                         │    https://my.org/myverse
    │    /elearnings                    │    https://my.org/myverse/elearnings
    │       /elearning1/1.glb           │    https://my.org/myverse/elearning/elearning1
    │       /elearning2/2.glb           │    https://my.org/myverse/elearning/elearning2
    │                                   │
    │  ┌──────────────────────────────┐ │
    │  │ github / webdav / dropbox etc│ │
    │  │                              │ │
    │  │ /mygames                     │ │    https://my.org/myverse/mygames
    │  │   /biggusgateWebXR           │ │    https://my.org/myverse/mygames/biggusgate
    │  │   /spasca                    │ │    https://my.org/myverse/mygames/spasca
    │  │ /otherxrforge                │ │    https://my.org/myverse/otherxrforge
    │  │                              │ │
    │  │  ┌───────────┐ ┌───────────┐ │ │
    │  │  │/manyfold  │ │archive.org│ │ │    https://my.org/myverse/manyfold
    │  │  └───────────┘ └───────────┘ │ │    https://my.org/myverse/myarchive
    │  │                              │ │
    │  │ +40 integrations!            │ │
    │  └──────────────────────────────┘ │
    └───────────────────────────────────┘ 

Usage / Radical Opensource

$ ./xrforge.com 
Usage: ./xrforge.com <cmd> [opts]

  ./xrforge.com test         run testsuite (selftest)
  ./xrforge.com admin        launch adminpanel to configure stuff (/admin)
  ./xrforge.com generate     generate www-folder with XR experiences
  ./xrforge.com help         display all possible flags
  ./xrforge.com createplugin generates skeleton plugin
  ./xrforge.com server       starts the webserver [without --nobrowser]
  ./xrforge.com build        build 

$ unzip xrforge.com
Archive:  result/bin/xrforge.com
  Length      Date    Time    Name
---------  ---------- -----   ----
     3992  08-03-2026 09:54   .init.lua
      242  08-03-2026 09:46   cmd/server.lua
     1014  07-23-2026 16:13   cmd/createplugin.lua
      580  07-24-2026 16:12   cmd/help.lua
                              ....

Profit! you have aqcuired the sourcecode from the binary: run and distribute modified versions if needed ♥

Adding content

First you need a directory with glTF or JanusXR experiences.
Just run this in the terminal:

$ unzip xrforge.com myverse
$ tree myverse
myverse
├── janusxr
│   ├── helloworld
│   │   └── janusxr.xml
│   ├── janusxr.png
│   └── tronverse -> ../tronverse      <---
└── tronverse                              |  recursive portals allowed
    ├── janusxr -> ../janusxr          <---   via symlinks
    ├── tron
    │   ├── README.md
    │   ├── tron.glb
    │   ├── tron.mp3
    │   └── tron.png
    └── tronverse.png

optionally you can run ./xrforge.com admin and change the myverse directory if needed.

Now xrforge.com will scan that local folder:

$ ./xrforge.gom
 scanning experiences (this make take a while..)
 ✅     └─ plugin/diskscan: detected .png thumbnail file
 ✅ ./myverse/janusxr 10927498
 ✅ ./myverse/janusxr/helloworld 10927500
 ✅     └─ plugin/janusxr: janusxr.xml
 ✅     └─ plugin/diskscan: detected .png thumbnail file
 ✅     └─ plugin/diskscan: detected .png thumbnail file
 ✅ ./myverse/tronverse 10927503
 ✅     └─ plugin/diskscan: detected .png thumbnail file
 ✅ ./myverse/tronverse/tron 10927504
 ✅     └─ plugin/xrfragments: detected .png sidecarfile
 ✅     └─ plugin/markdown: detected README.md
 ✅     └─ plugin/diskscan: detected .png thumbnail file
  ./myverse/janusxr/tronverse
 ✅     └─ plugin/diskscan: detected symlink..creating portal
  ./myverse/tronverse/janusxr
 ✅     └─ plugin/diskscan: detected symlink..creating portal

Customizing

After first (in the terminal) run a lua config file is created, which you can edit:

$ xrforge.com 
$ ls
xrforge.com
xrforge.lua

With basic HTML/CSS skills you can edit the templates by running this in the terminal:

$ unzip xrforge.com page css
$ ls
page css

Profit! You can now edit the extracted html-templates and css-files, they will be detected automatically when running xrforge.com

Optionally you can re-distribute xrforge.com with your modifications by running zip xrforge.com page

Plugins

xrforge is basically plugins working together.
You can create your own plugins by running:

$ ./xrforge.com createplugin > xrforge.myplugin.lua

Look in the src/plugin directory for examples

Scan manyfold


manual scan (via cli?)
curl -L -X 'GET'   'http://xrforge.isvery.ninja/models?page=1&order=name'     -H 'accept: application/vnd.manyfold.v0+json'
curl -L -X 'GET'   'http://xrforge.isvery.ninja/models?page=1&order=recent'   -H 'accept: application/vnd.manyfold.v0+json'

Developing

$ source .env            # not needed if your system has autoenv
$ build                  # fast: repeatable build
$ rebuild                # faster: lua-repeatable build
$ nix-build              # slow: reproducable nix build (for experts)

Then run with debug flag to see output of trace() calls

$ DEBUG=1 result/bin/xrforge.com

Permacomputing Spirit

  • developed on Dillo as lowest common denominator / compatibility
  • does not use javascript (WebXR viewer being the exception)
  • gracefully degrades to admin/filebrowser for >noscript>/potato-browsers
  • server is using lua-scripting via cosmopolitan libc's redbean

So yes, the codebase/html/css is intentionally 90-ish: that's exactly why it works on potato-devices AND modern devices.

Credits / Made with

Ideas

NOTES:


                   /admin.lua <--- define other instances..for CORS allow / mount http
                                   configure in-zip or filesystem-cache

                   opendirectory.lua <--- mount other instances over http (via xrforge or rclone)

.xrforge/hook/scandir <-- event to hook 

scan files                                      
----------             middleware/xrexperience.lua
  | events:            ---------------------
  + file               type: sidecarfile 
  + sidecarfiles --->  regex =  {"\.glb", "\.png", "\.vtt"} 
  |                    regex_minmatch = 2
  + folder             viewer = /view/janusweb/#janus.url=${file}.glb
                       template = [[
                         <div class="tile"> ... </div>
                       ]]