Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Contributing to the AnyPlay Network

Issues and pull requests from anyone are welcome here. The rules that hold in every AnyPlay repository (how to contribute, the line the project keeps, and no game data) are in the [organisation's CONTRIBUTING.md](https://github.com/anyplaynet/.github/blob/main/CONTRIBUTING.md), and the [Code of Conduct](https://github.com/anyplaynet/.github/blob/main/CODE_OF_CONDUCT.md) applies. This file adds what is specific to this repository.
Issues and pull requests from anyone are welcome here. This repository and the [launcher](https://github.com/anyplaynet/launcher) are open; the cloud, the website, the AnyPS5 fork and the organisation's `.github` repository take contributions from the team only until 25 April 2027. The rules that hold in every AnyPlay repository (how to contribute, the line the project keeps, and no game data) are in the [organisation's CONTRIBUTING.md](https://github.com/anyplaynet/.github/blob/main/CONTRIBUTING.md), and the [Code of Conduct](https://github.com/anyplaynet/.github/blob/main/CODE_OF_CONDUCT.md) applies. This file adds what is specific to this repository.

## Before you start

Expand All @@ -12,7 +12,7 @@ Issues and pull requests from anyone are welcome here. The rules that hold in ev

## Build and test

You need Rust 1.91 or newer. These are the commands CI runs on Windows and on Linux. A pull request needs all of them green:
You need Rust 1.91 or newer. These are the commands CI runs on Windows, Linux and macOS. A pull request needs all of them green:

```sh
cargo fmt --all -- --check
Expand Down Expand Up @@ -52,7 +52,7 @@ Never attach or link game dumps, keys, firmware, saves, platform or publisher to

- One topic per pull request, small commits, English commit messages, and a description that says what changed and why.
- Fill in the pull request template.
- A pull request needs one review and green CI. CI also checks the links in the Markdown files, the licences of dependencies and security advisories.
- A pull request needs one review and green CI. The first run of a first-time contributor waits for a maintainer's approval. CI also checks the links in the Markdown files, the licences of dependencies and security advisories.
- Dependencies must suit both licences below. `cargo-deny` checks this with `deny.toml`.

## Licence
Expand Down
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@ It reports whether the tunnel went direct or through a relay, the round trip, lo

| Path | What it is |
|---|---|
| `crates/net` | `anyplay-net`, the net service on each player's PC: account, cloud connection, bridge server, tunnels, voice and screen sharing |
| `crates/net` | `anyplay-net`, the net service on each player's PC: account, cloud connection, bridge server, tunnels, voice, screen sharing and share play |
| `crates/bridge-protocol` | the messages between the bridge and the net service |
| `crates/control` | the messages between the launcher and the net service |
| `crates/api` | the cloud's API, shared by the net service and the [cloud](https://github.com/anyplaynet/cloud) |
| `crates/voice` | `anyplay-voice`, the party voice engine |
| `crates/proof` | `anyplay-proof`, device keys, proofs of possession and PKCE for the cloud API |
| `crates/fake-game` | `anyplay-fake-game`, a game's side of the bridge, for tests and for trying the network without a game |
| `crates/share`, `crates/share-worker` | the share-screen media path, and the worker program that captures, encodes and shows the picture |
| `crates/share`, `crates/share-worker` | the media path for share screen and share play, and the worker program that captures, encodes and shows the picture, records clips and broadcasts |
| `crates/discord` | an optional Discord Social SDK seam, off by default ([ADR 0022](docs/adr/0022-discord-social-sdk.md)) |
| `crates/probe` | `anyplay-probe`, which measures a tunnel |
| `spec/` | the network's own specifications: [bridge protocol](spec/bridge-protocol.md), [control protocol](spec/control-protocol.md), [cloud API](spec/cloud-api.md), [portal API](spec/portal-api.md), [web API groups](spec/web-api/README.md) and more |
Expand All @@ -67,14 +68,15 @@ The network without games is live at anyplaynet.com, and the launcher uses it.
|---|---|
| Accounts, friends, presence, messages, notifications | Done and live. |
| Parties with voice and push to talk | Done and live. |
| Share screen to a party | Done. Game sound is Windows only. |
| Broadcast to Twitch, YouTube or RTMP | Done on Windows, with the game's sound; `rtmp://` and `rtmps://`. |
| Join links, Find Players, captures and clips sent to friends | Done. |
| Bridge: sign-in, identity, NAT type, web API forwarding, push events, online-permission check, peer-to-peer datagrams and streams | Merged in the fork. The end-to-end CI that runs the bridge against the net service is in review. |
| Share screen to a party | Done for the streamer on Windows, Linux and macOS. Game sound comes from Windows and macOS. A Mac cannot watch yet. |
| Broadcast to Twitch, YouTube or RTMP | Done on Windows, Linux and macOS; `rtmp://` and `rtmps://`. The game's sound is sent from Windows; elsewhere the track is silence. |
| Clips (the last seconds of a game, saved on the PC) | Done on Windows, Linux (GPU encode through NVENC or VA-API) and macOS. |
| Join links, Find Players, played with recently, captures and clips sent to friends | Done. |
| Bridge: sign-in, identity, NAT type, web API forwarding, push events, online-permission check, peer-to-peer datagrams and streams | Merged in the fork, speaking bridge protocol 1: the bridge and the net service prove the game start's token to each other with an HMAC challenge, and protocol 0 is no longer spoken ([ADR 0039](docs/adr/0039-the-bridge-proves-the-token-instead-of-sending-it.md)). The end-to-end CI that runs the bridge against the net service is in review. |
| Web API groups answered for games | `userProfile` and `communicationRestrictionStatus`. Every other group is refused and logged. |
| A first game played together over the internet | Not yet. This is phase 4 of the [roadmap](docs/DESIGN.md#roadmap). |
| Measuring tunnels between two real networks | Waiting for a second network (phase 0). |
| Share play (taking over a friend's pad) | Designed, not built. |
| Share play (taking over a friend's pad) | Built in the net service, the cloud and the worker, and tested with fakes. The engine side (frame ring, guest pad, a second user) is in review in the fork. The launcher keeps it hidden and the public cloud keeps it off until a legal review. |
| Several cloud nodes | Not built. The cloud runs as one node. |

[docs/gaps.md](docs/gaps.md) lists what each part still lacks.
Expand All @@ -91,13 +93,13 @@ cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
```

Every pull request runs these on Windows and Linux. The parsers are fuzzed every night ([fuzz/](fuzz/README.md)). Start with the [design](docs/DESIGN.md); the words are in [CONTEXT.md](CONTEXT.md). Issues and pull requests are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md). The rules shared by every AnyPlay repository are in the [organisation's CONTRIBUTING.md](https://github.com/anyplaynet/.github/blob/main/CONTRIBUTING.md).
Every pull request runs these on Windows, Linux and macOS. The parsers are fuzzed every night ([fuzz/](fuzz/README.md)). Start with the [design](docs/DESIGN.md); the words are in [CONTEXT.md](CONTEXT.md). Issues and pull requests are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md). The rules shared by every AnyPlay repository are in the [organisation's CONTRIBUTING.md](https://github.com/anyplaynet/.github/blob/main/CONTRIBUTING.md).

### macOS

`cargo build --release --locked -p anyplay-net --features devices` builds a native service with CoreAudio microphone and speaker support. CI builds and tests it on macOS as well as Windows and Linux. The launcher embeds the matching binary at build time with `ANYPLAY_NET_EMBED` and starts it over standard input/output with an explicit per-user data folder.

Run standalone with `--data <folder>` or use its default under `~/Library/Application Support/AnyPlay/net`. Sign-ins use the macOS Keychain when available; `--file-credentials` is intended for isolated tests. Microphone access belongs to the launcher app's privacy prompt. Share-screen capture and Discord's optional SDK are separate platform integrations; this does not add them or a game engine bridge.
Run standalone with `--data <folder>` or use its default under `~/Library/Application Support/AnyPlay/net`. Sign-ins use the macOS Keychain when available; `--file-credentials` is intended for isolated tests. Microphone access belongs to the launcher app's privacy prompt. On a Mac the share worker captures with ScreenCaptureKit and encodes with VideoToolbox ([ADR 0036](docs/adr/0036-macos-captures-with-screencapturekit-and-encodes-with-videotoolbox.md)), for share screen, clips and broadcast, and needs the Screen Recording permission. Discord's optional SDK is a separate integration, and there is no game engine bridge for macOS.

## Community

Expand Down
12 changes: 6 additions & 6 deletions docs/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ These hold for every line of code and every public statement. [ADR 0021](adr/002
The bridge is small on purpose. It forwards; it does not translate.

- **Switched on by the launcher.** The launcher sets `ANYPS5_NET_ENDPOINT` (a loopback port) and `ANYPS5_NET_TOKEN` (a secret for one game start). Without them every library behaves as it does today: offline and signed out.
- **One connection** to the net service, speaking the [bridge protocol](../spec/bridge-protocol.md). Request bodies pass through as opaque bytes, so the engine needs no JSON, WebSocket or ICE code.
- **One connection** to the net service, speaking the [bridge protocol](../spec/bridge-protocol.md) (version 1: both sides prove the game start's token with an HMAC challenge instead of sending it, [ADR 0039](adr/0039-the-bridge-proves-the-token-instead-of-sending-it.md)). Request bodies pass through as opaque bytes, so the engine needs no JSON, WebSocket or ICE code.
- **What it forwards:**
- sign-in state and its changes, reachability, the handle and account ID;
- the online-permission check. The target is the network's own rule: signed in and not banned, for play on the AnyPlay network only ([ADR 0021](adr/0021-the-line-is-drawn-at-the-law.md)). The bridge answers it by this rule;
Expand All @@ -50,8 +50,8 @@ A separate process that the launcher starts and watches ([ADR 0004](adr/0004-net
- **Membership follows the party's revision.** Every accepted copy of the party goes to the hub, which closes connections to members who left or changed their key, forgets them in the engine, and dials new ones; a copy with an older revision never gets there. A dial that fails is repeated with a pause of 0.5 s growing to 30 s.
- **Sound devices** sit behind the `devices` feature of `anyplay-net` (cpal). Release builds on Windows and Linux are built with `--features devices`; on Linux that needs the ALSA headers (`libasound2-dev`). Without the feature, which is what `cargo build` and the usual CI jobs use, the service builds and runs and voice answers that this build has no sound devices. A CI job builds and lints the feature on both systems.
- The launcher gets a `voice` event with the state, who is speaking and each link, at most ten a second, and sets push-to-talk, mode, volume, mute and the devices with the commands in the [control protocol](../spec/control-protocol.md). The launcher never sees tunnel keys.
- **Share screen** ([spec](../spec/screen-share.md), [ADR 0023](adr/0023-share-screen-is-watch-only-and-asks-the-cloud-for-nothing.md)). The watch-only part of share play: a player streams their game to the party, whose members choose to watch. A connection with the ALPN `anyplay/screen/0`, dialed by the streamer to each party member, carries share play's datagrams; no cloud state, no `share.enabled`. Built, with game sound on Windows; the share worker also publishes the picture live over RTMP for broadcasts.
- **Share play** ([spec](../spec/share-play.md), [ADR 0019](adr/0019-share-play-streams-through-a-worker.md); designed; built so far: the part that share screen uses, the bridge's `0x05xx` kinds with the frame ring and the guest pad on both sides of the bridge, and the host's pad rules. Not built: the invitation, the cloud's `Share` and the share connection). A third connection on the tunnels' endpoint, with the ALPN `anyplay/share/0`, carries a game's picture and sound to one party member and that member's pad states back. A separate share worker encodes and decodes; the net service checks who connects, validates and rate-limits pad states, and forwards datagrams.
- **Share screen** ([spec](../spec/screen-share.md), [ADR 0023](adr/0023-share-screen-is-watch-only-and-asks-the-cloud-for-nothing.md)). The watch-only part of share play: a player streams their game to the party, whose members choose to watch. A connection with the ALPN `anyplay/screen/0`, dialed by the streamer to each party member, carries share play's datagrams; no cloud state, no `share.enabled`. Built, with game sound on Windows and macOS (the streamer on macOS too, the viewer not yet); the share worker also publishes the picture live over RTMP for broadcasts, and keeps the last seconds of a game for [clips](../spec/clips.md).
- **Share play** ([spec](../spec/share-play.md), [ADR 0019](adr/0019-share-play-streams-through-a-worker.md); built here and tested with fakes: the part that share screen uses, the bridge's `0x05xx` kinds with the frame ring and the guest pad, the host's pad rules, the invitation, the cloud's `Share` and the share connection. Open: the engine side in the fork and the launcher's share window). A third connection on the tunnels' endpoint, with the ALPN `anyplay/share/0`, carries a game's picture and sound to one party member and that member's pad states back. A separate share worker encodes and decodes; the net service checks who connects, validates and rate-limits pad states, and forwards datagrams.
- **Version guard** before every join.

### Cloud ([anyplaynet/cloud](https://github.com/anyplaynet/cloud))
Expand Down Expand Up @@ -111,10 +111,10 @@ A link such as `anyps5://v1/join/…` never starts a game by itself; it opens th
| 5 More | matchmaking, leaderboards, save backups | by choice |
| S1–S6 Social | profiles and trophies, parties and messages, voice, feed and boards, share play, web profiles and sign-in ([SOCIAL.md](SOCIAL.md)) | each phase as SOCIAL.md says |

Where it stands (26 October 2026):
Where it stands (27 October 2026):

- **Phase 1 is done and live.** The cloud runs at anyplaynet.com as one node, and the launcher's online area uses it: accounts, friends, presence, messages, parties, voice and share screen. The social phases S1 to S6 are nearly done: share screen, the watch-only part of S5, is built, and handing a pad to a friend is open.
- **Phase 2 is nearly done.** In the AnyPS5 fork, sign-in, identity, NAT type, web API forwarding, push events, the online-permission check and the frame tests are merged (anyplaynet/AnyPS5#7, #10, #24). The end-to-end CI that runs the bridge against the net service is in review (#9). The net service measures the NAT type from iroh's net report and answers `userProfile` and `communicationRestrictionStatus`.
- **Phase 1 is done and live.** The cloud runs at anyplaynet.com as one node, and the launcher's online area uses it: accounts, friends, presence, messages, parties, voice and share screen. The social phases S1 to S6 are nearly done: share screen, the watch-only part of S5, is live, and share play (handing a pad to a friend) is built in the net service and the cloud but waits for the engine side.
- **Phase 2 is nearly done.** In the AnyPS5 fork, sign-in, identity, NAT type, web API forwarding, push events, the online-permission check and the frame tests are merged (anyplaynet/AnyPS5#7, #10, #24), and so is bridge protocol 1 (#31, network#125). The end-to-end CI that runs the bridge against the net service is in review (#9). The net service measures the NAT type from iroh's net report and answers `userProfile` and `communicationRestrictionStatus`.
- **Phase 3 is mostly done.** The fork carries peer-to-peer datagrams, session signaling and streams (#11, #12); fake games exchange packets through tunnels in CI.
- **Phase 4 is open.** The first game played together over the internet is not there yet. The current target is a game that reaches its title screen.
- **Phase 0 waits.** The probe is ready; a measurement between two real networks needs a second network.
Expand Down
2 changes: 1 addition & 1 deletion docs/SOCIAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ A queue of reports with the reported content attached, actions with a stated rea
| S5 Share play | streaming a game to a friend, taking over a pad | a friend without the game plays a level of it; the [plan](share-play-plan.md) splits it into watch, hand over and play together, each with numbers |
| S6 Web and sign-in | web profiles, passkeys, Apple, Google and Discord sign-in, moderation queue | a public profile opens in a browser; a player signs in with a passkey |

Where it stands (26 October 2026): S1 to S4 and S6 are nearly done and live in the launcher, with parties, voice, messages, the feed and web profiles. Of S5, share screen is built (on Windows with game sound); handing a pad to a friend is not. The numbers in each phase's "done when" are not all measured on real networks yet.
Where it stands (27 October 2026): S1 to S4 and S6 are nearly done and live in the launcher, with parties, voice, messages, the feed and web profiles. Of S5, share screen is built (for the streamer on Windows, Linux and macOS, with game sound on Windows and macOS), and share play is built in the net service and the cloud and tested with fakes; it waits for the engine side and for a launcher window. The numbers in each phase's "done when" are not all measured on real networks yet.

The infrastructure work in [anyplaynet/cloud](https://github.com/anyplaynet/cloud/blob/main/docs/ARCHITECTURE.md) runs beside these phases; every feature here is built for the cluster from its first line.
Loading
Loading