Update 3.0.5 focuses on reducing input latency, improving connection stability, and optimizing core performance. This release overhauls the P2P networking stack, rewrites the analog stick math for better precision, and introduces an Input Resiliency Engine to prevent dropped inputs on unstable connections. It also brings friends into the fold — a full Friends system with live online presence and one-click private P2P invites — and rewires native capture into a genuinely zero-copy GPU-direct pipeline.
Changes & Improvements
Core & Performance
- Background P2P Swarm Discovery: Replaced the legacy BitTorrent tracking backend with a redundant MQTT broker network. P2P sessions now connect in the background during setup, hiding the previous 15-second handshake latency.
- SCTP Input Prioritization: Fixed an issue where WebCodecs video frames could starve the network connection. The UDP video data channel is now explicitly down-prioritized so that gamepad inputs are transmitted first.
- WebCodecs Engine Pipeline: WebCodecs is now the primary decoding pipeline. This replaces standard WebRTC browser jitter buffers to offer lower latency hardware rendering.
- WebGL Zero-Copy Uploads: Applied performance tweaks to the WebGL shader pipeline, forcing the browser to bypass CPU color profiling and alpha-premultiplication for zero-copy hardware texture uploads.
- OBS Egress Pipeline: Removed the legacy browser-based WebRTC OBS capture system. The "OBS Target" button now spawns a native, frameless Electron pop-out window using raw memory pointers to pipe the hardware video stream directly to your screen.
- Input Only Mode: Added an "Input Only" mode for users broadcasting gameplay externally (e.g., Discord/OBS). It bypasses screen capture, sending a lightweight 5fps static placeholder to save upload bandwidth.
- Extreme Low Bandwidth Transcoding: Added
540p (Balanced),360p,240p, and144poptions to the Max Resolution selector. Re-wrote the scaling engine to dynamically calculate and enforce scaled dimensions directly into the hardwareVideoEncoderconfiguration and thescaleResolutionDownByparameter. - Aggressive Frame Queuing: Hardcoded a zero-frame queue threshold (
encodeQueueSize > 0) in the WebCodecs encoder loop to force immediate frame drops if busy, ensuring the stream is always synchronized with the absolute latest frame. - Desynchronized Rendering: Added
desynchronized: trueto the Viewer's Canvas contexts (both WebGL and 2D) to bypass VSync compositing delays. - Dynamic Host Latency Equalization: Elevated the "Host Delay Equalization" feature to a prominent toggle switch. The logic was rewritten to dynamically factor in video buffer bloat, adjusting the host's input buffer based on how long it takes to encode and transmit frames rather than relying purely on network ping.
- Windows Host Equalization: Expanded the Host Delay feature to fully support Windows. It reads physical controllers directly via XInput and routes delayed inputs through a virtual
vgamepaddevice.
Input Resiliency & Accuracy
- True Circular Deadzones: Rewrote the Viewer's analog stick math. Sticks now use a True Circular (Radial) Deadzone algorithm, eliminating "plus-shaped" crosshair snapping and providing better diagonal aiming precision.
- Historical Redundancy: Gamepad packets now carry compressed historical frames. If a UDP packet drops, the host reconstructs the timeline from the redundancy data to reduce missed button presses.
- Confidence Decay: If your internet stalls while holding an analog stick, the server now mathematically decays the stick back to center instead of letting your character run off-screen.
- Tournament Mode Kill-Switch: Resiliency buffering features are now hardcoded to automatically disable when Tournament Mode is active to ensure 0-buffer raw polling for fighting games.
- Frame-Synced Haptics: Implemented WebRTC Encoded Transforms to embed rumble metadata directly into the raw video frames, syncing rumble to the exact millisecond a frame is rendered.
- Analog Sensitivity Slider: Added a multiplier slider in the input settings menu to adjust the raw sensitivity of joystick inputs. Default sensitivity bumped to 1.50 for a snappier response.
- Input Stabilization Loop: Replaced the legacy
setIntervalgamepad polling engine in the Viewer with a synchronizedrequestAnimationFrameloop to eliminate input transmission jitter.
Friends & Social
- Friends List: The dashboard now sports a dedicated Friends panel where you can add players by their unique Friend ID, see who's online right now, and manage your roster with rename, copy-ID, and remove actions. Adding yourself is rejected outright so your roster stays meaningfully yours.
- Live Friend Presence: Friends announce their presence through lightweight pings, letting the dashboard show green online / red offline indicators and how long ago a friend was last seen — even across different servers. Pings stay in-memory and only write to disk when the roster actually changes, so presence never thrashes the server.
- Private Friend Invites: A new "Invite" button on all Host layouts spins up a private P2P session and sends your friend a room code directly, complete with accept/dismiss invitation cards and a fast room-join path.
- Semi-Offline Safety: Friend pings are stored safely server-side, and the roster, display names, and online windows survive both host and viewer page reloads.
- Enable Friends Banner: The friends panel is tucked behind a new settings toggle; when disabled, a dashed "Enable Friends" banner keeps one-click re-enabling one click away.
Capture & Performance
- GPU-Direct Capture (DRM/KMS): The former "Zero-Copy Video Capture" setting is now a real, honest capture-backend switch. Enabled, it forces native DRM/KMS capture — reading frames straight from the display controller with DMA-BUF readback and skipping the compositor entirely. Disabled, it keeps the standard capture ladder.
- Zero-Copy Frame Transport: The DRM capture worker was rebuilt as a worker thread that hands frames to the main process via transferred ArrayBuffers — zero copies, zero files. The previous per-frame
/tmpfile round-trip is gone, cutting disk I/O and syscalls from every single frame. - Honest Toggle Labeling: The dashboard toggle is now titled "GPU-Direct Capture (DRM/KMS)" with a description that says exactly what it does — no more claims of frames living entirely on the GPU.
- Paste-Your-Token Flow: zrok tunnels without an enabled token now ask for it when you actually hit start — a dedicated popup with a paste field, a "Skip" escape hatch, and clear install instructions restored to the tunnel setup panel.
- zrok2 Native Detection: Authentication detection now understands zrok v2's
Account Tokenstatus format alongside classic v0.x, so pre-authenticated setups no longer get pestered with a token prompt they already satisfied.
Viewer UI & Extensions
- WebGL Upscaling: Implemented a new zero-latency Single-Pass WebGL spatial upscaler. Options include Standard, Crisp (Sharp Bilinear), Pixel Perfect (Nearest Neighbor), and a 4-Tap Fast Bicubic (FSR-Lite) shader.
- Custom Viewer Keybinds: Added an interactive "Keyboard Binds" editor in the Viewer's Advanced Settings. Players can remap keyboard inputs dynamically and apply presets.
- Platform Identity: Game engines and web hosts can now detect Nearcade natively through the injected
Nearcade/<VERSION>User-Agent string on the host client. - Host Voice Integration: The Host can now see their own voice activity on the preview screen alongside viewers, and the Viewer's voice chat panel now properly incorporates the Host.
- Voice Chat Overlay Expansion: The persistent Host Voice Activity Overlay has been unified and deployed across all host layouts.
- Safe Session Exits: The "Leave Session" action now cleanly redirects viewers to the homepage origin instead of a blank page.
- Viewer UI Redesign: Replaced the dark gray aesthetic on the Viewer page with a custom Light Teal "Nord" theme.
- Display Tweaks Modal Polish: Eliminated faint clipping bars on the Display Tweaks popup and dynamically synchronized the modal's accent color with the viewer's chosen chat theme.
- Visual Keyboard Fixes: Expanded the Keyboard Bindings modal width to prevent layout squishing, correctly routed the
keyMapdata, and updated the unmapped actions list to accurately display mappable keyboard events. - Dark Mode Toggle: Added a "Dark Mode" toggle switch to the Advanced Settings modal. This preference syncs seamlessly with the Tampermonkey persist script.
- Dynamic Reload Protection: Intercepting
Ctrl+RandF5on the Host UI now informs the user what type of session they are terminating rather than throwing a generic Arcade warning. - Co-op Launcher Formatting: Fixed unclosed tags and improved CSS styling in the Co-op Launcher HTML file.
- Codec Benchmark Layout: Fixed a visual bug where the codec benchmark's tabular log data would vertically squish and wrap on narrow screens.
- Cleaned Up Host Control Rail: Restored original SVG icons to the host UI and removed redundant/accidental buttons to streamline the interface.
State Persistence
- Global Mic Kill Persistence: The Host's "Mute All Viewer Mics" toggle is now saved locally (
ns_master_mute). It persists through Host UI reloads to prevent unexpected voice-chat outbursts. - PIN Configuration Saving: Hardened authentication loops in the Node server to natively save and restore the
pinEnabledtoggle andlastPinacross server reboots. - Handshake Sync: Updated
/api/infoendpoints to exposepinEnabledstates to ensure the Host UI correctly matches the server's backend configuration upon a page reload. - Voice Preference Persistence: Viewer-side voice chat configurations are now persistently saved across sessions.
- Host Configuration Isolation: Stripped
electronAPIleakage from the Viewer client. Viewer preferences are now strictly sandboxed to browser local storage, guaranteeing they will never pollute the Host's globalnearcade.config.jsonfile. - Electron Boot V-Sync: Electron hardware acceleration overrides and V-Sync disabling flags are now properly tied to the user's saved
vsyncOffconfiguration.
Brand Unification & System Changes
- Nearcade Renaming: Purged legacy
nearsecreferences across system processes and repositories.nearsec-routerCargo project renamed tonearcade-router.- Removed
nearsec-router.serviceand replaced withnearcade-router.service. - Udev rules renamed to
99-nearcade-input.rules. - TURN usernames renamed to
nearcade.
- Caddyfile Streamlining: Removed hardcoded static file rewrites in the Caddy config, shifting static asset delivery natively back to the Node Express server.
- Version Bump: Updated
package.jsonand Cargo projects to version 3.0.5.
Bug Fixes
- Bug Fix #1 Linux VR Auto-Launch | Fixed a bug on Linux where loading the web lobby would aggressively wake up SteamVR. The WebXR subsystem is now only queried when explicitly requested by clicking the VR button.
- Bug Fix #2 P2P WebRTC Rescue | Fixed a crash where navigating to a viewer session via a
p2p://URL failed due to the browser attempting to runfetch()on a non-HTTP scheme. - Bug Fix #3 WebCodecs Buffer Bloat | Implemented
bufferedAmountchecks on all streaming pipelines to drop stale frames and request keyframes if the network backs up, preventing permanent latency degradation. - Bug Fix #4 Anti-Spoofing Arcade Rules | Activating "Input Only Mode" now transmits a flagged payload to the Cloudflare Worker to reject the session with a 403 Forbidden error, preventing source code tampering on public listings.
- Bug Fix #5 VPS Reconnect Loop | Fixed a race condition in the host client where manually tearing down a VPS socket would trigger a ghost
onclosereconnect timer, causing a connection loop. - Bug Fix #6 Ghost File Cleanup | Deleted 7 legacy and unused prototype files from
src/scriptsto keep the production bundle clean. - Bug Fix #7 Electron Bounds Safety | Added min/max checks to window dimensions during boot to prevent Electron from crashing if invalid coordinate data was passed.
- Bug Fix #8 Safe Object Disposal | Wrapped
peerConnection.close()calls intry/catchblocks during session destruction to prevent unhandled WebRTC errors from halting the script. - Bug Fix #9 WebRTC Offer Parameters | Enforced
{ offerToReceiveAudio: true, offerToReceiveVideo: false }explicitly during WebRTC renegotiation. - Bug Fix #10 Turn Server Authentication | Transitioned Community TURN server setups in
setup_turn.shfrom the deprecateduse-auth-secretto standard long-term credentials to improve WebRTC reliability. - Bug Fix #11 VPS Router Synchronization | The Rust VPS router now broadcasts
{"type":"host-connected"}to all standby viewers the moment the host successfully authenticates. - Bug Fix #12 VPS Hot-Swapping | Fixed a strict connection bug in the Rust VPS router where a micro-drop would prevent the host from reconnecting.
- Bug Fix #13 HIDMaestro Driver Update | Updated the internal HIDMaestro submodule to v1.3.22, leveraging the latest native virtual gamepad improvements and crash safety patches.
- Bug Fix #14 AppImage Sandbox Compatibility | Implemented a dynamic kernel-flag detection system on Linux to automatically inject the
--no-sandboxflag only when running in restricted environments. - Bug Fix #15 VPS Deployment Stability | Replaced basic backgrounding in
deploy.shwithnohupexecution, ensuring the Node.js server and Rust SFU router persist reliably after SSH sessions are disconnected. - Bug Fix #16 Markdown Chat & Safety | Re-wrote the chat DOM insertion logic to natively support Discord-style Markdown while safely escaping raw HTML to prevent XSS. Also fixed a crash where pressing
ArrowDownin an empty chat box renderedundefined. - Bug Fix #17 Codec Benchmark Accuracy | Resolved a browser performance quirk by temporarily mounting the dummy video element to the DOM during testing.
- Bug Fix #18 VAD Focus Stealing Fix | Fixed a bug where the Host's Voice Activity Detection engine would steal OS window/mouse focus away from the active game due to misfiring placeholder audio hooks.
- Bug Fix #19 Firefox Session Recording | Fixed a silent failure in Firefox where session recording would result in a 0-byte file by hooking directly into the DOM rendering layer via
mozCaptureStream(). - Bug Fix #20 Community TURN Hostname | The default metered.ca community relay pointed at a dead NXDOMAIN hostname (
openrelayproject.metered.ca); it now resolves to the liveopenrelay.metered.caendpoint. - Bug Fix #21 Misleading TURN Status Dot | The dead-by-design default community TURN listing no longer shows a red status dot, since that relay cannot pass live allocation probes — its listing is now dot-free while every other community server keeps real probing.
- Bug Fix #22 zrok Phantom Token Prompts |
zrok statusoutput was misread as unauthenticated whenever it lacked the classic v0.xContactline; detection now also recognizes v2'sAccount Tokenrow, so the token popup only appears when it's genuinely needed.