Skip to content
This repository was archived by the owner on Sep 10, 2026. It is now read-only.
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
34 changes: 22 additions & 12 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ verify the `latest` link on `reference/dart.md`.
## Documentation versions

The site is versioned on the **engine's release line**. Pre-1.0 that is the
minor, so `0.3.x` is one line and `0.4.0` starts the next. The label lives in
minor, so `0.4.x` is one line and `0.5.0` starts the next. The label lives in
`docusaurus.config.ts` under `versions.current.label`, and
`pnpm check-docs-version` asserts it against `info.version` in the committed
`api/openapi.json`. CI runs that check on every pull request.
Expand All @@ -160,25 +160,35 @@ between two answers:
**Freeze the old line**, the answer whenever a reader could still be running it:

```bash
pnpm docusaurus docs:version 0.3.x # the line being frozen, not the new one
pnpm docusaurus docs:version 0.4.x # the line being frozen, not the new one
```

That snapshots `docs/` into `versioned_docs/version-0.3.x/` at `/docs/0.3.x/*`,
That snapshots `docs/` into `versioned_docs/version-0.4.x/` at `/docs/0.4.x/*`,
and `docs/` becomes the new line at `/docs/*`. Then set
`versions.current.label` to the new line. The generated reference freezes with
everything else, which is what you want, since `sync-api` only ever writes to
`docs/`, so no part of that pipeline knows versions exist.

**Relabel in place**, only when the old line was never published, or nobody can
still be on it. Set `versions.current.label` and change nothing else. Both
crossings so far took this answer, and the second one is the useful precedent
because a cut was arguable: `0.2.x` was published and `eigen_flutter` 0.3.x was
on pub.dev pinned to it, but the engine had no adopters to strand, and the
release that crossed the line edited the game object's init migration in place,
so a `0.2.x` game's local state did not survive the upgrade regardless. A frozen
`0.2.x` line would have kept describing a wire no engine can speak, which is
worse than not having it. (`0.1.x` was simpler: the site's first public deploy
already described `0.2.x`, so no `0.1.x` page was ever reachable.)
still be on it. Set `versions.current.label` and change nothing else. All three
crossings so far took this answer.

`0.2.x` is the precedent for a cut being arguable and still declined: the line
was published and `eigen_flutter` 0.3.x was on pub.dev pinned to it, but the
engine had no adopters to strand, and the release that crossed the line edited
the game object's init migration in place, so a `0.2.x` game's local state did
not survive the upgrade regardless. A frozen `0.2.x` line would have kept
describing a wire no engine can speak, which is worse than not having it.

`0.3.x` is the precedent for a cut being declined on the old line's own merits.
Its paged reads were broken: a first-page request arrived with an empty `cursor`
that coerced to `0`, so every lobby and history list answered `200 []`. `0.4.0`
is the fix and it changes the wire, to opaque cursors and `nextCursor`. Freezing
`0.3.x` would have published a permanent, searchable account of a protocol whose
lists are always empty, sitting beside the one that works.

(`0.1.x` was simpler than either: the site's first public deploy already
described `0.2.x`, so no `0.1.x` page was ever reachable.)

Freezing is not free. A cut copies all of `docs/`, and most of this site by
volume is the generated TypeScript and HTTP reference, so each frozen line
Expand Down
86 changes: 54 additions & 32 deletions api/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"openapi": "3.1.0",
"info": {
"title": "EigenInteractive Engine API",
"version": "0.3.1",
"version": "0.4.0",
"description": "The server-authoritative game engine API. Client routes (`/api/engine/*`) require a Firebase ID token; the external-bot webhook (`/api/bot/action`) is HMAC-authenticated."
},
"tags": [
Expand Down Expand Up @@ -75,10 +75,18 @@
"items": {
"$ref": "#/components/schemas/GameSummary"
}
},
"nextCursor": {
"type": [
"string",
"null"
],
"description": "Pass as `cursor` to fetch the next page. Null when there are no more results."
}
},
"required": [
"games"
"games",
"nextCursor"
]
},
"GameSummary": {
Expand Down Expand Up @@ -402,7 +410,8 @@
"registrationRequired",
"imageTooLarge",
"unsupportedImageType",
"rateLimited"
"rateLimited",
"invalidCursor"
],
"description": "A stable machine code identifying why a request failed."
},
Expand All @@ -414,10 +423,18 @@
"items": {
"$ref": "#/components/schemas/GameSummary"
}
},
"nextCursor": {
"type": [
"string",
"null"
],
"description": "Pass as `cursor` to fetch the next page. Null when there are no more results."
}
},
"required": [
"games"
"games",
"nextCursor"
]
},
"Session": {
Expand Down Expand Up @@ -762,10 +779,18 @@
"items": {
"$ref": "#/components/schemas/GameSummary"
}
},
"nextCursor": {
"type": [
"string",
"null"
],
"description": "Pass as `cursor` to fetch the next page. Null when there are no more results."
}
},
"required": [
"games"
"games",
"nextCursor"
]
},
"RatingHistory": {
Expand Down Expand Up @@ -1263,10 +1288,18 @@
"items": {
"$ref": "#/components/schemas/GameSummary"
}
},
"nextCursor": {
"type": [
"string",
"null"
],
"description": "Pass as `cursor` to fetch the next page. Null when there are no more results."
}
},
"required": [
"games"
"games",
"nextCursor"
]
},
"UserSearch": {
Expand Down Expand Up @@ -1385,10 +1418,8 @@
},
{
"schema": {
"type": [
"integer",
"null"
]
"type": "string",
"minLength": 1
},
"required": false,
"name": "cursor",
Expand Down Expand Up @@ -1482,10 +1513,8 @@
},
{
"schema": {
"type": [
"integer",
"null"
]
"type": "string",
"minLength": 1
},
"required": false,
"name": "cursor",
Expand Down Expand Up @@ -1999,10 +2028,8 @@
},
{
"schema": {
"type": [
"integer",
"null"
]
"type": "string",
"minLength": 1
},
"required": false,
"name": "cursor",
Expand Down Expand Up @@ -2143,7 +2170,8 @@
"parameters": [
{
"schema": {
"type": "string"
"type": "string",
"minLength": 1
},
"required": false,
"name": "pool",
Expand Down Expand Up @@ -3210,11 +3238,9 @@
},
{
"schema": {
"type": [
"integer",
"null"
],
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"default": 0
},
"required": false,
Expand All @@ -3223,11 +3249,9 @@
},
{
"schema": {
"type": [
"integer",
"null"
],
"minimum": 0
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"required": false,
"name": "to",
Expand Down Expand Up @@ -3703,10 +3727,8 @@
},
{
"schema": {
"type": [
"integer",
"null"
]
"type": "string",
"minLength": 1
},
"required": false,
"name": "cursor",
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"responses":{"204":{"description":"The request was accepted"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["notActive","notReady","expired","notPending","stateUpdated","invalidPayload","illegalMove","unknownGame","notJoinable","gameFull","alreadyJoined","notParticipant","notCreator","creatorCannotLeave","schemaUnsupported","usernameInvalid","usernameTaken","friendsOnly","registrationRequired","imageTooLarge","unsupportedImageType","rateLimited"],"description":"A stable machine code identifying why a request failed.","title":"ErrorCode"}},"required":["error"],"title":"ErrorResponse"}}}},"401":{"description":"Missing or invalid token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["notActive","notReady","expired","notPending","stateUpdated","invalidPayload","illegalMove","unknownGame","notJoinable","gameFull","alreadyJoined","notParticipant","notCreator","creatorCannotLeave","schemaUnsupported","usernameInvalid","usernameTaken","friendsOnly","registrationRequired","imageTooLarge","unsupportedImageType","rateLimited"],"description":"A stable machine code identifying why a request failed.","title":"ErrorCode"}},"required":["error"],"title":"ErrorResponse"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["notActive","notReady","expired","notPending","stateUpdated","invalidPayload","illegalMove","unknownGame","notJoinable","gameFull","alreadyJoined","notParticipant","notCreator","creatorCannotLeave","schemaUnsupported","usernameInvalid","usernameTaken","friendsOnly","registrationRequired","imageTooLarge","unsupportedImageType","rateLimited"],"description":"A stable machine code identifying why a request failed.","title":"ErrorCode"}},"required":["error"],"title":"ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["notActive","notReady","expired","notPending","stateUpdated","invalidPayload","illegalMove","unknownGame","notJoinable","gameFull","alreadyJoined","notParticipant","notCreator","creatorCannotLeave","schemaUnsupported","usernameInvalid","usernameTaken","friendsOnly","registrationRequired","imageTooLarge","unsupportedImageType","rateLimited"],"description":"A stable machine code identifying why a request failed.","title":"ErrorCode"}},"required":["error"],"title":"ErrorResponse"}}}}}}
{"responses":{"204":{"description":"The request was accepted"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["notActive","notReady","expired","notPending","stateUpdated","invalidPayload","illegalMove","unknownGame","notJoinable","gameFull","alreadyJoined","notParticipant","notCreator","creatorCannotLeave","schemaUnsupported","usernameInvalid","usernameTaken","friendsOnly","registrationRequired","imageTooLarge","unsupportedImageType","rateLimited","invalidCursor"],"description":"A stable machine code identifying why a request failed.","title":"ErrorCode"}},"required":["error"],"title":"ErrorResponse"}}}},"401":{"description":"Missing or invalid token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["notActive","notReady","expired","notPending","stateUpdated","invalidPayload","illegalMove","unknownGame","notJoinable","gameFull","alreadyJoined","notParticipant","notCreator","creatorCannotLeave","schemaUnsupported","usernameInvalid","usernameTaken","friendsOnly","registrationRequired","imageTooLarge","unsupportedImageType","rateLimited","invalidCursor"],"description":"A stable machine code identifying why a request failed.","title":"ErrorCode"}},"required":["error"],"title":"ErrorResponse"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["notActive","notReady","expired","notPending","stateUpdated","invalidPayload","illegalMove","unknownGame","notJoinable","gameFull","alreadyJoined","notParticipant","notCreator","creatorCannotLeave","schemaUnsupported","usernameInvalid","usernameTaken","friendsOnly","registrationRequired","imageTooLarge","unsupportedImageType","rateLimited","invalidCursor"],"description":"A stable machine code identifying why a request failed.","title":"ErrorCode"}},"required":["error"],"title":"ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["notActive","notReady","expired","notPending","stateUpdated","invalidPayload","illegalMove","unknownGame","notJoinable","gameFull","alreadyJoined","notParticipant","notCreator","creatorCannotLeave","schemaUnsupported","usernameInvalid","usernameTaken","friendsOnly","registrationRequired","imageTooLarge","unsupportedImageType","rateLimited","invalidCursor"],"description":"A stable machine code identifying why a request failed.","title":"ErrorCode"}},"required":["error"],"title":"ErrorResponse"}}}}}}
2 changes: 1 addition & 1 deletion docs/reference/http-api/accept-friend-request.api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "acceptFriendRequest"
sidebar_label: "acceptFriendRequest"
hide_title: true
hide_table_of_contents: true
api: eJztV0tz2zYQ/iuYvdTuMJLdZHpg0nQU106UOonHUiYHjyZakSsREQnQwFKy6uF/7yxAyknkc04+EY/FPr79dgncg63JIWtrxjmkgFlGNV84TSa/ptuGPEMCjCsP6Q1MbKaxhFkCNTqsiMnJ+j34rKAKIb0H3tUEKXh22qwggUqbSzIrLiA9bRNwdNtoRzmk7BpKwGAl4o0nN84hAW0ghRq5gHYm0r62xpMXzX+cvJBPTj5zuhaPIYVpQcpFP9UWvYr+Uw5tAi9OTg4PjM0GS533hyCBzBomwyKKdV3qLKAx/OZF/pHQ7OIbZXKwdoId6+geOWfdIQKtGMjpMWjINJWgaiyPMtYbgkTG14T5Trbv6oBUWLwik8dTnpHpc50jUwQsxHOFu9JiWChLWmH5wQZ9jVkbuzVvBeag6L3VBhelzFZY0UVTlpAAlk6syubeIjrWma7RcFw4c4RsnSAWR2dojOVLwmAp4vTZ+KaurYvOSVolwx3o361McU0GElgGpvlPppSQHa2050jH654pCegKVzS19hLdKga1NzIOWwJsAg6ZLnWlxfYs+SnvI+VZ4lYVZoU2pCQrSudkWC932qzUttgp3JNpibqkfCDk11xK3s4lwWeSy/YHIt90qZ/9JHrdkRfatg1sPD1k4wftvdi2TnWJVGwjMk+0fKLlL6Hl80NafrSssCztNsT5xMQnJv4SJj7yfxcmLm1jnnj4xMNfwsP2Z38evxFXxIWVC3NtwzxcWVMYYq2HZFba0LBDbNg56of38ZbbDqNKSQVljdO8C3fopXa0QE+Q3szk8ttvTiRfkboPInuSFsx1n1SZLwgdSe7j4MK6ChlSeP9lCodQX3QK1fifePFIlCfDCr2ajxourNP/hSSn6k3Qp14FsddzdWSdmv8dZn/NlTXqCy0mNlsTq6ZeOczJHw+kqhaW31WYfecz1vpf2vW3/YIwDx53b4FzvSLzbKJXBrlxdOi1UXTHws5SLSz/5tW7D6Mz5fsDym7IKS5I0R1mvCfKwua7RC2kmSi2QWCOmSidq9xWqM1ARazVfHOavBJc/nzxev4yiNbkni0sqzXtlPZqLjaP3nyafp2M334cf3z7dXJ+dn0+FQM8zo/nAyVPk0iF4JtXW1yTV1vNRdDosSIVg1fahCXLBTmVa0fBr0EgsDZLG8DrOSv4jA2Tw9CM1Hk0MroaQwIbcj7idDJ4Pjg9QE+88uQ25J5hTDBj0CJNpvd3dDUeqLNSCxWcbZi8Opp/z+3f58eqKyyFhyx62cEfsxRw29KisHbd61lYHnbgHwueAmdwSMo8k5YZuCPVVWFo7x07Yu2oWI/qoSB/iHLPNKY7HtYlaiPaGlfKXqzVG6FhaO4S0UOHg9gypGIhgXT/Mu2KdpZAISWf3sD9vQT92ZVtK8u3DTmp5FkCG3Q69G6p61x7GeeQLrH0dODq/rcGR30rPVbSzh4Loa8gI+WzwbKRGSSwpt3DM7qdtUlfVuJB3Bz1Xac/dvATla6zb2xXnyZTaNv/AU58ouU=
api: eJztV01z2zgM/SscXDbZUe10N7MHtdsd15u0btMmEzvTQ8ZTwxJssZZIlYTseDP67zsgLaepc+8lJ4tfwMPDA0zeg63JIWtrRjmkgFlGNZ87TSa/pu8NeYYEGJce0lsY20xjCdMEanRYEZOT+XvwWUEVQnoPvK0JUvDstFlCApU2F2SWXED6sk3A0fdGO8ohZddQAgYr2d54cqMcEtAGUqiRC2instvX1njyYvmPk1P5yclnTteCGFKYFKRcxKk26FXETzm0CZyenBweGJk1ljrvDkECmTVMhmUr1nWps8BG/5uX/U+EZuffKJODtRPuWEd45Jx1hwy04iCnp6gh01TCqrE8yFivCRL5vibMt7J8VwemwuQVmTye8oxMN3WOTJGwEM8VbkuLYaIsaYnlJxvsNWZl7Ma8E5qDoQ9WG5yXMlpiRedNWUICWDrxKot7j+hYZ7pGw3Fi6AjZOmEsfg3RGMsXhMFT5OnG+KaurYvgJK2S4R3pP8xMcEUGElgEpflLU0rIjpbac5TjdaeUBHSFS5pYe4FuGYPaOxmFJSE2AYdMF7rSj4gZNs5bJ5J9rIOB8iw8qAqzQhtSkiWlczKsF1ttlmpTbBXuxbVAXVLek2LQXEoezyThQ8lt+0jYtzspTH/aer0TM7RtG9T58lCdn7T34ts6tcOv2EamnmX6LNNfItM/D2X62bLCsrSbEMKzMp+V+UuU+cR9QJS5sI151uWzLn+JLtuf8Tx9o66ICysX7tqGcbjyptDHWvfJLLWh/o7B/g6o79/HW3LbjyYlNZQ1TvM23MEX2tEcPUF6O5XLc7c4lvxFKT9s2Yu2YK67JMt4TuhItBA/zq2rkCGFD18mcEj1+c6gGv0bLyqJ8mRYoVezQcOFdfq/kPRUvQ321Ouw7c1MHVmnZv+E0d8zZY36QvOxzVbEqqmXDnPyxz2psrnl9xVmP2DGWn+kbfdaKAjzgHj3ljjTSzIvxnppkBtHh6iNojsWtZZqbvk3r95/GgyV7w4ouyanuCBFd5jxXihzm28TNZfmotiGDTPMxOhM5bZCbXoqcq1m65fJa+Hlr9M3s1dha03uxdyyWtFWaa9m4vPo7eXk63j07vPo87uv47Ph9dlEHPAoP571lDxtohQCNq82uCKvNpqLYNFjRSoGr7QJU5YLcirXjgKuXhCwNgsbyOs0K/yMDJPD0JzUWXQyuBpBAmtyPvJ00jvtnRywJ6g8uTW5FxgTzBisSNPp8A6uRj01LLVIwdmGyauj2Y/a/n12rHaFpfBQRa929McsBd42NC+sXXV25pb7O/KPhU+hMwCSMs+khQbtSHVVGNr9Th2xdlSsR/VQkI+i3CuN6Y77dYnaiLXGlbIWa/VWZBiavUT00PEgtgypWEgg3b9sd0U7TaCQkk9v4f5egr5xZdvK9PeGnFTyNIE1Oh16udR1rr1855AusPR0AHX/NwdHXWs9VtLOngqhqyAj5bPGspERJLCi7cMzvJ22SVdWgiAuDrqu0x07+FOVrrNvbFeX4wm07f9Xf7o5
sidebar_class_name: "post api-method"
info_path: docs/reference/http-api/eigeninteractive-engine-api
custom_edit_url: null
Expand Down
Loading