v0.5.2 — the splash's multiplayer door opens, and knows whether it should
The "Play multiplayer" door on index.html had sat disabled, labelled
"Coming soon", since before the server existed — Phases 2 through 4 built
a working lobby and nothing ever linked to it. Loading the site landed on
the same solitaire splash whether a real multiplayer server was behind it
or not, with no visible way in. Found packaging Phase 6 for StartOS.
The door is now a live link to ./play.html?lobby, and main.ts's start()
routes ?lobby straight to the lobby screen — the same showScreen('lobby');
runLobby(beginRemote) the in-game Multiplayer button already used —
instead of dealing a solitaire game first.
GET /api/health is new, and exists to be failed. The same dist/ ships both
served by src/server/ and uploaded as flat files by deploy-web.ts, and the
bundle is identical either way (D4), so the page cannot know from its own
build which it is; every other route 404s an unknown path exactly as a
static host does, so nothing distinguished them. The splash probes it on
load and closes the door when nothing names itself in reply.
The door starts open and only ever closes, deliberately: a wrong "no
server" is the bug above again — invisible, and it strands a player who
does have one — while a wrong "there is one" costs a click and a lobby
that says it cannot connect. The reply must name itself rather than merely
return 200, or a host answering every path with its index page would pass.
Verified: tsc clean; 659 tests pass (656 + 3); /api/health exercised live
against a running server — 200 with the right body, unauthenticated, while
an unknown path and a wrong method both still 404, which is what makes the
probe discriminate at all.
The probe's own test was vacuous on the first attempt — both its "closes"
cases reached close() through the .catch arm, so deleting the body-naming
check outright still passed. Caught by mutating splash.ts and re-running;
the test now covers all three closing routes and fails without the check.
This commit is contained in:
@@ -245,9 +245,16 @@ special handling: `pump` stops, and the next push simply carries a `Menu` contai
|
||||
POST /api/lobby/create, /api/lobby/join lobby
|
||||
POST /api/intent { gameId, seq, intent }
|
||||
GET /api/stream EventSource — per-seat frames, with Last-Event-ID resume
|
||||
GET /api/health { ok, service, engineVersion } — unauthenticated; see below
|
||||
GET / the client
|
||||
```
|
||||
|
||||
`/api/health` exists because the client cannot otherwise tell a server from a static host. The same
|
||||
`dist/` is served both ways and the bundle is identical (D4), and every other route 404s an unknown
|
||||
path exactly as a static host does — so the splash asks, and closes its multiplayer door only when
|
||||
nothing names itself in reply. It is unauthenticated on purpose: it reveals that a Station Master
|
||||
server is answering and nothing else, no game and no seat.
|
||||
|
||||
Chosen over WebSocket because this game is **idle most of the time** — turn-based with human
|
||||
think-time means a connection sits silent for minutes, exactly when proxies reap sockets. SSE's
|
||||
reconnection and `Last-Event-ID` resume are handled by the browser, and it needs no `Upgrade` support
|
||||
|
||||
Reference in New Issue
Block a user