icon.png replaces the scaffold placeholder — resized to 512x512 and palette-quantized (1.9MB source -> 52.9KB) to stay close to the packaging guide's 40 KiB guidance with no visible quality loss at icon size. Verified station-master_x86_64.s9pk builds clean with a single icon.* file (the packer errors on more than one) and `s9pk inspect` confirms icon.png is packed correctly. The `ui` interface now opens at `/play.html` instead of `/`. Root serves index.html, the game's marketing splash — identical to the public static solitaire site, and with no lobby or Multiplayer button on it; both live on play.html (src/web/main.ts's `start()`, reached from index.html's door link). That page is right for a stranger landing on the public site, wrong for someone who just installed a dedicated multiplayer server and found what looked like the same solitaire page with no way to host or join a game. Verified: fetching /play.html from inside the container and over the service's public address both return the page with the Multiplayer button present. Reinstalled on phoenix.local after each change.
34 lines
1.5 KiB
TypeScript
34 lines
1.5 KiB
TypeScript
import { i18n } from './i18n'
|
|
import { sdk } from './sdk'
|
|
import { uiPort } from './utils'
|
|
|
|
// One interface: the server serves the browser client, the lobby/intent HTTP API, and the SSE
|
|
// game stream all from this single port (deployment.md's same-origin rule in the game repo —
|
|
// baking in a second origin would break relative URLs). type: 'ui' is a label the client is
|
|
// meant for a browser; it does not stop the same port from also carrying the API calls that
|
|
// client makes back to itself.
|
|
export const setInterfaces = sdk.setupInterfaces(async ({ effects }) => {
|
|
const uiMulti = sdk.MultiHost.of(effects, 'ui-multi')
|
|
const uiMultiOrigin = await uiMulti.bindPort(uiPort, { protocol: 'http' })
|
|
const ui = sdk.createInterface(effects, {
|
|
name: i18n('Multiplayer Table'),
|
|
id: 'ui',
|
|
description: i18n('Create or join a game, and play in the browser'),
|
|
type: 'ui',
|
|
masked: false,
|
|
schemeOverride: null,
|
|
username: null,
|
|
// `/` serves index.html — the game's marketing splash, identical to the public static
|
|
// solitaire site and with no lobby or Multiplayer button on it (both live on play.html; see
|
|
// src/web/main.ts's `start()` and the door link in index.html). That page makes sense for a
|
|
// stranger landing on the public site, not for someone who just installed a dedicated
|
|
// multiplayer server — so this interface opens straight at the game screen instead.
|
|
path: '/play.html',
|
|
query: {},
|
|
})
|
|
|
|
const uiReceipt = await uiMultiOrigin.export([ui])
|
|
|
|
return [uiReceipt]
|
|
})
|