Rubylight Download 2.2.10
On this page
  1. Start streaming
  2. Build
  3. Run and migration
  4. Implementation
  5. Validation
  6. Profiles and features
  7. Updates

Rubylight developer guide #

Documentation · Build guide · Architecture · API · Release notes

The Windows host, protocol implementation, native helpers, service and setup are written in Rust. The browser console is Svelte. The Rust executables do not link the previous C++ host; codec libraries, GPU SDKs and Windows drivers are external dependencies.

The workspace version is 2.2.10. This guide covers development and isolated validation. For what Rubylight does, see Features; for measurements, PERFORMANCE.md.

Start streaming #

Use Getting started for installation, migration, pairing and client selection. Configuration covers capture, HDR, virtual displays, RTSS and updates; Troubleshooting covers symptoms and support reports.

Build #

The Cargo workspace is at the repository root. Build from a Windows x64 checkout with the pinned toolchain in rust-toolchain.toml and the SDK environment described in the build guide.

rustup toolchain install 1.98.1-x86_64-pc-windows-gnu --profile minimal --component rustfmt --component clippy
rustup target add x86_64-pc-windows-msvc --toolchain 1.98.1-x86_64-pc-windows-gnu

.\rust\build.ps1 -FetchDependencies -Package

Run in a Visual Studio x64 developer PowerShell for TrueHDR, or pass -MsvcSdk for a compatible xwin SDK layout. -SkipTrueHdr omits that optional NVIDIA DLL. Existing dependency roots can be supplied with -FfmpegRoot, -PyrowaveRoot and -NvidiaRoot.

The build script checks formatting, tests and lints, then builds and packages the runtime, helpers, performance probes, console, notices and SHA-256 manifest. PyroWave uses a pinned SDK identity and matching patches. CMake builds the external PyroWave SDK; Cargo builds the host. rust-windows.yml defines the Windows CI path.

Use release builds for stream-performance work. The build guide documents dependencies, output paths and packaging options.

Run and migration #

Run a packaged host against an explicitly selected development profile:

.\butterpollo.exe --config-dir C:\tests\butterpollo-profile --port 48123 --bind 127.0.0.1

This isolated base port uses web 48124, HTTPS 48118 and RTSP 48144. Standard Moonlight UDP offsets remain compatible. Initial administrator setup requires a local connection.

Mode Default profile Service
Portable / direct host Existing config folder beside the executable (2.2.6 or later); otherwise %LOCALAPPDATA%\ButterpolloRust\config Optional
Installed package %PROGRAMDATA%\Butterpollo\config ApolloService for migration compatibility

Without arguments, the host listens on all IPv4 interfaces with the console at https://localhost:47990. address_family=both enables dual-stack listeners; bind_address or --bind selects an interface. Running or building the host does not install a service. service.ps1 manages a portable service installation and refuses to alter one belonging to another executable.

Import into an empty destination without starting a host:

.\butterpollo.exe --config-dir C:\tests\new-profile --import-config C:\path\to\old\config

Import copies identity, settings, state, app IDs, permissions, certificates and covers into owned paths. Unknown fields survive. Game paths and preparation commands keep their existing meaning. Missing configured identity files, links/junctions or excessive profile sizes abort the import before the new profile is committed. The launcher refuses to overwrite a nonempty profile. State writes are atomic.

Keep development profiles and ports distinct from the installed service. See multiple instances for profile precedence, copied packages and multiseat launch requirements. Tests under rust/tests use isolated profiles and stop their own processes.

Implementation #

Workspace member Responsibility
core Moonlight protocol, crypto, FEC, input parsing, audio mixing, permissions and state.
windows Capture, GPU conversion, native codecs, audio, input, displays, limiter integration, tray and SCM.
host HTTP/TLS, administration, RTSP, ENet control, UDP transport and stream lifecycle.
setup Installation, upgrade and recovery.
vulkan-layer Implicit Vulkan HDR layer for owned sessions.
truehdr-runtime Separately built Rust MSVC DLL calling NVIDIA's NGX C ABI.

The Svelte console is packaged with the host; server-rendered pages remain a fallback. The architecture guide explains compute queues, producer/output fences, service-mode WGC, HDR and PyroWave.

Useful implementation entry points:

PyroWave shares D3D11/Vulkan planar textures and returns only the encoded bitstream to the CPU. Native NVENC uses the installed driver, with D3D11 4:2:0/8-bit 4:4:4 and CUDA interop for ten-bit 4:4:4; nvenc_legacy selects the FFmpeg compatibility path. Quick Sync imports D3D11 frames.

Validation #

The ordinary checks (formatting, Clippy with warnings denied, workspace tests) and the SDK environment they need are listed in the contributor guide. CI runs them through build.ps1 on every push to main and on pull requests that change the Rust tree. The layers beyond them:

Validation layer Entry points and scope
Ordinary tests Wire parsing, encryption/replay, FEC, input, state, migration, ownership and recovery policy.
Administration and browser web_api.py, console_browser.cjs, session_restart.py, otp_pairing.py.
Independent standard-codec streams interop.py, moonlight_client.c: real pairing, encrypted RTSP, transport/FEC, FFmpeg and Opus decode.
Independent PyroWave streams build-pyrowave-client.ps1, moonlight_client.c, pyrowave_transport.py.
Native GPU, driver and display tests Explicitly selected ignored tests; requirements and commands in Running the native checks.
Performance and pixel accuracy Release probes and fixtures indexed in PERFORMANCE.md.

Native fixtures may require an active moving desktop, codec DLLs, compatible drivers and particular hardware. Display-changing fixtures record restoration separately. Follow each fixture's prerequisites and run them in a suitable idle test session.

Running the native checks #

cargo test --workspace --locked
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test -p butterpollo-windows --locked -- --ignored --skip native_nvenc_loss_recovery_and_444_hdr_decode --skip native_av1_geometry_and_hdr_are_preserved --skip primary_multitouch_and_secondary_isolation_match_native_hid_reports --skip two_announced_touchpads_share_one_native_surface_side_by_side --test-threads=1 --nocapture

The native command needs the packaged codec DLLs on PATH, an AMD D3D11/AMF adapter, working interactive WGC, a moving desktop and a local network route; it does not change display modes, audio defaults or the installed service. motion_probe DISPLAY SECONDS REPORT.json current 128 can provide movement on an explicitly selected active output without changing its mode. Set BUTTERPOLLO_TEST_OPUS_ROOT to the packaged runtime directory, BUTTERPOLLO_TEST_FFMPEG to an independent FFmpeg decoder and BUTTERPOLLO_TEST_RFI_REPORT to a report file.

The separately selected primary_multitouch_and_secondary_isolation_match_native_hid_reports and two_announced_touchpads_share_one_native_surface_side_by_side tests require the signed VHF driver and an idle input session. They create and remove owned neutral DS4/DualSense devices; they are excluded from the codec command above.

On an NVIDIA host with a display attached to that adapter:

$env:BUTTERPOLLO_TEST_NVENC = '1'
$env:BUTTERPOLLO_TEST_NVENC_REPORT = 'C:\path\to\artifacts\nvenc.json'
$env:BUTTERPOLLO_TEST_FFMPEG = 'C:\path\to\ffmpeg.exe'
cargo test -p butterpollo-windows --locked native_nvenc_loss_recovery_and_444_hdr_decode -- --ignored --test-threads=1 --nocapture

tests/web_api.py, tests/console_browser.cjs, tests/session_restart.py, tests/interop.py and tests/otp_pairing.py run against isolated test-owned profiles and stop only their own processes.

Profiles and features #

The Rust host imports the Vibepollo/Apollo profile format and implements the Windows feature set listed in Features. Application overrides take precedence over client overrides; display recovery restores host-owned changes that the user has not subsequently altered.

The earlier C++ host, its CMake build and installer were removed after 2.0.0-rc.23; that tag and its archived references keep them for migration research. The released Rust package is built through build.ps1.

An optional Moonlight 6.2.0 source patch addresses cold-cache CSV artwork shutdown. Its focused Qt validation is recorded separately from the official Windows client's streaming checks.

Updates #

Configuration describes the notify-first controls and idle-install policy. The updater requires the installed service, verifies the official GitHub installer's advertised size and SHA-256 digest, then waits for one minute without active/pending streams, remote monitors or host apps. Install now skips that wait and runs setup with --end-streams; automatic updates always wait.

Setup backs up replaced package files, verifies that the requested host version starts and restores those files on copying or startup failure. A failed version is not retried automatically; the console offers a manual retry. Recovery records stay under the service profile's updates directory.

The installer is unsigned. Its digest check over HTTPS is an integrity check against the official release, distinct from an Authenticode signature. Portable hosts use release-page downloads. Release notes and the release's validation record describe package provenance.

View this page on GitHub