Funday game dock — platform shell (production)
Lifecycle: CURRENT production host dock contract
Describes the SvelteKitGameDockshell on/play/[gameId]. Prefer this page over any attic/legacy “game-dock” copies.
This document describes the SvelteKit host dock used on /play/[gameId]. For a plain-language map of the whole play screen (dock + right drawer + tokens), see Play Shell Cheatsheet.
What ships today (GameDock.svelte)
- Layout: Full-width bar,
position: fixed,bottom: 0,left: 0,right: 0(onmd+, when the right drawer is open,rightbecomesvar(--drawer-w)so the bar stays aligned with the game column). - z-index:
30(drawer/modals use higher layers per theme tokens inapp.css). - Theme: DaisyUI / Tailwind —
color-mixonbase-100,border-base-300,backdrop-filter: blur, spacing tokens (--space-*), pill-shaped buttons (--radius-pill). - Geometry: The dock measures its height and sets
--dock-hondocument.documentElementso.play-rootcan usebottom: var(--dock-h)and the game is not covered. - Drawer width:
--drawer-wdefaults to24reminapp.css; whileGameDraweris open, aResizeObserversyncs the live width in px so dock inset and panel stay matched.
Behaviour
- Lobby: Host injects a primary
lobbyaction; games may sendfunday:dock:set— iflobbyis missing, the host adds it. Single-player games (maxPlayers ≤ 1) hide the lobby action. - Icons: Lucide map in
GameDockfor knownaction.idvalues; games may send emojiiconstrings. Every control should havetitle+aria-label(icons are language-neutral; tooltips carry the human label). - Feedback: Opens
Modal+GameFeedbackfor the currentgameId. - Test hook: Primary lobby control uses
data-testid="dock-lobby"when present.
Bridge contract (funday:dock:set)
Implementation split: Games emit
funday:dock:set.gameViewport/messageHandlers.tsmaps actions to handlers thatpostMessage{type:'funday:action', id}.GameDock.svelterenders the context actions (and measures--dock-h); it does not own the full postMessage router. Default lobby/reconnect actions are registered byGameViewportwhen appropriate — single-player filters lobby in the dock.
Games (iframe or native) send:
// From the game embed
postMessage({
type: "funday:dock:set",
actions: [
{ id: "lobby", label: "Lobby" },
{ id: "restart", label: "Restart" },
{ id: "howto", label: "How to Play" },
],
})The host maps each action to a dock button that posts { type: 'funday:action', id } back into the game.
Game / iframe viewport
Reserve space for the host dock — the play route already shrinks the viewport with --dock-h. For extra in-iframe chrome (e.g. a second toolbar inside the game), you can still use:
.game-canvas-area {
padding-bottom: var(--dock-h, 0px);
}Optional pattern: floating pill inside the game only
Some games embed their own overlay (not the Funday host dock). A small bottom-right pill inside the iframe is fine for game-local tools; it is not a substitute for registering host actions when you need Lobby / platform utilities.
<!-- In-game overlay only — do not confuse with host GameDock -->
<div class="absolute bottom-4 right-4 z-[30] pointer-events-auto">
<div
class="flex items-center gap-1 rounded-lg border border-base-300/50 bg-base-200/95 p-1.5 shadow-lg backdrop-blur-md"
>
<!-- Game-local actions -->
</div>
</div>Use bind:offsetWidth (or measure) if that inner pill must push content so nothing sits under it.
Tactile / a11y (still recommended)
btn-ghost/btn-primaryfor host dock;active:scale-95(or similar) for tap feedback.prefers-reduced-motion: host dock fly transition and drawer slide respect reduced motion where implemented.- Tooltips: DaisyUI
tooltip+data-tipor nativetitlefor shortcut hints.
Integration checklist (host-aligned)
- Game sends
funday:dock:setafter load when it has custom actions (see Connect4updateDockActions()after bridge handshake). - Action ids use the host icon map when possible, or provide emoji
icon. - Labels are short; long copy belongs in modals.
- Do not duplicate platform chat — lobby/match channels are owned by the shell.
- Respect
--dock-hfor any full-bleed canvas inside the iframe.