The short version
The website is only a meeting point. When you host, it gives you a code. When a friend types that code, it tells each of you where the other one is. That takes a few seconds. After that your PCs talk straight to each other, and the website never sees your files, scenes or chat.
Host
Website
Friend
Opens a port, asks “what's my internet address?”
Host a session
Code + secret
The host shows the code and checks back every second
Opens a port, asks “what's my internet address?”
Join with the code
Host's address + key
Friend's address + key
Hellos both ways, 5 times a second
“Got it”: connected
From here on it's just your PCs. The website is out of the picture.
1
Getting ready
When you click Host a session or Join, the SDK spends up to 4 seconds on three things at once:
- Opens a port. One UDP port, 47320 unless you change it in the Host or Join window. If that's taken it uses any free one. Every friend in the session uses this same port.
- Asks for your internet address. It asks a STUN server (Google's or Cloudflare's) what your address looks like from outside. That's the address your friends will knock on.
- Asks your router to open the port (UPnP). Lots of routers say no, and that's fine. Step 3 usually gets through anyway.
It also notes your address on your home network, so two people on the same Wi-Fi can connect without going out to the internet and back.
2
The meeting point
Four small pages on reqid.io do the swapping. They're open and free. No account, no access code.
| Page | Who calls it | What it does |
| team-host | Host | Saves the host's name and addresses. Gives back a 6-character code and a secret only the host knows. |
| team-poll | Host, every second | “Anyone joined yet?” Gives back “not yet”, or the friend's name, addresses and the key. |
| team-join | Friend | Checks the code (and password, if there is one). Gives back the host's name, addresses and the key. |
| team-close | Host | Deletes the session when the host ends it. |
Codes, secrets and keys
- The code is 6 characters. Letters and numbers that look alike (0 and O, 1 and I) are left out, and spaces or dashes you type are ignored.
- The secret proves it's really the host checking for friends. The server only keeps a scrambled (hashed) copy.
- The key is a random token made with the session. Both PCs put it in every hello, so they only answer each other.
- The password is optional. The server only keeps a hashed copy and turns away a wrong one.
How long it lasts
- A code lasts 10 minutes after the last check, and 30 minutes at most. The SDK quietly gets a new one when it runs out (see step 6).
- One internet connection can start 12 sessions an hour. 20 wrong codes or passwords locks it out for 10 minutes.
- Old sessions are deleted automatically.
3
Finding each other
Now both PCs know a few addresses for the other one. They each send a tiny hello to all of them, 5 times a second. Most home routers block messages from strangers but allow replies to messages you sent. Since both sides send at the same time, each router sees the other's hello as a reply and lets it in. This is called hole punching.
Addresses tried, in order
- Your home network address, first, if the website saw you both coming from the same internet connection.
- Your internet address from step 1.
- The address the website saw you on, in case step 1 didn't get an answer.
- The home network address, last, for everyone else.
After 2 seconds with no answer it also tries the next 12 ports up, twice a second. Some routers change your port for each new contact, and this catches most of them.
After 15 seconds your friend sees an error and can click Join again. Your session stays open, and the chat says they couldn't get through.
4
The hello
A hello is one small message. Whoever gets a good one answers “got it”, and both sides switch to the real connection.
| In the hello | What it's for |
| code | Which session this is for |
| key | The key from the website, so only your session answers |
| pwd | A hash of the code and password. Never the password itself |
| g | Your editor's ID, the same every time, so a rejoin is recognized |
| n | A random number that changes on every script reload, so old messages are ignored |
| name, s | Your name and open scene, for the Team tab |
| mt, m | Team version (wpfma-team-7) and SDK version (1.15.0) |
What gets checked
- Code and key match (or the password does).
- Same Team version. If not, your friend is told which version each of you has, and the host gets a note in chat. Nobody ends up half-connected.
- Room left. If the host already has 3 friends in, the newcomer is told the session is full.
5
Connected
Each friend now has a direct connection to the host. It runs on its own, so it keeps going while Unity is busy importing.
- Messages are cut into pieces of 1,200 bytes or less, so they fit through VPNs like Tailscale.
- Every piece is confirmed. Anything lost is sent again, in order. Camera positions are the exception: an old one is useless, so they're just sent fresh.
- It speeds up when the line is clear and slows down when pieces start getting lost.
- Big files are compressed when that makes them smaller.
- A tiny check goes out every second. That's where the ping in the Team tab comes from. 12 seconds of silence means the line dropped (see step 7).
6
More friends
A session holds 4 people: the host and 3 friends. Friends only connect to the host. The host passes everything on (edits, files, chat, cameras, selections), so friends never have to get through each other's routers.
- The code keeps working. While there's room, the host keeps checking the website every second. Each new friend goes through steps 2 to 4 the same way.
- One port for everyone. The host's port sorts each incoming message to the right friend.
- Everyone knows who's here. When someone joins or leaves, the host sends everyone the new list of people.
- New code after 30 minutes. When a code runs out, the host gets a new one and shows it. People already in aren't affected.
If two people join in the exact same second, one of them might get “Could not connect”. Just click Join again.
7
Staying connected
None of this goes back through the website. The two PCs send hellos to the last address that worked until they hear each other, then pick up where they left off. Anything not confirmed yet gets sent again.
| What happened | What the SDK does | Others wait |
| Script reload | Tells the others “reloading scripts” (or “entering Play mode”), then reconnects afterwards | 4 min |
| Closed Unity | Tells the others “closed Unity” and saves the session. Opening the project again rejoins by itself | 10 min |
| Crash | Nothing gets sent, but the session is saved every 20 seconds, so reopening still rejoins | 10 min |
| Internet blip | After 12 quiet seconds both sides show “reconnecting” and keep sending hellos | 10 min |
| Someone leaves | A friend leaving: everyone else carries on. The host leaving ends it for everyone | – |
Without the website
For friends on the same network, or on Tailscale (free). In the Host or Join window, pick Same home network or Tailscale instead of Over the internet. The host gets a code, an address and a port, and friends type those in. That skips steps 1 and 2 and goes straight to the hello. The host checks the password, then makes up its own key.
If it won't connect
| You see | Why | Try this |
| Could not connect | A router or firewall blocks it. Common on phone hotspots, school and work networks | Click Join again. If it keeps failing, both get Tailscale and pick Same home network or Tailscale |
| No session with that code | A typo, or the code ran out | Ask the host for the code showing in their Team tab now |
| Wrong password | The password doesn't match | Ask the host. 20 wrong tries locks you out for 10 minutes |
| Different version | You have different SDK versions | Everyone grabs the newest download |
| Session is full | The host already has 3 friends in | Someone leaves, or the host removes someone |
| Can't reach reqid.io | No internet, or the site is down | Connect without the website |
What the server sees
Kept for a few minutes
- The code, and hashed copies of the secret and password
- Your names (32 characters max)
- Your addresses, and the address each of you connected from
- When the session started and when someone joined
- How many sessions and wrong codes came from an address, cleared after an hour
Never sent to it
- Your files, scenes, edits, chat or camera
- Your VRChat login, or anything from VRChat
- Readable passwords. They travel over HTTPS and are stored hashed
The connection is direct, so everyone in a session can see each other's IP address. Only team up with people you trust, or use Tailscale.
All the numbers
| What | Value |
| Port | 47320 (change it in the Host or Join window) |
| Getting ready | 4 seconds max |
| Host checks for friends | Every second |
| Hellos while connecting | Every 0.2 seconds |
| Next-port tries | 12 ports up, after 2 seconds |
| Gives up connecting | 15 seconds |
| Piece size | 1,200 bytes |
| Line check | Every second, dropped after 12 quiet seconds |
| Rejoin window | 10 minutes (4 for a script reload) |
| Crash save | Every 20 seconds |
| People per session | 4 (host + 3) |
| Code lasts | 10 minutes idle, 30 minutes max |
| Sessions per address | 12 an hour |
| Wrong codes before lockout | 20 in 10 minutes |