Skip to main content

joystream

Turn a phone into a gamepad using the iPhone app or a browser. Linux uses a single-file Python server and /dev/uinput; macOS uses a standalone Swift server. Both serve HTTP and WebSockets on port 8000.

Embed in Python

pip install . installs the receiver with only websockets. It serves the same browser page and accepts the iPhone app directly, without a system gamepad, Swift server, or HID entitlement:

from joystream_input import Receiver

with Receiver(port=8000) as pad:
    # Inside your application's existing loop:
    state = pad.read()  # nonblocking; e.g. state.lx, state.a

state.connected means input is fresh; silence/disconnect returns neutral after at most 0.5 seconds. Applications decide how to handle lost input. See polling and cfclient adapter examples. For a pip-installed Linux system gamepad, use pip install '.[linux]'.

Setup and run

On Linux, install dependencies and load uinput:

sudo apt install python3-websockets python3-evdev  # or: pip install -r requirements.txt
sudo modprobe uinput

Your user needs write access to /dev/uinput. If it belongs to the input group, use sudo usermod -aG input "$USER", then log out and back in. On macOS, complete the signing and Accessibility setup first.

python3 joystream.py                     # Linux
./macos/run.sh                           # macOS
# Custom address: --host ADDRESS --port PORT (macOS: ./macos/run.sh run ...)

Open the printed http:// address on the phone, or enter it in the iPhone app. Both devices must be reachable over Wi-Fi or Tailscale; allow incoming/local network connections when prompted. Keep the http:// prefix in browser URLs.

Play

Hold the phone in landscape. Touch and drag on either half to position its stick; buttons work simultaneously. Safari's Add to Home Screen gives a fullscreen client. Keep Auto-Lock off when playing in the browser; the native app keeps the screen awake. Tap the app's status label to change servers.

One phone controls the gamepad at a time; a new connection replaces the old one. Disconnects or 0.5 seconds of silence release controls. The device persists across client reconnects. Verify input with evtest on Linux or xcrun swift macos/verify.swift on macOS.

Protocol and development

Send full JSON snapshots to /ws, including a heartbeat every 100 ms:

{"lx":0,"ly":-0.5,"rx":0,"ry":0,"a":1,"b":0,"x":0,"y":0,"l1":0,"r1":0,"select":0,"start":0}

Axes range from −1 to 1, with Y positive downward; buttons are 0/1. Missing fields mean neutral. Edit index.html for browser controls, joystream.py for Linux mappings, or macos/Reports.swift for macOS reports. See the platform READMEs for build and test commands.

Metadata

Release files for joystream 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for joystream 0.0.2
File Size Uploaded
joystream-0.0.2.tar.gz 12.1 kB Details

Release files / joystream-0.0.2.tar.gz

Download URL joystream-0.0.2.tar.gz
Size 12.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9d5bf50edebe5f410d7daa31f409ef69a33f53d87694d2f9cf56928797d679e9
BLAKE2b-256 checksum
How to use checksums
6b9233d38b35bae3b2a96eff331f7b5acd14535f19bf0215e074197e89909d1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

0.0.2 This release

1 release file

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page