Documentation

openX is a host, not an executor. It gives the Capi / Xeno.dll ABI a real interface — the execution engine comes from the DLL you load.

Install

  1. Download openX-1.0-win64.zip and extract it anywhere.
  2. Put your Xeno.dll next to openX.host.exe, or click the core chip in the sidebar after launch.
  3. Double-click openX.exe.

That's it. There's no installer and nothing is written to the registry.

Which exe? openX.exe is a native launcher. It checks for .NET Framework 4.7.2, installs it from Microsoft if it's missing, then starts openX.host.exe. If you launch the host directly on a machine without the framework, Windows will refuse to run it.

First run

On a machine with .NET 4.7.2 already present (Windows 10 1809+ / Windows 11), the launcher hands off immediately. Otherwise you'll see one prompt:

// openX - first run
openX needs .NET Framework 4.7.2, which is not installed.
Download and install it now?
About 84 MB from Microsoft. Windows will ask for permission,
and a restart may be needed.

The installer is fetched from Microsoft's own go.microsoft.com link, run with /q /norestart, and deleted afterwards. Exit codes 0, 3010 and 1641 are treated as success; 3010 offers to start the app anyway after telling you a reboot is recommended.

Loading a core

openX looks for Xeno.dll in this order:

  1. the path in CorePath= inside config.ini
  2. Xeno.dll next to openX.host.exe
  3. bin\Xeno.dll under the exe

On load the host maps the DLL with LOAD_WITH_ALTERED_SEARCH_PATH, so its own dependencies (libcrypto-3-x64.dll, libssl-3-x64.dll) resolve beside it rather than in the app folder, then binds five exports:

ExportSignatureUsed for
Initializevoid()called once on load
Attachvoid()injection
GetClientsptr()client list for the dropdown
Executevoid(byte*, char**, int)running a script
Compilableptr(byte*)syntax check

If an export is missing you get the name of the missing export instead of a TypeInitializationException. The SHA-256 of the mapped file is printed to the console on every load and shortened on the core chip in the sidebar.

The chip is the only core UI: it shows loaded, attached or not found. Click it to pick a DLL, or right-click for reload and unload. The chosen path is saved to config.ini, so it only has to be done once.

Using the editor

Every open file gets its own tab at the top of the window. A dot on the tab means unsaved changes; close the tab and openX asks before throwing them away. Right-click a tab for a list of every open document, so tabs that have scrolled out of reach are still one click away.

ActionKey
Execute current scriptF5
SaveCtrl+S
Save asCtrl+Shift+S
OpenCtrl+O
New tabCtrl+N
Rename tab (and file)F2 or double-click
Close tabCtrl+W
Cycle tabsCtrl+Tab / Ctrl+Shift+Tab
Clear consoleCtrl+L

The sidebar lists scripts/ and autoexec/. Click a file to open it in a tab. Attach injects into the selected client and refreshes the client list. With auto-inject enabled the host retries on a timer, so you can launch Roblox after openX.

setup.lua runs once per client, before your first script, unless you untick the option. It is a local file and opens like any other document — the original wrapper fetched it over the network on every execution.

Autoexec

Anything in autoexec/ runs automatically after injection. The order is:

  1. attach to the client
  2. scripts/setup.lua — once per client
  3. every autoexec/*.lua, in filename order — once per client
  4. your script, when you press F5

The run autoexec/ after inject checkbox in the sidebar turns step 3 off. Files are tracked per client, so a script is not re-run just because the client list refreshed. Subfolders are not scanned; keep the files directly in autoexec/.

Files

openX.exe              native launcher + .NET bootstrapper
openX.host.exe         the app
Xeno.dll               the core (you supply)
config.ini             written on exit
scripts/               *.lua and *.txt appear in the sidebar
scripts/setup.lua      local API bootstrap
scripts/examples/      sample script
autoexec/              *.lua run once per client after injection

Troubleshooting

core: missing

The chip in the sidebar is amber and says click to locate. Click it and pick your Xeno.dll; the path is saved. The console also prints the full path it tried.

autoexec didn't run

Check three things: the run autoexec/ after inject box is ticked, the files are directly in autoexec/ with a .lua extension, and the client was already attached when you added them. Files run once per client — detach and attach to re-run.

export not found: Name

The DLL is loaded but doesn't export that symbol. Either it's a different ABI or the file is not the core. Dump its exports with dumpbin /exports Xeno.dll before guessing.

Attach does nothing

Start Roblox first, then attach. If the client list stays empty, the core isn't finding the process — that's inside the DLL, not the host.

Check syntax crashes

The host frees the pointer returned by Compilable with Marshal.FreeCoTaskMem, mirroring the original wrapper. If the DLL allocated with malloc, that free is wrong. Use F5 and read the console instead.

loadstring is nil

That comes from the core's Lua environment, not from openX. Confirm with print(type(loadstring)). Nothing outside the DLL can add it.

Building from source

You need Windows with Visual Studio 2022, or MSBuild + NuGet.

# PowerShell, in the project root
.\build.ps1

Or open openX.sln. Output lands in src\openX\bin\Release\. The launcher builds from launcher/openx_launcher.c — plain C, no dependencies. A prebuilt openX.exe is included, so you can skip that step.

Audit notes

The original Capi package is a thin P/Invoke layer with a broken bootstrap. Every endpoint it used is dead:

EndpointPurposeStatus
cloudyExecutor/webb releasecore download404
cxapi.versionupdate check404
brod.castbroadcast404
cloudyweb.vercel.app/hash/setup.luaremote code on every execute404

openX removes all four: no runtime download, no update check, no broadcast channel, and no remote loadstring prefix on your scripts.

Ban risk. Script execution violates Roblox's Terms of Service. Testing on an account you care about is a bad idea.