Cordial

# Cordial Runs Roblox's official Android build natively on Linux, with no emulator, container or virtual machine, on x86-64 or aarch64. GPL-3.0-or-later.

Join the Cordial Discord Read the Cordial documentation

Documentation: **[cordial.mintlify.app](https://cordial.mintlify.app)**, built from [`docs/`](docs/README.md). ## Demo

Roblox DOORS running under Cordial on Linux

Roblox **DOORS**, unmodified, on Cordial. [Full size](https://raw.githubusercontent.com/luohoa97/cordial/main/docs/media/cordial-doors.mp4), more in [`docs/media`](docs/media).

Roblox's Meta Quest build in VR on Linux, playing TUNNELER

Roblox's **Meta Quest** build in VR on Linux, playing [TUNNELER](https://www.roblox.com/games/4635669637/TUNNELER). [Full size](https://raw.githubusercontent.com/luohoa97/cordial/main/docs/media/cordial-vr.mp4); setting it up is in [`docs/vr.md`](docs/vr.md). ## Why Cordial I used Sober for a year, and it worked really well. Cordial started off as a weekend project because I was bored, and I believe a project like this is something people have the right to read, modify, and learn from. Credit to sober for making android Roblox runtimes possible ## Status Experimental. Full table in [`docs/status.md`](docs/status.md). **Works:** loading an experience, sign-in, keyboard and mouse, camera, text entry with IME preedit, audio, voice chat, pointer capture, fullscreen, two accounts side by side, asset overlays, joining a public server from a game's Servers list, and joining a private server (0.19.0). **Known broken**, with issue numbers: | | | |---|---| | Roblox can stop drawing on the loading screen after sign-in (the launcher restarts it, up to twice) | [#92](https://github.com/luohoa97/cordial/issues/92) | | No window on some COSMIC, KWin and wlroots setups (it opens on KWin on a Steam Deck) | [#38](https://github.com/luohoa97/cordial/issues/38) | Controller buttons and sticks work on common pads; the brand of glyph Roblox draws may be wrong, and a pad with an unusual layout may have a stick misread ([`docs/controllers.md`](docs/controllers.md)). No force feedback. Roblox's own Record Video button does nothing on Android. Cordial can record the session itself, with `ffmpeg`, with or without the game's own sound. Press F9 in the game window to start and stop ([`docs/recording.md`](docs/recording.md)). Frame-rate numbers are not quoted here because the two measurements in this repo contradict each other; see [`docs/status.md`](docs/status.md). **Tested platforms.** Development happens on Fedora with GNOME and Mesa. There is no systematic test matrix — other compositors and GPU vendors are reported working or broken through issues, not verified here. ## How it works Cordial mmaps and relocates Roblox's unmodified `libroblox.so` with a ported AOSP bionic linker rather than the system one. Every symbol the engine imports resolves as **cordial** (an Android behaviour implemented here), **host** (forwarded to glibc), or **stub** — and a stub reports failure rather than faking success, so a gap stays visible instead of surfacing later as an unrelated bug. `libjnivm` stands in for Android's ART, and a framework layer answers the JNI calls the client makes into the platform. Symbol resolution reads the engine's own ELF imports rather than a checked-in list, so an ordinary libc import resolves from the host automatically ([`docs/adr/ADR-034-symbol-resolution-asks-the-library.md`](docs/adr/ADR-034-symbol-resolution-asks-the-library.md)). Compatibility gaps are fixed at that framework layer, never by patching the binary ([`docs/adr/ADR-001-in-process-hooking.md`](docs/adr/ADR-001-in-process-hooking.md)). Diagram and data flow: [`docs/architecture.md`](docs/architecture.md). ## Install x86-64 or aarch64 Linux. Wayland is the primary backend and X11 is supported ([`docs/adr/ADR-024-x11-is-supported-again.md`](docs/adr/ADR-024-x11-is-supported-again.md)). aarch64 is new and untested on real ARM64 hardware — see [`docs/multiarch.md`](docs/multiarch.md) for what has and has not been checked. The Arch package is x86-64 only; Arch Linux itself does not build for aarch64. You also need Roblox's Android build. Cordial does not ship it. First run has a **Download Roblox** button that fetches it from APKPure, refuses anything not signed by Roblox's own certificate, and keeps its own copy. If [Sober](https://sober.vinegarhq.org/) is installed, you can copy its build in instead; Cordial does not follow Sober's updates afterwards. Details in [`docs/install.md`](docs/install.md). **Flatpak (recommended):** it runs on the same GNOME 50 runtime everywhere, with the GTK, WebKit, Vulkan loader and audio libraries Cordial is built and tested against. Most compatibility problems reported with the other packages, from a distribution's own versions of those libraries, do not happen in it. ```bash flatpak remote-add --if-not-exists cordial https://luohoa97.github.io/cordial/cordial.flatpakrepo flatpak install cordial io.github.luohoa97.Cordial flatpak run io.github.luohoa97.Cordial ``` The remote is signed. Its key fingerprint, and what to do if you added it before it was, are in [`docs/install.md`](docs/install.md#check-what-you-downloaded). A plain install lands on `stable`, which moves only when a release is tagged. `master` follows every commit to `main`: ```bash flatpak install cordial io.github.luohoa97.Cordial//master ``` **AppImage**, from the [releases page](https://github.com/luohoa97/cordial/releases). Newer and less proven than the Flatpak; its web-view path fix has been measured on a stand-in, not on a real machine without WebKitGTK, and not outside Fedora ([`docs/install.md`](docs/install.md#appimage)): ```bash chmod +x Cordial-*.AppImage && ./Cordial-*.AppImage # -x86_64 or -aarch64 ``` **Packages** on the releases page, each with a cosign signature: ```bash sudo apt install ./cordial_*_amd64.deb # or _arm64.deb sudo dnf install ./cordial-*.x86_64.rpm # or .aarch64.rpm; Fedora 44 only sudo pacman -U cordial-*-x86_64.pkg.tar.zst # x86-64 only -- see above ``` Signed apt, dnf and pacman repositories are published too; the setup commands are in [`docs/install.md`](docs/install.md). The `cordial`, `cordial-bin` and `cordial-git` packages on the AUR are maintained by someone outside this project and were last updated at 0.17.0. **From source:** ```bash git clone --recursive https://github.com/luohoa97/cordial cd cordial cargo build --release ``` Needs Clang — AOSP bionic uses C11 `_Atomic` in C++ headers and GCC rejects it — plus GTK4 >= 4.12 and libadwaita >= 1.5 development packages. PipeWire and WebKitGTK-6.0 headers are optional and probed at build time; without them the binary is quietly less capable. Play in VR needs `--features cordial-runtime/vr` and Boost's headers. The Nix flake's package builds and runs `--help` and `--diagnostics`, but has never run a game ([CONTRIBUTING.md](CONTRIBUTING.md#or-use-the-flake)). Full list: [`docs/install.md`](docs/install.md#from-source). ## Configuration **FastFlags** live in `~/.local/share/cordial/profiles//flags.json`, or wherever `CORDIAL_FLAGS` points. Settings → FastFlags → Import reads a Bloxstrap, Fishstrap or Sober list (`cordial --import-flags` does it from a terminal). Layering, syntax and import: [`docs/fastflags.md`](docs/fastflags.md). **VR (experimental, x86-64).** Settings → VR → Play in VR runs the Meta Quest build of Roblox, copied from your own headset, through an OpenXR runtime such as WiVRn. See [`docs/vr.md`](docs/vr.md). **Something not working?** `cordial --doctor` checks the display, GPU and Vulkan, sound, keyring and the Roblox build, with what to do about each; Report a Problem in the main menu shows the same. [`docs/doctor.md`](docs/doctor.md). **Mouse acceleration** is a Settings control — cursor and camera (the default), or cursor only for raw camera movement — stored in `$XDG_CONFIG_HOME/cordial/shell.json`. **Shaders**, sharpening and anti-aliasing over the game through [vkBasalt](https://github.com/DadSchoorse/vkBasalt)'s Vulkan layer, are a Settings switch offered once vkBasalt is installed: install per distro, the Flatpak extension, the generated config's path and its toggle key are all in [`docs/shaders.md`](docs/shaders.md). **MangoHUD**, a frame rate and load overlay, is a Settings switch offered once MangoHud's Vulkan layer is installed. Install routes and what it shows: [`docs/mangohud.md`](docs/mangohud.md). **PartyDeck and gamescope.** Several windows side by side, one profile each, started with `cordial --profile P1 --play`: [`docs/partydeck.md`](docs/partydeck.md). **NVIDIA graphics** have not been tested on NVIDIA hardware. What is known from people running the same engine, what Cordial does about it, and the Flatpak driver-extension trap: [`docs/nvidia.md`](docs/nvidia.md). **Profiles** are picked from the button at the left of the header bar. Its menu also holds New Profile… and Delete Profile…, which removes the shown one, its keyring sign-in included, after a confirmation. **Frame rate limit**, under Settings → Graphics, holds the engine's own frame cap at 90 to 480 fps in a running game; Display refresh (the default) follows your monitor's rate above 60 Hz. Any FastFlag you set now also stays set across Roblox's two-minute settings refresh. Details: [`docs/fastflags.md`](docs/fastflags.md). **Separate data roots** per instance come from `XDG_DATA_HOME`, which moves both the profile root and the client's data directory. `CORDIAL_PROFILE_ROOT` moves only the profile root and not the client. **Plugins** install from a `.tar.zst` archive through **Settings → Plugins → Install from a file** and unpack to `~/.local/share/cordial/plugins//`. They run as separate processes on Deno with named capabilities, default-deny, granted per profile in `plugin-grants.json`. Four ship with Cordial; only FPS Flex starts switched off. Installing, updating, removing, enabling, disabling or granting one reaches an already-running client within a second or two, no restart needed. [`docs/plugins.md`](docs/plugins.md), [`docs/adr/ADR-007-host-resources-are-brokered.md`](docs/adr/ADR-007-host-resources-are-brokered.md), [`docs/adr/ADR-038-plugin-hot-swap.md`](docs/adr/ADR-038-plugin-hot-swap.md). Runtime knobs — monitor, resolution, DPI scale, frame pacing, pointer lock, controller glyphs — are environment variables listed in [`docs/install.md`](docs/install.md). ## What Cordial is not **Not affiliated with Roblox Corporation**, not endorsed by it, and not approved by it. Roblox does not support third-party clients and bans accounts for using them, in waves, including false positives. If your account matters to you, do not use it here. **Does not ship Roblox's client.** You supply the Android build. **Not a cheat, exploit or mod injector.** There is no script execution, no hooking and no memory access into the Roblox process — absent from the API rather than disabled, so there is no primitive to re-enable in a fork ([`docs/adr/ADR-001-in-process-hooking.md`](docs/adr/ADR-001-in-process-hooking.md), [`docs/adr/ADR-003-plugin-isolation.md`](docs/adr/ADR-003-plugin-isolation.md)). Requests for it are declined. Plugins extend Cordial, not Roblox. Also permanently out of scope: client-side integrity flags, watermarks, and obfuscation-as-security. ## AI disclosure Implementation leans heavily on Claude Code. Architecture decisions, including the ones that were reversed, are written down in [`docs/adr/`](docs/adr). ## Contributing [`CONTRIBUTING.md`](CONTRIBUTING.md). Bugs and feature requests go on [GitHub](https://github.com/luohoa97/cordial/issues/new/choose), not Discord — every template needs a Diagnostics block from the main menu's **Report a Problem** or `cordial --diagnostics`, and the bug templates want its **Save logs…** archive attached. Security issues go through [a private advisory](https://github.com/luohoa97/cordial/security/advisories/new). Questions and help: [Discord](https://discord.gg/qJzU3Xfr9b). ## Licence GPL-3.0-or-later. See [`LICENSE`](LICENSE). The one exception is [`crates/cordial-protocol`](crates/cordial-protocol), the wire protocol other launchers and runtimes implement, which is `MIT OR Apache-2.0`. Third-party components keep their own licences, reproduced in [`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md): `third_party/libbadcpu` (MIT, from Sober OSS), `third_party/mocktail-webview` (Apache-2.0, from mocktail), `mcpelauncher-linker` (MIT), AOSP bionic (Apache-2.0 and BSD), `libjnivm` (MIT). **Sober** is why anyone believes a Roblox client can run natively on Linux. Its public issue tracker is a research corpus here ([`docs/adr/ADR-017-sober-issue-corpus.md`](docs/adr/ADR-017-sober-issue-corpus.md)) and watching it run corrected a claim made here about text input. Sober's code was never read; it is not source-available. **mocktail** is Apache-2.0 and settled more here than a line in a list conveys: the web-view policy is derived from it, the permission bridge follows its discovery pattern, the Settings performance tables are adapted from its own, and it established the field order of Roblox's `NativeTextBoxInfo` along with several flag values. Each is credited at the point of use.