← Future Forge
How-to Friends room

Multiplayer · remote friends

Multiplayer over the Internet
with Tailscale Funnel.

Invite remote friends to a Future Forge friends room without them installing anything. Only you (the host) need Tailscale; friends open a normal browser URL.

This path is for a session on a machine you control (laptop/desktop). For a long-lived public server, prefer a VPS/PaaS deploy instead — see the Future Forge README.

What you get

Host runs the game. Friends click a link.

Who Needs
Host (you) Future Forge (npm start), Tailscale, Funnel enabled on your tailnet
Friends A browser and the HTTPS link you send them — no Tailscale, no install

Future Forge already serves the UI, REST APIs, and friends WebSocket (/ws/rooms) from one Node process (default port 8765). Funnel publishes that process to the public Internet over HTTPS while Funnel is on.

Funnel vs Serve

Do not mix these up

Mode Who can open the game Friends install Tailscale?
tailscale funnel Anyone with the public HTTPS URL No — this is what you want for remote friends
tailscale serve Only devices on your tailnet Yes — private mesh only

Use Funnel for “friends just click a link.” Use Serve only if everyone is already on your tailnet and you want zero public exposure.

Before you start

Prerequisites

  1. Node.js 18+ and the Future Forge repo installed (npm install).
  2. Tailscale installed and logged in on the host machine (Download Tailscale). Check: tailscale status shows this device Online.
  3. Funnel allowed on your tailnet (one-time admin setting). If Funnel is disabled, the CLI will error until you enable it in the Tailscale admin console (Funnel / HTTPS features for your tailnet). Personal plans usually allow this; org policies may not.
  4. Optional for full AI co-inventor / vision: SuperGrok session (grok login) or XAI_API_KEY on the host. Without either, the game still runs with the local co-inventor fallback.

Copy-paste

Session setup

Use two terminals on the host. Leave both open for the whole game.

1 Start Future Forge

cd /path/to/future-forge   # the game repo
npm start

You should see something like:

Future Forge → http://127.0.0.1:8765 (bound 0.0.0.0)
Friends rooms: ON · WS /ws/rooms

Default port is 8765. Override with PORT if needed (then point Funnel at the same port).

Local smoke check:

curl -sS http://127.0.0.1:8765/api/health

Expect JSON with "rooms": true when friends multiplayer is enabled.

2 Open a public Funnel URL

Foreground (recommended for a one-off game night — Ctrl+C turns the public URL off):

tailscale funnel 8765

Background (if you want the terminal free):

tailscale funnel --bg 8765
tailscale funnel status

Funnel prints a public HTTPS URL, typically:

https://<your-machine-name>.<tailnet-name>.ts.net

Example shape (yours will differ):

https://my-laptop.example-tailnet.ts.net

Use exactly the URL Funnel prints. Everyone — including you — should open that URL, not only http://127.0.0.1:8765, so the browser and WebSocket share the same origin and HTTPS/wss: setup.

3 Create a room and invite friends

On the host:

  1. Open the Funnel HTTPS URL in a browser.
  2. Play with friends → Create room (pick a display name).
  3. Note the 6-character room code.
  4. Send friends both: the Funnel HTTPS URL, and the room code.

Friends:

  1. Open the same HTTPS URL (any browser, any network).
  2. Play with friends → Join.
  3. Enter the room code and a display name.

They do not install Tailscale.

Room codes only locate a room. Seat auth is the player/host token stored in the browser after join. Treat the Funnel URL as semi-secret (see Security).

4 When the session ends

Stop the game (Ctrl+C in the npm start terminal).

Turn Funnel off:

# If funnel was foreground: Ctrl+C in that terminal is enough.

# If you used --bg, or to clear any leftover config:
tailscale funnel reset

Confirm:

tailscale funnel status

You want no active Funnel config (public link dead).

Short form

Checklist

  • npm start → game on 8765
  • tailscale funnel 8765 → copy the https://….ts.net URL
  • Host opens Funnel URL → Create room → copy code
  • Friends open same URL → Join with code
  • After play: Ctrl+C game + funnel reset

Stay safe

Security

Funnel is public Internet access to your machine’s Future Forge process for as long as Funnel is running.

Point Detail
Who can load the site Anyone who has (or guesses/finds) the Funnel URL
Room codes Short locators — not strong passwords
No site login wall Future Forge does not require an account to open the UI or try joining
API keys Stay on the server only; never put XAI_API_KEY in the browser or git. Friends can still spend your AI quota while using your host’s co-inventor/vision
Home network You do not need to open router ports or expose your home WAN IP; Funnel uses Tailscale’s public path
When finished Always tailscale funnel reset (or Ctrl+C foreground Funnel) so the public URL dies

Practical habits:

  • Share the URL + code in a private chat, not a public post.
  • Prefer foreground Funnel so the public path stops when the terminal closes.
  • Kick unwanted players in the lobby before the quest starts (if host kick is enabled).
  • Do not leave Funnel up overnight “just in case.”

License: Free Personal Use is private hobby self-host on infrastructure you control — not offering Future Forge as a product/service for third parties. Friends co-op as a personal hobby is the intended free case; schools, companies, and multi-tenant hosting need a paid license. See LICENSE.md and COMMERCIAL.md on GitHub.

When it breaks

Troubleshooting

Symptom What to try
funnel errors / “not enabled” Enable Funnel for your tailnet in the Tailscale admin console; re-run tailscale funnel 8765
Page won’t load for friends Funnel still running? tailscale funnel status. Game still running? Share the HTTPS Funnel URL, not a LAN 192.168.x.x address
Host works on localhost, friends do not Host must use the same Funnel URL as friends when creating the room (same origin for assets + /ws/rooms)
Join fails / rooms missing GET /api/health should show "rooms": true. Ensure ENABLE_ROOMS is not set to 0
Live sync freezes after join Confirm everyone is on https://… (WebSocket upgrades to wss://). Mixed http/https or different hosts break the client
Wrong port If you set PORT=9000, run tailscale funnel 9000 (must match)
Stale public URL tailscale funnel reset, then start Funnel again

Host-only debug:

tailscale status
tailscale funnel status
curl -sS http://127.0.0.1:8765/api/health
# After Funnel is up, also try the printed https URL + /api/health from your machine

Optional

Variants

Background Funnel

tailscale funnel --bg 8765
# … play …
tailscale funnel reset

Custom listen port

PORT=9000 npm start
# other terminal:
tailscale funnel 9000

Private only (everyone on Tailscale)

If friends will install Tailscale and join your tailnet, prefer Serve (no public Internet):

npm start
tailscale serve 8765
# share the Serve / MagicDNS URL only with tailnet members

That is a different security model (private mesh). It is not “friends need nothing.”

Ready for game night?

Get Future Forge, then open a Funnel

Install the game, start a session, and send friends one HTTPS link plus a room code. Part of Warmer Sun — the missing subject.