Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
5515851
[auth][api] accept the 20250424.01 client
djdevin Aug 13, 2026
ec52985
[2025] unstable
djdevin Aug 13, 2026
3edc315
20250718.0
djdevin Aug 14, 2026
7430116
correct one this time
djdevin Aug 14, 2026
dda18b0
stubs
djdevin Aug 14, 2026
8ea0caa
more stubs
djdevin Aug 14, 2026
11b037a
more stubs
djdevin Aug 15, 2026
ba0aec9
[lists] add worker
djdevin Aug 16, 2026
5ef95a9
[ai] route stubs
djdevin Aug 16, 2026
603a005
[api] player photo setting
djdevin Aug 16, 2026
bd94a83
[econ] add roomEconConfig route
djdevin Aug 16, 2026
b92d3ac
[infra] update worker generators
djdevin Aug 17, 2026
76132e2
[worker] add cards/moderation/platformnotification workers
djdevin Aug 17, 2026
765c2aa
[lists] updates to some endpoints
djdevin Aug 17, 2026
0638b80
[clubs] stub out announcement endpoint, for now
djdevin Aug 17, 2026
3307556
[econ] stub out season endpoints for now
djdevin Aug 17, 2026
95252cb
[chat] apps/chat stub out party endpoint not sure the shape yet
djdevin Aug 17, 2026
f1a573a
[api] stub out statsig and lockeditems
djdevin Aug 17, 2026
40b8365
[doc] new services
djdevin Aug 17, 2026
3729c14
[lists] stub the bulk endpoint
djdevin Aug 17, 2026
e3cbe38
[datacollection] add placeholder service until we can kill it
djdevin Aug 17, 2026
d8d97c3
[api] set gifting to lvl5
djdevin Aug 17, 2026
c85ec65
update lock
djdevin Aug 17, 2026
5d032eb
[cdn] enable cache
djdevin Aug 17, 2026
e4d543a
[match] matchmake v2
djdevin Aug 17, 2026
29e9635
[lists] stub some lists
djdevin Aug 18, 2026
ba300ac
[ai] stubs
djdevin Aug 18, 2026
7052858
[rooms] new subroom save endpoint
djdevin Aug 18, 2026
2db1add
[econ] add bulk purchase endpoint
djdevin Aug 18, 2026
bd9439a
[discovery] update featured creator to 1 for fun
djdevin Aug 18, 2026
2e2c8f4
[api] add photo settings flag
djdevin Aug 18, 2026
b8b73ca
[chat] fixup chat permissions (sorta)
djdevin Aug 18, 2026
92a4be5
[auth] restrictions endpoint
djdevin Aug 18, 2026
a3184c4
[rooms] contributed endpoint
djdevin Aug 18, 2026
0249602
[api] fix outfit endpoint
djdevin Aug 18, 2026
19a0227
[discovery] attempt to fix store
djdevin Aug 18, 2026
6b9bfd7
[chat] privacy endpoints
djdevin Aug 18, 2026
5b2bc33
[api] cheered images
djdevin Aug 18, 2026
b3023d7
[rooms] add xp endpoint (disbaled)
djdevin Aug 18, 2026
b9afb2e
[rooms] add xp endpoint (disabled)
djdevin Aug 18, 2026
7aced4a
update images-db for cheers
djdevin Aug 18, 2026
d92eb83
[rooms] add autocomplete endpoint
djdevin Aug 18, 2026
3cb8a37
[cdn/img] increase cache ttl for statics
djdevin Aug 18, 2026
2136c27
[api] bulk route for images
djdevin Aug 18, 2026
61b4947
[accounts] add banner image
djdevin Aug 18, 2026
244da79
[api] add misc missing endpoints
djdevin Aug 18, 2026
20579ca
[discovery] remove AI tab
djdevin Aug 18, 2026
c8aea15
[platformnotifications] stub some endpoints
djdevin Aug 18, 2026
7a71274
[lists] add some more lists
djdevin Aug 18, 2026
d4765da
[rooms] additional endpoints
djdevin Aug 18, 2026
d866e1f
[chat] stub a few privacy endpoints
djdevin Aug 18, 2026
7110061
[econ] stub some endpoints
djdevin Aug 18, 2026
600303b
misc db fixes
djdevin Aug 18, 2026
e8e76fa
[api] tweak shape for images v6
djdevin Aug 18, 2026
4c50eef
[rooms] dont show trending RROs
djdevin Aug 18, 2026
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
38 changes: 35 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
# Base domain all service hosts are derived from, e.g. accounts.<domain>.
RECFLARE_DOMAIN=rec.example.com

# Optional per-app subdomain overrides, as a compact JSON object keyed by the
# worker's directory name. Defaults to the directory name when unset.
# RECFLARE_SUBDOMAINS='{"playersettings":"settings"}'
# Optional per-service subdomain overrides, as a compact JSON object keyed by the
# service's default subdomain (which, for a service backed by a worker, is that
# worker's directory name). Unlisted services keep their default.
#
# One entry moves both sides: it decides which host `just deploy` puts the worker on
# AND which host the `ns` discovery document advertises to the client, so the two can't
# drift apart. Redeploy `ns` (`just deploy -F ns`) after changing this.
#
# {"playersettings":"settings"} the playersettings worker moves to settings.<domain>
# {"moderation":"api"} Moderation has no worker of its own, so this is a pure
# client-side redirect: it points the client's Moderation
# calls at the api worker, which is where the
# /api/PlayerReporting/… routes actually live
#
# Keep it compact — no spaces. Services are listed in SERVICES.md.
# RECFLARE_SUBDOMAINS='{"moderation":"api"}'

# Id of the shared `recflare` D1 database (create it manually with
# `wrangler d1 create recflare`). All D1-backed workers bind this one database.
Expand Down Expand Up @@ -85,6 +98,25 @@ RECFLARE_DOMAIN=rec.example.com
# live instance, which is already in whichever room it was created in.
# RECFLARE_ROOM_REDIRECTS=2=MyHub

# The Photon applications the client connects to (`match`, GET /player/connection-info).
# EMPTY unless you set them: recflare ships no Photon application, so until these name
# yours the client is handed empty ids and connects to nothing. Create the three apps in
# the Photon dashboard (Realtime, Voice, Chat) and paste their app ids here. They are not
# secrets — the client is handed all three in the clear — which is why they are vars and
# not Secrets Store entries.
# RECFLARE_PHOTON_REALTIME_APP_ID=
# RECFLARE_PHOTON_VOICE_APP_ID=
# RECFLARE_PHOTON_CHAT_APP_ID=

# The Photon region every session is pinned to (`match`). Unlike the app ids above this
# does default, to `us` (us-east1) — an instance stamped with an empty region is one the
# client cannot connect to, so there is no "unset" state for it to have. It is
# named in the connection info AND stamped on every room instance, and one var feeds both:
# the client authenticates against the app above and connects to the region on its
# instance, so the two disagreeing is a session nobody can join. The QoS pings the client
# reports are ranked but never acted on — one deployment runs in one region.
# RECFLARE_PHOTON_REGION=us

# RecCenterTokens a new player is granted, the first time their balance is read (`econ`).
# 0 means players start broke. Applies only to players who haven't been granted yet —
# raising it later does NOT top up existing players.
Expand Down
8 changes: 8 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ inconsistency here without checking the client first.
The payload shapes are recovered from the client's own decoder in
`apps/notify/src/notification-payloads.ts` — build frames against those interfaces (econ
does) so a renamed key fails the build instead of silently vanishing on the wire.
- Every matchmake response (`match`: `/matchmake/*`, refusals and the ban middleware's
included) must echo the request's `CorrelationId` back as `correlationId` — the client
tags each attempt with a GUID and fails with "Unable to connect to game session" if it
can't match the response to the attempt. A request that names none gets the all-zero
`Guid.Empty` rather than null: the client's field is a non-nullable Guid. The code is
served under TWO names, `result` (what the client reads) and `errorCode` (what this
server has always sent); they are the same number and must never disagree, which is why
everything answers through `matchmakeResult` rather than building the envelope by hand.
- Accessibility is sent as the `RoomAccessibility` enum NAME on
`rooms` `PUT /rooms/:id/subrooms/:sid/accessibility` (`accessibility=Private`), not the
ordinal the room-level `/rooms/:id/accessibility` takes. The enum has five members
Expand Down
17 changes: 14 additions & 3 deletions DEPLOYING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,16 @@ cp .env.example .env

Edit `.env` and set `RECFLARE_DOMAIN` to your domain (or declare it with `export RECFLARE_DOMAIN=rec.example.com`)

(Optional) - per-app subdomain overrides come from
`RECFLARE_SUBDOMAINS` (a JSON object, e.g. `'{"playersettings":"settings"}'`). This would be used
if you wanted to merge two services together e.g. send `datacollection` calls to `api`.
(Optional) - per-service subdomain overrides come from `RECFLARE_SUBDOMAINS`, a JSON
object keyed by each service's default subdomain (see `SERVICES.md`), e.g.
`'{"playersettings":"settings"}'`. A single entry both decides which host `just deploy`
puts that worker on and which host the `ns` discovery document advertises to the client,
so the two can't drift apart.

This is also how you merge two services together: `'{"moderation":"api"}'` points the
client's Moderation calls at the `api` worker (which is where the `/api/PlayerReporting/…`
routes already live) without deploying anything on `moderation.<domain>`. Redeploy `ns`
after changing it — `just deploy -F ns`.

**Create the storage resources:**

Expand Down Expand Up @@ -192,6 +199,10 @@ edit the value, then re-deploy the worker that reads them.
| `RECFLARE_MAX_ACCOUNTS_PER_IP` | `auth` | `3` | Accounts one signup IP may create. `0` disables. |
| `RECFLARE_STARTING_TOKENS` | `econ` | `10000` | RecCenterTokens a new player is granted. |
| `RECFLARE_ROOM_REDIRECTS` | `match` | unset | Rooms to switch out on matchmake, e.g. `2=MyHub`. |
| `RECFLARE_PHOTON_REALTIME_APP_ID` | `match` | empty | Your Photon Realtime app id. No app ships with recflare. |
| `RECFLARE_PHOTON_VOICE_APP_ID` | `match` | empty | Your Photon Voice app id. |
| `RECFLARE_PHOTON_CHAT_APP_ID` | `match` | empty | Your Photon Chat app id. |
| `RECFLARE_PHOTON_REGION` | `match` | `us` | Photon region every session is pinned to. |

Then deploy just the worker that reads it:

Expand Down
86 changes: 48 additions & 38 deletions SERVICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,55 @@ Each is reached at `https://<subdomain>.<your-domain>`. Services with a worker i
`apps/` are implemented here; the rest are advertised in the endpoints document
but not yet backed by a Worker. Not all services are fully implemented.

The subdomains below are the defaults. Any of them can be redirected from `.env` via
`RECFLARE_SUBDOMAINS`, keyed by the subdomain in this table — which both moves where the
worker deploys and what `ns` advertises. Pointing one service at another merges them, e.g.
`'{"moderation":"api"}'` sends the client's Moderation calls to the `api` worker, where the
`/api/PlayerReporting/…` routes already live. See `DEPLOYING.md`.

That override is still the one to set for Moderation: the `moderation` worker deploys but
is a stub, so with no override the client's reporting calls reach it and 404 rather than
reaching the routes in `api`. Drop the override once `moderation` serves them itself.

A small `ns` worker itself serves this discovery document at the
apex/`ns` host and isn't listed within it. Each implemented worker has its own
`README.md` under `apps/<name>/` documenting its routes.

| Service | Subdomain | Worker | Notes |
| --------------------- | ----------------------- | ---------------- | ------------------------------------------------------------------------- |
| Accounts | `accounts` | `accounts` | Player accounts & profile reads/writes (D1) |
| AI | `ai` | | Not yet implemented |
| API | `api` | `api` | Core Game API — config, social, avatar, rooms, image uploads (D1, R2) |
| Auth | `auth` | `auth` | OAuth token issuance (`/connect/token`); (D1) |
| BugReporting | `bugreporting` | — | Not yet implemented |
| Cards | `cards` | | Not yet implemented |
| CDN | `cdn` | `cdn` | Binary CDN — room data (R2) |
| Chat | `chat` | `chat` | Player chat service (not in room) |
| Clubs | `clubs` | `clubs` | Clubs, not yet implemented |
| CMS | `cms` | — | Not yet implemented |
| Commerce | `commerce` | `commerce` | Store / purchase endpoints |
| Data | `data` | — | Not yet implemented |
| DataCollection | `datacollection` | `datacollection` | Client telemetry / analytics sink |
| Discovery | `discovery` | | Not yet implemented |
| Econ | `econ` | `econ` | Economy & avatar endpoints (separate from `api`) |
| GameLogs | `gamelogs` | — | Not yet implemented |
| Geo | `geo` | — | Not yet implemented |
| Images | `img` | `img` | Image storage & signed delivery (R2) |
| Leaderboard | `leaderboard` | — | Not yet implemented |
| Link | `link` | — | Not yet implemented |
| Lists | `lists` | | Not yet implemented |
| Matchmaking | `match` | `match` | Matchmaking & per-player presence (D1, KV) |
| Moderation | `moderation` | | Not yet implemented |
| Notifications | `notify` | `notify` | Real-time notifications over SignalR/WebSockets (Durable Object) |
| PlatformNotifications | `platformnotifications` | — | Not yet implemented |
| PlayerSettings | `playersettings` | `playersettings` | Per-player settings (KV) |
| RoomComments | `roomcomments` | — | Not yet implemented |
| RoomieIntegrations | `roomieintegrations` | — | Not yet implemented |
| Rooms | `rooms` | `rooms` | Room storage & queries; seeds the Dorm & Orientation rooms (D1) |
| Storage | `storage` | — | Room uploader |
| Strings | `strings` | — | Not yet implemented |
| StringsCDN | `strings-cdn` | — | Not yet implemented |
| Studio | `studio` | — | Not yet implemented |
| Thorn | `thorn` | — | Not yet implemented |
| Videos | `videos` | — | Not yet implemented |
| WWW | `www` | — | Website/Panel |
| Service | Subdomain | Worker | Notes |
| --------------------- | ----------------------- | ----------------------- | --------------------------------------------------------------------- |
| Accounts | `accounts` | `accounts` | Player accounts & profile reads/writes (D1) |
| AI | `ai` | `ai` | Game AI access check (always refuses — no model runs here) |
| API | `api` | `api` | Core Game API — config, social, avatar, rooms, image uploads (D1, R2) |
| Auth | `auth` | `auth` | OAuth token issuance (`/connect/token`); (D1) |
| BugReporting | `bugreporting` | — | Not yet implemented |
| Cards | `cards` | `cards` | Stub — deploys and answers, no card endpoints yet |
| CDN | `cdn` | `cdn` | Binary CDN — room data (R2) |
| Chat | `chat` | `chat` | Player chat service (not in room) |
| Clubs | `clubs` | `clubs` | Clubs, not yet implemented |
| CMS | `cms` | — | Not yet implemented |
| Commerce | `commerce` | `commerce` | Store / purchase endpoints |
| Data | `data` | — | Not yet implemented |
| DataCollection | `datacollection` | `datacollection` | Client telemetry / analytics sink |
| Discovery | `discovery` | `discovery` | Discovery page layouts (static assets) |
| Econ | `econ` | `econ` | Economy & avatar endpoints (separate from `api`) |
| GameLogs | `gamelogs` | — | Not yet implemented |
| Geo | `geo` | — | Not yet implemented |
| Images | `img` | `img` | Image storage & signed delivery (R2) |
| Leaderboard | `leaderboard` | — | Not yet implemented |
| Link | `link` | — | Not yet implemented |
| Lists | `lists` | `lists` | Curated & algorithmic discovery lists (canned — nothing ranks yet) |
| Matchmaking | `match` | `match` | Matchmaking & per-player presence (D1, KV) |
| Moderation | `moderation` | `moderation` | Stub — the reporting routes still live in `api`; see note below |
| Notifications | `notify` | `notify` | Real-time notifications over SignalR/WebSockets (Durable Object) |
| PlatformNotifications | `platformnotifications` | `platformnotifications` | Stub — deploys and answers, no notification endpoints yet |
| PlayerSettings | `playersettings` | `playersettings` | Per-player settings (KV) |
| RoomComments | `roomcomments` | — | Not yet implemented |
| RoomieIntegrations | `roomieintegrations` | — | Not yet implemented |
| Rooms | `rooms` | `rooms` | Room storage & queries; seeds the Dorm & Orientation rooms (D1) |
| Storage | `storage` | — | Room uploader |
| Strings | `strings` | — | Not yet implemented |
| StringsCDN | `strings-cdn` | — | Not yet implemented |
| Studio | `studio` | — | Not yet implemented |
| Thorn | `thorn` | — | Not yet implemented |
| Videos | `videos` | — | Not yet implemented |
| WWW | `www` | — | Website/Panel |
Loading
Loading