18 KiB
Molotov: Architecture & Technical Specification
- Project Name: Molotov
- License: GNU General Public License v3.0 or later (GPL-3.0-or-later)
- Target Platform: Linux x86_64 (Wayland & X11)
- Implementation Language: Rust 1.75+
- Specification Date: 2026-09-29
1. Executive Summary & Project Identity
Molotov is an open-source native Roblox runtime and bootstrapper for Linux. Its primary objective is running Roblox with full fidelity—including microphone voice chat, controller support with rumble, IME preedit text input, and zero launch freezes—while maximizing graphics and memory performance on Linux hardware.
Molotov is not a Roblox engine reimplementation, nor does it run inside Wine, an Android emulator, a virtual machine, or a container. Instead, Molotov runs Roblox's unmodified Android x86_64 dynamic library (libroblox.so) directly within a native Linux host process. It provides the necessary Android Bionic ELF loading environment, JNI virtual machine, and Bridges to native Linux desktop subsystems: PipeWire for low-latency audio, SDL3 for windowing, text input, and gamepads, and Vulkan/OpenGL for rendering.
Integrated into the same binary is a comprehensive bootstrapper with feature parity to Bloxstrap and Froststrap, providing FastFlag profile switching, multi-instance sandboxing, resource modding, and Discord Rich Presence.
2. Non-Negotiable Architectural Constraints
- Strictly No Wine / Proton: Hyperion and anti-cheat mechanisms actively flag or restrict Wine-based Windows emulation. Molotov executes the Android x86_64 binary natively.
- No Faking Success (Fail Fast & Explicitly): Every symbol requested by
libroblox.somust be resolved to one of three categories:cordial: A genuine native implementation of the Android behavior.host: A verified forward to host glibc where ABIs match.stub: An explicit failure returning-ENOSYS,-1, orNULLaccompanied by diagnostic logging.- Rule: Never return a plausible-looking fake 0 or success for unhandled symbols. Faking success masks failures and causes silent memory corruption or unrecoverable freezes down the line.
- Zero Bundled Roblox Code: Molotov distributes no proprietary APKs, binaries, or assets. All Roblox assets and binaries are retrieved directly from official Roblox CDNs on first launch and cryptographically validated against official Roblox signing certificates.
- Voice Chat Precision (Zero Persistent Mic Indicators): Desktop Linux environments (GNOME, KDE) display a privacy indicator whenever a PipeWire capture stream exists. Molotov must only allocate and connect a PipeWire capture stream during active transmission (
AAudioStream_requestStart) and destroy the stream node immediately uponrequestPause,requestStop, orclose. - Open Source & Auditable: Distributed under GPL-3.0-or-later to guarantee freedom, community verification, and architectural transparency.
3. System Architecture & Workspace Structure
Molotov is implemented as a Cargo workspace with a single multicall binary entry point:
molotov/
├── Cargo.toml # Workspace manifest
├── crates/
│ ├── molotov-core/ # Bionic ELF linker, JNI VM, Audio/Graphics/Input bridges
│ ├── molotov-bootstrap/ # CDN client, APK parser, signature verifier, mods, bwrap
│ ├── molotov-gui/ # egui desktop interface
│ └── molotov-cli/ # Command-line interface & headless orchestration
├── src/
│ └── main.rs # Multicall dispatcher (GUI vs CLI subcommands)
├── packaging/
│ ├── flatpak/ # io.github.molotov.Molotov.yaml
│ ├── appimage/ # AppImage packaging recipes
│ └── aur/ # Arch User Repository PKGBUILDs
├── docs/
│ ├── status.md # Real-time subsystem status & known bugs
│ ├── comparison.md # Objective feature matrix (Sober, Mocktail, Cordial)
│ └── building.md # Distribution build instructions
└── tests/
└── ci_audio_loopback.rs # Automated 440 Hz PipeWire audio loopback test
Component Roles & Boundaries
molotov-core:- Direct dependencies:
libc,ash/vulkano,sdl3,pipewire,jni,tracing. - Encapsulates memory management (
mmap), dynamic symbol tables, TLS initialization, synthetic JavaVM/JNIEnv tables, AAudio C-ABI callbacks, and SDL3 event translation.
- Direct dependencies:
molotov-bootstrap:- Direct dependencies:
reqwest,sha2,zip,x509-parser,rbx-dom,serde,serde_json,nix. - Manages version queries, signature parsing, APK package extraction, FastFlag profile persistence, asset overlay generation, and
bwrapcontainerization.
- Direct dependencies:
molotov-gui:- Direct dependencies:
egui,eframe,molotov-bootstrap,molotov-core. - Provides the user-facing settings dashboard, launch controls, and diagnostics panel.
- Direct dependencies:
molotov-cli:- Direct dependencies:
clap,molotov-bootstrap,molotov-core. - Provides headless scripting, FastFlag modification, and version maintenance subcommands.
- Direct dependencies:
molotov(root binary):- Reads invocation arguments. If arguments are passed (e.g.
molotov launch <place_id>), routes tomolotov-cli; if launched without arguments or via.desktop, initializesmolotov-gui.
- Reads invocation arguments. If arguments are passed (e.g.
4. Bootstrapper & Ingestion Pipeline
4.1 Version Discovery & Retrieval
- Query: Hits Roblox Client Settings endpoint (
https://clientsettings.roblox.com/v2/client-version/Android) to fetch the current version GUID and build timestamp. - Comparison: Compares the remote version against local cache in
~/.local/share/molotov/versions/. If an update is required or on initial install, prompts the user (or executes automatically in CLI mode). - Atomic Download: Streams the official Android x86_64 APK directly from the official CDN into
~/.cache/molotov/downloads/<version_guid>.apk.partwith real-time SHA-256 calculation, renaming to.apkupon completion.
4.2 Cryptographic Verification
- Parses APK Zip structures to inspect
META-INF/signatures:- Verifies JAR signing (
.RSA/.DSAcertificates) and APK Signature Scheme v2/v3 blocks. - Validates the DER-encoded public key and X.509 certificate against Roblox Corporation's known SHA-256 fingerprint:
Roblox Android Certificate Fingerprint:1c:00:81:4e:66:35:b0:b3:f1:ff:37:37:3e:38:29:b9:28:90:54:e5:cf:51:65:70:e4:65:fc:e0:bc:95:68:5b
- If the signature fails verification, the downloaded archive is discarded and execution is aborted.
- Verifies JAR signing (
4.3 Targeted Extraction & In-Memory Modding
- Extraction: Unpacks only necessary binaries and data into
~/.local/share/molotov/versions/<version_guid>/:lib/x86_64/libroblox.so- Engine assets from
assets/
- Non-Destructive Mod Overlay:
- User mods (custom death sound
ouch.ogg, cursors, fonts) are placed in~/.config/molotov/mods/. - The base APK and extracted files are never modified on disk.
- Asset loading in
molotov-coreinterceptsAAssetManager_opencalls: if a path matches a user-supplied mod, the runtime redirects to the custom file path in~/.config/molotov/mods/.
- User mods (custom death sound
4.4 Multi-Instance Isolation (bwrap)
To run multiple independent Roblox accounts concurrently:
- Molotov launches independent game instances inside
bubblewrap(bwrap) sandboxes. - Each instance receives:
- A dedicated
XDG_DATA_HOME(~/.local/share/molotov/instances/<id>/data) - A dedicated
XDG_CONFIG_HOME(~/.local/share/molotov/instances/<id>/config) - Read-only bind mounts for the system libraries and base Roblox version folder.
- Dedicated IPC and network sockets to ensure separate authentication cookies and process states without mutual interference.
- A dedicated
5. FastFlag Engine & Performance Optimizations
5.1 Configuration & Profiles
- FastFlags are stored in standard JSON format:
- Master configuration:
~/.config/molotov/fflags.json - Named profiles:
~/.config/molotov/profiles/<name>.json
- Master configuration:
- Employs
rbx-domto parse, serialize, and validate Roblox FastFlag structures. - FastFlag types supported:
FFlag,FInt,FString,DFInt,DFFlag,DFString. - Enforces the official Roblox FastFlag allowlist: flags outside the allowlist trigger an amber warning in the UI/CLI.
5.2 Performance-Specific Features
- VRAM Optimization (NVIDIA Driver Stability):
- Sober and other loaders frequently crash with GL/VK Out Of Memory errors under proprietary NVIDIA drivers.
- Molotov exposes prominent toggles and default profiles enabling:
FIntDebugTextureManagerSkipMips = 1(or2for low-VRAM GPUs)DFIntTextureCompositorActiveJobs = 2
- Frame Pacing & Uncapped FPS:
- Does not enforce FIFO / V-Sync pinning.
- Exposes
DFIntTaskSchedulerTargetFpsto allow setting custom limits (e.g. 144, 240, uncapped). - Configures the SDL3 display presentation mode to
MailboxorImmediate.
- Process Scheduling Priority:
- Sets Linux CPU priority (
nice -5) vialibc::setpriority. - Sets I/O priority via
ioprio_set(Best-Effort priority 2) to prevent frame hitching during asset streaming.
- Sets Linux CPU priority (
5.3 Startup Watchdog & "Safe Mode" Auto-Recovery
- Tracks startup health via
~/.local/state/molotov/launch_state.json. - If a launch freezes or terminates prior to the first rendered frame within a 15-second window:
- A consecutive failure counter increments.
- Upon 2 consecutive failures, Molotov automatically triggers Safe Mode:
- Disables all custom FastFlags and mod overlays.
- Boots with the minimal validated default flag configuration.
- Prompts the user with diagnostic logs and an option to reset conflicting flags.
6. Core Runtime: Bionic Linker & JNI VM
6.1 Custom Bionic Linker (molotov-core)
Roblox’s libroblox.so is compiled against Android Bionic libc. Molotov implements a custom in-memory ELF loader:
- ELF Parsing & Memory Layout:
- Reads ELF64 headers and iterates over
PT_LOADsegments. - Maps segments using
mmapwithMAP_PRIVATE | MAP_ANONYMOUS. - Sets initial protections (
PROT_READ | PROT_WRITE) during relocation patching, then applies final segment protections (PROT_READ | PROT_EXEC).
- Reads ELF64 headers and iterates over
- Dynamic Relocations:
- Traverses
DT_RELA,DT_REL, andDT_JMPRELsections. - Implements relocation types:
R_X86_64_RELATIVE: Base address slide.R_X86_64_GLOB_DAT: Global symbol resolution.R_X86_64_JUMP_SLOT: PLT function pointer resolution.R_X86_64_64: 64-bit absolute address fixup.
- Traverses
- Thread-Local Storage (TLS):
- Allocates dedicated Bionic TLS blocks according to Android x86_64 TLS memory conventions, preserving the host glibc TCB on the calling thread.
6.2 Strict Symbol Resolution Triage Table
Every imported symbol requested by libroblox.so is resolved via a strict three-tier lookup:
| Tier | Category | Description | Examples | Failure Behavior |
|---|---|---|---|---|
| Tier 1 | cordial |
Native Android reimplementation | __android_log_print, AAssetManager_*, ANativeWindow_*, AAudioStreamBuilder_* |
Handled internally by Molotov bridges |
| Tier 2 | host |
Direct forward to host glibc | malloc, free, memcpy, memmove, sin, cos, epoll_*, pthread_mutex_* |
Host ABI execution |
| Tier 3 | stub |
Unimplemented / unneeded symbol | Obsolete telemetry, unsupported proprietary services | Returns -ENOSYS, -1, or NULL. Never returns fake 0/success. |
Logging Requirement: Every unresolved symbol encountered at runtime emits a tracing::warn! record with the symbol name and caller return address.
6.3 JNI VM & Android Activity Lifecycle
- Synthetic JNI Tables:
- Implements
JavaVMandJNIEnvfunction pointer tables conforming to the standard JNI specification. - Intercepts
FindClass,GetMethodID,GetStaticMethodID,Call*Method, andNewStringUTF.
- Implements
- Emulated Android Framework Classes:
android.content.Context: Returns paths for package files, cache directories, and asset manager references.android.os.Build: Supplies an x86_64 Android 13/14 device profile (ro.build.version.sdk = 33,ro.product.cpu.abi = x86_64).com.roblox.client.*: Handles application lifecycle notifications and session token handoffs.
- Initialization Flow:
- Calls
JNI_OnLoad(JavaVM*, void*)inlibroblox.so. - Resolves and executes
ANativeActivity_onCreate. - Registers native callbacks:
onNativeWindowCreated,onNativeWindowResized,onInputQueueCreated,onNativeWindowDestroyed.
- Calls
7. Hardware & I/O Bridges
7.1 Voice Chat: AAudio → PipeWire
- The Problem: On modern Linux desktop environments, active PipeWire capture streams keep the desktop microphone icon illuminated, causing privacy concern and confusion. Cordial lacked voice chat entirely; other implementations maintain open streams continuously.
- The Solution: Dynamic Ephemeral Capture:
AAudioStreamBuilder_openStreamwithAAUDIO_DIRECTION_INPUT: Prepares internal audio buffers and parameters, but does not create or connect a PipeWire capture node.AAudioStream_requestStart: Initializes a PipeWire stream (PW_DIRECTION_INPUT) connected to the default audio source (SPA_AUDIO_FORMAT_F32_LE, 48000 Hz).AAudioStream_requestPause/requestStop/close: Immediately tears down and destroys the PipeWire stream node. The desktop mic indicator turns off instantaneously.
- Playback Pipeline:
AAUDIO_DIRECTION_OUTPUTconnects to a PipeWire playback stream with a lock-free ring buffer ensuring latency under 15ms.
- Automated CI Audio Verification Test:
- Included in
tests/ci_audio_loopback.rs:- Generates a 440 Hz pure sine wave into a PipeWire virtual sink.
- Captures the signal through Molotov's AAudio capture pipeline.
- Computes an FFT frequency spectrum.
- Asserts peak detection at 440 Hz ± 1 Hz with ≥ 95% waveform correlation.
- Included in
7.2 Text Input & IME Preedit
- SDL3 Text Input API:
- Hooks game text focus events to
SDL_StartTextInput()andSDL_StopTextInput(). - Monitors
SDL_EVENT_TEXT_INPUTfor confirmed UTF-8 characters.
- Hooks game text focus events to
- IME Support (fcitx5, ibus, Wayland text-input-v3):
- Listens for
SDL_EVENT_TEXT_EDITINGto capture in-progress preedit composition strings. - Dynamically repositions the candidate popup window using
SDL_SetTextInputArea()matching the in-game text cursor coordinates. - Transmits preedit and commit strings to the engine via synthetic Android
InputConnectionevents.
- Listens for
7.3 Gamepad & Force Feedback (Rumble)
- SDL3 Gamepad API:
- Detects Xbox, PlayStation (DualShock 4 / DualSense), Switch Pro, and standard HID controllers.
- Translates SDL axis and button inputs to Android
InputDevicemotion and key events. - Fixes glyph rendering by reporting accurate physical button layouts to the engine.
- Haptic Rumble:
- Intercepts Android
Vibrator.vibrate(VibrationEffect)JNI calls. - Dispatches dual-motor low/high frequency vibration using
SDL_RumbleGamepad(gamepad, low_freq, high_freq, duration_ms). - Supports trigger rumble via
SDL_RumbleGamepadTriggerson supported hardware.
- Intercepts Android
7.4 Rendering & Display Bridge
- Creates an SDL3 window with Vulkan backing (
SDL_WINDOW_VULKAN). - Wraps the native window handle in an
ANativeWindowC structure. - Directs swapchain buffers into the engine's Vulkan/OpenGL presentation queue.
8. Graphical Interface (molotov-gui)
Built with egui for minimal overhead and zero C toolkit dependencies.
Tab Navigation
- Play: Launch Roblox, version status indicator, Safe Mode toggle, one-click update button.
- FastFlags: Profile manager (
Default,Low VRAM,Competitive,Custom), searchable FastFlag table with allowlist validation indicators, and manual flag entry. - Mods: Mod management cards with file drop targets for
ouch.oggdeath sound, custom cursor packs, and custom TTF/OTF fonts. - Audio & Voice: Input microphone selector, volume sliders, and interactive "Test Voice Chat Loopback" button with live waveform visualizer.
- Multi-Instance: Instance switcher, status monitor, and one-click instance launcher.
- Maintenance & Logs: Cache and stale version cleaner, Discord RPC settings toggle, and real-time log viewer filtering
[CORDIAL],[HOST], and[STUB]events.
9. Packaging & Distribution Plan
- Flatpak:
- Target Flathub distribution:
io.github.molotov.Molotov. - Runtime:
org.freedesktop.Platform//24.08. - Permissions:
--socket=wayland,--socket=fallback-x11,--device=dri,--socket=pipewire,--filesystem=xdg-data/molotov:create.
- Target Flathub distribution:
- AppImage:
- Self-contained binary bundle created via
cargo-appimageorlinuxdeploy.
- Self-contained binary bundle created via
- Arch Linux (AUR):
molotov: Release builds from source tarballs.molotov-git: Development builds trackingmain.
- Debian/Ubuntu & Fedora:
- Pre-built
.deb(viacargo-deb) and.rpm(viacargo-generate-rpm).
- Pre-built
10. Documentation & Open Source Transparency
docs/status.md: Living documentation modeled after Cordial, listing exact subsystem status:- Bionic Linker (Relocations, TLS)
- JNI VM (Emulated classes, callbacks)
- Audio (Playback, Ephemeral capture)
- Graphics (Vulkan, EGL)
- Input (IME preedit, Gamepad rumble)
- Known issues with linked issue tracker IDs.
docs/comparison.md: Honest, objective comparison matrix against Sober, Mocktail, and Cordial detailing voice chat, IME behavior, Wine-independence, and areas where Molotov is still evolving.docs/building.md: Comprehensive build guide detailing required host libraries (libpipewire-0.3-dev,libsdl3-dev,libvulkan-dev) and compilation commands for Fedora, Arch, and Ubuntu.
11. Acceptance Criteria ("Definition of Done")
A user on Fedora, Arch, or Ubuntu with GNOME/KDE, PipeWire audio, and an NVIDIA/AMD/Intel GPU can:
- Install and launch Molotov.
- Automatically fetch and cryptographically verify the official Roblox Android x86_64 build on first run.
- Sign in to Roblox and join an experience.
- Enable Voice Chat: desktop microphone indicator lights up only while actively transmitting and turns off immediately when paused/stopped.
- Play with a controller and experience force feedback / rumble.
- Chat in-game using an IME (e.g. fcitx5) with working preedit composition.
- Experience smooth frame pacing without startup freezes or VRAM exhaustion crashes.