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
- Download
openX-1.0-win64.zipand extract it anywhere. - Put your
Xeno.dllnext toopenX.host.exe, or click the core chip in the sidebar after launch. - Double-click
openX.exe.
That's it. There's no installer and nothing is written to the registry.
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:
- the path in
CorePath=insideconfig.ini Xeno.dllnext toopenX.host.exebin\Xeno.dllunder 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:
| Export | Signature | Used for |
|---|---|---|
Initialize | void() | called once on load |
Attach | void() | injection |
GetClients | ptr() | client list for the dropdown |
Execute | void(byte*, char**, int) | running a script |
Compilable | ptr(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.
| Action | Key |
|---|---|
| Execute current script | F5 |
| Save | Ctrl+S |
| Save as | Ctrl+Shift+S |
| Open | Ctrl+O |
| New tab | Ctrl+N |
| Rename tab (and file) | F2 or double-click |
| Close tab | Ctrl+W |
| Cycle tabs | Ctrl+Tab / Ctrl+Shift+Tab |
| Clear console | Ctrl+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:
- attach to the client
scripts/setup.lua— once per client- every
autoexec/*.lua, in filename order — once per client - 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:
| Endpoint | Purpose | Status |
|---|---|---|
cloudyExecutor/webb release | core download | 404 |
cxapi.version | update check | 404 |
brod.cast | broadcast | 404 |
cloudyweb.vercel.app/hash/setup.lua | remote code on every execute | 404 |
openX removes all four: no runtime download, no update check, no broadcast channel, and no
remote loadstring prefix on your scripts.