This repository has been archived on 2026-10-10. You can view files and clone it, but cannot push or open issues or pull requests.
molotov/docs/superpowers/specs/2026-09-29-molotov-architecture-design.md

18 KiB
Raw Blame History

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

  1. 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.
  2. No Faking Success (Fail Fast & Explicitly): Every symbol requested by libroblox.so must 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, or NULL accompanied 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.
  3. 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.
  4. 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 upon requestPause, requestStop, or close.
  5. 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.
  • 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 bwrap containerization.
  • molotov-gui:
    • Direct dependencies: egui, eframe, molotov-bootstrap, molotov-core.
    • Provides the user-facing settings dashboard, launch controls, and diagnostics panel.
  • molotov-cli:
    • Direct dependencies: clap, molotov-bootstrap, molotov-core.
    • Provides headless scripting, FastFlag modification, and version maintenance subcommands.
  • molotov (root binary):
    • Reads invocation arguments. If arguments are passed (e.g. molotov launch <place_id>), routes to molotov-cli; if launched without arguments or via .desktop, initializes molotov-gui.

4. Bootstrapper & Ingestion Pipeline

4.1 Version Discovery & Retrieval

  1. Query: Hits Roblox Client Settings endpoint (https://clientsettings.roblox.com/v2/client-version/Android) to fetch the current version GUID and build timestamp.
  2. 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).
  3. Atomic Download: Streams the official Android x86_64 APK directly from the official CDN into ~/.cache/molotov/downloads/<version_guid>.apk.part with real-time SHA-256 calculation, renaming to .apk upon completion.

4.2 Cryptographic Verification

  • Parses APK Zip structures to inspect META-INF/ signatures:
    • Verifies JAR signing (.RSA/.DSA certificates) 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.

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-core intercepts AAssetManager_open calls: if a path matches a user-supplied mod, the runtime redirects to the custom file path in ~/.config/molotov/mods/.

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.

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
  • Employs rbx-dom to 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

  1. 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 (or 2 for low-VRAM GPUs)
      • DFIntTextureCompositorActiveJobs = 2
  2. Frame Pacing & Uncapped FPS:
    • Does not enforce FIFO / V-Sync pinning.
    • Exposes DFIntTaskSchedulerTargetFps to allow setting custom limits (e.g. 144, 240, uncapped).
    • Configures the SDL3 display presentation mode to Mailbox or Immediate.
  3. Process Scheduling Priority:
    • Sets Linux CPU priority (nice -5) via libc::setpriority.
    • Sets I/O priority via ioprio_set (Best-Effort priority 2) to prevent frame hitching during asset streaming.

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:

  1. ELF Parsing & Memory Layout:
    • Reads ELF64 headers and iterates over PT_LOAD segments.
    • Maps segments using mmap with MAP_PRIVATE | MAP_ANONYMOUS.
    • Sets initial protections (PROT_READ | PROT_WRITE) during relocation patching, then applies final segment protections (PROT_READ | PROT_EXEC).
  2. Dynamic Relocations:
    • Traverses DT_RELA, DT_REL, and DT_JMPREL sections.
    • 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.
  3. 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 JavaVM and JNIEnv function pointer tables conforming to the standard JNI specification.
    • Intercepts FindClass, GetMethodID, GetStaticMethodID, Call*Method, and NewStringUTF.
  • 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:
    1. Calls JNI_OnLoad(JavaVM*, void*) in libroblox.so.
    2. Resolves and executes ANativeActivity_onCreate.
    3. Registers native callbacks: onNativeWindowCreated, onNativeWindowResized, onInputQueueCreated, onNativeWindowDestroyed.

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_openStream with AAUDIO_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_OUTPUT connects 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.

7.2 Text Input & IME Preedit

  • SDL3 Text Input API:
    • Hooks game text focus events to SDL_StartTextInput() and SDL_StopTextInput().
    • Monitors SDL_EVENT_TEXT_INPUT for confirmed UTF-8 characters.
  • IME Support (fcitx5, ibus, Wayland text-input-v3):
    • Listens for SDL_EVENT_TEXT_EDITING to 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 InputConnection events.

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 InputDevice motion 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_RumbleGamepadTriggers on supported hardware.

7.4 Rendering & Display Bridge

  • Creates an SDL3 window with Vulkan backing (SDL_WINDOW_VULKAN).
  • Wraps the native window handle in an ANativeWindow C 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

  1. Play: Launch Roblox, version status indicator, Safe Mode toggle, one-click update button.
  2. FastFlags: Profile manager (Default, Low VRAM, Competitive, Custom), searchable FastFlag table with allowlist validation indicators, and manual flag entry.
  3. Mods: Mod management cards with file drop targets for ouch.ogg death sound, custom cursor packs, and custom TTF/OTF fonts.
  4. Audio & Voice: Input microphone selector, volume sliders, and interactive "Test Voice Chat Loopback" button with live waveform visualizer.
  5. Multi-Instance: Instance switcher, status monitor, and one-click instance launcher.
  6. 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

  1. 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.
  2. AppImage:
    • Self-contained binary bundle created via cargo-appimage or linuxdeploy.
  3. Arch Linux (AUR):
    • molotov: Release builds from source tarballs.
    • molotov-git: Development builds tracking main.
  4. Debian/Ubuntu & Fedora:
    • Pre-built .deb (via cargo-deb) and .rpm (via cargo-generate-rpm).

10. Documentation & Open Source Transparency

  1. 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.
  2. 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.
  3. 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:

  1. Install and launch Molotov.
  2. Automatically fetch and cryptographically verify the official Roblox Android x86_64 build on first run.
  3. Sign in to Roblox and join an experience.
  4. Enable Voice Chat: desktop microphone indicator lights up only while actively transmitting and turns off immediately when paused/stopped.
  5. Play with a controller and experience force feedback / rumble.
  6. Chat in-game using an IME (e.g. fcitx5) with working preedit composition.
  7. Experience smooth frame pacing without startup freezes or VRAM exhaustion crashes.