feat(build): add a standalone mode for deploys with no backend - #166
Merged
Merged
Conversation
`npx vite build --mode standalone` produces a build with multiplayer switched off, for any deploy served as plain static files that cannot reach the signaling server. The gate already existed — `main.ts`'s `MULTIPLAYER_SERVER_CONFIGURED = Boolean(import.meta.env.VITE_MULTIPLAYER_SERVER_URL)`, with `updateMultiplayerTabEnabled` hiding the tab when it is unset. What was missing was a way to ask for it: a default `vite build` runs in production mode and loads `.env.production.local`, so the URL is always present and the tab always appears. On a host the signaling server does not accept, that advertises a mode which cannot connect — found by uploading to itch.io and clicking it. **Named for what it is, not where it was first needed.** Nothing here is itch-specific: it applies to any subpath host, any fork without a server of its own, any static mirror. An earlier draft called the mode `itch` and that was simply the wrong noun. `.env.standalone` sets the variable to empty explicitly rather than letting the mode work by having no env file at all, so the intent is greppable in one place. **It is documentation, not a guarantee, and this was measured rather than assumed.** Vite's precedence is `.env` < `.env.local` < `.env.[mode]` < `.env.[mode].local`. Dropping a `.env.standalone.local` in place brings the Multiplayer tab straight back — verified, and it does so identically whether the tracked file exists or not. So the explicit file buys discoverability, not safety; the only check that holds is on the built artifact. Verified in both directions, since the risk here is symmetric: - `--mode standalone` → tabs are Local / Repo / Demos / gear, no Multiplayer - default `vite build` → Multiplayer still present, so the real deploy is untouched by this file existing Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
npx vite build --mode standaloneproduces a build with multiplayer switched off, for any deploy served as plain static files that cannot reach the signaling server.The problem
The gate already existed:
with
updateMultiplayerTabEnabledhiding the tab when it is unset. What was missing was a way to ask for it — a defaultvite buildruns in production mode and loads.env.production.local, so the URL is always present and the tab always appears.On a host the signaling server does not accept, that advertises a mode which cannot connect. Found by uploading to itch.io and clicking it.
Named for what it is
Nothing here is itch-specific — it applies to any subpath host, any fork without a server of its own, any static mirror. An earlier draft called the mode
itch, which was simply the wrong noun.The honest limitation
.env.standalonesets the variable to empty explicitly, rather than letting the mode work by having no env file at all, so the intent is greppable in one place.That file is documentation, not a guarantee — and this was measured rather than assumed. Vite's precedence is:
Dropping a
.env.standalone.localin place brings the Multiplayer tab straight back. I tested it, and it behaves identically whether the tracked file exists or not — so the explicit file buys discoverability, not safety. My first instinct was that explicit-empty would be more robust than absence; it isn't, and the test is what said so.The only check that holds is on the built artifact:
Verification — both directions
The risk here is symmetric: the mode has to work, and it must not leak into the real deploy.
--mode standalonevite buildPlus the usual gate:
npm run buildclean with bundle hygiene,vitest --dir src3,682 passing across 135 files,docPins72 passing.Not included
No README entry yet — the mode is documented in
.env.standalone's own comment and is greppable from there. Say if you would rather it were listed under Development Scripts too.🤖 Generated with Claude Code
https://claude.ai/code/session_017ncJfux8GDacSTeLDcqrhr