Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Recipe: Native two-kart driving on a Steam Deck
- Recipe by Seth Robinson
- Tested on an original LCD Steam Deck
- Build a native Linux free-driving app for two Mario Kart Live: Home Circuit karts,
- with simultaneous cameras, pairing and controller setup. This describes a working
- private prototype. Give this recipe to your AI, have it inspect the public projects
- below, then implement each milestone. Keep a build log and pin working revisions.
- 1. Start from the existing interoperability work.
- OpenKart SDK [1], by Sam Edwards (CFSworks) and contributors, supplies the kart
- communication and pairing foundation. mk-live [2], by xmrius, supplies a Linux/
- Steam Deck implementation, browser cockpit, deployment work and a useful camera
- transport parser. Study its video_worker.py; the two video paths are not
- interchangeable. Follow upstream setup documentation, including patched hostapd
- [3], and preserve MIT/BSD notices when adapting code. Obtain dependencies from
- their projects. This recipe supplies no private code, firmware, authentication
- material or pairing data. Switchbrew [4] provides protocol background.
- 2. Prove one kart works before building the interface.
- Start with one charged kart, Ethernet development access and the Deck's built-in
- controls. Inspect the actual Wi-Fi chipset, driver and AP-mode support. Testing
- used an original LCD Steam Deck and its built-in RTL8822CE Wi-Fi. The OLED model
- has different wireless hardware and has not been tested with this setup; other
- models and adapters also need separate testing. Establish pairing and continuously
- changing video with the upstream stack. Make Wi-Fi a temporary kart access point:
- ordinary networking stays the boot default, returns on exit, and has a
- crash-recovery command. Develop over Ethernet. If association succeeds but
- networking stalls, investigate DHCP. Our setup needed DHCP replies delivered by
- Ethernet unicast with an IPv4 broadcast destination; ordinary alternatives failed.
- 3. Separate the native interface from the protocol service.
- Use C++20, SDL2, SDL_ttf, FFmpeg/libavcodec and libqrencode for the window, input,
- video decoding, text and QR display. Retain an OpenKart-derived Python service
- for kart communication and radio management. Replace the browser frontend with
- a private local Unix socket carrying bounded status messages, compressed H.264
- frames and control commands. Run the UI without root; isolate privileged network
- operations. Porting that service to C++ is not a proven latency improvement. Sample input
- independently of video, send controls around 30 Hz, and give each kart its own
- stream state and input deadline.
- 4. Make the first video feed correct, then add the second.
- Keep transport reassembly, decoding and display scheduling separate. Start from
- mk-live's parser, validate payload boundaries, and retain startup frames so setup
- does not lose the initial keyframe. Decode H.264 directly. A rising frame counter
- does not prove the picture is changing: test movement, corruption and missing
- keyframes. Add the second kart with its own assembler, decoder and bounded
- presentation queue. Decode reference frames promptly; optionally
- delay display by 0, 33 or 67 ms, defaulting to 33 ms, to smooth bursts. Never
- buffer driving commands. Reset/recover only the affected camera, keep decoders
- alive across menus, and do not restart the Wi-Fi access point for video pacing.
- Recovery may still wait for a keyframe; do not promise firmware will produce one.
- 5. Make controller ownership explicit and persistent.
- Use analog steering, trigger throttle/reverse and a full-throttle button. Support
- separate gamepads, Deck plus an external pad, and an optional duel mode
- where one controller's sticks drive different karts. Offer steering-only or
- steering-plus-throttle sticks and separate acceleration/reverse buttons. In
- Controllers, let Start assign the pressed pad to the selected kart, replacing its
- old owner; show model names and distinguish identical pads.
- Steam Input can hide physical names behind virtual gamepads; SDL's Steam support
- [5] is a useful reference. Save mode, assignments, swaps and stick options using
- available stable identity, not temporary SDL instance IDs. Ambiguous matches need
- explicit reassignment. Require neutral controls after reconnect or reassignment.
- From Drive, Start on any pad, including an unassigned Deck, opens the menu. Menus/focus
- loss stop both karts; disconnects, stale input or IPC loss must stop affected
- driving. One-player full screen must park the hidden kart.
- 6. Pairing and status should describe what actually happened.
- Offer a large, high-contrast QR with an intact quiet zone. Immediately distinguish
- scanning, joining, saved/reconnecting and connected. Persist successful pairing
- before reconnection; an offline kart should not require another scan. Explicit
- replacement forgets only the selected kart. Preserve the shared main-network
- identity. Battery telemetry reports four bars, not precise percentages: use
- segmented graphics and distinguish unknown/stale readings from empty.
- 7. Package, diagnose and test incrementally.
- Use CMake/Ninja and optionally a container toolchain; keep large builds on the
- Deck's data partition. Add the native app to Steam with its Gamepad layout and
- verify analog input in Gaming Mode. Offer side-by-side, stacked and one-player
- views. Optional local diagnostics should provide app-framebuffer screenshots,
- per-kart counters, bounded traces and graceful quit/restart through a private
- socket. Default them off and allow build-time removal. Use virtual pads and
- moving-video fixtures before supervised kart tests. Check saved settings,
- hotplug, neutral rearming and independent inputs.
- What was actually verified
- Both karts paired and ran together; Deck duel, camera layouts and Deck plus Xbox
- driving worked. Deck plus a USB-wired Xbox worked well in the physical test.
- Two Bluetooth Xbox controllers assigned correctly, but play quality was poor;
- other Bluetooth tests showed substantial camera loss on this setup. Start with
- wired controls when diagnosing camera problems. Do not infer transport from
- Steam's virtual USB devices. Reconnection can take time. Broad adapter support,
- every disconnect/recovery combination and measured camera-to-screen latency
- remain unverified. This recipe is a starting point, not a turnkey installer.
- Public sources and credits
- [1] OpenKart SDK: https://github.com/OpenKart-SDK/openkart
- [2] mk-live: https://github.com/xmrius/mk-live
- [3] OpenKart hostapd patches: https://github.com/OpenKart-SDK/hostapd
- Upstream hostapd, Jouni Malinen and contributors: https://w1.fi/hostapd/
- [4] Switchbrew research: https://switchbrew.org/wiki/Mario_Kart_Live:_Home_Circuit
- [5] SDL Steam controller reference: https://github.com/libsdl-org/SDL/blob/SDL2/src/joystick/SDL_steam_virtual_gamepad.c
Advertisement
Add Comment
Please, Sign In to add comment