import type { GameContext } from "../runtime/gameContext.js"; export type SettingValue = number | boolean | string; export type SettingKind = "slider" | "toggle" | "select"; export type BuiltInSettingCategory = "sound" | "graphics" | "gameplay" | "controls" | "accessibility"; /** Built-in category ids keep autocomplete; any other string makes a fresh category. */ export type SettingCategory = BuiltInSettingCategory | (string & {}); export declare const BUILT_IN_SETTING_CATEGORIES: readonly BuiltInSettingCategory[]; export interface SettingOption { value: string; label: string; } /** Declares or relabels/reorders a category tab; use it for a custom category or to reshape the built-ins. */ export interface SettingCategoryDef { id: SettingCategory; label: string; order?: number; } /** Extra setting a game appends to a built-in category via `defineGame({ settings: { extra } })`. */ export interface GameSettingDef { id: string; label: string; category: SettingCategory; kind: SettingKind; default: SettingValue; /** Slider bounds — always pass both for a `slider`; omitted defaults (0..1) collapse the thumb. */ min?: number; max?: number; step?: number; options?: readonly SettingOption[]; /** Applies the new value to game state; the value is already persisted before this runs. */ onChange?: (value: SettingValue, ctx: GameContext) => void; } /** `quick` shows compact on-screen volume/graphics buttons; `false` (default) mounts no engine trigger — open the menu from your own UI with `` or `useSettings().open()`. */ export type SettingsSurface = "quick"; /** The four themed settings layouts, chosen with `defineGame({ settings: { variant } })`. All read the game's `--jg-*` theme tokens. */ export type SettingsVariant = "panel" | "sheet" | "sidebar" | "fullscreen"; /** A game-state action (Restart, Quit to menu, …) shown as rows in the first "Game" settings tab — never a floating button or a rebindable key. */ export interface SettingsActionDef { id: string; label: string; /** `danger` styles destructive actions (restart, quit) apart from neutral ones. */ kind?: "default" | "danger"; /** Optional one-line hint under the label. */ description?: string; /** Runs the action; the menu closes right after. */ run: (ctx: GameContext) => void; } export interface GameSettingsConfig { /** Layout + skin of the menu; all four theme off `--jg-*`. Default `panel`. */ variant?: SettingsVariant; /** `quick` shows compact on-screen volume/graphics buttons; omitted mounts no engine trigger — open the menu yourself with `` / `useSettings().open()`, or render `useSettings().categories` your own way. */ surface?: SettingsSurface | false; /** Rows appended to any category — built-in or a brand-new one named by `category`. */ extra?: readonly GameSettingDef[]; /** Declare custom category tabs, or relabel/reorder the built-ins. */ categories?: readonly SettingCategoryDef[]; /** Built-in categories to hide. */ hide?: readonly SettingCategory[]; /** Game-state actions (Restart, Quit…) — become the first "Game" tab, shown before anything else. */ actions?: readonly SettingsActionDef[]; /** Input actions to drop from the rebindable Controls list — game-state keys like `restart` that belong in `actions`, not the rebind grid. */ hideBindings?: readonly string[]; } export declare const SETTINGS_STORAGE_PREFIX = "jgengine:setting:"; export declare const SETTING_IDS: { readonly masterVolume: "sound.master"; readonly graphicsQuality: "graphics.quality"; readonly graphicsShadows: "graphics.shadows"; readonly graphicsUiScale: "graphics.uiScale"; readonly graphicsRenderScale: "graphics.renderScale"; readonly graphicsPostAo: "graphics.post.ao"; readonly graphicsPostBloom: "graphics.post.bloom"; readonly graphicsPostDof: "graphics.post.dof"; readonly graphicsPostSmaa: "graphics.post.smaa"; readonly graphicsFrameRateLimit: "graphics.frameRateLimit"; readonly graphicsAnisotropy: "graphics.anisotropy"; readonly graphicsShowFps: "graphics.showFps"; readonly touchStyle: "controls.touchStyle"; readonly touchJoystick: "controls.touchJoystick"; }; export type GraphicsQuality = "low" | "medium" | "high" | "ultra"; export declare const GRAPHICS_QUALITY_OPTIONS: readonly SettingOption[]; export declare const DEFAULT_MASTER_VOLUME = 1; export declare const DEFAULT_GRAPHICS_QUALITY: GraphicsQuality; export declare const DEFAULT_GRAPHICS_SHADOWS = true; /** Player-controlled multiplier on the HUD's computed fit scale — one lever on desktop and mobile alike. */ export declare const DEFAULT_UI_SCALE = 1; export declare const UI_SCALE_MIN = 0.5; export declare const UI_SCALE_MAX = 1.5; /** Device-pixel-ratio ceiling per quality tier — the shell's `Canvas` dpr cap. */ export declare const GRAPHICS_QUALITY_DPR: Record; export declare function busVolumeSettingId(busId: string): string; export declare function settingStorageKey(id: string): string; interface WebStorageLike { getItem(key: string): string | null; setItem(key: string, value: string): void; } export declare function loadSettingValue(id: string, fallback: T, storage?: Pick | null | undefined): T; export declare function saveSettingValue(id: string, value: SettingValue, storage?: Pick | null | undefined): void; export interface SettingsStore { get(id: string, fallback: T): T; set(id: string, value: SettingValue): void; subscribe(listener: () => void): () => void; } /** Reactive, localStorage-backed settings store shared by the shell wiring and React hooks. */ export declare function createSettingsStore(storage?: Pick | null | undefined): SettingsStore; export {};