@jgengine/react 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/dist/actionHud.d.ts +5 -5
- package/dist/actionHud.js +14 -12
- package/dist/bars.d.ts +103 -0
- package/dist/bars.js +180 -0
- package/dist/barsPreview.d.ts +4 -0
- package/dist/barsPreview.js +47 -0
- package/dist/characterSheet.d.ts +120 -0
- package/dist/characterSheet.js +134 -0
- package/dist/components.d.ts +8 -1
- package/dist/components.js +8 -1
- package/dist/hooks.d.ts +31 -0
- package/dist/hooks.js +53 -0
- package/dist/hud.d.ts +21 -4
- package/dist/hud.js +38 -27
- package/dist/hudFrame.d.ts +47 -0
- package/dist/hudFrame.js +80 -0
- package/dist/hudLayout.d.ts +13 -1
- package/dist/hudLayout.js +18 -12
- package/dist/hudLayoutPersist.d.ts +23 -0
- package/dist/hudLayoutPersist.js +19 -0
- package/dist/hudTheme.d.ts +76 -0
- package/dist/hudTheme.js +156 -0
- package/dist/hudThemePreview.d.ts +4 -0
- package/dist/hudThemePreview.js +37 -0
- package/dist/iconTreatment.d.ts +50 -0
- package/dist/iconTreatment.js +84 -0
- package/dist/iconsPreview.d.ts +4 -0
- package/dist/iconsPreview.js +29 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/inventoryGrid.d.ts +20 -0
- package/dist/inventoryGrid.js +135 -0
- package/dist/map.d.ts +72 -10
- package/dist/map.js +84 -15
- package/dist/panels.d.ts +107 -0
- package/dist/panels.js +215 -0
- package/dist/selectionHud.d.ts +11 -5
- package/dist/selectionHud.js +11 -5
- package/dist/slots.d.ts +47 -0
- package/dist/slots.js +37 -0
- package/package.json +2 -2
- package/skills/jgengine/SKILL.md +8 -4
- package/skills/jgengine/api.md +182 -81
- package/skills/jgengine/capabilities.md +104 -2
- package/skills/jgengine/recipes/minimal-game.md +88 -0
- package/skills/jgengine-ui/SKILL.md +17 -10
- package/skills/jgengine-ui/api.md +316 -51
- package/skills/jgengine-ui/capabilities.md +135 -2
- package/skills/jgengine-ui/recipes/portable-minimap.md +150 -0
- package/skills/jgengine-ui/reference.md +59 -9
- package/skills/jgengine-ui/references/visual-scorecard.md +1 -1
- package/skills/jgengine/reference-cartridge.md +0 -72
|
@@ -115,6 +115,9 @@
|
|
|
115
115
|
- `LayoutRegion` (interface): interface LayoutRegion — A physical rectangle a UI subsystem occupies, published to the shared registry.
|
|
116
116
|
- `LookPreset` (type): type LookPreset = "cinematic" | "flat" — Named default-look preset composing the existing lighting/sky/fog/post knobs into one field. `"cinematic"` (the default when unset) draws a scene lit like a shipped game — a real day sky with a view-following shadow-casting sun + hemisphere fill, a network-free image-based-lighting environment so PBR surfaces catch soft reflections, and a tuned tone-map/bloom/AO/vignette post stack. `"flat"` opts out of the sky/IBL/post rig to the bare ambient+directional default (pre-#773). The upgraded default primitive materials — tuned roughness/metalness plus subtle procedural surface detail so un-modeled boxes/capsules stop reading as flat plastic — apply under both presets.
|
|
117
117
|
- `MobileHudBehavior` (type): type MobileHudBehavior = | "persistent" | "compact" | "icon" | "transient" | "hidden" | "sheet" | "modal" — How a HUD element adapts on phones.
|
|
118
|
+
- `PanelDef` (interface): interface PanelDef — A caller-authored panel/window declaration — the DATA input to the model. Only `id` is required so a bag, a character sheet, and a one-off dialog all share the shape.
|
|
119
|
+
- `PanelPosition` (interface): interface PanelPosition — Headless, serializable model for a set of player-toggled windows/panels — the data layer behind a WoW-style UI where B opens the bag, C the character sheet, and ESC closes the topmost window. It carries *which panels are open*, their focus/z stacking order, per-panel position overrides, and exclusive-group membership, with zero rendering opinion. The React chrome in `@jgengine/react/panels` consumes this; a game keeps layout, skin, keybinds, and window content caller-owned. Pure and immutable: every reducer returns a new state and never mutates its input.
|
|
120
|
+
- `PanelState` (interface): interface PanelState — Serializable state for a set of panels: which are `open`, their `z` focus stack (higher renders on top), optional per-panel `pos` overrides, and the `meta` registry (group/closable) captured from the defs so the reducers below need no defs argument. Plain JSON — persist and rehydrate it freely.
|
|
118
121
|
- `PopoverOptions` (interface): interface PopoverOptions — Options for {@link placePopover}.
|
|
119
122
|
- `PopoverPlacement` (interface): interface PopoverPlacement — The resolved popover position — the side it actually opened on and its clamped top-left.
|
|
120
123
|
- `PopoverSide` (type): type PopoverSide = "top" | "bottom" | "left" | "right" — Which side of its anchor a popover opens toward.
|
|
@@ -149,19 +152,28 @@
|
|
|
149
152
|
- `actionCost` (function): function actionCost(resourceId: string, amount: number, available?: number): ActionCost — Build an {@link ActionCost}. `met` is true unless `available` is provided and below `amount`.
|
|
150
153
|
- `actionTooltip` (function): function actionTooltip(action: ResolvedAction): TooltipContent — Build {@link TooltipContent} from a {@link ResolvedAction}: title from the label, the group as a subtitle, the description as the body, and the blocking reasons as warning notes. The single place an action's tooltip copy is assembled, so every renderer shows the same thing.
|
|
151
154
|
- `busVolumeSettingId` (function): function busVolumeSettingId(busId: string): string — ⚠ undocumented
|
|
155
|
+
- `closePanel` (function): function closePanel(state: PanelState, id: string): PanelState — Close panel `id`. No-op if it is already closed. Its position override is kept so reopening restores the last placement.
|
|
156
|
+
- `closeTopPanel` (function): function closeTopPanel(state: PanelState): PanelState — Close the topmost closable open panel — the ESC handler. Skips panels pinned with `closable: false` and returns the same state when nothing closable is open.
|
|
157
|
+
- `createPanelState` (function): function createPanelState(defs: readonly PanelDef[]): PanelState — Build the initial {@link PanelState} from the panel defs: panels flagged `initial` start open (in declaration order, respecting group exclusivity), and every def's group/closable is captured into the state so later reducers need no defs.
|
|
152
158
|
- `createSettingsStore` (function): function createSettingsStore(storage: Pick<WebStorageLike, "getItem" | "setItem"> | null | undefined = defaultStorage()): SettingsStore — Reactive, localStorage-backed settings store shared by the shell wiring and React hooks.
|
|
159
|
+
- `focusPanel` (function): function focusPanel(state: PanelState, id: string): PanelState — Raise open panel `id` to the top of the focus stack (assign it the highest z). No-op if it is closed or already on top, so a pointer-down that refocuses the top window returns the same state.
|
|
153
160
|
- `formatDelta` (function): function formatDelta(seconds: number, decimals: 0 | 1 | 2 = 2): string — Format a signed time gap as `+m:ss.ff` / `-m:ss.ff`, for race deltas and split times.
|
|
154
161
|
- `formatDistance` (function): function formatDistance(meters: number, options: DistanceFormat = {}): string — Format a distance given in meters as a HUD-ready string, switching to km automatically past 1000m when `unit: "auto"`.
|
|
155
162
|
- `formatDuration` (function): function formatDuration(seconds: number, options: DurationFormat = {}): string — Format a duration in seconds as a clock string (`m:ss`, `m:ss.ff`, or `h:mm:ss`), the shape every timer and racing HUD needs.
|
|
156
163
|
- `formatOrdinal` (function): function formatOrdinal(value: number): string — English ordinal for a placement number: 1 → "1st", 2 → "2nd", 3 → "3rd", 11 → "11th".
|
|
157
164
|
- `formatSpeed` (function): function formatSpeed(metersPerSecond: number, options: SpeedFormat = {}): string — Format a speed given in meters/second as a HUD-ready string in km/h, mph, knots, or m/s — the one conversion table every speedometer and telemetry readout should share.
|
|
158
165
|
- `hudScaleForViewport` (function): function hudScaleForViewport(fit: Required<HudFitConfig>, viewport: HudSize): number — The one scaling rule for every display: the ratio of the live viewport to the authored design size along the limiting axis, clamped. 1 on a viewport at or above design size; smoothly below 1 down to `minScale` on phones.
|
|
166
|
+
- `isOpen` (function): function isOpen(state: PanelState, id: string): boolean — Whether panel `id` is currently open.
|
|
159
167
|
- `listHudPanelTypes` (function): function listHudPanelTypes(): HudPanelTypeDef[] — Every registered panel type, sorted by id — editor palette / agent listing.
|
|
160
168
|
- `moveGridFocus` (function): function moveGridFocus(current: number, count: number, columns: number, dir: FocusDirection, options?: GridFocusOptions): number — Pure grid focus math for keyboard and controller navigation of an action card laid out in `columns`-wide rows. Given the current index (`-1` for none) it returns the next index, clamped to `[0, count)` — or wrapped when `wrap` is set. `left/right` move within/across columns, `up/down` across rows, `next/prev` walk the flat order, `first/last` jump to the ends. Renderer-agnostic: radial and list layouts pass `columns: 1` (or `count`) to get sensible 1-D stepping.
|
|
169
|
+
- `movePanel` (function): function movePanel(state: PanelState, id: string, pos: PanelPosition): PanelState — Set panel `id`'s position override — the drag commit. Does not require the panel to be open, so a caller can pre-place a window before it is shown.
|
|
161
170
|
- `moveSelectionFocus` (function): function moveSelectionFocus(count: number, current: number, dir: SelectionFocusDirection): number — Pure next-focus math for the selection strip: step the focus index by one member (wrapping), or jump to an end. `-1` (no focus) steps to the first/last member. Returns `-1` for an empty selection.
|
|
171
|
+
- `openPanel` (function): function openPanel(state: PanelState, id: string): PanelState — Open panel `id`, raising it to the top of the focus stack. If it belongs to a `group`, the other open panels in that group are closed (exclusive windows). Opening an already-open panel just refocuses it. Position overrides are preserved.
|
|
172
|
+
- `orderedOpen` (function): function orderedOpen(state: PanelState, defs: readonly PanelDef[]): PanelDef[] — The open panels' defs sorted ascending by z — the render order for a window host (map to elements so the last, highest-z window paints on top). Defs unknown to the state are skipped.
|
|
162
173
|
- `orientationGateActive` (function): function orientationGateActive(requirement: OrientationRequirement, liveOrientation: LayoutOrientation): boolean — The rotate gate blocks gameplay: a hard requirement (or `unsupported`) the live orientation doesn't satisfy.
|
|
163
174
|
- `orientationHintActive` (function): function orientationHintActive(requirement: OrientationRequirement, liveOrientation: LayoutOrientation): boolean — An advisory rotate hint applies: a preference (not a hard gate) the live orientation doesn't satisfy.
|
|
164
175
|
- `overflowingPanels` (function): function overflowingPanels(panels: readonly { id: string; rect: HudRect }[], viewport: HudSize, tolerance = 1.5): HudOverflow[] — Every panel rect that escapes the viewport — the data behind the HUD overflow gate.
|
|
176
|
+
- `panelByHotkey` (function): function panelByHotkey(defs: readonly PanelDef[], code: string): string | null — Find the panel whose `hotkey` matches `code`, case-insensitively — the keybind router. `code` may be a `KeyboardEvent.code` (`"KeyB"`) or key (`"b"`); it is compared verbatim to each def's `hotkey`, so author the hotkey in whichever form the caller feeds in. Returns the first match's id, or null.
|
|
165
177
|
- `placePopover` (function): function placePopover(anchor: UiRect, content: UiSize, viewport: UiSize, options?: PopoverOptions): PopoverPlacement — Position a popover/tooltip of `content` size against its `anchor` rectangle inside `viewport`: open on the `preferred` side, flip to the opposite when that side lacks room and the opposite has more, then clamp the top-left so the box stays fully on screen (respecting `margin`). Pure and deterministic — no DOM reads — so it is SSR-safe and unit-testable, and the React tooltip is a thin shell over it.
|
|
166
178
|
- `registerHudPanelType` (function): function registerHudPanelType(def: HudPanelTypeDef): void — Register a HUD panel type so the editor can list/add/configure it and canvas resize knows axes.
|
|
167
179
|
- `resizePanelSize` (function): function resizePanelSize(current: HudSize, delta: { dw: number; dh: number }, axes: HudResizeAxes, limits?: { minWidth?: number; maxWidth?: number; minHeight?: number; maxHeight?: number; }): HudSize — Semantic resize: apply pixel deltas only on growable axes, clamped to min/max. Never scales content — callers reflow layout size (track length, list rows).
|
|
@@ -174,6 +186,7 @@
|
|
|
174
186
|
- `selectionWindow` (function): function selectionWindow(members: readonly EntitySummaryDef[], scroll: number, size: number): SelectionWindow — Compute a virtualization window over a large selection: a `size`-length slice starting near `scroll`, clamped so the window never runs past the end. Render only `items`, offsetting by `start * itemSize`, to keep a thousand-unit selection from mounting a thousand portraits.
|
|
175
187
|
- `summarizeSelection` (function): function summarizeSelection(members: readonly EntitySummaryDef[], options?: SummarizeSelectionOptions): SelectionView — Summarize a selected-entity list into a {@link SelectionView}: resolve the primary focus, keep the ordered members, and bucket them by `kind`. Pure and stable — deterministic group ordering and a clamped focus index, so it is safe to call every render and to assert on in a test.
|
|
176
188
|
- `swingTimerState` (function): function swingTimerState(player: SwingPlayerInput, target: SwingTargetInput | null, prevPeriod: number, prevTimer: number): SwingTimerState — Pure swing-timer bar state — no hidden state, no clock, no DOM. The caller threads `prevPeriod`/`prevTimer` back each frame. The period is recovered on the reset edge (when `swingTimer` jumps up = a new swing began) as `max(swingTimer, weapon.speed)`, so the fill is correct even without knowing the weapon's exact cadence. Hidden unless auto-attacking a live, non-object target.
|
|
189
|
+
- `togglePanel` (function): function togglePanel(state: PanelState, id: string): PanelState — Toggle panel `id` — open it (with group exclusivity) if closed, close it if open. The one-key behavior behind a keybind like `B` for the bag.
|
|
177
190
|
|
|
178
191
|
## @jgengine/core/ui/actionModel
|
|
179
192
|
|
|
@@ -259,6 +272,22 @@
|
|
|
259
272
|
- `resolveMobileOrientationRule` (function): function resolveMobileOrientationRule(orientation: GameOrientation | undefined): MobileOrientationRule — Normalize the `orientation` field (legacy string or object) to a single mobile rule.
|
|
260
273
|
- `resolveOrientationRequirement` (function): function resolveOrientationRequirement(orientation: GameOrientation | undefined, platform: "mobile" | "desktop"): OrientationRequirement — Resolve the game's orientation declaration into a concrete requirement for a platform. Desktop is always unconstrained.
|
|
261
274
|
|
|
275
|
+
## @jgengine/core/ui/panelModel
|
|
276
|
+
|
|
277
|
+
- `PanelDef` (interface): interface PanelDef — A caller-authored panel/window declaration — the DATA input to the model. Only `id` is required so a bag, a character sheet, and a one-off dialog all share the shape.
|
|
278
|
+
- `PanelPosition` (interface): interface PanelPosition — Headless, serializable model for a set of player-toggled windows/panels — the data layer behind a WoW-style UI where B opens the bag, C the character sheet, and ESC closes the topmost window. It carries *which panels are open*, their focus/z stacking order, per-panel position overrides, and exclusive-group membership, with zero rendering opinion. The React chrome in `@jgengine/react/panels` consumes this; a game keeps layout, skin, keybinds, and window content caller-owned. Pure and immutable: every reducer returns a new state and never mutates its input.
|
|
279
|
+
- `PanelState` (interface): interface PanelState — Serializable state for a set of panels: which are `open`, their `z` focus stack (higher renders on top), optional per-panel `pos` overrides, and the `meta` registry (group/closable) captured from the defs so the reducers below need no defs argument. Plain JSON — persist and rehydrate it freely.
|
|
280
|
+
- `closePanel` (function): function closePanel(state: PanelState, id: string): PanelState — Close panel `id`. No-op if it is already closed. Its position override is kept so reopening restores the last placement.
|
|
281
|
+
- `closeTopPanel` (function): function closeTopPanel(state: PanelState): PanelState — Close the topmost closable open panel — the ESC handler. Skips panels pinned with `closable: false` and returns the same state when nothing closable is open.
|
|
282
|
+
- `createPanelState` (function): function createPanelState(defs: readonly PanelDef[]): PanelState — Build the initial {@link PanelState} from the panel defs: panels flagged `initial` start open (in declaration order, respecting group exclusivity), and every def's group/closable is captured into the state so later reducers need no defs.
|
|
283
|
+
- `focusPanel` (function): function focusPanel(state: PanelState, id: string): PanelState — Raise open panel `id` to the top of the focus stack (assign it the highest z). No-op if it is closed or already on top, so a pointer-down that refocuses the top window returns the same state.
|
|
284
|
+
- `isOpen` (function): function isOpen(state: PanelState, id: string): boolean — Whether panel `id` is currently open.
|
|
285
|
+
- `movePanel` (function): function movePanel(state: PanelState, id: string, pos: PanelPosition): PanelState — Set panel `id`'s position override — the drag commit. Does not require the panel to be open, so a caller can pre-place a window before it is shown.
|
|
286
|
+
- `openPanel` (function): function openPanel(state: PanelState, id: string): PanelState — Open panel `id`, raising it to the top of the focus stack. If it belongs to a `group`, the other open panels in that group are closed (exclusive windows). Opening an already-open panel just refocuses it. Position overrides are preserved.
|
|
287
|
+
- `orderedOpen` (function): function orderedOpen(state: PanelState, defs: readonly PanelDef[]): PanelDef[] — The open panels' defs sorted ascending by z — the render order for a window host (map to elements so the last, highest-z window paints on top). Defs unknown to the state are skipped.
|
|
288
|
+
- `panelByHotkey` (function): function panelByHotkey(defs: readonly PanelDef[], code: string): string | null — Find the panel whose `hotkey` matches `code`, case-insensitively — the keybind router. `code` may be a `KeyboardEvent.code` (`"KeyB"`) or key (`"b"`); it is compared verbatim to each def's `hotkey`, so author the hotkey in whichever form the caller feeds in. Returns the first match's id, or null.
|
|
289
|
+
- `togglePanel` (function): function togglePanel(state: PanelState, id: string): PanelState — Toggle panel `id` — open it (with group exclusivity) if closed, close it if open. The one-key behavior behind a keybind like `B` for the bag.
|
|
290
|
+
|
|
262
291
|
## @jgengine/core/ui/selectionModel
|
|
263
292
|
|
|
264
293
|
- `EntitySummaryDef` (interface): interface EntitySummaryDef — A caller-provided summary of one selectable entity — the DATA input. `kind` is the grouping key used to bucket a large selection (unit type, catalog id); `icon` is a portrait id the renderer resolves. Only `id` is required.
|
|
@@ -295,7 +324,7 @@
|
|
|
295
324
|
## @jgengine/react
|
|
296
325
|
|
|
297
326
|
- `AbilitySlotBindingOptions` (interface): interface AbilitySlotBindingOptions — ⚠ undocumented
|
|
298
|
-
- `ActionBar` (function): function ActionBar({ defs, columns, layout = "grid", wrap, hotkeys, itemSize, ariaLabel, onActivate, renderItem, className, style, }: { defs: readonly ActionDef[]; columns?: number; layout?: "grid" | "list"; wrap?: boolean; hotkeys?: boolean; itemSize?: number; ariaLabel?: string; onActivate?: (id: … —
|
|
327
|
+
- `ActionBar` (function): function ActionBar({ defs, columns, layout = "grid", wrap, hotkeys, itemSize, ariaLabel, onActivate, renderItem, className, style, }: { defs: readonly ActionDef[]; columns?: number; layout?: "grid" | "list"; wrap?: boolean; hotkeys?: boolean; itemSize?: number; ariaLabel?: string; onActivate?: (id: … — Convenience composition of {@link useActionBar} + glass {@link ActionBarChrome} for demos and scaffolding — not a shipped game face. Pass `defs`, choose `grid`/`list`, and hand it `onActivate`. Games that own their UI compose the headless hook + custom chrome (or swap `renderItem`) instead of shipping this default panel.
|
|
299
328
|
- `ActionBarChrome` (function): function ActionBarChrome({ model, layout = "grid", itemSize = 52, gap = 6, ariaLabel = "Actions", renderItem, className, style, }: { model: ActionBarModel; layout?: "grid" | "list"; itemSize?: number; gap?: number; ariaLabel?: string; renderItem?: (action: ResolvedAction, ctx: ActionItemContext) => … — The composable RENDERER: lay the model's actions out as a `grid` or `list` toolbar with roving tabindex, arrow-key navigation, and a moved DOM focus. `renderItem` swaps per-item chrome; omit it for {@link ActionButton}. A radial or bespoke UI can skip this entirely and read the model. Purely a wiring/behavior layer — no panel skin — so a game art-directs freely.
|
|
300
329
|
- `ActionBarKeyResult` (interface): interface ActionBarKeyResult — The intent a key press resolves to over an action bar: move focus, activate, or ignore.
|
|
301
330
|
- `ActionBarModel` (interface): interface ActionBarModel — The live action-bar model returned by {@link useActionBar}.
|
|
@@ -304,12 +333,21 @@
|
|
|
304
333
|
- `ActionKeyEvent` (interface): interface ActionKeyEvent — A minimal keyboard-event shape — a real `KeyboardEvent`/React synthetic satisfies it.
|
|
305
334
|
- `ActionTooltip` (function): function ActionTooltip({ content, className, style, }: { content: TooltipContent; className?: string; style?: CSSProperties; }): React.JSX.Element — Render {@link TooltipContent} (from `actionTooltip`) as a styled block: title, subtitle, body, hotkey, cost lines, cooldown, and a warning footer of blocking notes. Drop it inside a {@link Popover} for an action's hover/focus description.
|
|
306
335
|
- `AddFriendButton` (function): function AddFriendButton({ toUserId, className, children, onRequested, onRejected, }: { toUserId: string; className?: string; children?: ReactNode; onRequested?: (requestId: string) => void; onRejected?: (reason: string) => void; }): React.JSX.Element | null — ⚠ undocumented
|
|
336
|
+
- `AmmoCounter` (function): function AmmoCounter({ loaded, reserve, magazine, width = 160, style, className, }: { loaded: number; reserve?: number; /** Magazine capacity; drives the segment count and fill fraction. Default = `loaded`. */ magazine?: number; width?: number | string; style?: CSSProperties; className?: string; }):… — Loaded-vs-reserve ammunition counter — a segmented magazine plus a reserve tally.
|
|
337
|
+
- `ArmorSlots` (function): function ArmorSlots(props: SlotGridProps): React.JSX.Element — Armor piece slots.
|
|
338
|
+
- `AtomicBarProps` (interface): interface AtomicBarProps — Shared props for every atomic bar — bound to a stat (`statId`/`entityId`) or explicit (`value`).
|
|
339
|
+
- `BarShape` (type): type BarShape = "rect" | "pill" | "skew" | "chamfer" — Trough shape language — `rect` (default), `pill` (fully round), `skew` (parallelogram, upright label), or `chamfer` (cut corners). Matches a game's skin without hand-rolling a local bar.
|
|
340
|
+
- `BarTokens` (interface): interface BarTokens — Atomic, purpose-named vitals — one component per readout (`HealthBar`, `ShieldBar`, …), never a `tone`-switched umbrella and never a bundled combo. Every bar reads the same shared CSS custom properties (`--jg-health`, `--jg-shield`, `--jg-xp`, plus frame/shape tokens). Default token colors are scaffolding only: games own layout, framing, and art direction, and must set tokens (or replace the markup) so the HUD is unique to the pitch — the engine ships parts, not a face.
|
|
341
|
+
- `BarsPreview` (function): function BarsPreview({ className }: { className?: string }): React.JSX.Element — Renders the atomic bar matrix twice under different token blocks to prove global re-theming.
|
|
307
342
|
- `BetterAuthSessionState` (interface): interface BetterAuthSessionState — ⚠ undocumented
|
|
308
343
|
- `BetterAuthUserShape` (interface): interface BetterAuthUserShape — ⚠ undocumented
|
|
344
|
+
- `BossBar` (function): function BossBar(props: AtomicBarProps & { name?: string }): React.JSX.Element — A wide encounter/boss health bar with the boss name at the start.
|
|
309
345
|
- `CaptureOdds` (function): function CaptureOdds({ chance, className, fillClassName, }: { chance: number; className?: string; fillClassName?: string; }): React.JSX.Element — ⚠ undocumented
|
|
310
346
|
- `CardFace` (function): function CardFace({ rank, suit, faceDown = false, width = 64, height = 90, className, style, children, }: { rank: Rank; suit: Suit; faceDown?: boolean; width?: number; height?: number; className?: string; style?: CSSProperties; children?: ReactNode; }): React.JSX.Element — A single playing-card face: rank + suit pips, or a patterned back when `faceDown`.
|
|
311
347
|
- `CardStack` (function): function CardStack({ pile, zone, cardOf, ...rest }: { pile: CardPileState; zone: string; cardOf: (id: string) => PlayingCard; } & Omit<Parameters<typeof StackedPile>[0], "cards">): React.JSX.Element — `StackedPile` bound to a headless `CardPileState` zone: reads the ordered card ids from `pile.zones[zone]` and resolves each to a `PlayingCard` via `cardOf`.
|
|
312
348
|
- `ChannelTabs` (function): function ChannelTabs({ channels, active, onSelect, className, tabClassName, activeTabClassName, renderTab, }: { channels?: readonly string[]; active: string; onSelect: (channelId: string) => void; className?: string; tabClassName?: string; activeTabClassName?: string; renderTab?: (channelId: string,… — ⚠ undocumented
|
|
349
|
+
- `CharacterSheet` (function): function CharacterSheet({ slots, stats, name, subtitle, portrait, header, title = "Character", variation = "themed", slotSize, onSlotActivate, className, style, }: CharacterSheetProps): ReactNode — Drop-in character sheet: a {@link HudFrame} wrapping an optional name/subtitle/portrait header, the equip-slot {@link Paperdoll}, and the derived-stat {@link StatList}. The game supplies slots, stats, header content, and the activation callback, and owns the window that toggles it (this component does not manage its own open/close). Pure composition over existing primitives and HudTheme tokens.
|
|
350
|
+
- `CharacterSheetProps` (interface): interface CharacterSheetProps — Props for {@link CharacterSheet}.
|
|
313
351
|
- `ChatBubble` (interface): interface ChatBubble — ⚠ undocumented
|
|
314
352
|
- `ChatBubblesOptions` (interface): interface ChatBubblesOptions — ⚠ undocumented
|
|
315
353
|
- `ChatInput` (function): function ChatInput({ channelId, className, inputClassName, buttonClassName, placeholder, sendLabel, onSent, onRejected, }: { channelId: string; className?: string; inputClassName?: string; buttonClassName?: string; placeholder?: string; sendLabel?: ReactNode; onSent?: (message: ChatMessage) => void;… — ⚠ undocumented
|
|
@@ -318,14 +356,16 @@
|
|
|
318
356
|
- `ClerkUserShape` (interface): interface ClerkUserShape — ⚠ undocumented
|
|
319
357
|
- `ClerkUserState` (interface): interface ClerkUserState — ⚠ undocumented
|
|
320
358
|
- `Clock` (function): function Clock({ format = "24h", showDay = true, controls = false, style, className, }: { format?: "24h" | "12h"; showDay?: boolean; controls?: boolean; style?: CSSProperties; className?: string; }): React.JSX.Element — A time-of-day clock reading the sim calendar — `Day N · HH:MM`, 24h or 12h. `controls` adds pause + the game's speed multipliers as clickable pills (the "fast-forward" bar), off by default so a game opts into letting the player scrub time.
|
|
321
|
-
- `Coins` (function): function Coins({ currencyId, icon = "🪙", style, className, }: { currencyId: string; icon?: ReactNode; style?: CSSProperties; className?: string; }): React.JSX.Element — A currency counter — an icon (emoji/char, default a coin) plus the live amount for `currencyId`.
|
|
322
|
-
- `Compass` (function): function Compass({ facingYaw, center, markers, width = 340, fov = (Math.PI * 2) / 3, kindStyles = DEFAULT_MARKER_KINDS, className, }: CompassProps): ReactNode — Horizontal compass strip centered on the player's facing direction, with the eight cardinals and optional marker pips
|
|
359
|
+
- `Coins` (function): function Coins({ currencyId, icon = "🪙", style, className, }: { currencyId: string; icon?: ReactNode; style?: CSSProperties; className?: string; }): React.JSX.Element — A currency counter — an icon (emoji/char, default a coin) plus the live amount for `currencyId`. *
|
|
360
|
+
- `Compass` (function): function Compass({ facingYaw, center, markers, width = 340, fov = (Math.PI * 2) / 3, kindStyles = DEFAULT_MARKER_KINDS, className, }: CompassProps): ReactNode — Horizontal compass strip centered on the player's facing direction, with the eight cardinals and optional marker pips from static views, an external source, or a native `MarkerSet`.
|
|
323
361
|
- `CompassProps` (interface): interface CompassProps — ⚠ undocumented
|
|
324
362
|
- `ControlHint` (interface): interface ControlHint — One row of a control legend. Name the game action(s) whose bound key(s) to show (`action`) so the glyphs come straight from the keybind map — never re-typed — or give literal `keys` for controls that live outside the map (`"Mouse"`, `"LMB"`). `label` says what the control does.
|
|
325
363
|
- `ControlsList` (function): function ControlsList({ bindings, controls, hideOnCoarsePointer = true, separator = " / ", className, rowClassName, keysClassName, keyClassName, separatorClassName, labelClassName, renderKey, renderRow, }: { bindings?: ActionCodesMap; controls: readonly ControlHint[]; hideOnCoarsePointer?: boolean; … — Renders a controls legend whose key glyphs come from the game's keybind map, so bindings live in one place and never drift from a hand-typed table. Hides itself on coarse-pointer devices (a touchscreen has no keyboard) via the same `data-jg-kbd-hint` marker as `KeyHint`. Headless: every part carries a `className` slot and `data-*` hook; pass `renderKey`/`renderRow` to fully own the markup.
|
|
326
364
|
- `Crosshair` (function): function Crosshair({ size = 18, gap = 5, thickness = 2, color = "rgba(255,255,255,0.85)", style, className, }: { size?: number; gap?: number; thickness?: number; color?: string; style?: CSSProperties; className?: string; }): React.JSX.Element — A minimal center crosshair reticle — four ticks around a gap. Purely presentational.
|
|
327
365
|
- `CurrencyPill` (function): function CurrencyPill({ currencyId, className }: { currencyId: string; className?: string }): React.JSX.Element — ⚠ undocumented
|
|
366
|
+
- `DEFAULT_BAR_TOKENS` (const): const DEFAULT_BAR_TOKENS: Required<BarTokens> — Built-in default values for every vitals token — scaffolding/preview only, not a shipped look.
|
|
328
367
|
- `DeathScreen` (function): function DeathScreen({ statId = "health", open, className, children, }: { statId?: string; open?: boolean; className?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
368
|
+
- `DefaultEquipSlotId` (type): type DefaultEquipSlotId = | "head" | "chest" | "hands" | "legs" | "feet" | "mainHand" | "offHand" | "ring1" | "ring2" | "trinket" — Slot ids used by {@link defaultEquipLayout}'s convenience arrangement.
|
|
329
369
|
- `DialogueBox` (function): function DialogueBox({ dialogue, onChoice, rng, className, lineClassName, speakerClassName, choicesClassName, choiceClassName, checkClassName, }: { dialogue: DialogueDef; onChoice?: (choice: DialogueChoice, result: CheckResult | null) => void; rng?: () => number; className?: string; lineClassName?: … — ⚠ undocumented
|
|
330
370
|
- `DialogueCheck` (interface): interface DialogueCheck — ⚠ undocumented
|
|
331
371
|
- `DialogueChoice` (interface): interface DialogueChoice — ⚠ undocumented
|
|
@@ -342,8 +382,13 @@
|
|
|
342
382
|
- `EmoteWheel` (function): function EmoteWheel({ emotes, radius, open = true, className, emoteClassName, onPlayed, onRejected, renderEmote, }: { emotes: readonly string[]; radius?: number; open?: boolean; className?: string; emoteClassName?: string; onPlayed?: (emoteId: string) => void; onRejected?: (reason: string) => void; … — ⚠ undocumented
|
|
343
383
|
- `EntityPortrait` (function): function EntityPortrait({ entity, selected = false, size = 44, vitalId = "health", tabIndex, onSelect, renderIcon, className, style, }: { entity: EntitySummaryDef; selected?: boolean; size?: number; vitalId?: string; tabIndex?: number; onSelect?: (id: string) => void; renderIcon?: (entity: EntitySum… — A selectable entity portrait tile — icon/initials, an optional thin health strip, and complete selected/hover/focus states as a real `<button>` (`aria-pressed`). The unit-of-a-selection chrome; swap the face via `renderIcon`. Accessible and keyboard-focusable.
|
|
344
384
|
- `EntitySummary` (function): function EntitySummary({ entity, renderVital, className, style, }: { entity: EntitySummaryDef; renderVital?: (vital: EntityVital) => ReactNode; className?: string; style?: CSSProperties; }): React.JSX.Element — The primary-entity detail chrome — name, tags, and full vital bars for the focused member. The "who is selected" summary a single-selection or the head of a multi-selection shows. Swap the vital rows via `renderVital`.
|
|
385
|
+
- `EquipSlot` (interface): interface EquipSlot — One named equip slot: a stable `id`, a display `label`, its worn `item` (or `null` = empty), and where it sits.
|
|
386
|
+
- `EquipSlotLayout` (type): type EquipSlotLayout = readonly EquipSlot[] — An ordered set of equip slots that make up a paperdoll. Caller-supplied; see {@link defaultEquipLayout}.
|
|
387
|
+
- `EquipSlotPosition` (type): type EquipSlotPosition = "left" | "right" | "bottom" — Character-sheet / paperdoll composition (#1033 follow-up): a drop-in `<CharacterSheet>` that arranges caller-supplied equip slots as a paperdoll around a portrait and lists derived stats, all inside a {@link HudFrame}. It reuses the atomic slot rendering ({@link EquipmentSlots}) and the shared `--jg-slot-*` / `--jg-accent` HudTheme tokens (#1034) — the game owns which slots and which stats matter (both are props), the skin, and the window that toggles it open/closed. No genre list is baked in; {@link defaultEquipLayout} is a convenience arrangement the game can override wholesale.
|
|
388
|
+
- `EquipmentSlots` (function): function EquipmentSlots(props: SlotGridProps): React.JSX.Element — Worn-gear slots (head/chest/hands/…): one atomic grid, painted icons, themed from tokens.
|
|
345
389
|
- `EventMeterView` (interface): interface EventMeterView — A rendered snapshot of an {@link EventMeter}: current value, fill fraction, active tier, and ready-to-consume flag.
|
|
346
390
|
- `EventfulEngineStore` (interface): interface EventfulEngineStore<TEventMap extends object> — ⚠ undocumented
|
|
391
|
+
- `ExperienceBar` (const): const ExperienceBar: (props: AtomicBarProps) => React.JSX.Element — Level progress / experience.
|
|
347
392
|
- `FriendRequestsList` (function): function FriendRequestsList({ className, rowClassName, acceptClassName, declineClassName, emptyState, renderRequest, }: { className?: string; rowClassName?: string; acceptClassName?: string; declineClassName?: string; emptyState?: ReactNode; renderRequest?: (request: FriendRequestEntry) => ReactNode… — ⚠ undocumented
|
|
348
393
|
- `FriendRow` (function): function FriendRow({ friend, className, dotClassName, children, }: { friend: FriendEntry; className?: string; dotClassName?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
349
394
|
- `FriendsList` (function): function FriendsList({ className, rowClassName, dotClassName, emptyState, renderFriend, }: { className?: string; rowClassName?: string; dotClassName?: string; emptyState?: ReactNode; renderFriend?: (friend: FriendEntry) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
@@ -353,15 +398,36 @@
|
|
|
353
398
|
- `GamePreviewStates` (type): type GamePreviewStates = Record<string, GamePreviewComponent> — ⚠ undocumented
|
|
354
399
|
- `GameProvider` (function): function GameProvider({ context, children }: { context: GameContext; children?: ReactNode }): React.JSX.Element — ⚠ undocumented
|
|
355
400
|
- `GameViewportProvider` (function): function GameViewportProvider({ platforms, className, style, children, }: { platforms?: readonly HudPlatform[]; className?: string; style?: CSSProperties; children?: ReactNode; }): React.JSX.Element — Provides the shared game viewport layout to everything it wraps. Mount it once around the whole game presentation (world, HUD, controls, system UI) so every subsystem reads one coordinated geometry and registers its rect for collision detection. Publishes live `--jg-viewport-*` / `--jg-visual-viewport-*` / `--jg-safe-*` CSS variables on its root.
|
|
356
|
-
- `
|
|
357
|
-
- `
|
|
401
|
+
- `HUD_THEME_PRESETS` (const): const HUD_THEME_PRESETS: { "arcane-stone": HudTheme; "survival-wood": HudTheme; "military-flat": HudTheme; "sleek-hex": HudTheme; "elemental-circle": HudTheme; "sandbox-slot": HudTheme; } — Built-in theme presets for demos/scaffold only — not product identity; games author their own theme.
|
|
402
|
+
- `HealthBar` (const): const HealthBar: (props: AtomicBarProps) => React.JSX.Element — Player/enemy health — danger-flashes to `--jg-health-low` below a quarter full.
|
|
403
|
+
- `Hotbar` (function): function Hotbar({ inventoryId, activeSlot, keys, slotSize = 46, itemIcon, style, className, }: { inventoryId: string; activeSlot?: number; keys?: readonly string[]; slotSize?: number; /** Caller-supplied item id → icon registry; return null/undefined to fall back to the default glyph. */ itemIcon?: … — A numbered hotbar bound to an inventory — painted iconed slots (a `GameIcon` glyph over a school-keyed gradient with a count badge, #1035), an active-slot highlight, and a keycap per slot. Place it and pass the `inventoryId`; `activeSlot` highlights the equipped one. Supply `itemIcon` to map your item ids to your own glyphs — the default resolves a `GameIcon` from the item id.
|
|
358
404
|
- `HudCanvas` (function): function HudCanvas({ layout, editChord, compactScale, showDuring, className, style, children, }: { layout: HudLayoutStore; editChord?: HudEditChord | false; /** Zoom applied to the whole HUD on compact displays. Default 0.85. */ compactScale?: number; /** Opt-in play-phase gate: render the HUD only … — Full-viewport HUD surface. Panels declared with `HudPanel` flow into nine anchor regions and stack automatically with a gap — no per-panel pixel offsets, no manual clearance for sibling panels, the touch-control dock (`--jg-hud-dock-clearance`), or device safe areas. On compact displays the whole surface scales down and each panel applies its `compact` behavior.
|
|
359
405
|
- `HudCompactMode` (type): type HudCompactMode = "keep" | "chip" | "hide" — How a panel behaves on compact (phone-scale) displays. `keep` stays visible at the global compact scale, `chip` collapses to a small tap-to-expand pill, `hide` unmounts entirely.
|
|
360
406
|
- `HudEditChord` (interface): interface HudEditChord — ⚠ undocumented
|
|
407
|
+
- `HudFrame` (function): function HudFrame({ variation = "glass", shape = "rounded", title, aside, padding, width, interactive, className, style, children, }: HudFrameProps): ReactNode — Optional framed panel primitive — a single `<div data-hud-frame>` with a `glass`, `plate`, `retro`, or `themed` skin, optional `title`/`aside` header, and caller `style` merged last. Shared building block for demos and token-themed widgets; games own product chrome and art direction (see AGENTS.md).
|
|
408
|
+
- `HudFrameProps` (interface): interface HudFrameProps — Props for {@link HudFrame}.
|
|
409
|
+
- `HudFrameShape` (type): type HudFrameShape = "rounded" | "circle" | "square" — Frame corner shape — `rounded` (the variation's default radius), `circle` (fully round), or `square` (no radius).
|
|
410
|
+
- `HudFrameVariation` (type): type HudFrameVariation = "glass" | "plate" | "retro" | "themed" — Frame skin — `glass` (the shared dark-glass panel), `plate` (a heavier opaque plate), `retro` (a hard black-outlined frame), or `themed` (driven by the `--jg-frame-*` `HudTheme` tokens).
|
|
411
|
+
- `HudLayoutPersist` (type): type HudLayoutPersist = (id: string, panel: EditorUiPanelLayout) => void — Host-owned callback that commits one HUD panel layout into the scene document (typically an undoable `setUiPanel` dispatch). Injected by the editor so product UI never reaches for editor globals.
|
|
412
|
+
- `HudLayoutPersistProvider` (function): function HudLayoutPersistProvider({ onPanelCommit, children, }: { onPanelCommit: HudLayoutPersist; children?: ReactNode; }): React.JSX.Element — Provides {@link HudLayoutPersist} / `onPanelCommit` to descendant `useHudLayout` calls. Mount around game UI when a host can accept document UI patches (editor). Absent provider → canvas moves/resizes are no-ops for document writes.
|
|
361
413
|
- `HudPanel` (function): function HudPanel({ id, anchor = "top-left", order, compact: compactMode = "keep", chip, interactive, inset, locked, showDuring, priority, mobileBehavior, allowOverlapWith, collisionGroup, region = true, width, height, type, className, style, children, }: { id: string; anchor?: HudAnchor; /** Stack … — A HUD block that lives in one of the nine anchor regions. Panels sharing a region stack outward from the screen edge in ascending `order`. On fine pointers panels stay draggable through the edit chord; a dragged panel leaves the flow and keeps its custom placement. On compact displays custom placements are ignored and the `compact` behavior applies.
|
|
414
|
+
- `HudTheme` (interface): interface HudTheme — A full HUD theme.
|
|
415
|
+
- `HudThemeBar` (interface): interface HudThemeBar — Framed-trough tokens shared by every atomic bar.
|
|
416
|
+
- `HudThemeFrame` (interface): interface HudThemeFrame — Frame material + shape tokens (panels, `HudFrame variation="themed"`).
|
|
417
|
+
- `HudThemePalette` (interface): interface HudThemePalette — `HudTheme` (#1034): one token object that restyles shared token-driven building blocks at once. It is the superset of the atomic-bar tokens (#1033) — `hudThemeVars(theme)` emits the same `--jg-*` custom properties the bars already read, plus frame / slot / minimap-ring tokens — so setting a **game-authored** theme on any HUD ancestor re-skins those primitives. Purely CSS-token driven (no image assets). Tokens are not a finished UI: every game still owns composition, skin, and art direction (see AGENTS.md). Built-in presets are demo/scaffold starting points only.
|
|
418
|
+
- `HudThemePreset` (type): type HudThemePreset = keyof typeof HUD_THEME_PRESETS — Built-in demo/scaffold theme preset name — not a game identity.
|
|
419
|
+
- `HudThemePreview` (function): function HudThemePreview({ className }: { className?: string }): React.JSX.Element — Renders the default theme plus every genre preset as a deterministic matrix.
|
|
420
|
+
- `HudThemeSlot` (interface): interface HudThemeSlot — Action/inventory slot tokens.
|
|
362
421
|
- `HudViewportContextValue` (interface): interface HudViewportContextValue — ⚠ undocumented
|
|
363
422
|
- `HudViewportProvider` (function): function HudViewportProvider({ platforms, config, userScale, children, }: { platforms: readonly HudPlatform[] | undefined; config: HudViewportConfig | undefined; userScale?: number; children?: ReactNode; }): React.JSX.Element — Mounted by the shell around `GameUI` so every `HudCanvas` inside the game picks up the game's `platforms`/`hudFit` declaration and the player's UI scale setting without any game-side wiring.
|
|
423
|
+
- `IconSchool` (type): type IconSchool = | "fire" | "frost" | "arcane" | "nature" | "holy" | "tech" | "shadow" | "steel" | "neutral" — `IconTreatment` (#1035): a procedural painted-icon face — a glyph over a school-keyed radial gradient, with a vignette inset shadow, a top gloss highlight, and optional count/keycap badges. Turns the engine's flat white `GameIcon` glyphs (and game-icons.net SVGs) into painted ability / item icons that read as AAA slots, not debug UI. Theme-aware: the frame reads the `--jg-slot-*` and `--jg-accent` `HudTheme` tokens (#1034), so a theme change re-skins every treated icon.
|
|
424
|
+
- `IconTreatment` (function): function IconTreatment({ icon, glyph, school = "neutral", size = 44, count, keycap, active = false, className, style, }: IconTreatmentProps): React.JSX.Element — A painted icon face — gradient + vignette + gloss behind a glyph, with count/keycap badges.
|
|
425
|
+
- `IconTreatmentProps` (interface): interface IconTreatmentProps — Props for {@link IconTreatment}.
|
|
426
|
+
- `IconsPreview` (function): function IconsPreview({ className }: { className?: string }): React.JSX.Element — Renders the school-gradient row and a treated-icon hotbar — the deterministic #1035 fixture.
|
|
364
427
|
- `IdentitySource` (interface): interface IdentitySource — ⚠ undocumented
|
|
428
|
+
- `InventoryGrid` (function): function InventoryGrid({ inventoryId, columns, size = 44, gap = 6, itemIcon, onActivate, className, style, }: InventoryGridProps): React.JSX.Element — A drop-in inventory grid with drag/swap/stack-merge/split and full keyboard control, bound to `inventoryId`.
|
|
429
|
+
- `InventoryGridBinding` (interface): interface InventoryGridBinding — Live slots plus `move`/`split` actions bound to `inventoryId`, routed through the notifying `inventory.move`/`inventory.split` commands so React re-renders.
|
|
430
|
+
- `InventoryGridProps` (interface): interface InventoryGridProps — Props for {@link InventoryGrid}.
|
|
365
431
|
- `InviteToWorldButton` (function): function InviteToWorldButton({ toUserId, target, className, children, onInvited, onRejected, }: { toUserId: string; target: WorldInviteTarget; className?: string; children?: ReactNode; onInvited?: (inviteId: string) => void; onRejected?: (reason: string) => void; }): React.JSX.Element | null — ⚠ undocumented
|
|
366
432
|
- `JoinByCode` (function): function JoinByCode({ onJoin, className, inputClassName, buttonClassName, placeholder, children, }: { onJoin: (code: string) => void; className?: string; inputClassName?: string; buttonClassName?: string; placeholder?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
367
433
|
- `KeyHint` (function): function KeyHint({ children, className, style, }: { children: ReactNode; className?: string; style?: CSSProperties; }): React.JSX.Element | null — Wraps a keyboard/mouse control hint (a cap plus what it does). Renders nothing on coarse-pointer devices — a touchscreen has no keyboard, so the hint is noise and only fights the on-screen controls for space. The `data-jg-kbd-hint` marker is also hidden by an engine stylesheet as a hydration-safe backstop, so a hint stays hidden on touch even before this component's effect runs. Put the touch equivalent (a `TouchControls` dock, a tappable button) on the coarse branch instead.
|
|
@@ -370,20 +436,31 @@
|
|
|
370
436
|
- `LayoutRegionSpec` (type): type LayoutRegionSpec = Omit<LayoutRegion, "rect"> — A region descriptor without its measured rectangle — the caller supplies geometry through `useRegisterLayoutRegion`.
|
|
371
437
|
- `LeavePartyButton` (function): function LeavePartyButton({ className, children, }: { className?: string; children?: ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
372
438
|
- `LevelUpFlash` (function): function LevelUpFlash({ stat, durationMs = 1600, className, children, renderFlash, }: { stat?: string; durationMs?: number; className?: string; children?: ReactNode; renderFlash?: (event: StatLevelUpEvent) => ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
439
|
+
- `ManaBar` (const): const ManaBar: (props: AtomicBarProps) => React.JSX.Element — Spell/energy resource pool.
|
|
373
440
|
- `MapBounds` (interface): interface MapBounds — ⚠ undocumented
|
|
374
441
|
- `MicToggle` (function): function MicToggle({ voice, className, mutedLabel, unmutedLabel, }: { voice: VoiceState; className?: string; mutedLabel?: ReactNode; unmutedLabel?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
375
|
-
- `Minimap` (function): function Minimap({ markers, center, worldRadius, fog, size = 176, facingYaw = 0, rotate = false, kindStyles = DEFAULT_MARKER_KINDS, background, mapBounds, routes, zones, cellStates, onWorldClick, className, title = "Map", children, }: MinimapProps): ReactNode — Framed circular minimap: optional baked terrain background, reveal-on-event fog overlay, categorized marker icons, and a facing arrow. Reads a
|
|
442
|
+
- `Minimap` (function): function Minimap({ markers, center, worldRadius, fog, size = 176, facingYaw = 0, rotate = false, kindStyles = DEFAULT_MARKER_KINDS, background, mapBounds, routes, zones, cellStates, onWorldClick, className, style, title = "Map", children, }: MinimapProps): ReactNode — Framed circular minimap: optional baked terrain background, reveal-on-event fog overlay, categorized marker icons, and a facing arrow. Reads static marker views, an external marker source, or a native `MarkerSet`; supply your own `kindStyles` palette to reskin. Does not require `GameProvider`.
|
|
376
443
|
- `MinimapChrome` (function): function MinimapChrome({ view, frame = false, frameColor = "rgba(148,163,184,0.4)", frameStrokeWidth = 1.5, cardinalLabel = "N", markers = [], markerColor = "#e2e8f0", markerRadius = 5, className, }: MinimapChromeProps): ReactNode — Headless minimap chrome — nests inside a game's own `<svg>`: an optional ring frame, and edge-clamped marker dots that draw as directional arrows when a marker carries a `heading` (the compass-arrow / player-blip layer ~8 games were re-drawing by hand over `projectToMinimap`/`clampToMinimapEdge`). Renders a bare `<g>` — no background, panel, or title; compose your own content layer (routes, zones, terrain) as sibling SVG nodes for full control of z-order, or call `MinimapChrome` twice (once for `frame`, again for `markers`) to sandwich custom content between the ring and the blips.
|
|
377
444
|
- `MinimapChromeMarker` (interface): interface MinimapChromeMarker — One dot (or, with `heading`, a rotated arrow) drawn by `MinimapChrome`.
|
|
378
445
|
- `MinimapChromeProps` (interface): interface MinimapChromeProps — Props for `MinimapChrome`.
|
|
379
446
|
- `MinimapPanel` (function): function MinimapPanel({ zoneLabel, clock, showCompass = true, compassProps, headerClassName, zoneLabelClassName, clockClassName, compassClassName, children, ...minimapProps }: MinimapPanelProps): ReactNode — Composed circular-minimap chrome: optional zone-label + clock header above the `Minimap`, optional `Compass` strip below. Purely a wiring layer over the existing primitives — the game supplies the zone name and clock text, this only places them; omit either slot and the header disappears.
|
|
380
447
|
- `MinimapPanelProps` (interface): interface MinimapPanelProps extends MinimapProps — Props for `MinimapPanel` — all `MinimapProps` plus the zone-label/clock header and compass slots.
|
|
381
448
|
- `MinimapProps` (interface): interface MinimapProps — ⚠ undocumented
|
|
449
|
+
- `MinimapTrack` (function): function MinimapTrack({ spans = [], pips = [], width = "100%", height = 12, railColor = "rgba(255,255,255,0.10)", className, style, children, }: MinimapTrackProps): ReactNode — Horizontal linear track minimap — a rounded progress rail with colored zone `spans` and gate/exit/player `pips` positioned by 0..1 fraction. The structural counterpart to the radial {@link Minimap} for corridor/route games: fractions are supplied by the caller (via core `trackFraction`), so it reads no store and stays presentation-only, sharing chrome with the radial minimap.
|
|
450
|
+
- `MinimapTrackPip` (interface): interface MinimapTrackPip — A point marker on the {@link MinimapTrack} rail at a 0..1 fraction (e.g. a gate, the exit, or the player).
|
|
451
|
+
- `MinimapTrackProps` (interface): interface MinimapTrackProps — Props for {@link MinimapTrack}.
|
|
452
|
+
- `MinimapTrackSpan` (interface): interface MinimapTrackSpan — A colored span across the {@link MinimapTrack} rail, given by 0..1 `start`/`end` fractions (e.g. from core `trackFraction`).
|
|
453
|
+
- `PanelHost` (function): function PanelHost({ manager, render, panels, variation, shape, width, className, windowClassName, windowStyle, bodyStyle, }: { manager: PanelsManager; /** Content for a panel by id. Takes precedence over `panels`. */ render?: (id: string) => ReactNode; /** Static content map by panel id, used when … — Renders the open panels of a {@link usePanels} manager as absolutely-positioned, draggable, closable windows in z-order — the WoW window layer. Each window uses {@link HudFrame} chrome, is dragged by its title bar, raises focus on pointer-down, and gets its content from the `render` prop (or a `panels` map). Accessible: every window is a `role="dialog"` with an `aria-label` and a focusable close button; ESC-close is wired by the manager. Unskinned — art-direct via `HudTheme` tokens and the `variation`.
|
|
454
|
+
- `PanelKeyResult` (interface): interface PanelKeyResult — React chrome over the headless panel/window model (`@jgengine/core/ui/panelModel`) — the toggleable, draggable, z-stacked windows a WoW-style UI is made of (B for bag, C for character, ESC to close). `usePanels` is the DATA/HOOK layer (open/close/toggle/focus + a keybind listener), `PanelHost` renders the open windows in z-order, and `Window` is a standalone one-off window. All unskinned and token-driven: games reskin via `HudTheme` tokens and by swapping the `HudFrame` variation.
|
|
455
|
+
- `PanelsManager` (interface): interface PanelsManager — The live panel manager returned by {@link usePanels} and consumed by {@link PanelHost}.
|
|
456
|
+
- `Paperdoll` (function): function Paperdoll({ slots, portrait, slotSize = 44, onSlotActivate, className, style }: PaperdollProps): ReactNode — Arranges caller-supplied equip slots as a paperdoll — worn gear in two flanking columns around a center `portrait` (or a silhouette placeholder), with any `bottom` slots in a row beneath it. Each slot reuses the atomic {@link EquipmentSlots} tile (filled icon or themed empty placeholder), carries a label, and is a focusable `role="group"` with an `aria-label`; `onSlotActivate` fires on click/Enter/Space so games can wire drag or an equip picker. Composition and skin stay the game's.
|
|
457
|
+
- `PaperdollProps` (interface): interface PaperdollProps — Props for {@link Paperdoll}.
|
|
382
458
|
- `PartyFrame` (function): function PartyFrame({ className, rowClassName, dotClassName, emptyState, renderMember, }: { className?: string; rowClassName?: string; dotClassName?: string; emptyState?: ReactNode; renderMember?: (member: PartyMemberEntry) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
383
459
|
- `PartyInviteToast` (function): function PartyInviteToast({ className, acceptClassName, declineClassName, renderInvite, }: { className?: string; acceptClassName?: string; declineClassName?: string; renderInvite?: (invite: PartyInviteEntry) => ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
384
460
|
- `PartyMemberRow` (function): function PartyMemberRow({ member, className, dotClassName, children, }: { member: PartyMemberEntry; className?: string; dotClassName?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
385
461
|
- `PlayingCard` (interface): interface PlayingCard — A single card in a stack: an id plus its face and orientation.
|
|
386
462
|
- `Popover` (function): function Popover({ open, anchorRef, side = "top", gap = 8, role = "tooltip", id, children, className, style, }: { open: boolean; anchorRef: { current: HTMLElement | null }; side?: PopoverSide; gap?: number; role?: string; id?: string; children: ReactNode; className?: string; style?: CSSProperties; }… — An accessible popover shell positioned by the pure {@link placePopover} math — flips and clamps against the viewport, renders nothing while closed, and defaults to `role="tooltip"`. Reuse it for an action's hover/focus description or any anchored panel.
|
|
463
|
+
- `PotionSlots` (function): function PotionSlots(props: SlotGridProps): React.JSX.Element — Consumable (health/shield potion) slots.
|
|
387
464
|
- `PresenceDot` (function): function PresenceDot({ userId, className }: { userId: string; className?: string }): React.JSX.Element — ⚠ undocumented
|
|
388
465
|
- `ProximityPrompt` (function): function ProximityPrompt({ prompt, className, }: { prompt: ProximityPromptDef; className?: string; }): React.JSX.Element — ⚠ undocumented
|
|
389
466
|
- `PushToTalkButton` (function): function PushToTalkButton({ voice, className, children, }: { voice: VoiceState; className?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
@@ -402,7 +479,7 @@
|
|
|
402
479
|
- `SelectionGroupChip` (function): function SelectionGroupChip({ group, onSelect, renderIcon, className, style, }: { group: SelectionGroup; onSelect?: (group: SelectionGroup) => void; renderIcon?: (group: SelectionGroup) => ReactNode; className?: string; style?: CSSProperties; }): React.JSX.Element — A same-kind selection chip — icon plus count — for the grouped large-selection view. The default chrome {@link SelectionCollectionChrome} renders per group; swap it via `renderGroup`.
|
|
403
480
|
- `SelectionKeyEvent` (interface): interface SelectionKeyEvent — A minimal keyboard-event shape — a real `KeyboardEvent`/React synthetic satisfies it.
|
|
404
481
|
- `SelectionModel` (interface): interface SelectionModel — The live selection model returned by {@link useSelectionView}.
|
|
405
|
-
- `SelectionPanel` (function): function SelectionPanel({ members, model: providedModel, groupThreshold, labelOf, windowSize, renderPrimary, renderMember, renderVital, onFocusChange, className, style, }: { members?: readonly EntitySummaryDef[]; model?: SelectionModel; groupThreshold?: number; labelOf?: (kind: string) => string; wi… —
|
|
482
|
+
- `SelectionPanel` (function): function SelectionPanel({ members, model: providedModel, groupThreshold, labelOf, windowSize, renderPrimary, renderMember, renderVital, onFocusChange, className, style, }: { members?: readonly EntitySummaryDef[]; model?: SelectionModel; groupThreshold?: number; labelOf?: (kind: string) => string; wi… — Convenience composition: skinned glass panel with {@link EntitySummary} for the primary member beside {@link SelectionCollectionChrome} for the rest — demos/scaffold only, not a finished game face. Pass `members` (or a prebuilt `model`); swap sub-renderers or compose the headless pieces under game-owned chrome for product UI.
|
|
406
483
|
- `SettingsActionView` (interface): interface SettingsActionView — A resolved game-state action — `run` is already bound to the game context and closes the menu.
|
|
407
484
|
- `SettingsCategoryView` (interface): interface SettingsCategoryView — A settings menu category with its rows and keybinds, ready to render.
|
|
408
485
|
- `SettingsController` (interface): interface SettingsController — The live settings controller — every category/row/keybind/action plus open-state. Render it any way you like or drive the engine menu.
|
|
@@ -411,20 +488,30 @@
|
|
|
411
488
|
- `SettingsProvider` (function): function SettingsProvider({ store, children }: { store: SettingsStore; children: ReactNode }): React.JSX.Element — ⚠ undocumented
|
|
412
489
|
- `SettingsRow` (interface): interface SettingsRow — One editable setting rendered in a settings menu category.
|
|
413
490
|
- `SettingsTrigger` (function): function SettingsTrigger({ className, children, label = "Settings", }: { className?: string; children?: ReactNode; label?: string; }): React.JSX.Element | null — Inline settings entry — drop it anywhere in your game's menu or HUD; it opens the themed settings menu. Headless: pass `className` for placement/skin and `children` to replace the default gear glyph. Renders nothing when the game has no settings to show, so it never leaves a dead button behind.
|
|
491
|
+
- `ShieldBar` (const): const ShieldBar: (props: AtomicBarProps) => React.JSX.Element — Absorb/armor shield overlay.
|
|
414
492
|
- `SignOutButton` (function): function SignOutButton({ className, children, }: { className?: string; children?: ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
415
493
|
- `SkillCheckBar` (function): function SkillCheckBar({ config, startedAt, className, trackClassName, zoneClassName, markerClassName, renderStatus, }: { config: SkillCheckConfig; startedAt: number; className?: string; trackClassName?: string; zoneClassName?: string; markerClassName?: string; renderStatus?: (result: SkillCheckResu… — ⚠ undocumented
|
|
416
494
|
- `SlotGrid` (function): function SlotGrid({ inventoryId, className, renderSlot, }: { inventoryId: string; className?: string; renderSlot?: (slot: InventorySlot, index: number) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
495
|
+
- `SlotGridProps` (interface): interface SlotGridProps — Props shared by every atomic slot grid.
|
|
496
|
+
- `SlotItem` (interface): interface SlotItem — Atomic, purpose-named slot grids (#1033): one component per category — `EquipmentSlots`, `WeaponSlots`, `ArmorSlots`, `PotionSlots` — for paperdoll / equip layouts where each grid holds a single gear category. A full multi-category backpack that binds to a live inventory with drag/swap/stack/split is a different, supported shape: reach for `<InventoryGrid>` (`inventoryGrid.tsx`) there, and use these atomic grids for the equip slots around it. Each renders a grid of painted {@link IconTreatment} tiles (glyph + gradient + count badge) for filled slots and a themed placeholder for empty ones, all reading the shared `--jg-slot-*` / `--jg-accent` HudTheme tokens (#1034). Composition stays the game's; the engine ships the grid.
|
|
497
|
+
- `SoulBar` (const): const SoulBar: (props: AtomicBarProps) => React.JSX.Element — Resource-charge / soul-box meter — segmented by default.
|
|
417
498
|
- `SpeakingIndicator` (function): function SpeakingIndicator({ voice, userId, className, threshold = 0.01, children, }: { voice: VoiceState; userId: string; className?: string; threshold?: number; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
418
499
|
- `Speedometer` (function): function Speedometer({ entityId, scale = 3.6, unit = "km/h", max = 60, size = 96, style, className, }: { entityId?: string; scale?: number; unit?: string; max?: number; size?: number; style?: CSSProperties; className?: string; }): React.JSX.Element — A speedometer for an entity (defaults to the local player) — an SVG arc gauge + a digital readout. `scale` converts world units/second to your display unit (3.6 → km/h, 2.237 → mph); `max` sets the gauge's top of scale.
|
|
419
500
|
- `StackedPile` (function): function StackedPile({ cards, faceDown, offsetX = 0, offsetY = 20, cardWidth = 64, cardHeight = 90, layer, dropId, draggableFrom = 0, className, cardClassName, onCardClick, renderOverlay, }: { cards: readonly PlayingCard[]; faceDown?: boolean; offsetX?: number; offsetY?: number; cardWidth?: number; … — An overlapping fan of `CardFace`s. Plain-props: pass `cards`. Optional drag: pass a `layer` to make each card a `DraggableCard`, and `dropId` to wrap the pile in a `DropZone`.
|
|
501
|
+
- `StaminaBar` (const): const StaminaBar: (props: AtomicBarProps) => React.JSX.Element — Sprint/action stamina pool.
|
|
420
502
|
- `StartScreen` (function): function StartScreen({ open = true, className, style, children, settings, settingsPlacement = "top-right", settingsClassName, settingsWrapperClassName, }: { open?: boolean; className?: string; style?: CSSProperties; children?: ReactNode; settings?: boolean | ReactNode; settingsPlacement?: StartScree… — Composable title/attract-screen scaffold: a full-bleed `data-jg-menu` overlay that positions and centers the game's own content, with an opt-in settings corner. It imposes no look — the game supplies the title, art, and buttons as children and styles the container through `className`/`style` (per the composable-chrome rule: a placement hook, not a mandated menu).
|
|
421
503
|
- `StartScreenCorner` (type): type StartScreenCorner = "top-left" | "top-right" | "bottom-left" | "bottom-right" — Which corner of a `StartScreen` the opt-in settings slot is pinned to.
|
|
422
504
|
- `StatBar` (function): function StatBar({ statId = "health", entityId, tone = "health", label, showValue = true, width = 200, icon, style, className, }: { statId?: string; entityId?: string; tone?: StatTone; label?: string; showValue?: boolean; width?: number; icon?: ReactNode; style?: CSSProperties; className?: string; }… — A polished stat bar (health/mana/stamina/shield/xp) — a rounded, glassy meter with a tone-colored fill and an optional value readout. Reads `statId` off `entityId` (defaults to the local player). Renders nothing until the stat exists.
|
|
505
|
+
- `StatList` (function): function StatList({ stats, className, style }: StatListProps): ReactNode — Renders derived character stats as clean small-caps label→value rows, token-themed. Rows carrying a `group` field are bucketed under a small uppercase header (consecutive same-group rows share one). Pure and prop-driven — the game supplies the rows (from `useEntityStat`/derived values); the engine ships no stat list of its own.
|
|
506
|
+
- `StatListProps` (interface): interface StatListProps — Props for {@link StatList}.
|
|
507
|
+
- `StatMeter` (function): function StatMeter({ instanceId, statId, className, fillClassName, }: { instanceId: string; statId: string; className?: string; fillClassName?: string; }): React.JSX.Element | null — A headless, unstyled stat meter — an accessible `role="progressbar"` you paint entirely through `className`/`fillClassName`. This is the class-hook primitive for teams supplying their own CSS; for a batteries-included themed bar use the atomic, token-styled components in `@jgengine/react/bars` (`HealthBar`, `ShieldBar`, …). Renamed from `HealthBar` in #1033 so the purpose-named atomic bar owns that name and no two components share it.
|
|
508
|
+
- `StatRow` (interface): interface StatRow — One derived-stat row. `group` optionally buckets rows under a small header.
|
|
423
509
|
- `StatTone` (type): type StatTone = keyof typeof TONES — A stat tone — picks the bar's color ramp.
|
|
424
510
|
- `Suit` (type): type Suit = "clubs" | "diamonds" | "hearts" | "spades" — The four French-deck suits.
|
|
425
511
|
- `ToastStack` (function): function ToastStack({ action, limit = 4, className, renderToast, }: { action: string; limit?: number; className?: string; renderToast?: (entry: FeedEntry, index: number) => ReactNode; }): React.JSX.Element | null — Render `ctx.game.feed`'s entries for `action` as a newest-first toast stack — the feed-backed sibling of `@jgengine/core/game/toasts`' `createToastQueue`. Reach for this when the message source is already an engine event bound onto `ctx.game.feed` (kill feed, quest updates, loot log); reach for a `createToastQueue` when the game raises ad-hoc messages that need their own TTL independent of the feed's ring buffer.
|
|
426
512
|
- `UseActionBarOptions` (interface): interface UseActionBarOptions — Options for {@link useActionBar}.
|
|
427
513
|
- `UseAxisChannelResult` (interface): interface UseAxisChannelResult — ⚠ undocumented
|
|
514
|
+
- `UsePanelsOptions` (interface): interface UsePanelsOptions — Options for {@link usePanels}.
|
|
428
515
|
- `UseSelectionViewOptions` (interface): interface UseSelectionViewOptions — Options for {@link useSelectionView}.
|
|
429
516
|
- `UseVoiceOptions` (interface): interface UseVoiceOptions — ⚠ undocumented
|
|
430
517
|
- `UserBadge` (function): function UserBadge({ className, avatarClassName, nameClassName, renderBadge, }: { className?: string; avatarClassName?: string; nameClassName?: string; renderBadge?: (session: AuthSession) => ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
@@ -433,6 +520,8 @@
|
|
|
433
520
|
- `VoiceRoster` (function): function VoiceRoster({ voice, className, participantClassName, renderParticipant, }: { voice: VoiceState; className?: string; participantClassName?: string; renderParticipant?: (participant: VoiceParticipant, gain: number) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
434
521
|
- `VoiceState` (interface): interface VoiceState — ⚠ undocumented
|
|
435
522
|
- `WaveBanner` (function): function WaveBanner({ wave, label = "Wave", subtitle, style, className, }: { wave: number | string; label?: string; subtitle?: ReactNode; style?: CSSProperties; className?: string; }): React.JSX.Element — A wave / round banner — a bold centered pill for "WAVE 3" style callouts, with an optional subtitle (enemies remaining, timer). Pure display: pass the current `wave` and whatever subtitle you track.
|
|
523
|
+
- `WeaponSlots` (function): function WeaponSlots(props: SlotGridProps): React.JSX.Element — Weapon loadout slots.
|
|
524
|
+
- `Window` (function): function Window({ title, ariaLabel, closable = true, onClose, x, y, onMove, z, width, variation, shape, className, style, bodyStyle, children, }: { title: ReactNode; ariaLabel?: string; closable?: boolean; onClose?: () => void; /** Initial (uncontrolled) or current (controlled, with `onMove`) x posi… — A single standalone window — title bar, close button, and title-bar drag over {@link HudFrame} chrome — usable without the {@link usePanels} manager for a one-off dialog. Position is uncontrolled (seeded by `x`/`y`) unless both `x`/`y` and `onMove` are supplied, in which case the caller owns placement. Accessible: `role="dialog"` with an `aria-label` and a focusable close button.
|
|
436
525
|
- `WorldBrowser` (function): function WorldBrowser({ listings, onJoin, className, rowClassName, joinClassName, emptyState, renderListing, }: { listings: readonly SessionListing[]; onJoin: (listing: SessionListing) => void; className?: string; rowClassName?: string; joinClassName?: string; emptyState?: ReactNode; renderListing?:… — ⚠ undocumented
|
|
437
526
|
- `WorldBrowserState` (interface): interface WorldBrowserState — ⚠ undocumented
|
|
438
527
|
- `WorldInviteToast` (function): function WorldInviteToast({ className, acceptClassName, declineClassName, onAccepted, renderInvite, }: { className?: string; acceptClassName?: string; declineClassName?: string; onAccepted: (target: WorldInviteTarget) => void; renderInvite?: (invite: WorldInvite) => ReactNode; }): React.JSX.Element … — ⚠ undocumented
|
|
@@ -441,18 +530,28 @@
|
|
|
441
530
|
- `abilityKitNeedsHeartbeat` (function): function abilityKitNeedsHeartbeat(kit: AbilityKit, resourceAvailable?: number): boolean — ⚠ undocumented
|
|
442
531
|
- `actionBarKeyAction` (function): function actionBarKeyAction(actions: readonly ResolvedAction[], focusedId: string | null, columns: number, key: string, options?: { wrap?: boolean }): ActionBarKeyResult — Pure keyboard/controller resolver for an action bar: arrows/Home/End move grid focus, Enter/Space activate the focused action, and any other single key routes through {@link actionByHotkey}. Returns the resulting intent without touching the DOM, so it unit-tests headless and `useActionBar` is a thin shell over it.
|
|
443
532
|
- `actionFromAbilitySlot` (function): function actionFromAbilitySlot(slot: AbilitySlotSnapshot, extra?: Partial<ActionDef> & { resourceId?: string }): ActionDef — Composable React renderers over the headless action view model (`@jgengine/core/ui/actionModel`) — the data/renderer/chrome split for an RTS command card, an ability action bar, a build menu, or a radial. `useActionBar` is the DATA/HOOK layer (resolution + focus/hover/keyboard/hotkey), `ActionBarChrome` is the composable RENDERER (swap `renderItem` for custom chrome, or ignore it and consume the model directly for a radial), and `ActionBar` is the batteries-included default. A game swaps renderer or chrome without forking the logic. Layout, dimensions, hotkeys, and catalog-id mapping stay caller-owned.
|
|
533
|
+
- `barTokens` (function): function barTokens(tokens: BarTokens): CSSProperties — A style object binding vitals tokens to CSS custom properties — spread onto any HUD ancestor to restyle every atomic bar under it at once. Only the keys you pass are set; the rest fall back to {@link DEFAULT_BAR_TOKENS} inside the bars. This is the single global-theming seam.
|
|
444
534
|
- `betterAuthIdentity` (function): function betterAuthIdentity(state: BetterAuthSessionState, options?: { signOut?: () => void }): IdentitySource — ⚠ undocumented
|
|
445
535
|
- `chatTransportFromSync` (function): function chatTransportFromSync(sync: ChatSync): ChatTransport — Lifts a callback-style ChatSync (e.g. createWsBackend().chatSyncFor(serverId)) into the hook-shaped ChatTransport contract. Create once per sync — outside render or inside useMemo — so subscriptions survive re-renders.
|
|
446
536
|
- `clerkIdentity` (function): function clerkIdentity(state: ClerkUserState, options?: { signOut?: () => void }): IdentitySource — ⚠ undocumented
|
|
447
537
|
- `createHeldKeyTracker` (function): function createHeldKeyTracker(target: HeldKeyEventTarget): { isDown: (code: string) => boolean; dispose: () => void; } — ⚠ undocumented
|
|
538
|
+
- `defaultEquipLayout` (function): function defaultEquipLayout(items: Partial<Record<DefaultEquipSlotId, SlotItem | null>> = {}): EquipSlot[] — A sensible default paperdoll arrangement — worn armor down the left flank, held gear and jewelry down the right — that the game fills by passing worn items keyed by slot id. Every id is optional; unfilled slots render empty. Games that need a different slot set pass their own {@link EquipSlotLayout}.
|
|
539
|
+
- `defaultHudTheme` (const): const defaultHudTheme: HudTheme — Default theme tokens for previews/scaffold — not a finished game look; author a custom theme.
|
|
448
540
|
- `eventMeterNeedsHeartbeat` (function): function eventMeterNeedsHeartbeat(meter: EventMeter, previous: EventMeterView | null): boolean — True when `meter`'s value/fraction/tier/ready diverge from `previous` — the re-render check `useEventMeter` polls on its heartbeat.
|
|
449
541
|
- `guestIdentity` (function): function guestIdentity(seed?: string): IdentitySource — ⚠ undocumented
|
|
542
|
+
- `hudThemeVars` (function): function hudThemeVars(theme: HudTheme): CSSProperties — Emits the CSS custom properties for a theme — spread onto any HUD ancestor to re-skin the subtree.
|
|
450
543
|
- `hudVisibleInPhase` (function): function hudVisibleInPhase(showDuring: readonly GamePhase[] | undefined, phase: GamePhase): boolean — Whether a HUD element opted into `showDuring` is visible in the current phase; `undefined` = always visible (default).
|
|
451
544
|
- `isRedSuit` (function): function isRedSuit(suit: Suit): boolean — True for the red suits (hearts, diamonds).
|
|
452
545
|
- `latestChatBubbles` (function): function latestChatBubbles(messages: readonly ChatMessage[], nowMs: number, ttlMs: number): ChatBubble[] — ⚠ undocumented
|
|
453
546
|
- `localPlayerEntity` (function): function localPlayerEntity(ctx: GameContext): SceneEntity | null — ⚠ undocumented
|
|
547
|
+
- `panelKeyAction` (function): function panelKeyAction(defs: readonly PanelDef[], state: PanelState, event: { code?: string; key?: string }): PanelKeyResult — Pure keybind resolver for a panel set: ESC resolves to `closeTop` when a closable window is open, and any other key routes through {@link panelByHotkey} (trying `code` then `key`) to a `toggle`. Returns the intent without touching the DOM, so it unit-tests headless and `usePanels` is a thin shell over it.
|
|
454
548
|
- `resolveDialogueInvoke` (function): function resolveDialogueInvoke(choice: DialogueChoice, result: CheckResult | null): { command: string; args?: unknown } | null — ⚠ undocumented
|
|
549
|
+
- `resolveHudTheme` (function): function resolveHudTheme(theme?: HudThemePreset | HudTheme): HudTheme — Resolves a preset name (or a full theme) to a `HudTheme`; falls back to the default theme.
|
|
455
550
|
- `runDialogueChoice` (function): function runDialogueChoice(commands: { run(name: string, input?: unknown): unknown }, choice: DialogueChoice, result: CheckResult | null): void — Route a {@link DialogueBox} choice through the `features.dialogue` bridge: resolve the choice's invoke (honoring a skill-check `result`), run that command, and otherwise close the dialogue — the write side that replaces a per-game `onChoice` that hand-rolls `resolveDialogueInvoke` + `dialogue.close`.
|
|
551
|
+
- `schoolForAction` (function): function schoolForAction(action: string): IconSchool — Infers an {@link IconSchool} from an action id (keyword match); `neutral` when nothing matches.
|
|
552
|
+
- `schoolForItem` (function): function schoolForItem(itemId: string): IconSchool — Infers an {@link IconSchool} from an item id (keyword match); `neutral` when nothing matches.
|
|
553
|
+
- `treatedActionIcon` (function): function treatedActionIcon(action: { id?: string; label?: string; icon?: ReactNode }, size = 40): ReactNode — A ready-made `ActionButton` `renderIcon` that paints the action's `GameIcon` with a treatment.
|
|
554
|
+
- `treatedItemIcon` (function): function treatedItemIcon(itemId: string, options: { size?: number; count?: number; keycap?: string } = {}): ReactNode — Maps an item id to a treated icon — resolves a `GameIcon` glyph and an inferred school.
|
|
456
555
|
- `useAbilitySlot` (function): function useAbilitySlot(kit: AbilityKit, slotId: string, resourceAvailable?: number, options?: AbilitySlotBindingOptions): AbilitySlotSnapshot | null — ⚠ undocumented
|
|
457
556
|
- `useAbilitySlots` (function): function useAbilitySlots(kit: AbilityKit, resourceAvailable?: number, options?: AbilitySlotBindingOptions): AbilitySlotSnapshot[] — ⚠ undocumented
|
|
458
557
|
- `useActionBar` (function): function useActionBar(defs: readonly ActionDef[], options?: UseActionBarOptions): ActionBarModel — The DATA/HOOK layer: resolve `defs` into a live view model with focus, hover, keyboard grid navigation, and hotkey activation. Rendering-agnostic — feed the returned model to {@link ActionBarChrome}, or read it directly to lay out a radial or a bespoke card.
|
|
@@ -481,18 +580,22 @@
|
|
|
481
580
|
- `useGameViewportLayout` (function): function useGameViewportLayout(): GameViewportLayout — The live shared viewport layout. Returns a neutral default outside a `GameViewportProvider` so it never throws in previews.
|
|
482
581
|
- `useHasSettings` (function): function useHasSettings(): boolean — True when the game has any setting or game-action to show — gate your own settings entry on it.
|
|
483
582
|
- `useHeldKeys` (function): function useHeldKeys(): (code: string) => boolean — Held-key predicate backed by window keydown/keyup/blur listeners (blur clears held state so a released-off-window key doesn't stick). SSR-safe: listeners attach in an effect, never at module scope. The returned predicate is stable across renders.
|
|
484
|
-
- `useHudLayout` (function): function useHudLayout(options?: { storageKey?: string; snap?: number; locked?: boolean; /** * Scene-document `ui` section — source of truth for panel placement/size. * When provided, hydrates the layout store (and wins over legacy localStorage). */ documentUi?: EditorUiDocument; /** When true (
|
|
583
|
+
- `useHudLayout` (function): function useHudLayout(options?: { storageKey?: string; snap?: number; locked?: boolean; /** * Scene-document `ui` section — source of truth for panel placement/size. * When provided, hydrates the layout store (and wins over legacy localStorage). */ documentUi?: EditorUiDocument; /** * When true (def… — Layout state for `HudCanvas` — panel placements, edit-mode drag/resize, and per-game persistence.
|
|
584
|
+
- `useHudLayoutPersist` (function): function useHudLayoutPersist(): HudLayoutPersist | null — Injected panel-commit port, or `null` when no host has provided one.
|
|
485
585
|
- `useHudViewport` (function): function useHudViewport(): HudViewportContextValue | null — ⚠ undocumented
|
|
486
586
|
- `useInventory` (function): function useInventory(inventoryId: string): readonly InventorySlot[] — ⚠ undocumented
|
|
587
|
+
- `useInventoryGrid` (function): function useInventoryGrid(inventoryId: string): InventoryGridBinding — Binds a live inventory to a HUD grid: `slots` from {@link useInventory}, and `move`/`split` that run the built-in `inventory.move`/`inventory.split` commands (which notify, so the grid re-renders).
|
|
487
588
|
- `useKeyedStore` (function): function useKeyedStore<T>(handle: KeyedStoreHandle<T>, id: string): T — Subscribe a component to one owner's slot of a typed keyed-family store defined with `defineKeyedStore`. Returns the current value for `id` (or the definition's initial before any write for that id), re-rendering only when that owner's slot changes — the cast-free, boilerplate-free replacement for a hand-written `useGameStore((ctx) => ctx.game.store.get(`prefix:${id}`) as T)`.
|
|
488
589
|
- `useLayoutCollisions` (function): function useLayoutCollisions(): readonly LayoutCollision[] — Live forbidden/warned region collisions (empty outside a provider).
|
|
489
590
|
- `useLeaderboard` (function): function useLeaderboard(stat: string, options: { scope: LeaderboardScope; limit?: number }): { userId: string; value: number }[] — ⚠ undocumented
|
|
591
|
+
- `useLiveMarkers` (function): function useLiveMarkers(rebuild: (markers: MarkerSet, ctx: GameContext) => void, options?: { intervalMs?: number; deps?: DependencyList }): MarkerSet — A self-ticking {@link MarkerSet} kept in sync with the live scene: on a heartbeat (default 100ms, and once immediately) it clears the set and calls `rebuild(markers, ctx)` to repopulate it from the current scene, so a HUD map never hand-rolls a `setInterval` + `markers.clear()` + rescan. Each heartbeat also re-renders the calling component, so player-centered props derived from the live scene each tick (`center`, `facingYaw`, zone name) stay fresh — this fully subsumes the hand-rolled ticker, not just the marker rebuild. The set is stable across renders and re-seeded whenever `ctx`, `intervalMs`, or the supplied `deps` change. SSR-safe: the heartbeat only arms when `window` is available.
|
|
490
592
|
- `useLocalPlayerDead` (function): function useLocalPlayerDead(healthStatId = "health"): boolean — ⚠ undocumented
|
|
491
|
-
- `useMarkers` (function): function useMarkers(markers: MarkerSet): readonly MapMarker[] —
|
|
593
|
+
- `useMarkers` (function): function useMarkers<TMeta = unknown>(markers: MarkerSet<TMeta>): readonly MapMarker<TMeta>[] — Subscribe to a native marker set or external marker source, or read a static marker array.
|
|
492
594
|
- `useNearestWorldItem` (function): function useNearestWorldItem(radius: number): WorldItemRecord | null — Nearest ground item within `radius` of the local player — drives a pickup prompt/highlight.
|
|
493
595
|
- `useOpenDialogueId` (function): function useOpenDialogueId(): string | null — The id of the dialogue `ctx.game.dialogue` (or a `talkable(id)` prompt) currently has open, or `null`. The read side of the `features.dialogue` bridge — a panel looks the id up in its own dialogue catalog and renders {@link DialogueBox}, with no per-game open/close store.
|
|
494
596
|
- `useOptionalGameContext` (function): function useOptionalGameContext(): GameContext | null — The game context if a `GameProvider` is present, otherwise `null` — for chrome that may render outside a running game (showcases, previews).
|
|
495
597
|
- `useOptionalGamePhase` (function): function useOptionalGamePhase(): GamePhase — Live run phase that degrades to `"playing"` when rendered outside a `GameProvider` (component showcases, previews), so phase-gated chrome never throws.
|
|
598
|
+
- `usePanels` (function): function usePanels(defs: readonly PanelDef[], options?: UsePanelsOptions): PanelsManager — The DATA/HOOK layer: wrap the core panel model in state and install a window keybind listener — per-panel hotkeys toggle their window and ESC closes the topmost closable one. Hotkeys are ignored while the player is typing in an input/textarea/contenteditable. The listener is cleaned up on unmount and SSR-safe (armed in an effect). Feed the returned manager to {@link PanelHost}, or drive a bespoke window layout from it directly.
|
|
496
599
|
- `useParty` (function): function useParty(): PartyMemberEntry[] — ⚠ undocumented
|
|
497
600
|
- `usePartyInvites` (function): function usePartyInvites(): PartyInviteEntry[] — ⚠ undocumented
|
|
498
601
|
- `usePlayer` (function): function usePlayer(): { userId: string; isNew: boolean } — ⚠ undocumented
|
|
@@ -521,7 +624,7 @@
|
|
|
521
624
|
|
|
522
625
|
## @jgengine/react/actionHud
|
|
523
626
|
|
|
524
|
-
- `ActionBar` (function): function ActionBar({ defs, columns, layout = "grid", wrap, hotkeys, itemSize, ariaLabel, onActivate, renderItem, className, style, }: { defs: readonly ActionDef[]; columns?: number; layout?: "grid" | "list"; wrap?: boolean; hotkeys?: boolean; itemSize?: number; ariaLabel?: string; onActivate?: (id: … —
|
|
627
|
+
- `ActionBar` (function): function ActionBar({ defs, columns, layout = "grid", wrap, hotkeys, itemSize, ariaLabel, onActivate, renderItem, className, style, }: { defs: readonly ActionDef[]; columns?: number; layout?: "grid" | "list"; wrap?: boolean; hotkeys?: boolean; itemSize?: number; ariaLabel?: string; onActivate?: (id: … — Convenience composition of {@link useActionBar} + glass {@link ActionBarChrome} for demos and scaffolding — not a shipped game face. Pass `defs`, choose `grid`/`list`, and hand it `onActivate`. Games that own their UI compose the headless hook + custom chrome (or swap `renderItem`) instead of shipping this default panel.
|
|
525
628
|
- `ActionBarChrome` (function): function ActionBarChrome({ model, layout = "grid", itemSize = 52, gap = 6, ariaLabel = "Actions", renderItem, className, style, }: { model: ActionBarModel; layout?: "grid" | "list"; itemSize?: number; gap?: number; ariaLabel?: string; renderItem?: (action: ResolvedAction, ctx: ActionItemContext) => … — The composable RENDERER: lay the model's actions out as a `grid` or `list` toolbar with roving tabindex, arrow-key navigation, and a moved DOM focus. `renderItem` swaps per-item chrome; omit it for {@link ActionButton}. A radial or bespoke UI can skip this entirely and read the model. Purely a wiring/behavior layer — no panel skin — so a game art-directs freely.
|
|
526
629
|
- `ActionBarKeyResult` (interface): interface ActionBarKeyResult — The intent a key press resolves to over an action bar: move focus, activate, or ignore.
|
|
527
630
|
- `ActionBarModel` (interface): interface ActionBarModel — The live action-bar model returned by {@link useActionBar}.
|
|
@@ -535,6 +638,26 @@
|
|
|
535
638
|
- `actionFromAbilitySlot` (function): function actionFromAbilitySlot(slot: AbilitySlotSnapshot, extra?: Partial<ActionDef> & { resourceId?: string }): ActionDef — Composable React renderers over the headless action view model (`@jgengine/core/ui/actionModel`) — the data/renderer/chrome split for an RTS command card, an ability action bar, a build menu, or a radial. `useActionBar` is the DATA/HOOK layer (resolution + focus/hover/keyboard/hotkey), `ActionBarChrome` is the composable RENDERER (swap `renderItem` for custom chrome, or ignore it and consume the model directly for a radial), and `ActionBar` is the batteries-included default. A game swaps renderer or chrome without forking the logic. Layout, dimensions, hotkeys, and catalog-id mapping stay caller-owned.
|
|
536
639
|
- `useActionBar` (function): function useActionBar(defs: readonly ActionDef[], options?: UseActionBarOptions): ActionBarModel — The DATA/HOOK layer: resolve `defs` into a live view model with focus, hover, keyboard grid navigation, and hotkey activation. Rendering-agnostic — feed the returned model to {@link ActionBarChrome}, or read it directly to lay out a radial or a bespoke card.
|
|
537
640
|
|
|
641
|
+
## @jgengine/react/bars
|
|
642
|
+
|
|
643
|
+
- `AmmoCounter` (function): function AmmoCounter({ loaded, reserve, magazine, width = 160, style, className, }: { loaded: number; reserve?: number; /** Magazine capacity; drives the segment count and fill fraction. Default = `loaded`. */ magazine?: number; width?: number | string; style?: CSSProperties; className?: string; }):… — Loaded-vs-reserve ammunition counter — a segmented magazine plus a reserve tally.
|
|
644
|
+
- `AtomicBarProps` (interface): interface AtomicBarProps — Shared props for every atomic bar — bound to a stat (`statId`/`entityId`) or explicit (`value`).
|
|
645
|
+
- `BarShape` (type): type BarShape = "rect" | "pill" | "skew" | "chamfer" — Trough shape language — `rect` (default), `pill` (fully round), `skew` (parallelogram, upright label), or `chamfer` (cut corners). Matches a game's skin without hand-rolling a local bar.
|
|
646
|
+
- `BarTokens` (interface): interface BarTokens — Atomic, purpose-named vitals — one component per readout (`HealthBar`, `ShieldBar`, …), never a `tone`-switched umbrella and never a bundled combo. Every bar reads the same shared CSS custom properties (`--jg-health`, `--jg-shield`, `--jg-xp`, plus frame/shape tokens). Default token colors are scaffolding only: games own layout, framing, and art direction, and must set tokens (or replace the markup) so the HUD is unique to the pitch — the engine ships parts, not a face.
|
|
647
|
+
- `BossBar` (function): function BossBar(props: AtomicBarProps & { name?: string }): React.JSX.Element — A wide encounter/boss health bar with the boss name at the start.
|
|
648
|
+
- `DEFAULT_BAR_TOKENS` (const): const DEFAULT_BAR_TOKENS: Required<BarTokens> — Built-in default values for every vitals token — scaffolding/preview only, not a shipped look.
|
|
649
|
+
- `ExperienceBar` (const): const ExperienceBar: (props: AtomicBarProps) => React.JSX.Element — Level progress / experience.
|
|
650
|
+
- `HealthBar` (const): const HealthBar: (props: AtomicBarProps) => React.JSX.Element — Player/enemy health — danger-flashes to `--jg-health-low` below a quarter full.
|
|
651
|
+
- `ManaBar` (const): const ManaBar: (props: AtomicBarProps) => React.JSX.Element — Spell/energy resource pool.
|
|
652
|
+
- `ShieldBar` (const): const ShieldBar: (props: AtomicBarProps) => React.JSX.Element — Absorb/armor shield overlay.
|
|
653
|
+
- `SoulBar` (const): const SoulBar: (props: AtomicBarProps) => React.JSX.Element — Resource-charge / soul-box meter — segmented by default.
|
|
654
|
+
- `StaminaBar` (const): const StaminaBar: (props: AtomicBarProps) => React.JSX.Element — Sprint/action stamina pool.
|
|
655
|
+
- `barTokens` (function): function barTokens(tokens: BarTokens): CSSProperties — A style object binding vitals tokens to CSS custom properties — spread onto any HUD ancestor to restyle every atomic bar under it at once. Only the keys you pass are set; the rest fall back to {@link DEFAULT_BAR_TOKENS} inside the bars. This is the single global-theming seam.
|
|
656
|
+
|
|
657
|
+
## @jgengine/react/barsPreview
|
|
658
|
+
|
|
659
|
+
- `BarsPreview` (function): function BarsPreview({ className }: { className?: string }): React.JSX.Element — Renders the atomic bar matrix twice under different token blocks to prove global re-theming.
|
|
660
|
+
|
|
538
661
|
## @jgengine/react/cards
|
|
539
662
|
|
|
540
663
|
- `CardFace` (function): function CardFace({ rank, suit, faceDown = false, width = 64, height = 90, className, style, children, }: { rank: Rank; suit: Suit; faceDown?: boolean; width?: number; height?: number; className?: string; style?: CSSProperties; children?: ReactNode; }): React.JSX.Element — A single playing-card face: rank + suit pips, or a patterned back when `faceDown`.
|
|
@@ -547,6 +670,21 @@
|
|
|
547
670
|
- `Suit` (type): type Suit = "clubs" | "diamonds" | "hearts" | "spades" — The four French-deck suits.
|
|
548
671
|
- `isRedSuit` (function): function isRedSuit(suit: Suit): boolean — True for the red suits (hearts, diamonds).
|
|
549
672
|
|
|
673
|
+
## @jgengine/react/characterSheet
|
|
674
|
+
|
|
675
|
+
- `CharacterSheet` (function): function CharacterSheet({ slots, stats, name, subtitle, portrait, header, title = "Character", variation = "themed", slotSize, onSlotActivate, className, style, }: CharacterSheetProps): ReactNode — Drop-in character sheet: a {@link HudFrame} wrapping an optional name/subtitle/portrait header, the equip-slot {@link Paperdoll}, and the derived-stat {@link StatList}. The game supplies slots, stats, header content, and the activation callback, and owns the window that toggles it (this component does not manage its own open/close). Pure composition over existing primitives and HudTheme tokens.
|
|
676
|
+
- `CharacterSheetProps` (interface): interface CharacterSheetProps — Props for {@link CharacterSheet}.
|
|
677
|
+
- `DefaultEquipSlotId` (type): type DefaultEquipSlotId = | "head" | "chest" | "hands" | "legs" | "feet" | "mainHand" | "offHand" | "ring1" | "ring2" | "trinket" — Slot ids used by {@link defaultEquipLayout}'s convenience arrangement.
|
|
678
|
+
- `EquipSlot` (interface): interface EquipSlot — One named equip slot: a stable `id`, a display `label`, its worn `item` (or `null` = empty), and where it sits.
|
|
679
|
+
- `EquipSlotLayout` (type): type EquipSlotLayout = readonly EquipSlot[] — An ordered set of equip slots that make up a paperdoll. Caller-supplied; see {@link defaultEquipLayout}.
|
|
680
|
+
- `EquipSlotPosition` (type): type EquipSlotPosition = "left" | "right" | "bottom" — Character-sheet / paperdoll composition (#1033 follow-up): a drop-in `<CharacterSheet>` that arranges caller-supplied equip slots as a paperdoll around a portrait and lists derived stats, all inside a {@link HudFrame}. It reuses the atomic slot rendering ({@link EquipmentSlots}) and the shared `--jg-slot-*` / `--jg-accent` HudTheme tokens (#1034) — the game owns which slots and which stats matter (both are props), the skin, and the window that toggles it open/closed. No genre list is baked in; {@link defaultEquipLayout} is a convenience arrangement the game can override wholesale.
|
|
681
|
+
- `Paperdoll` (function): function Paperdoll({ slots, portrait, slotSize = 44, onSlotActivate, className, style }: PaperdollProps): ReactNode — Arranges caller-supplied equip slots as a paperdoll — worn gear in two flanking columns around a center `portrait` (or a silhouette placeholder), with any `bottom` slots in a row beneath it. Each slot reuses the atomic {@link EquipmentSlots} tile (filled icon or themed empty placeholder), carries a label, and is a focusable `role="group"` with an `aria-label`; `onSlotActivate` fires on click/Enter/Space so games can wire drag or an equip picker. Composition and skin stay the game's.
|
|
682
|
+
- `PaperdollProps` (interface): interface PaperdollProps — Props for {@link Paperdoll}.
|
|
683
|
+
- `StatList` (function): function StatList({ stats, className, style }: StatListProps): ReactNode — Renders derived character stats as clean small-caps label→value rows, token-themed. Rows carrying a `group` field are bucketed under a small uppercase header (consecutive same-group rows share one). Pure and prop-driven — the game supplies the rows (from `useEntityStat`/derived values); the engine ships no stat list of its own.
|
|
684
|
+
- `StatListProps` (interface): interface StatListProps — Props for {@link StatList}.
|
|
685
|
+
- `StatRow` (interface): interface StatRow — One derived-stat row. `group` optionally buckets rows under a small header.
|
|
686
|
+
- `defaultEquipLayout` (function): function defaultEquipLayout(items: Partial<Record<DefaultEquipSlotId, SlotItem | null>> = {}): EquipSlot[] — A sensible default paperdoll arrangement — worn armor down the left flank, held gear and jewelry down the right — that the game fills by passing worn items keyed by slot id. Every id is optional; unfilled slots render empty. Games that need a different slot set pass their own {@link EquipSlotLayout}.
|
|
687
|
+
|
|
550
688
|
## @jgengine/react/chat
|
|
551
689
|
|
|
552
690
|
- `ChannelTabs` (function): function ChannelTabs({ channels, active, onSelect, className, tabClassName, activeTabClassName, renderTab, }: { channels?: readonly string[]; active: string; onSelect: (channelId: string) => void; className?: string; tabClassName?: string; activeTabClassName?: string; renderTab?: (channelId: string,… — ⚠ undocumented
|
|
@@ -573,7 +711,6 @@
|
|
|
573
711
|
- `DialogueChoice` (interface): interface DialogueChoice — ⚠ undocumented
|
|
574
712
|
- `DialogueDef` (interface): interface DialogueDef — ⚠ undocumented
|
|
575
713
|
- `DialogueLine` (type): type DialogueLine = { speaker: string; text: string } | { choices: readonly DialogueChoice[] } — ⚠ undocumented
|
|
576
|
-
- `HealthBar` (function): function HealthBar({ instanceId, statId, className, fillClassName, }: { instanceId: string; statId: string; className?: string; fillClassName?: string; }): React.JSX.Element | null — ⚠ undocumented
|
|
577
714
|
- `KeybindRow` (function): function KeybindRow({ action, keys, className, }: { action: string; keys: readonly string[]; className?: string; }): React.JSX.Element — ⚠ undocumented
|
|
578
715
|
- `LevelUpFlash` (function): function LevelUpFlash({ stat, durationMs = 1600, className, children, renderFlash, }: { stat?: string; durationMs?: number; className?: string; children?: ReactNode; renderFlash?: (event: StatLevelUpEvent) => ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
579
716
|
- `ProximityPrompt` (function): function ProximityPrompt({ prompt, className, }: { prompt: ProximityPromptDef; className?: string; }): React.JSX.Element — ⚠ undocumented
|
|
@@ -581,6 +718,7 @@
|
|
|
581
718
|
- `Screen` (function): function Screen({ id, open = true, className, children, }: { id: string; open?: boolean; className?: string; children?: ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
582
719
|
- `SkillCheckBar` (function): function SkillCheckBar({ config, startedAt, className, trackClassName, zoneClassName, markerClassName, renderStatus, }: { config: SkillCheckConfig; startedAt: number; className?: string; trackClassName?: string; zoneClassName?: string; markerClassName?: string; renderStatus?: (result: SkillCheckResu… — ⚠ undocumented
|
|
583
720
|
- `SlotGrid` (function): function SlotGrid({ inventoryId, className, renderSlot, }: { inventoryId: string; className?: string; renderSlot?: (slot: InventorySlot, index: number) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
721
|
+
- `StatMeter` (function): function StatMeter({ instanceId, statId, className, fillClassName, }: { instanceId: string; statId: string; className?: string; fillClassName?: string; }): React.JSX.Element | null — A headless, unstyled stat meter — an accessible `role="progressbar"` you paint entirely through `className`/`fillClassName`. This is the class-hook primitive for teams supplying their own CSS; for a batteries-included themed bar use the atomic, token-styled components in `@jgengine/react/bars` (`HealthBar`, `ShieldBar`, …). Renamed from `HealthBar` in #1033 so the purpose-named atomic bar owns that name and no two components share it.
|
|
584
722
|
- `ToastStack` (function): function ToastStack({ action, limit = 4, className, renderToast, }: { action: string; limit?: number; className?: string; renderToast?: (entry: FeedEntry, index: number) => ReactNode; }): React.JSX.Element | null — Render `ctx.game.feed`'s entries for `action` as a newest-first toast stack — the feed-backed sibling of `@jgengine/core/game/toasts`' `createToastQueue`. Reach for this when the message source is already an engine event bound onto `ctx.game.feed` (kill feed, quest updates, loot log); reach for a `createToastQueue` when the game raises ad-hoc messages that need their own TTL independent of the feed's ring buffer.
|
|
585
723
|
- `resolveDialogueInvoke` (function): function resolveDialogueInvoke(choice: DialogueChoice, result: CheckResult | null): { command: string; args?: unknown } | null — ⚠ undocumented
|
|
586
724
|
- `runDialogueChoice` (function): function runDialogueChoice(commands: { run(name: string, input?: unknown): unknown }, choice: DialogueChoice, result: CheckResult | null): void — Route a {@link DialogueBox} choice through the `features.dialogue` bridge: resolve the choice's invoke (honoring a skill-check `result`), run that command, and otherwise close the dialogue — the write side that replaces a per-game `onChoice` that hand-rolls `resolveDialogueInvoke` + `dialogue.close`.
|
|
@@ -638,6 +776,7 @@
|
|
|
638
776
|
|
|
639
777
|
- `AbilitySlotBindingOptions` (interface): interface AbilitySlotBindingOptions — ⚠ undocumented
|
|
640
778
|
- `EventMeterView` (interface): interface EventMeterView — A rendered snapshot of an {@link EventMeter}: current value, fill fraction, active tier, and ready-to-consume flag.
|
|
779
|
+
- `InventoryGridBinding` (interface): interface InventoryGridBinding — Live slots plus `move`/`split` actions bound to `inventoryId`, routed through the notifying `inventory.move`/`inventory.split` commands so React re-renders.
|
|
641
780
|
- `UseAxisChannelResult` (interface): interface UseAxisChannelResult — ⚠ undocumented
|
|
642
781
|
- `WorldBrowserState` (interface): interface WorldBrowserState — ⚠ undocumented
|
|
643
782
|
- `abilityKitNeedsHeartbeat` (function): function abilityKitNeedsHeartbeat(kit: AbilityKit, resourceAvailable?: number): boolean — ⚠ undocumented
|
|
@@ -662,7 +801,9 @@
|
|
|
662
801
|
- `useGameStoreValue` (function): function useGameStoreValue<T>(key: string, fallback: T): T — Subscribe to a single keyed slice of the game store, returning `fallback` until the key is set.
|
|
663
802
|
- `useHeldKeys` (function): function useHeldKeys(): (code: string) => boolean — Held-key predicate backed by window keydown/keyup/blur listeners (blur clears held state so a released-off-window key doesn't stick). SSR-safe: listeners attach in an effect, never at module scope. The returned predicate is stable across renders.
|
|
664
803
|
- `useInventory` (function): function useInventory(inventoryId: string): readonly InventorySlot[] — ⚠ undocumented
|
|
804
|
+
- `useInventoryGrid` (function): function useInventoryGrid(inventoryId: string): InventoryGridBinding — Binds a live inventory to a HUD grid: `slots` from {@link useInventory}, and `move`/`split` that run the built-in `inventory.move`/`inventory.split` commands (which notify, so the grid re-renders).
|
|
665
805
|
- `useLeaderboard` (function): function useLeaderboard(stat: string, options: { scope: LeaderboardScope; limit?: number }): { userId: string; value: number }[] — ⚠ undocumented
|
|
806
|
+
- `useLiveMarkers` (function): function useLiveMarkers(rebuild: (markers: MarkerSet, ctx: GameContext) => void, options?: { intervalMs?: number; deps?: DependencyList }): MarkerSet — A self-ticking {@link MarkerSet} kept in sync with the live scene: on a heartbeat (default 100ms, and once immediately) it clears the set and calls `rebuild(markers, ctx)` to repopulate it from the current scene, so a HUD map never hand-rolls a `setInterval` + `markers.clear()` + rescan. Each heartbeat also re-renders the calling component, so player-centered props derived from the live scene each tick (`center`, `facingYaw`, zone name) stay fresh — this fully subsumes the hand-rolled ticker, not just the marker rebuild. The set is stable across renders and re-seeded whenever `ctx`, `intervalMs`, or the supplied `deps` change. SSR-safe: the heartbeat only arms when `window` is available.
|
|
666
807
|
- `useLocalPlayerDead` (function): function useLocalPlayerDead(healthStatId = "health"): boolean — ⚠ undocumented
|
|
667
808
|
- `useNearestWorldItem` (function): function useNearestWorldItem(radius: number): WorldItemRecord | null — Nearest ground item within `radius` of the local player — drives a pickup prompt/highlight.
|
|
668
809
|
- `useOptionalGamePhase` (function): function useOptionalGamePhase(): GamePhase — Live run phase that degrades to `"playing"` when rendered outside a `GameProvider` (component showcases, previews), so phase-gated chrome never throws.
|
|
@@ -684,14 +825,21 @@
|
|
|
684
825
|
## @jgengine/react/hud
|
|
685
826
|
|
|
686
827
|
- `Clock` (function): function Clock({ format = "24h", showDay = true, controls = false, style, className, }: { format?: "24h" | "12h"; showDay?: boolean; controls?: boolean; style?: CSSProperties; className?: string; }): React.JSX.Element — A time-of-day clock reading the sim calendar — `Day N · HH:MM`, 24h or 12h. `controls` adds pause + the game's speed multipliers as clickable pills (the "fast-forward" bar), off by default so a game opts into letting the player scrub time.
|
|
687
|
-
- `Coins` (function): function Coins({ currencyId, icon = "🪙", style, className, }: { currencyId: string; icon?: ReactNode; style?: CSSProperties; className?: string; }): React.JSX.Element — A currency counter — an icon (emoji/char, default a coin) plus the live amount for `currencyId`.
|
|
828
|
+
- `Coins` (function): function Coins({ currencyId, icon = "🪙", style, className, }: { currencyId: string; icon?: ReactNode; style?: CSSProperties; className?: string; }): React.JSX.Element — A currency counter — an icon (emoji/char, default a coin) plus the live amount for `currencyId`. *
|
|
688
829
|
- `Crosshair` (function): function Crosshair({ size = 18, gap = 5, thickness = 2, color = "rgba(255,255,255,0.85)", style, className, }: { size?: number; gap?: number; thickness?: number; color?: string; style?: CSSProperties; className?: string; }): React.JSX.Element — A minimal center crosshair reticle — four ticks around a gap. Purely presentational.
|
|
689
|
-
- `Hotbar` (function): function Hotbar({ inventoryId, activeSlot, keys, slotSize = 46, style, className, }: { inventoryId: string; activeSlot?: number; keys?: readonly string[]; slotSize?: number;
|
|
830
|
+
- `Hotbar` (function): function Hotbar({ inventoryId, activeSlot, keys, slotSize = 46, itemIcon, style, className, }: { inventoryId: string; activeSlot?: number; keys?: readonly string[]; slotSize?: number; /** Caller-supplied item id → icon registry; return null/undefined to fall back to the default glyph. */ itemIcon?: … — A numbered hotbar bound to an inventory — painted iconed slots (a `GameIcon` glyph over a school-keyed gradient with a count badge, #1035), an active-slot highlight, and a keycap per slot. Place it and pass the `inventoryId`; `activeSlot` highlights the equipped one. Supply `itemIcon` to map your item ids to your own glyphs — the default resolves a `GameIcon` from the item id.
|
|
690
831
|
- `Speedometer` (function): function Speedometer({ entityId, scale = 3.6, unit = "km/h", max = 60, size = 96, style, className, }: { entityId?: string; scale?: number; unit?: string; max?: number; size?: number; style?: CSSProperties; className?: string; }): React.JSX.Element — A speedometer for an entity (defaults to the local player) — an SVG arc gauge + a digital readout. `scale` converts world units/second to your display unit (3.6 → km/h, 2.237 → mph); `max` sets the gauge's top of scale.
|
|
691
832
|
- `StatBar` (function): function StatBar({ statId = "health", entityId, tone = "health", label, showValue = true, width = 200, icon, style, className, }: { statId?: string; entityId?: string; tone?: StatTone; label?: string; showValue?: boolean; width?: number; icon?: ReactNode; style?: CSSProperties; className?: string; }… — A polished stat bar (health/mana/stamina/shield/xp) — a rounded, glassy meter with a tone-colored fill and an optional value readout. Reads `statId` off `entityId` (defaults to the local player). Renders nothing until the stat exists.
|
|
692
833
|
- `StatTone` (type): type StatTone = keyof typeof TONES — A stat tone — picks the bar's color ramp.
|
|
693
834
|
- `WaveBanner` (function): function WaveBanner({ wave, label = "Wave", subtitle, style, className, }: { wave: number | string; label?: string; subtitle?: ReactNode; style?: CSSProperties; className?: string; }): React.JSX.Element — A wave / round banner — a bold centered pill for "WAVE 3" style callouts, with an optional subtitle (enemies remaining, timer). Pure display: pass the current `wave` and whatever subtitle you track.
|
|
694
835
|
|
|
836
|
+
## @jgengine/react/hudFrame
|
|
837
|
+
|
|
838
|
+
- `HudFrame` (function): function HudFrame({ variation = "glass", shape = "rounded", title, aside, padding, width, interactive, className, style, children, }: HudFrameProps): ReactNode — Optional framed panel primitive — a single `<div data-hud-frame>` with a `glass`, `plate`, `retro`, or `themed` skin, optional `title`/`aside` header, and caller `style` merged last. Shared building block for demos and token-themed widgets; games own product chrome and art direction (see AGENTS.md).
|
|
839
|
+
- `HudFrameProps` (interface): interface HudFrameProps — Props for {@link HudFrame}.
|
|
840
|
+
- `HudFrameShape` (type): type HudFrameShape = "rounded" | "circle" | "square" — Frame corner shape — `rounded` (the variation's default radius), `circle` (fully round), or `square` (no radius).
|
|
841
|
+
- `HudFrameVariation` (type): type HudFrameVariation = "glass" | "plate" | "retro" | "themed" — Frame skin — `glass` (the shared dark-glass panel), `plate` (a heavier opaque plate), `retro` (a hard black-outlined frame), or `themed` (driven by the `--jg-frame-*` `HudTheme` tokens).
|
|
842
|
+
|
|
695
843
|
## @jgengine/react/hudLayout
|
|
696
844
|
|
|
697
845
|
- `HudCanvas` (function): function HudCanvas({ layout, editChord, compactScale, showDuring, className, style, children, }: { layout: HudLayoutStore; editChord?: HudEditChord | false; /** Zoom applied to the whole HUD on compact displays. Default 0.85. */ compactScale?: number; /** Opt-in play-phase gate: render the HUD only … — Full-viewport HUD surface. Panels declared with `HudPanel` flow into nine anchor regions and stack automatically with a gap — no per-panel pixel offsets, no manual clearance for sibling panels, the touch-control dock (`--jg-hud-dock-clearance`), or device safe areas. On compact displays the whole surface scales down and each panel applies its `compact` behavior.
|
|
@@ -699,7 +847,30 @@
|
|
|
699
847
|
- `HudEditChord` (interface): interface HudEditChord — ⚠ undocumented
|
|
700
848
|
- `HudPanel` (function): function HudPanel({ id, anchor = "top-left", order, compact: compactMode = "keep", chip, interactive, inset, locked, showDuring, priority, mobileBehavior, allowOverlapWith, collisionGroup, region = true, width, height, type, className, style, children, }: { id: string; anchor?: HudAnchor; /** Stack … — A HUD block that lives in one of the nine anchor regions. Panels sharing a region stack outward from the screen edge in ascending `order`. On fine pointers panels stay draggable through the edit chord; a dragged panel leaves the flow and keeps its custom placement. On compact displays custom placements are ignored and the `compact` behavior applies.
|
|
701
849
|
- `hudVisibleInPhase` (function): function hudVisibleInPhase(showDuring: readonly GamePhase[] | undefined, phase: GamePhase): boolean — Whether a HUD element opted into `showDuring` is visible in the current phase; `undefined` = always visible (default).
|
|
702
|
-
- `useHudLayout` (function): function useHudLayout(options?: { storageKey?: string; snap?: number; locked?: boolean; /** * Scene-document `ui` section — source of truth for panel placement/size. * When provided, hydrates the layout store (and wins over legacy localStorage). */ documentUi?: EditorUiDocument; /** When true (
|
|
850
|
+
- `useHudLayout` (function): function useHudLayout(options?: { storageKey?: string; snap?: number; locked?: boolean; /** * Scene-document `ui` section — source of truth for panel placement/size. * When provided, hydrates the layout store (and wins over legacy localStorage). */ documentUi?: EditorUiDocument; /** * When true (def… — Layout state for `HudCanvas` — panel placements, edit-mode drag/resize, and per-game persistence.
|
|
851
|
+
|
|
852
|
+
## @jgengine/react/hudLayoutPersist
|
|
853
|
+
|
|
854
|
+
- `HudLayoutPersist` (type): type HudLayoutPersist = (id: string, panel: EditorUiPanelLayout) => void — Host-owned callback that commits one HUD panel layout into the scene document (typically an undoable `setUiPanel` dispatch). Injected by the editor so product UI never reaches for editor globals.
|
|
855
|
+
- `HudLayoutPersistProvider` (function): function HudLayoutPersistProvider({ onPanelCommit, children, }: { onPanelCommit: HudLayoutPersist; children?: ReactNode; }): React.JSX.Element — Provides {@link HudLayoutPersist} / `onPanelCommit` to descendant `useHudLayout` calls. Mount around game UI when a host can accept document UI patches (editor). Absent provider → canvas moves/resizes are no-ops for document writes.
|
|
856
|
+
- `useHudLayoutPersist` (function): function useHudLayoutPersist(): HudLayoutPersist | null — Injected panel-commit port, or `null` when no host has provided one.
|
|
857
|
+
|
|
858
|
+
## @jgengine/react/hudTheme
|
|
859
|
+
|
|
860
|
+
- `HUD_THEME_PRESETS` (const): const HUD_THEME_PRESETS: { "arcane-stone": HudTheme; "survival-wood": HudTheme; "military-flat": HudTheme; "sleek-hex": HudTheme; "elemental-circle": HudTheme; "sandbox-slot": HudTheme; } — Built-in theme presets for demos/scaffold only — not product identity; games author their own theme.
|
|
861
|
+
- `HudTheme` (interface): interface HudTheme — A full HUD theme.
|
|
862
|
+
- `HudThemeBar` (interface): interface HudThemeBar — Framed-trough tokens shared by every atomic bar.
|
|
863
|
+
- `HudThemeFrame` (interface): interface HudThemeFrame — Frame material + shape tokens (panels, `HudFrame variation="themed"`).
|
|
864
|
+
- `HudThemePalette` (interface): interface HudThemePalette — `HudTheme` (#1034): one token object that restyles shared token-driven building blocks at once. It is the superset of the atomic-bar tokens (#1033) — `hudThemeVars(theme)` emits the same `--jg-*` custom properties the bars already read, plus frame / slot / minimap-ring tokens — so setting a **game-authored** theme on any HUD ancestor re-skins those primitives. Purely CSS-token driven (no image assets). Tokens are not a finished UI: every game still owns composition, skin, and art direction (see AGENTS.md). Built-in presets are demo/scaffold starting points only.
|
|
865
|
+
- `HudThemePreset` (type): type HudThemePreset = keyof typeof HUD_THEME_PRESETS — Built-in demo/scaffold theme preset name — not a game identity.
|
|
866
|
+
- `HudThemeSlot` (interface): interface HudThemeSlot — Action/inventory slot tokens.
|
|
867
|
+
- `defaultHudTheme` (const): const defaultHudTheme: HudTheme — Default theme tokens for previews/scaffold — not a finished game look; author a custom theme.
|
|
868
|
+
- `hudThemeVars` (function): function hudThemeVars(theme: HudTheme): CSSProperties — Emits the CSS custom properties for a theme — spread onto any HUD ancestor to re-skin the subtree.
|
|
869
|
+
- `resolveHudTheme` (function): function resolveHudTheme(theme?: HudThemePreset | HudTheme): HudTheme — Resolves a preset name (or a full theme) to a `HudTheme`; falls back to the default theme.
|
|
870
|
+
|
|
871
|
+
## @jgengine/react/hudThemePreview
|
|
872
|
+
|
|
873
|
+
- `HudThemePreview` (function): function HudThemePreview({ className }: { className?: string }): React.JSX.Element — Renders the default theme plus every genre preset as a deterministic matrix.
|
|
703
874
|
|
|
704
875
|
## @jgengine/react/hudViewport
|
|
705
876
|
|
|
@@ -707,6 +878,20 @@
|
|
|
707
878
|
- `HudViewportProvider` (function): function HudViewportProvider({ platforms, config, userScale, children, }: { platforms: readonly HudPlatform[] | undefined; config: HudViewportConfig | undefined; userScale?: number; children?: ReactNode; }): React.JSX.Element — Mounted by the shell around `GameUI` so every `HudCanvas` inside the game picks up the game's `platforms`/`hudFit` declaration and the player's UI scale setting without any game-side wiring.
|
|
708
879
|
- `useHudViewport` (function): function useHudViewport(): HudViewportContextValue | null — ⚠ undocumented
|
|
709
880
|
|
|
881
|
+
## @jgengine/react/iconTreatment
|
|
882
|
+
|
|
883
|
+
- `IconSchool` (type): type IconSchool = | "fire" | "frost" | "arcane" | "nature" | "holy" | "tech" | "shadow" | "steel" | "neutral" — `IconTreatment` (#1035): a procedural painted-icon face — a glyph over a school-keyed radial gradient, with a vignette inset shadow, a top gloss highlight, and optional count/keycap badges. Turns the engine's flat white `GameIcon` glyphs (and game-icons.net SVGs) into painted ability / item icons that read as AAA slots, not debug UI. Theme-aware: the frame reads the `--jg-slot-*` and `--jg-accent` `HudTheme` tokens (#1034), so a theme change re-skins every treated icon.
|
|
884
|
+
- `IconTreatment` (function): function IconTreatment({ icon, glyph, school = "neutral", size = 44, count, keycap, active = false, className, style, }: IconTreatmentProps): React.JSX.Element — A painted icon face — gradient + vignette + gloss behind a glyph, with count/keycap badges.
|
|
885
|
+
- `IconTreatmentProps` (interface): interface IconTreatmentProps — Props for {@link IconTreatment}.
|
|
886
|
+
- `schoolForAction` (function): function schoolForAction(action: string): IconSchool — Infers an {@link IconSchool} from an action id (keyword match); `neutral` when nothing matches.
|
|
887
|
+
- `schoolForItem` (function): function schoolForItem(itemId: string): IconSchool — Infers an {@link IconSchool} from an item id (keyword match); `neutral` when nothing matches.
|
|
888
|
+
- `treatedActionIcon` (function): function treatedActionIcon(action: { id?: string; label?: string; icon?: ReactNode }, size = 40): ReactNode — A ready-made `ActionButton` `renderIcon` that paints the action's `GameIcon` with a treatment.
|
|
889
|
+
- `treatedItemIcon` (function): function treatedItemIcon(itemId: string, options: { size?: number; count?: number; keycap?: string } = {}): ReactNode — Maps an item id to a treated icon — resolves a `GameIcon` glyph and an inferred school.
|
|
890
|
+
|
|
891
|
+
## @jgengine/react/iconsPreview
|
|
892
|
+
|
|
893
|
+
- `IconsPreview` (function): function IconsPreview({ className }: { className?: string }): React.JSX.Element — Renders the school-gradient row and a treated-icon hotbar — the deterministic #1035 fixture.
|
|
894
|
+
|
|
710
895
|
## @jgengine/react/identity
|
|
711
896
|
|
|
712
897
|
- `BetterAuthSessionState` (interface): interface BetterAuthSessionState — ⚠ undocumented
|
|
@@ -724,6 +909,11 @@
|
|
|
724
909
|
- `useAuthedPlayer` (function): function useAuthedPlayer(options?: { guestSeed?: string }): PlayerIdentity | null — ⚠ undocumented
|
|
725
910
|
- `useSession` (function): function useSession(): IdentitySource — ⚠ undocumented
|
|
726
911
|
|
|
912
|
+
## @jgengine/react/inventoryGrid
|
|
913
|
+
|
|
914
|
+
- `InventoryGrid` (function): function InventoryGrid({ inventoryId, columns, size = 44, gap = 6, itemIcon, onActivate, className, style, }: InventoryGridProps): React.JSX.Element — A drop-in inventory grid with drag/swap/stack-merge/split and full keyboard control, bound to `inventoryId`.
|
|
915
|
+
- `InventoryGridProps` (interface): interface InventoryGridProps — Props for {@link InventoryGrid}.
|
|
916
|
+
|
|
727
917
|
## @jgengine/react/keyHint
|
|
728
918
|
|
|
729
919
|
- `KeyHint` (function): function KeyHint({ children, className, style, }: { children: ReactNode; className?: string; style?: CSSProperties; }): React.JSX.Element | null — Wraps a keyboard/mouse control hint (a cap plus what it does). Renders nothing on coarse-pointer devices — a touchscreen has no keyboard, so the hint is noise and only fights the on-screen controls for space. The `data-jg-kbd-hint` marker is also hidden by an engine stylesheet as a hydration-safe backstop, so a hint stays hidden on touch even before this component's effect runs. Put the touch equivalent (a `TouchControls` dock, a tappable button) on the coarse branch instead.
|
|
@@ -738,20 +928,34 @@
|
|
|
738
928
|
|
|
739
929
|
## @jgengine/react/map
|
|
740
930
|
|
|
741
|
-
- `Compass` (function): function Compass({ facingYaw, center, markers, width = 340, fov = (Math.PI * 2) / 3, kindStyles = DEFAULT_MARKER_KINDS, className, }: CompassProps): ReactNode — Horizontal compass strip centered on the player's facing direction, with the eight cardinals and optional marker pips
|
|
931
|
+
- `Compass` (function): function Compass({ facingYaw, center, markers, width = 340, fov = (Math.PI * 2) / 3, kindStyles = DEFAULT_MARKER_KINDS, className, }: CompassProps): ReactNode — Horizontal compass strip centered on the player's facing direction, with the eight cardinals and optional marker pips from static views, an external source, or a native `MarkerSet`.
|
|
742
932
|
- `CompassProps` (interface): interface CompassProps — ⚠ undocumented
|
|
743
933
|
- `MapBounds` (interface): interface MapBounds — ⚠ undocumented
|
|
744
|
-
- `Minimap` (function): function Minimap({ markers, center, worldRadius, fog, size = 176, facingYaw = 0, rotate = false, kindStyles = DEFAULT_MARKER_KINDS, background, mapBounds, routes, zones, cellStates, onWorldClick, className, title = "Map", children, }: MinimapProps): ReactNode — Framed circular minimap: optional baked terrain background, reveal-on-event fog overlay, categorized marker icons, and a facing arrow. Reads a
|
|
934
|
+
- `Minimap` (function): function Minimap({ markers, center, worldRadius, fog, size = 176, facingYaw = 0, rotate = false, kindStyles = DEFAULT_MARKER_KINDS, background, mapBounds, routes, zones, cellStates, onWorldClick, className, style, title = "Map", children, }: MinimapProps): ReactNode — Framed circular minimap: optional baked terrain background, reveal-on-event fog overlay, categorized marker icons, and a facing arrow. Reads static marker views, an external marker source, or a native `MarkerSet`; supply your own `kindStyles` palette to reskin. Does not require `GameProvider`.
|
|
745
935
|
- `MinimapChrome` (function): function MinimapChrome({ view, frame = false, frameColor = "rgba(148,163,184,0.4)", frameStrokeWidth = 1.5, cardinalLabel = "N", markers = [], markerColor = "#e2e8f0", markerRadius = 5, className, }: MinimapChromeProps): ReactNode — Headless minimap chrome — nests inside a game's own `<svg>`: an optional ring frame, and edge-clamped marker dots that draw as directional arrows when a marker carries a `heading` (the compass-arrow / player-blip layer ~8 games were re-drawing by hand over `projectToMinimap`/`clampToMinimapEdge`). Renders a bare `<g>` — no background, panel, or title; compose your own content layer (routes, zones, terrain) as sibling SVG nodes for full control of z-order, or call `MinimapChrome` twice (once for `frame`, again for `markers`) to sandwich custom content between the ring and the blips.
|
|
746
936
|
- `MinimapChromeMarker` (interface): interface MinimapChromeMarker — One dot (or, with `heading`, a rotated arrow) drawn by `MinimapChrome`.
|
|
747
937
|
- `MinimapChromeProps` (interface): interface MinimapChromeProps — Props for `MinimapChrome`.
|
|
748
938
|
- `MinimapPanel` (function): function MinimapPanel({ zoneLabel, clock, showCompass = true, compassProps, headerClassName, zoneLabelClassName, clockClassName, compassClassName, children, ...minimapProps }: MinimapPanelProps): ReactNode — Composed circular-minimap chrome: optional zone-label + clock header above the `Minimap`, optional `Compass` strip below. Purely a wiring layer over the existing primitives — the game supplies the zone name and clock text, this only places them; omit either slot and the header disappears.
|
|
749
939
|
- `MinimapPanelProps` (interface): interface MinimapPanelProps extends MinimapProps — Props for `MinimapPanel` — all `MinimapProps` plus the zone-label/clock header and compass slots.
|
|
750
940
|
- `MinimapProps` (interface): interface MinimapProps — ⚠ undocumented
|
|
941
|
+
- `MinimapTrack` (function): function MinimapTrack({ spans = [], pips = [], width = "100%", height = 12, railColor = "rgba(255,255,255,0.10)", className, style, children, }: MinimapTrackProps): ReactNode — Horizontal linear track minimap — a rounded progress rail with colored zone `spans` and gate/exit/player `pips` positioned by 0..1 fraction. The structural counterpart to the radial {@link Minimap} for corridor/route games: fractions are supplied by the caller (via core `trackFraction`), so it reads no store and stays presentation-only, sharing chrome with the radial minimap.
|
|
942
|
+
- `MinimapTrackPip` (interface): interface MinimapTrackPip — A point marker on the {@link MinimapTrack} rail at a 0..1 fraction (e.g. a gate, the exit, or the player).
|
|
943
|
+
- `MinimapTrackProps` (interface): interface MinimapTrackProps — Props for {@link MinimapTrack}.
|
|
944
|
+
- `MinimapTrackSpan` (interface): interface MinimapTrackSpan — A colored span across the {@link MinimapTrack} rail, given by 0..1 `start`/`end` fractions (e.g. from core `trackFraction`).
|
|
751
945
|
- `WorldMap` (function): function WorldMap({ markers, bounds, player, facingYaw = 0, fog, background, width = 520, height, kindStyles = DEFAULT_MARKER_KINDS, routes, zones, cellStates, onWorldClick, className, title = "World Map", onClose, }: WorldMapProps): ReactNode — Full-bounds top-down world map (the "press M" overlay): baked terrain background, reveal-on-event fog, all markers with labels, and the player. Rectangular linear projection over the supplied world `bounds`.
|
|
752
946
|
- `WorldMapProps` (interface): interface WorldMapProps — ⚠ undocumented
|
|
753
947
|
- `useFog` (function): function useFog(fog: FogField): ReturnType<FogField["cells"]> — ⚠ undocumented
|
|
754
|
-
- `useMarkers` (function): function useMarkers(markers: MarkerSet): readonly MapMarker[] —
|
|
948
|
+
- `useMarkers` (function): function useMarkers<TMeta = unknown>(markers: MarkerSet<TMeta>): readonly MapMarker<TMeta>[] — Subscribe to a native marker set or external marker source, or read a static marker array.
|
|
949
|
+
|
|
950
|
+
## @jgengine/react/panels
|
|
951
|
+
|
|
952
|
+
- `PanelHost` (function): function PanelHost({ manager, render, panels, variation, shape, width, className, windowClassName, windowStyle, bodyStyle, }: { manager: PanelsManager; /** Content for a panel by id. Takes precedence over `panels`. */ render?: (id: string) => ReactNode; /** Static content map by panel id, used when … — Renders the open panels of a {@link usePanels} manager as absolutely-positioned, draggable, closable windows in z-order — the WoW window layer. Each window uses {@link HudFrame} chrome, is dragged by its title bar, raises focus on pointer-down, and gets its content from the `render` prop (or a `panels` map). Accessible: every window is a `role="dialog"` with an `aria-label` and a focusable close button; ESC-close is wired by the manager. Unskinned — art-direct via `HudTheme` tokens and the `variation`.
|
|
953
|
+
- `PanelKeyResult` (interface): interface PanelKeyResult — React chrome over the headless panel/window model (`@jgengine/core/ui/panelModel`) — the toggleable, draggable, z-stacked windows a WoW-style UI is made of (B for bag, C for character, ESC to close). `usePanels` is the DATA/HOOK layer (open/close/toggle/focus + a keybind listener), `PanelHost` renders the open windows in z-order, and `Window` is a standalone one-off window. All unskinned and token-driven: games reskin via `HudTheme` tokens and by swapping the `HudFrame` variation.
|
|
954
|
+
- `PanelsManager` (interface): interface PanelsManager — The live panel manager returned by {@link usePanels} and consumed by {@link PanelHost}.
|
|
955
|
+
- `UsePanelsOptions` (interface): interface UsePanelsOptions — Options for {@link usePanels}.
|
|
956
|
+
- `Window` (function): function Window({ title, ariaLabel, closable = true, onClose, x, y, onMove, z, width, variation, shape, className, style, bodyStyle, children, }: { title: ReactNode; ariaLabel?: string; closable?: boolean; onClose?: () => void; /** Initial (uncontrolled) or current (controlled, with `onMove`) x posi… — A single standalone window — title bar, close button, and title-bar drag over {@link HudFrame} chrome — usable without the {@link usePanels} manager for a one-off dialog. Position is uncontrolled (seeded by `x`/`y`) unless both `x`/`y` and `onMove` are supplied, in which case the caller owns placement. Accessible: `role="dialog"` with an `aria-label` and a focusable close button.
|
|
957
|
+
- `panelKeyAction` (function): function panelKeyAction(defs: readonly PanelDef[], state: PanelState, event: { code?: string; key?: string }): PanelKeyResult — Pure keybind resolver for a panel set: ESC resolves to `closeTop` when a closable window is open, and any other key routes through {@link panelByHotkey} (trying `code` then `key`) to a `toggle`. Returns the intent without touching the DOM, so it unit-tests headless and `usePanels` is a thin shell over it.
|
|
958
|
+
- `usePanels` (function): function usePanels(defs: readonly PanelDef[], options?: UsePanelsOptions): PanelsManager — The DATA/HOOK layer: wrap the core panel model in state and install a window keybind listener — per-panel hotkeys toggle their window and ESC closes the topmost closable one. Hotkeys are ignored while the player is typing in an input/textarea/contenteditable. The listener is cleaned up on unmount and SSR-safe (armed in an effect). Feed the returned manager to {@link PanelHost}, or drive a bespoke window layout from it directly.
|
|
755
959
|
|
|
756
960
|
## @jgengine/react/preview
|
|
757
961
|
|
|
@@ -786,7 +990,7 @@
|
|
|
786
990
|
- `SelectionGroupChip` (function): function SelectionGroupChip({ group, onSelect, renderIcon, className, style, }: { group: SelectionGroup; onSelect?: (group: SelectionGroup) => void; renderIcon?: (group: SelectionGroup) => ReactNode; className?: string; style?: CSSProperties; }): React.JSX.Element — A same-kind selection chip — icon plus count — for the grouped large-selection view. The default chrome {@link SelectionCollectionChrome} renders per group; swap it via `renderGroup`.
|
|
787
991
|
- `SelectionKeyEvent` (interface): interface SelectionKeyEvent — A minimal keyboard-event shape — a real `KeyboardEvent`/React synthetic satisfies it.
|
|
788
992
|
- `SelectionModel` (interface): interface SelectionModel — The live selection model returned by {@link useSelectionView}.
|
|
789
|
-
- `SelectionPanel` (function): function SelectionPanel({ members, model: providedModel, groupThreshold, labelOf, windowSize, renderPrimary, renderMember, renderVital, onFocusChange, className, style, }: { members?: readonly EntitySummaryDef[]; model?: SelectionModel; groupThreshold?: number; labelOf?: (kind: string) => string; wi… —
|
|
993
|
+
- `SelectionPanel` (function): function SelectionPanel({ members, model: providedModel, groupThreshold, labelOf, windowSize, renderPrimary, renderMember, renderVital, onFocusChange, className, style, }: { members?: readonly EntitySummaryDef[]; model?: SelectionModel; groupThreshold?: number; labelOf?: (kind: string) => string; wi… — Convenience composition: skinned glass panel with {@link EntitySummary} for the primary member beside {@link SelectionCollectionChrome} for the rest — demos/scaffold only, not a finished game face. Pass `members` (or a prebuilt `model`); swap sub-renderers or compose the headless pieces under game-owned chrome for product UI.
|
|
790
994
|
- `UseSelectionViewOptions` (interface): interface UseSelectionViewOptions — Options for {@link useSelectionView}.
|
|
791
995
|
- `VitalBar` (function): function VitalBar({ vital, width = 120, showLabel = true, className, style, }: { vital: EntityVital; width?: number; showLabel?: boolean; className?: string; style?: CSSProperties; }): React.JSX.Element — A compact current/max vital meter for an entity summary; tone maps to a colour ramp. Reuse it as the vital row inside {@link EntitySummary} or any custom entity panel.
|
|
792
996
|
- `useSelectionView` (function): function useSelectionView(members: readonly EntitySummaryDef[], options?: UseSelectionViewOptions): SelectionModel — The DATA/HOOK layer: summarize a selected-entity list into a live model with a focused primary, ordered members, same-kind groups, keyboard focus stepping, and a virtualization window. Rendering-agnostic — feed it to {@link SelectionPanel} or read the `view` directly.
|
|
@@ -806,6 +1010,15 @@
|
|
|
806
1010
|
- `useSettings` (function): function useSettings(): SettingsController — The engine settings controller for the current game — render your own settings UI from `categories`, or open the built-in menu with `open()`. Null-safe stub when mounted outside the shell.
|
|
807
1011
|
- `useSettingsStore` (function): function useSettingsStore(): SettingsStore — The shared settings store, or a standalone one when no provider is mounted (game code read outside the shell).
|
|
808
1012
|
|
|
1013
|
+
## @jgengine/react/slots
|
|
1014
|
+
|
|
1015
|
+
- `ArmorSlots` (function): function ArmorSlots(props: SlotGridProps): React.JSX.Element — Armor piece slots.
|
|
1016
|
+
- `EquipmentSlots` (function): function EquipmentSlots(props: SlotGridProps): React.JSX.Element — Worn-gear slots (head/chest/hands/…): one atomic grid, painted icons, themed from tokens.
|
|
1017
|
+
- `PotionSlots` (function): function PotionSlots(props: SlotGridProps): React.JSX.Element — Consumable (health/shield potion) slots.
|
|
1018
|
+
- `SlotGridProps` (interface): interface SlotGridProps — Props shared by every atomic slot grid.
|
|
1019
|
+
- `SlotItem` (interface): interface SlotItem — Atomic, purpose-named slot grids (#1033): one component per category — `EquipmentSlots`, `WeaponSlots`, `ArmorSlots`, `PotionSlots` — for paperdoll / equip layouts where each grid holds a single gear category. A full multi-category backpack that binds to a live inventory with drag/swap/stack/split is a different, supported shape: reach for `<InventoryGrid>` (`inventoryGrid.tsx`) there, and use these atomic grids for the equip slots around it. Each renders a grid of painted {@link IconTreatment} tiles (glyph + gradient + count badge) for filled slots and a themed placeholder for empty ones, all reading the shared `--jg-slot-*` / `--jg-accent` HudTheme tokens (#1034). Composition stays the game's; the engine ships the grid.
|
|
1020
|
+
- `WeaponSlots` (function): function WeaponSlots(props: SlotGridProps): React.JSX.Element — Weapon loadout slots.
|
|
1021
|
+
|
|
809
1022
|
## @jgengine/react/social
|
|
810
1023
|
|
|
811
1024
|
- `AddFriendButton` (function): function AddFriendButton({ toUserId, className, children, onRequested, onRejected, }: { toUserId: string; className?: string; children?: ReactNode; onRequested?: (requestId: string) => void; onRejected?: (reason: string) => void; }): React.JSX.Element | null — ⚠ undocumented
|
|
@@ -846,23 +1059,16 @@
|
|
|
846
1059
|
- `VoiceState` (interface): interface VoiceState — ⚠ undocumented
|
|
847
1060
|
- `useVoice` (function): function useVoice(options?: UseVoiceOptions): VoiceState — Mic capture + push-to-talk + channel roster over the VoiceTransport signaling seam. Transmission gates the captured tracks' `enabled` flag; the media plane that actually moves audio bytes (WebRTC/SFU) stays behind the transport, host-supplied. Call once per voice channel and hand the returned state to the voice components.
|
|
848
1061
|
|
|
849
|
-
## @jgengine/shell/GameHost
|
|
850
|
-
|
|
851
|
-
- `GameHost` (function): function GameHost({ playable, gameId, wsUrl, multiplayer, resolveMultiplayer }: GameHostProps): React.JSX.Element — ⚠ undocumented
|
|
852
|
-
- `GameHostProps` (interface): interface GameHostProps — ⚠ undocumented
|
|
853
|
-
|
|
854
1062
|
## @jgengine/shell/GamePhaseStamp
|
|
855
1063
|
|
|
856
1064
|
- `GamePhaseStamp` (function): function GamePhaseStamp(): null — ⚠ undocumented
|
|
857
1065
|
|
|
858
1066
|
## @jgengine/shell/GamePlayer
|
|
859
1067
|
|
|
860
|
-
- `GamePlayer` (function): function GamePlayer({ gameId, registry, fallbackGameId, loading = null, multiplayer = null }: GamePlayerProps): React.JSX.Element — ⚠ undocumented
|
|
861
1068
|
- `GamePlayerProps` (type): type GamePlayerProps = { gameId: string; registry: GameRegistry; fallbackGameId?: string; loading?: ReactNode; multiplayer?: ShellMultiplayer | null; } — ⚠ undocumented
|
|
862
1069
|
|
|
863
1070
|
## @jgengine/shell/GamePlayerShell
|
|
864
1071
|
|
|
865
|
-
- `GamePlayerShell` (function): function GamePlayerShell({ playable, multiplayer: rawMultiplayer = null, poster = false, onContextReady, }: { playable: PlayableGame; multiplayer?: ShellMultiplayer | null; poster?: boolean; /** Called once per boot after onInit/onNewPlayer with the live GameContext — a staging seam for screenshots,… — ⚠ undocumented
|
|
866
1072
|
- `resolvePhysicsTuning` (function): function resolvePhysicsTuning(physics: PhysicsConfig | undefined): MovementTuningOverrides | undefined — Maps a game's declared `physics` onto the movement controllers' tuning. `PhysicsConfig.gravity` is a signed world acceleration (negative points down), but the controllers integrate `velocityY -= gravityAcceleration * dt` and expect a positive downward magnitude — so gravity is negated here to keep down-pointing gravity pulling down.
|
|
867
1073
|
|
|
868
1074
|
## @jgengine/shell/GameUiPreview
|
|
@@ -885,6 +1091,11 @@
|
|
|
885
1091
|
- `Vec3` (interface): interface Vec3 — ⚠ undocumented
|
|
886
1092
|
- `createAudioEngine` (function): function createAudioEngine(config: AudioSceneConfig = {}): AudioEngine — ⚠ undocumented
|
|
887
1093
|
|
|
1094
|
+
## @jgengine/shell/audio/loopParams
|
|
1095
|
+
|
|
1096
|
+
- `MAX_LOOP_RATE` (const): const MAX_LOOP_RATE: 4 — Highest live playback-rate multiplier (two octaves above authored pitch).
|
|
1097
|
+
- `MIN_LOOP_RATE` (const): const MIN_LOOP_RATE: 0.25 — Pure clamps for retained-loop live control (#1051). Kept dependency-free so the playback-rate/gain windows are one testable source of truth the audio engine reads.
|
|
1098
|
+
|
|
888
1099
|
## @jgengine/shell/audio/musicDirector
|
|
889
1100
|
|
|
890
1101
|
- `CrossfadeOptions` (interface): interface CrossfadeOptions — Options for a music crossfade.
|
|
@@ -909,7 +1120,9 @@
|
|
|
909
1120
|
|
|
910
1121
|
## @jgengine/shell/camera
|
|
911
1122
|
|
|
1123
|
+
- `CAMERA_TRANSPARENT_USERDATA` (const): const CAMERA_TRANSPARENT_USERDATA: { readonly jgCameraTransparent: true } — userData applied to the group wrapping author `WorldOverlay` decor so the spring-arm ignores it by default.
|
|
912
1124
|
- `CameraFollowListener` (type): type CameraFollowListener = (state: CameraFollowState) => void — ⚠ undocumented
|
|
1125
|
+
- `CameraOccluder` (interface): interface CameraOccluder — Camera spring-arm occlusion filtering.
|
|
913
1126
|
- `CameraShakeChannel` (interface): interface CameraShakeChannel — ⚠ undocumented
|
|
914
1127
|
- `CameraShakeContext` (const): const CameraShakeContext: React.Context<CameraShakeChannel> — ⚠ undocumented
|
|
915
1128
|
- `GAME_SIM_FRAME_PRIORITY` (const): const GAME_SIM_FRAME_PRIORITY: 0 — Run simulation/movement before orbit follow so poses are current.
|
|
@@ -926,6 +1139,7 @@
|
|
|
926
1139
|
- `PlayerFovState` (interface): interface PlayerFovState — ⚠ undocumented
|
|
927
1140
|
- `ViewmodelProps` (interface): interface ViewmodelProps — Props handed to a custom viewmodel component (#542): a live cue ref (velocity/bob/firing/reloading/recoil/hit) for the followed entity, driven from your own `useFrame` — read `cuesRef.current` there rather than storing it as render state.
|
|
928
1141
|
- `defaultCameraShakeChannel` (const): const defaultCameraShakeChannel: CameraShakeChannel — Process-wide default channel. A shell mounts its own channel via `CameraShakeContext`, but game systems that have no React context (e.g. a `loop.onTick` reacting to `entity.died`) can import `cameraShake` and feed the default channel directly.
|
|
1142
|
+
- `isCameraOccluderTransparent` (function): function isCameraOccluderTransparent(object: CameraOccluder | null | undefined): boolean — Should the camera spring-arm ignore this raycast hit? Walks the object up its `.parent` chain and honors the nearest camera tag: `jgCameraCollide === true` blocks (opt back in), `jgCameraTransparent === true` passes through. Untagged geometry blocks as before, so engine-owned ground/entities are unaffected.
|
|
929
1143
|
- `readFirstPersonMuzzle` (function): function readFirstPersonMuzzle(target: THREE.Vector3): boolean — World position of the first-person weapon muzzle, or false when no viewmodel is mounted.
|
|
930
1144
|
- `usePlayerFov` (function): function usePlayerFov(): PlayerFovState — ⚠ undocumented
|
|
931
1145
|
|
|
@@ -964,13 +1178,19 @@
|
|
|
964
1178
|
|
|
965
1179
|
- `CameraBlendScratch` (interface): interface CameraBlendScratch — ⚠ undocumented
|
|
966
1180
|
|
|
1181
|
+
## @jgengine/shell/camera/cameraCollision
|
|
1182
|
+
|
|
1183
|
+
- `CAMERA_TRANSPARENT_USERDATA` (const): const CAMERA_TRANSPARENT_USERDATA: { readonly jgCameraTransparent: true } — userData applied to the group wrapping author `WorldOverlay` decor so the spring-arm ignores it by default.
|
|
1184
|
+
- `CameraOccluder` (interface): interface CameraOccluder — Camera spring-arm occlusion filtering.
|
|
1185
|
+
- `isCameraOccluderTransparent` (function): function isCameraOccluderTransparent(object: CameraOccluder | null | undefined): boolean — Should the camera spring-arm ignore this raycast hit? Walks the object up its `.parent` chain and honors the nearest camera tag: `jgCameraCollide === true` blocks (opt back in), `jgCameraTransparent === true` passes through. Untagged geometry blocks as before, so engine-owned ground/entities are unaffected.
|
|
1186
|
+
|
|
967
1187
|
## @jgengine/shell/camera/cameraRigs
|
|
968
1188
|
|
|
969
1189
|
- `CAMERA_POST_FRAME_PRIORITY` (const): const CAMERA_POST_FRAME_PRIORITY: number — ⚠ undocumented
|
|
970
1190
|
- `CAMERA_RIG_FRAME_PRIORITY` (const): const CAMERA_RIG_FRAME_PRIORITY: -1 — ⚠ undocumented
|
|
971
1191
|
- `CameraBlendScratch` (interface): interface CameraBlendScratch — ⚠ undocumented
|
|
972
1192
|
- `ChaseRig` (function): function ChaseRig(props: RigProps): null — ⚠ undocumented
|
|
973
|
-
- `CinematicRig` (function): function CinematicRig(props: RigProps): null — ⚠ undocumented
|
|
1193
|
+
- `CinematicRig` (function): function CinematicRig(props: RigProps & { onComplete?: () => void }): null — ⚠ undocumented
|
|
974
1194
|
- `LockOnRig` (function): function LockOnRig(props: RigProps): null — ⚠ undocumented
|
|
975
1195
|
- `ObserverRig` (function): function ObserverRig(props: RigProps): null — Detached spectator/photo cam (#120): binds to any entity or fixed point and auto-orbits it, reading no player input at all — the van CCTV / photo-mode / kill-cam rig. Distinct from every other rig, which drives from mouse/keys.
|
|
976
1196
|
- `RigProps` (interface): interface RigProps — ⚠ undocumented
|
|
@@ -1039,11 +1259,6 @@
|
|
|
1039
1259
|
|
|
1040
1260
|
- `CommandSink` (interface): interface CommandSink — Where a gameplay command goes when the shell dispatches it — run locally, or sent to the authoritative host.
|
|
1041
1261
|
|
|
1042
|
-
## @jgengine/shell/defineGame
|
|
1043
|
-
|
|
1044
|
-
- `GameConfig` (type): type GameConfig<TAssetRef extends ModelAssetRef = ModelAssetRef> = EngineFields<TAssetRef> & PresentationFields — ⚠ undocumented
|
|
1045
|
-
- `defineGame` (function): function defineGame<TAssetRef extends ModelAssetRef = ModelAssetRef>(config: GameConfig<TAssetRef>): PlayableGame — ⚠ undocumented
|
|
1046
|
-
|
|
1047
1262
|
## @jgengine/shell/devtools/ColPanel
|
|
1048
1263
|
|
|
1049
1264
|
- `ColPanel` (function): function ColPanel(): React.JSX.Element — ⚠ undocumented
|
|
@@ -1121,8 +1336,10 @@
|
|
|
1121
1336
|
## @jgengine/shell/diagnostics/RuntimeDiagnostics
|
|
1122
1337
|
|
|
1123
1338
|
- `DiagnosticOverlay` (function): function DiagnosticOverlay({ diagnostics, gameName }: { diagnostics: RuntimeDiagnostic[]; gameName: string }): React.JSX.Element | null — ⚠ undocumented
|
|
1339
|
+
- `ErrorReportActions` (function): function ErrorReportActions({ report, issueTitle }: { report: string; issueTitle: string }): React.JSX.Element — "Copy error" + "File issue" buttons for any error surface. `report` is the full text to copy / prefill.
|
|
1124
1340
|
- `GameUiErrorBoundary` (class): class GameUiErrorBoundary extends Component< { children: ReactNode; onRuntimeError: (error: unknown, phase: string, componentStack?: string) => void }, { failed: boolean } > — ⚠ undocumented
|
|
1125
1341
|
- `RuntimeDiagnostic` (interface): interface RuntimeDiagnostic — ⚠ undocumented
|
|
1342
|
+
- `errorReportContext` (function): function errorReportContext(): string — Standalone error footer text (page, browser, engine) shared by every error surface.
|
|
1126
1343
|
- `logRuntimeError` (function): function logRuntimeError(error: unknown, phase: string, componentStack?: string): Omit<RuntimeDiagnostic, "id"> — ⚠ undocumented
|
|
1127
1344
|
|
|
1128
1345
|
## @jgengine/shell/drivers/FrameDriver
|
|
@@ -1181,7 +1398,7 @@
|
|
|
1181
1398
|
|
|
1182
1399
|
## @jgengine/shell/environment/RoadRibbons
|
|
1183
1400
|
|
|
1184
|
-
- `RoadRibbons` (function): function RoadRibbons({ road, field }: { road: RoadEnvironmentDescriptor; field: TerrainField }): React.JSX.Element | null — Renders one `road()` descriptor: an asphalt ribbon plus optional dashed centerline
|
|
1401
|
+
- `RoadRibbons` (function): function RoadRibbons({ road, field, exclusions = [], }: { road: RoadEnvironmentDescriptor; field: TerrainField; exclusions?: readonly DashExclusion[]; }): React.JSX.Element | null — Renders one `road()` descriptor: an asphalt ribbon, a curb/edge strip along each border, plus an optional dashed centerline (draped on the terrain, and interrupted through any `exclusions` — the welded junction patches — so the center line does not paint across intersections).
|
|
1185
1402
|
|
|
1186
1403
|
## @jgengine/shell/environment/VolumetricClouds
|
|
1187
1404
|
|
|
@@ -1271,7 +1488,7 @@
|
|
|
1271
1488
|
|
|
1272
1489
|
## @jgengine/shell/postfx/PostProcessing
|
|
1273
1490
|
|
|
1274
|
-
- `PostProcessing` (function): function PostProcessing({ config }: { config: PostProcessingConfig }): null — Mounts an `EffectComposer` inside the shell Canvas and takes over rendering (priority-1 `useFrame`, which disables R3F auto-render) to run the configured post chain: RenderPass → GTAO → UnrealBloom → OutputPass → Grade. Rendered only when `PlayableGame.postProcessing` is set, so games without it draw unchanged.
|
|
1491
|
+
- `PostProcessing` (function): function PostProcessing({ config, quality = "high" }: { config: PostProcessingConfig; quality?: GraphicsQuality }): null — Mounts an `EffectComposer` inside the shell Canvas and takes over rendering (priority-1 `useFrame`, which disables R3F auto-render) to run the configured post chain: RenderPass → GTAO → UnrealBloom → OutputPass → Grade. Rendered only when `PlayableGame.postProcessing` is set, so games without it draw unchanged.
|
|
1275
1492
|
|
|
1276
1493
|
## @jgengine/shell/postfx/gradeShader
|
|
1277
1494
|
|
|
@@ -1280,11 +1497,15 @@
|
|
|
1280
1497
|
## @jgengine/shell/registry
|
|
1281
1498
|
|
|
1282
1499
|
- `GameRegistry` (type): type GameRegistry = Record<string, () => Promise<PlayableGame>> — ⚠ undocumented
|
|
1283
|
-
- `PlayableGame` (type): type PlayableGame = EnginePlayableGame< ComponentType, ComponentType, RenderEntity, RenderObject, ComponentType<ViewmodelProps>, ComponentType<WorldOverlayProps> > —
|
|
1500
|
+
- `PlayableGame` (type): type PlayableGame = EnginePlayableGame< ComponentType, ComponentType, RenderEntity, RenderObject, ComponentType<ViewmodelProps>, ComponentType<WorldOverlayProps> > — The concrete React-bound playable a shell `defineGame` returns and `GameHost` mounts — the one PlayableGame games handle.
|
|
1284
1501
|
- `RenderEntity` (type): type RenderEntity = (entity: SceneEntity) => ReactNode — ⚠ undocumented
|
|
1285
1502
|
- `RenderObject` (type): type RenderObject = (object: SceneObject) => ReactNode — ⚠ undocumented
|
|
1286
1503
|
- `resolveGameLoader` (function): function resolveGameLoader(registry: GameRegistry, gameId: string, fallbackGameId?: string): (() => Promise<PlayableGame>) | undefined — ⚠ undocumented
|
|
1287
1504
|
|
|
1505
|
+
## @jgengine/shell/render/PartMotion
|
|
1506
|
+
|
|
1507
|
+
- `PartMotionRig` (function): function PartMotionRig({ parts, model, instanceId, renderPart, children, }: { parts: readonly ModelPart[]; model: ModelConfig; instanceId?: string; /** Renders one part's model content (the shell passes its part renderer to avoid an import cycle). */ renderPart: (part: ModelPart, index: number) => R… — Procedural motion rig for a rig-less part-composed character (`ModelPart.role` — see `@jgengine/core/game/partAnimation`). Wraps the whole composition in a root group that bobs, breathes, flinches on `combat.hitReaction`, and topples on `entity.died`, while each role-tagged part swings around its authored transform — legs/arms counter-phase from the entity's live movement speed, head counter-sway, tail wag, wing flap. Untagged parts render as static kit pieces. Children are the base model content (primitive, attachments).
|
|
1508
|
+
|
|
1288
1509
|
## @jgengine/shell/render/SceneLighting
|
|
1289
1510
|
|
|
1290
1511
|
- `BackdropFog` (function): function BackdropFog({ fog }: { fog: BackdropConfig["fog"] }): React.JSX.Element | null — ⚠ undocumented
|
|
@@ -1292,9 +1513,23 @@
|
|
|
1292
1513
|
|
|
1293
1514
|
## @jgengine/shell/render/SceneModels
|
|
1294
1515
|
|
|
1295
|
-
- `EntityModel` (function): function EntityModel({ model, instanceId }: { model: ModelConfig; instanceId?: string }): React.JSX.Element — ⚠ undocumented
|
|
1516
|
+
- `EntityModel` (function): function EntityModel({ model, instanceId, measure, }: { model: ModelConfig; instanceId?: string; measure?: MeasureTarget; }): React.JSX.Element — ⚠ undocumented
|
|
1296
1517
|
- `EntitySprite` (function): function EntitySprite({ sprite }: { sprite: EntitySpriteConfig }): React.JSX.Element — ⚠ undocumented
|
|
1297
|
-
- `IsolatedEntityModel` (function): function IsolatedEntityModel({ model, instanceId, fallback, }: { model: ModelConfig; instanceId?: string; fallback?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
1518
|
+
- `IsolatedEntityModel` (function): function IsolatedEntityModel({ model, instanceId, measure, fallback, }: { model: ModelConfig; instanceId?: string; measure?: MeasureTarget; fallback?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
1519
|
+
- `MeasureTarget` (interface): interface MeasureTarget — Where a measured model reports its rendered bounds: an entity kind or an object catalog id.
|
|
1520
|
+
|
|
1521
|
+
## @jgengine/shell/render/assetBase
|
|
1522
|
+
|
|
1523
|
+
- `installAssetBase` (function): function installAssetBase(base: string): void — Installs the app base URL (pass `import.meta.env.BASE_URL`) so root-absolute asset paths load from under it. Call once at app startup, before any game loads. Bases that are not root-absolute (`/`, `./`) reset to the pass-through default. Also registers {@link resolveAssetBaseUrl} on `THREE.DefaultLoadingManager`, covering `TextureLoader`, drei's `useTexture` / `useGLTF`, and every other loader on the default manager.
|
|
1524
|
+
- `resolveAssetBaseUrl` (function): function resolveAssetBaseUrl(url: string): string — Resolves a root-absolute asset URL (`/models/…`, `/materials/…`) against the installed app base. Relative, protocol-relative, absolute-scheme (`https:`, `blob:`, `data:`), and already-based URLs pass through unchanged. Installed as the URL modifier on THREE loading managers so every model and texture load resolves correctly wherever the app is mounted.
|
|
1525
|
+
|
|
1526
|
+
## @jgengine/shell/render/measureBounds
|
|
1527
|
+
|
|
1528
|
+
- `MEASURE_EXCLUDE_KEY` (const): const MEASURE_EXCLUDE_KEY: "jgMeasureExclude" — Subtrees flagged with this userData key are excluded from bounds measurement — debug gizmos, selection quads, effect billboards that should not inflate the hitbox. Sprites and invisible subtrees are always excluded.
|
|
1529
|
+
- `MeasuredBoundsGroup` (function): function MeasuredBoundsGroup({ target, measureKey, children, }: { target: "entity" | "object"; measureKey: string; children: ReactNode; }): React.JSX.Element — Wraps custom-rendered actor content (`renderEntity` / `renderObject`) and reports its measured entity-local bounds into collider resolution, so the hitbox wraps what is actually on screen instead of the fixed-size fallback box. A successful measure re-reports only when the subtree gained or lost meshes (async fill-in), not when idle animation nudges the same meshes.
|
|
1530
|
+
- `MeasuredLocalBounds` (interface): interface MeasuredLocalBounds — Entity-local AABB of the meshes under a measured root, plus how many meshes contributed — the count lets callers detect async subtree fill-in without diffing bounds.
|
|
1531
|
+
- `measureLocalBounds` (function): function measureLocalBounds(root: THREE.Object3D): MeasuredLocalBounds | null — Measure the meshes under `root` in `root`'s own frame (root's transform is the measuring frame, children compose their local matrices below it). Returns `null` when nothing measurable is mounted. Skinned meshes measure at bind pose — the standard engine approximation.
|
|
1532
|
+
- `reportMeasuredBounds` (function): function reportMeasuredBounds(ctx: GameContext, target: "entity" | "object", key: string, bounds: MeasuredLocalBounds): void — Forward a measured result into the context (entity kind or object catalog id), deduping repeat reports of the same shape so remounts and multi-instance kinds don't churn collider resolution.
|
|
1298
1533
|
|
|
1299
1534
|
## @jgengine/shell/render/modelRender
|
|
1300
1535
|
|
|
@@ -1311,6 +1546,10 @@
|
|
|
1311
1546
|
|
|
1312
1547
|
- `useEntityRenderCues` (function): function useEntityRenderCues(instanceId: string | undefined, tuning?: RenderCueTuning): MutableRefObject<EntityRenderCues> — Live motion + animation cues for one entity, read from a mutable ref inside your own `useFrame` — no re-render per frame, no diffing the parent group's position, no game-side module map for attack/hit timing. Backs both custom `renderEntity` rigs and a custom first-person viewmodel (#542): call it with `entity.id` / the local player's userId and drive bob/recoil/reload poses from `cuesRef.current` inside the calling component's own `useFrame`.
|
|
1313
1548
|
|
|
1549
|
+
## @jgengine/shell/render/useModelAnimation
|
|
1550
|
+
|
|
1551
|
+
- `useModelAnimation` (function): function useModelAnimation(scene: THREE.Object3D, clips: THREE.AnimationClip[], animationInput: ModelAnimationConfig | "auto" | "none" | undefined, instanceId?: string): void — The engine's model animation driver as a standalone hook — the same mixer `EntityModel` runs, for games that render a cloned scene themselves (custom materials, procedural composition). Handles `"auto"` derivation from the GLB's clip names, speed-driven idle/walk/run crossfades read from the entity's live position when `instanceId` is set, one-shots fired from `entity.animation` / `combat.hitReaction` / `entity.died`, held poses, and the death clamp.
|
|
1552
|
+
|
|
1314
1553
|
## @jgengine/shell/replay/useSessionRecorder
|
|
1315
1554
|
|
|
1316
1555
|
- `RecordedPose` (interface): interface RecordedPose — ⚠ undocumented
|
|
@@ -1336,7 +1575,7 @@
|
|
|
1336
1575
|
- `AuthoredObjectsProps` (interface): interface AuthoredObjectsProps — Props for {@link AuthoredObjects}: document, ground field, and optional lift / onExisting.
|
|
1337
1576
|
- `AuthoredPaths` (function): function AuthoredPaths({ document, field, kinds }: AuthoredPathsProps): React.JSX.Element — Renders a document's non-scatter paths (roads, routes, corridors) as ground-draped ribbons — the editor authors the polyline, the engine drapes it over the live terrain at runtime. Width comes from `path.width`, color from `path.meta.color`/`path.color`. A game never hand-rolls path meshes.
|
|
1338
1577
|
- `AuthoredPathsProps` (interface): interface AuthoredPathsProps — Props for {@link AuthoredPaths}: the document, the ground field to drape over, and a kind filter.
|
|
1339
|
-
- `AuthoredScene` (function): function AuthoredScene({ document, field, pathKinds, scatterModels, assets, live = true, placeObjects, }: AuthoredSceneProps): React.JSX.Element — Renders an editor document's scene content — draped paths plus GPU-instanced foliage — from one mount, grounded on the live `field`. The runtime counterpart to authoring a scene in the editor: drag paths and foliage regions, save `editor.scene.json`, and the game plays them with no bespoke render code. When a live-sync bus is installed (editor host), document patches stream in and re-render automatically — document is authoritative; runtime overrides stay ephemeral unless written back. Terrain/collision come from the world's ground field (`environment({ sculpt })`); place markers with your own entity spawns. Pass `scatterModels`+`assets` to resolve palette items to real catalog GLBs; unmapped items keep the stylized proxy.
|
|
1578
|
+
- `AuthoredScene` (function): function AuthoredScene({ document, field, pathKinds, scatterModels, assets, live = true, placeObjects, groundColorAt, }: AuthoredSceneProps): React.JSX.Element — Renders an editor document's scene content — draped paths plus GPU-instanced foliage — from one mount, grounded on the live `field`. The runtime counterpart to authoring a scene in the editor: drag paths and foliage regions, save `editor.scene.json`, and the game plays them with no bespoke render code. When a live-sync bus is installed (editor host), document patches stream in and re-render automatically — document is authoritative; runtime overrides stay ephemeral unless written back. Terrain/collision come from the world's ground field (`environment({ sculpt })`); place markers with your own entity spawns. Pass `scatterModels`+`assets` to resolve palette items to real catalog GLBs; unmapped items keep the stylized proxy.
|
|
1340
1579
|
- `AuthoredSceneProps` (interface): interface AuthoredSceneProps — Props for {@link AuthoredScene}: the document to render and the ground field to drape/ground on.
|
|
1341
1580
|
|
|
1342
1581
|
## @jgengine/shell/scene/AuthoredScene
|
|
@@ -1345,7 +1584,7 @@
|
|
|
1345
1584
|
- `AuthoredObjectsProps` (interface): interface AuthoredObjectsProps — Props for {@link AuthoredObjects}: document, ground field, and optional lift / onExisting.
|
|
1346
1585
|
- `AuthoredPaths` (function): function AuthoredPaths({ document, field, kinds }: AuthoredPathsProps): React.JSX.Element — Renders a document's non-scatter paths (roads, routes, corridors) as ground-draped ribbons — the editor authors the polyline, the engine drapes it over the live terrain at runtime. Width comes from `path.width`, color from `path.meta.color`/`path.color`. A game never hand-rolls path meshes.
|
|
1347
1586
|
- `AuthoredPathsProps` (interface): interface AuthoredPathsProps — Props for {@link AuthoredPaths}: the document, the ground field to drape over, and a kind filter.
|
|
1348
|
-
- `AuthoredScene` (function): function AuthoredScene({ document, field, pathKinds, scatterModels, assets, live = true, placeObjects, }: AuthoredSceneProps): React.JSX.Element — Renders an editor document's scene content — draped paths plus GPU-instanced foliage — from one mount, grounded on the live `field`. The runtime counterpart to authoring a scene in the editor: drag paths and foliage regions, save `editor.scene.json`, and the game plays them with no bespoke render code. When a live-sync bus is installed (editor host), document patches stream in and re-render automatically — document is authoritative; runtime overrides stay ephemeral unless written back. Terrain/collision come from the world's ground field (`environment({ sculpt })`); place markers with your own entity spawns. Pass `scatterModels`+`assets` to resolve palette items to real catalog GLBs; unmapped items keep the stylized proxy.
|
|
1587
|
+
- `AuthoredScene` (function): function AuthoredScene({ document, field, pathKinds, scatterModels, assets, live = true, placeObjects, groundColorAt, }: AuthoredSceneProps): React.JSX.Element — Renders an editor document's scene content — draped paths plus GPU-instanced foliage — from one mount, grounded on the live `field`. The runtime counterpart to authoring a scene in the editor: drag paths and foliage regions, save `editor.scene.json`, and the game plays them with no bespoke render code. When a live-sync bus is installed (editor host), document patches stream in and re-render automatically — document is authoritative; runtime overrides stay ephemeral unless written back. Terrain/collision come from the world's ground field (`environment({ sculpt })`); place markers with your own entity spawns. Pass `scatterModels`+`assets` to resolve palette items to real catalog GLBs; unmapped items keep the stylized proxy.
|
|
1349
1588
|
- `AuthoredSceneProps` (interface): interface AuthoredSceneProps — Props for {@link AuthoredScene}: the document to render and the ground field to drape/ground on.
|
|
1350
1589
|
|
|
1351
1590
|
## @jgengine/shell/scene/GeneratedAssetRenderer
|
|
@@ -1385,7 +1624,7 @@
|
|
|
1385
1624
|
|
|
1386
1625
|
- `AudioSettingsBridge` (function): function AudioSettingsBridge({ store, engine, buses, }: { store: SettingsStore; engine: AudioEngine; buses: Record<string, AudioBusDef> | undefined; }): null — ⚠ undocumented
|
|
1387
1626
|
- `TOUCH_STYLE_AUTO` (const): const TOUCH_STYLE_AUTO: "auto" — Sentinel Controls value meaning "defer to the game's suggested touch skin".
|
|
1388
|
-
- `useGraphicsSettings` (function): function useGraphicsSettings(store: SettingsStore, shadowsDefault: boolean): { shadows: boolean; dpr: number; uiScale: number } — ⚠ undocumented
|
|
1627
|
+
- `useGraphicsSettings` (function): function useGraphicsSettings(store: SettingsStore, shadowsDefault: boolean): { shadows: boolean; dpr: number; uiScale: number; quality: GraphicsQuality } — ⚠ undocumented
|
|
1389
1628
|
- `useSettingsRevision` (function): function useSettingsRevision(store: SettingsStore): number — ⚠ undocumented
|
|
1390
1629
|
|
|
1391
1630
|
## @jgengine/shell/settings/settingsController
|
|
@@ -1414,7 +1653,7 @@
|
|
|
1414
1653
|
- `InstancedBuildingsProps` (interface): interface InstancedBuildingsProps — ⚠ undocumented
|
|
1415
1654
|
- `PlacementGhost` (function): function PlacementGhost({ preview, height = 1, validColor = "#34d399", invalidColor = "#f87171", }: PlacementGhostProps): React.JSX.Element | null — Cursor-following build ghost: valid/invalid tint from a placement controller preview.
|
|
1416
1655
|
- `PlacementGhostProps` (interface): interface PlacementGhostProps — ⚠ undocumented
|
|
1417
|
-
- `TransformGizmo` (const): const TransformGizmo: React.MemoExoticComponent<({ position, rotationY, mode, snapMode, gridSize, lift, size, groundSnap, onDraggingChange, onRelease, }: TransformGizmoProps) => React.JSX.Element> — Runtime selection/move gizmo shared by games and the editor. Wraps TransformControls; callers own selection and commit side-effects.
|
|
1656
|
+
- `TransformGizmo` (const): const TransformGizmo: React.MemoExoticComponent<({ position, rotationY, mode, snapMode, gridSize, space, rotationSnap, scaleSnap, lift, size, groundSnap, onDraggingChange, onRelease, }: TransformGizmoProps) => React.JSX.Element> — Runtime selection/move gizmo shared by games and the editor. Wraps TransformControls; callers own selection and commit side-effects.
|
|
1418
1657
|
- `TransformGizmoMode` (type): type TransformGizmoMode = "translate" | "rotate" | "scale" — Active TransformControls mode for the runtime selection gizmo.
|
|
1419
1658
|
- `TransformGizmoPose` (interface): interface TransformGizmoPose — Pose reported by {@link TransformGizmo} when the user releases a drag.
|
|
1420
1659
|
- `TransformGizmoProps` (interface): interface TransformGizmoProps — Props for the shared runtime/editor selection gizmo.
|
|
@@ -1431,7 +1670,7 @@
|
|
|
1431
1670
|
- `InstancedBuildingsProps` (interface): interface InstancedBuildingsProps — ⚠ undocumented
|
|
1432
1671
|
- `PlacementGhost` (function): function PlacementGhost({ preview, height = 1, validColor = "#34d399", invalidColor = "#f87171", }: PlacementGhostProps): React.JSX.Element | null — Cursor-following build ghost: valid/invalid tint from a placement controller preview.
|
|
1433
1672
|
- `PlacementGhostProps` (interface): interface PlacementGhostProps — ⚠ undocumented
|
|
1434
|
-
- `TransformGizmo` (const): const TransformGizmo: React.MemoExoticComponent<({ position, rotationY, mode, snapMode, gridSize, lift, size, groundSnap, onDraggingChange, onRelease, }: TransformGizmoProps) => React.JSX.Element> — Runtime selection/move gizmo shared by games and the editor. Wraps TransformControls; callers own selection and commit side-effects.
|
|
1673
|
+
- `TransformGizmo` (const): const TransformGizmo: React.MemoExoticComponent<({ position, rotationY, mode, snapMode, gridSize, space, rotationSnap, scaleSnap, lift, size, groundSnap, onDraggingChange, onRelease, }: TransformGizmoProps) => React.JSX.Element> — Runtime selection/move gizmo shared by games and the editor. Wraps TransformControls; callers own selection and commit side-effects.
|
|
1435
1674
|
- `TransformGizmoMode` (type): type TransformGizmoMode = "translate" | "rotate" | "scale" — Active TransformControls mode for the runtime selection gizmo.
|
|
1436
1675
|
- `TransformGizmoPose` (interface): interface TransformGizmoPose — Pose reported by {@link TransformGizmo} when the user releases a drag.
|
|
1437
1676
|
- `TransformGizmoProps` (interface): interface TransformGizmoProps — Props for the shared runtime/editor selection gizmo.
|
|
@@ -1460,11 +1699,13 @@
|
|
|
1460
1699
|
|
|
1461
1700
|
## @jgengine/shell/structures/TransformGizmo
|
|
1462
1701
|
|
|
1463
|
-
- `
|
|
1702
|
+
- `DEFAULT_ROTATION_SNAP` (const): const DEFAULT_ROTATION_SNAP: number — Default rotation snap increment (radians) when callers don't configure one.
|
|
1703
|
+
- `TransformGizmo` (const): const TransformGizmo: React.MemoExoticComponent<({ position, rotationY, mode, snapMode, gridSize, space, rotationSnap, scaleSnap, lift, size, groundSnap, onDraggingChange, onRelease, }: TransformGizmoProps) => React.JSX.Element> — Runtime selection/move gizmo shared by games and the editor. Wraps TransformControls; callers own selection and commit side-effects.
|
|
1464
1704
|
- `TransformGizmoMode` (type): type TransformGizmoMode = "translate" | "rotate" | "scale" — Active TransformControls mode for the runtime selection gizmo.
|
|
1465
1705
|
- `TransformGizmoPose` (interface): interface TransformGizmoPose — Pose reported by {@link TransformGizmo} when the user releases a drag.
|
|
1466
1706
|
- `TransformGizmoProps` (interface): interface TransformGizmoProps — Props for the shared runtime/editor selection gizmo.
|
|
1467
1707
|
- `TransformGizmoSnap` (type): type TransformGizmoSnap = "grid" | "free" | "ground" — Snap policy: grid quantize, free drag, or ground-height sample on release.
|
|
1708
|
+
- `TransformGizmoSpace` (type): type TransformGizmoSpace = "world" | "local" — Gizmo handle orientation: world axes, or the target's local (yaw-rotated) axes.
|
|
1468
1709
|
|
|
1469
1710
|
## @jgengine/shell/terrain
|
|
1470
1711
|
|
|
@@ -1476,13 +1717,16 @@
|
|
|
1476
1717
|
- `FieldGroundOptions` (interface): interface FieldGroundOptions — ⚠ undocumented
|
|
1477
1718
|
- `FractalNoiseConfig` (interface): interface FractalNoiseConfig — Octave settings for {@link fractalNoise}: frequency, layering, and optional ridged shaping.
|
|
1478
1719
|
- `GrassBladeGeometryOptions` (interface): interface GrassBladeGeometryOptions — ⚠ undocumented
|
|
1479
|
-
- `GrassField` (function): function GrassField({ count = DEFAULT_GRASS_COUNT, density = DEFAULT_GRASS_DENSITY, budget, area = 40, seed = 1, segments = 4, bladeHeight, bladeWidth, bladeBend,
|
|
1720
|
+
- `GrassField` (function): function GrassField({ count = DEFAULT_GRASS_COUNT, density = DEFAULT_GRASS_DENSITY, budget, area = 40, seed = 1, segments = 4, bladeHeight, bladeWidth, bladeBend, tuftBlades = GRASS_TUFT_BLADES, tuftRadius, edgeFeather, exclude, heightAt, colorBase, colorTip, colorGround, colorVariation, wind, dista… — ⚠ undocumented
|
|
1480
1721
|
- `GrassFieldProps` (interface): interface GrassFieldProps extends Omit<ThreeElements["mesh"], "args" | "children" | "geometry" | "material"> — ⚠ undocumented
|
|
1481
1722
|
- `GrassMaterialHandle` (interface): interface GrassMaterialHandle — ⚠ undocumented
|
|
1482
1723
|
- `GrassMaterialOptions` (interface): interface GrassMaterialOptions — ⚠ undocumented
|
|
1483
1724
|
- `GrassRange` (type): type GrassRange = number | readonly [min: number, max: number] — ⚠ undocumented
|
|
1484
1725
|
- `GrassShaderUniforms` (interface): interface GrassShaderUniforms — ⚠ undocumented
|
|
1485
1726
|
- `GrassWindOptions` (interface): interface GrassWindOptions — ⚠ undocumented
|
|
1727
|
+
- `HeightfieldColorFn` (type): type HeightfieldColorFn = (x: number, z: number, height: number, out: THREE.Color) => void — Per-vertex color hook for {@link displaceHeightfieldGeometry}; write the tone into `out`.
|
|
1728
|
+
- `HeightfieldDisplaceOptions` (interface): interface HeightfieldDisplaceOptions — Options for {@link displaceHeightfieldGeometry}.
|
|
1729
|
+
- `HeightfieldRect` (interface): interface HeightfieldRect — XZ rectangle in world units — matches the shape of a terraform snapshot's `bounds`.
|
|
1486
1730
|
- `NoiseFieldConfig` (interface): interface NoiseFieldConfig — Configuration for {@link noiseField}: seed, amplitude, and fractal noise shaping.
|
|
1487
1731
|
- `ProceduralGround` (function): function ProceduralGround({ terrain, colors, roughness = 0.94, metalness = 0, receiveShadow = true, ...meshProps }: ProceduralGroundProps): React.JSX.Element — ⚠ undocumented
|
|
1488
1732
|
- `ProceduralGroundProps` (interface): interface ProceduralGroundProps extends Omit<ThreeElements["mesh"], "args" | "children" | "geometry" | "material"> — ⚠ undocumented
|
|
@@ -1498,6 +1742,7 @@
|
|
|
1498
1742
|
- `TerrainNormal` (type): type TerrainNormal = readonly [number, number, number] — A surface normal vector at a terrain sample point.
|
|
1499
1743
|
- `TerrainSeed` (type): type TerrainSeed = number | string — ⚠ undocumented
|
|
1500
1744
|
- `TerrainVertexColorOptions` (interface): interface TerrainVertexColorOptions — ⚠ undocumented
|
|
1745
|
+
- `displaceHeightfieldGeometry` (function): function displaceHeightfieldGeometry(geometry: THREE.BufferGeometry, sampleHeight: (x: number, z: number) => number, options: HeightfieldDisplaceOptions): void — Re-samples a `PlaneGeometry(width, depth, segments, segments).rotateX(-π/2)` heightfield mesh from a `sampleHeight` field in place: vertex Y, optional vertex color, grid central-difference normals, and an analytically maintained bounding sphere. With a dirty `region`, the work is O(region vertices) — heights/colors update inside the covering vertex window, normals inside the window plus a one-vertex ring — never a whole-mesh `computeVertexNormals`/`computeBoundingSphere` pass, which is what keeps per-frame brush stamps inside the editor's frame budget. The bounding sphere derives from the fixed plane extents plus a running height range kept on `geometry.userData`; partial passes only expand it, a full pass resets it exactly.
|
|
1501
1746
|
|
|
1502
1747
|
## @jgengine/shell/terrain
|
|
1503
1748
|
|
|
@@ -1509,13 +1754,16 @@
|
|
|
1509
1754
|
- `FieldGroundOptions` (interface): interface FieldGroundOptions — ⚠ undocumented
|
|
1510
1755
|
- `FractalNoiseConfig` (interface): interface FractalNoiseConfig — Octave settings for {@link fractalNoise}: frequency, layering, and optional ridged shaping.
|
|
1511
1756
|
- `GrassBladeGeometryOptions` (interface): interface GrassBladeGeometryOptions — ⚠ undocumented
|
|
1512
|
-
- `GrassField` (function): function GrassField({ count = DEFAULT_GRASS_COUNT, density = DEFAULT_GRASS_DENSITY, budget, area = 40, seed = 1, segments = 4, bladeHeight, bladeWidth, bladeBend,
|
|
1757
|
+
- `GrassField` (function): function GrassField({ count = DEFAULT_GRASS_COUNT, density = DEFAULT_GRASS_DENSITY, budget, area = 40, seed = 1, segments = 4, bladeHeight, bladeWidth, bladeBend, tuftBlades = GRASS_TUFT_BLADES, tuftRadius, edgeFeather, exclude, heightAt, colorBase, colorTip, colorGround, colorVariation, wind, dista… — ⚠ undocumented
|
|
1513
1758
|
- `GrassFieldProps` (interface): interface GrassFieldProps extends Omit<ThreeElements["mesh"], "args" | "children" | "geometry" | "material"> — ⚠ undocumented
|
|
1514
1759
|
- `GrassMaterialHandle` (interface): interface GrassMaterialHandle — ⚠ undocumented
|
|
1515
1760
|
- `GrassMaterialOptions` (interface): interface GrassMaterialOptions — ⚠ undocumented
|
|
1516
1761
|
- `GrassRange` (type): type GrassRange = number | readonly [min: number, max: number] — ⚠ undocumented
|
|
1517
1762
|
- `GrassShaderUniforms` (interface): interface GrassShaderUniforms — ⚠ undocumented
|
|
1518
1763
|
- `GrassWindOptions` (interface): interface GrassWindOptions — ⚠ undocumented
|
|
1764
|
+
- `HeightfieldColorFn` (type): type HeightfieldColorFn = (x: number, z: number, height: number, out: THREE.Color) => void — Per-vertex color hook for {@link displaceHeightfieldGeometry}; write the tone into `out`.
|
|
1765
|
+
- `HeightfieldDisplaceOptions` (interface): interface HeightfieldDisplaceOptions — Options for {@link displaceHeightfieldGeometry}.
|
|
1766
|
+
- `HeightfieldRect` (interface): interface HeightfieldRect — XZ rectangle in world units — matches the shape of a terraform snapshot's `bounds`.
|
|
1519
1767
|
- `NoiseFieldConfig` (interface): interface NoiseFieldConfig — Configuration for {@link noiseField}: seed, amplitude, and fractal noise shaping.
|
|
1520
1768
|
- `ProceduralGround` (function): function ProceduralGround({ terrain, colors, roughness = 0.94, metalness = 0, receiveShadow = true, ...meshProps }: ProceduralGroundProps): React.JSX.Element — ⚠ undocumented
|
|
1521
1769
|
- `ProceduralGroundProps` (interface): interface ProceduralGroundProps extends Omit<ThreeElements["mesh"], "args" | "children" | "geometry" | "material"> — ⚠ undocumented
|
|
@@ -1531,6 +1779,7 @@
|
|
|
1531
1779
|
- `TerrainNormal` (type): type TerrainNormal = readonly [number, number, number] — A surface normal vector at a terrain sample point.
|
|
1532
1780
|
- `TerrainSeed` (type): type TerrainSeed = number | string — ⚠ undocumented
|
|
1533
1781
|
- `TerrainVertexColorOptions` (interface): interface TerrainVertexColorOptions — ⚠ undocumented
|
|
1782
|
+
- `displaceHeightfieldGeometry` (function): function displaceHeightfieldGeometry(geometry: THREE.BufferGeometry, sampleHeight: (x: number, z: number) => number, options: HeightfieldDisplaceOptions): void — Re-samples a `PlaneGeometry(width, depth, segments, segments).rotateX(-π/2)` heightfield mesh from a `sampleHeight` field in place: vertex Y, optional vertex color, grid central-difference normals, and an analytically maintained bounding sphere. With a dirty `region`, the work is O(region vertices) — heights/colors update inside the covering vertex window, normals inside the window plus a one-vertex ring — never a whole-mesh `computeVertexNormals`/`computeBoundingSphere` pass, which is what keeps per-frame brush stamps inside the editor's frame budget. The bounding sphere derives from the fixed plane extents plus a running height range kept on `geometry.userData`; partial passes only expand it, a full pass resets it exactly.
|
|
1534
1783
|
|
|
1535
1784
|
## @jgengine/shell/terrain/CarvedTerrain
|
|
1536
1785
|
|
|
@@ -1546,7 +1795,8 @@
|
|
|
1546
1795
|
|
|
1547
1796
|
- `DEFAULT_GRASS_COUNT` (const): const DEFAULT_GRASS_COUNT: 1500 — ⚠ undocumented
|
|
1548
1797
|
- `DEFAULT_GRASS_DENSITY` (const): const DEFAULT_GRASS_DENSITY: 4 — Blades per square meter — matches `@jgengine/core/world/vegetation`'s `VEGETATION_DEFAULTS.density`, so an editor-placed grass volume and a bare `<GrassField>` agree on what "4" means.
|
|
1549
|
-
- `
|
|
1798
|
+
- `GRASS_TUFT_BLADES` (const): const GRASS_TUFT_BLADES: 5 — Blades baked into each tuft instance — one instance reads as a clump, not a lone blade.
|
|
1799
|
+
- `GrassField` (function): function GrassField({ count = DEFAULT_GRASS_COUNT, density = DEFAULT_GRASS_DENSITY, budget, area = 40, seed = 1, segments = 4, bladeHeight, bladeWidth, bladeBend, tuftBlades = GRASS_TUFT_BLADES, tuftRadius, edgeFeather, exclude, heightAt, colorBase, colorTip, colorGround, colorVariation, wind, dista… — ⚠ undocumented
|
|
1550
1800
|
- `GrassFieldProps` (interface): interface GrassFieldProps extends Omit<ThreeElements["mesh"], "args" | "children" | "geometry" | "material"> — ⚠ undocumented
|
|
1551
1801
|
|
|
1552
1802
|
## @jgengine/shell/terrain/ProceduralGround
|
|
@@ -1566,22 +1816,37 @@
|
|
|
1566
1816
|
|
|
1567
1817
|
## @jgengine/shell/terrain/grassGeometry
|
|
1568
1818
|
|
|
1819
|
+
- `GRASS_TUFT_BLADES` (const): const GRASS_TUFT_BLADES: 5 — Blades baked into each tuft instance — one instance reads as a clump, not a lone blade.
|
|
1569
1820
|
- `GrassBladeGeometryOptions` (interface): interface GrassBladeGeometryOptions — ⚠ undocumented
|
|
1821
|
+
- `GrassExclusion` (interface): interface GrassExclusion — A rectangle (patch-local XZ) the grass bake keeps clear — soil patches, water, plazas.
|
|
1570
1822
|
- `GrassRange` (type): type GrassRange = number | readonly [min: number, max: number] — ⚠ undocumented
|
|
1571
1823
|
- `ResolvedGrassBladeGeometryOptions` (interface): interface ResolvedGrassBladeGeometryOptions — ⚠ undocumented
|
|
1572
1824
|
|
|
1573
1825
|
## @jgengine/shell/terrain/grassMaterial
|
|
1574
1826
|
|
|
1827
|
+
- `DEFAULT_GRASS_DISTANCE_FADE` (const): const DEFAULT_GRASS_DISTANCE_FADE: Required<GrassDistanceFadeOptions> — Default camera-distance fade band: tufts start thinning at 35 m and are gone by 95 m.
|
|
1575
1828
|
- `DEFAULT_GRASS_WIND` (const): const DEFAULT_GRASS_WIND: Required<GrassWindOptions> — ⚠ undocumented
|
|
1829
|
+
- `GrassDistanceFadeOptions` (interface): interface GrassDistanceFadeOptions — Camera-distance fade band: tufts thin out between `start` and `end` meters, so the instance budget spends where the camera lives.
|
|
1576
1830
|
- `GrassMaterialHandle` (interface): interface GrassMaterialHandle — ⚠ undocumented
|
|
1577
1831
|
- `GrassMaterialOptions` (interface): interface GrassMaterialOptions — ⚠ undocumented
|
|
1578
1832
|
- `GrassShaderUniforms` (interface): interface GrassShaderUniforms — ⚠ undocumented
|
|
1579
1833
|
- `GrassWindOptions` (interface): interface GrassWindOptions — ⚠ undocumented
|
|
1580
1834
|
|
|
1835
|
+
## @jgengine/shell/terrain/heightfieldGeometry
|
|
1836
|
+
|
|
1837
|
+
- `HeightfieldColorFn` (type): type HeightfieldColorFn = (x: number, z: number, height: number, out: THREE.Color) => void — Per-vertex color hook for {@link displaceHeightfieldGeometry}; write the tone into `out`.
|
|
1838
|
+
- `HeightfieldDisplaceOptions` (interface): interface HeightfieldDisplaceOptions — Options for {@link displaceHeightfieldGeometry}.
|
|
1839
|
+
- `HeightfieldRect` (interface): interface HeightfieldRect — XZ rectangle in world units — matches the shape of a terraform snapshot's `bounds`.
|
|
1840
|
+
- `displaceHeightfieldGeometry` (function): function displaceHeightfieldGeometry(geometry: THREE.BufferGeometry, sampleHeight: (x: number, z: number) => number, options: HeightfieldDisplaceOptions): void — Re-samples a `PlaneGeometry(width, depth, segments, segments).rotateX(-π/2)` heightfield mesh from a `sampleHeight` field in place: vertex Y, optional vertex color, grid central-difference normals, and an analytically maintained bounding sphere. With a dirty `region`, the work is O(region vertices) — heights/colors update inside the covering vertex window, normals inside the window plus a one-vertex ring — never a whole-mesh `computeVertexNormals`/`computeBoundingSphere` pass, which is what keeps per-frame brush stamps inside the editor's frame budget. The bounding sphere derives from the fixed plane extents plus a running height range kept on `geometry.userData`; partial passes only expand it, a full pass resets it exactly.
|
|
1841
|
+
|
|
1581
1842
|
## @jgengine/shell/terrain/random
|
|
1582
1843
|
|
|
1583
1844
|
- `TerrainSeed` (type): type TerrainSeed = number | string — ⚠ undocumented
|
|
1584
1845
|
|
|
1846
|
+
## @jgengine/shell/terrain/soilPatchMaterial
|
|
1847
|
+
|
|
1848
|
+
- `SoilPatchEdge` (interface): interface SoilPatchEdge — Optional noise-eroded edge-fade config for {@link createSoilPatchMaterial} — the patch dissolves into the ground at its border.
|
|
1849
|
+
|
|
1585
1850
|
## @jgengine/shell/terrain/terrainDetailMaterial
|
|
1586
1851
|
|
|
1587
1852
|
- `TerrainDetailMaterialHandle` (interface): interface TerrainDetailMaterialHandle — The built procedural detail terrain material, ready to mount on the ground mesh.
|
|
@@ -1651,7 +1916,7 @@
|
|
|
1651
1916
|
- `DEFAULT_OCEAN_WAVE_SCALE` (const): const DEFAULT_OCEAN_WAVE_SCALE: 18 — Shared with `@jgengine/core/world/water` — primary wavelength in world units.
|
|
1652
1917
|
- `MAX_OCEAN_WAVES` (const): const MAX_OCEAN_WAVES: 6 — ⚠ undocumented
|
|
1653
1918
|
- `OCEAN_QUALITY_PRESETS` (const): const OCEAN_QUALITY_PRESETS: Record<OceanQualityPreset, { size: number; resolution: number }> — ⚠ undocumented
|
|
1654
|
-
- `Ocean` (function): function Ocean({ config, ...meshProps }: OceanProps): React.JSX.Element — ⚠ undocumented
|
|
1919
|
+
- `Ocean` (function): function Ocean({ config, depthAt, ...meshProps }: OceanProps): React.JSX.Element — ⚠ undocumented
|
|
1655
1920
|
- `OceanColorConfig` (interface): interface OceanColorConfig — ⚠ undocumented
|
|
1656
1921
|
- `OceanConfig` (interface): interface OceanConfig — ⚠ undocumented
|
|
1657
1922
|
- `OceanDirectionVector` (interface): interface OceanDirectionVector — ⚠ undocumented
|
|
@@ -1675,7 +1940,7 @@
|
|
|
1675
1940
|
- `DEFAULT_OCEAN_WAVE_SCALE` (const): const DEFAULT_OCEAN_WAVE_SCALE: 18 — Shared with `@jgengine/core/world/water` — primary wavelength in world units.
|
|
1676
1941
|
- `MAX_OCEAN_WAVES` (const): const MAX_OCEAN_WAVES: 6 — ⚠ undocumented
|
|
1677
1942
|
- `OCEAN_QUALITY_PRESETS` (const): const OCEAN_QUALITY_PRESETS: Record<OceanQualityPreset, { size: number; resolution: number }> — ⚠ undocumented
|
|
1678
|
-
- `Ocean` (function): function Ocean({ config, ...meshProps }: OceanProps): React.JSX.Element — ⚠ undocumented
|
|
1943
|
+
- `Ocean` (function): function Ocean({ config, depthAt, ...meshProps }: OceanProps): React.JSX.Element — ⚠ undocumented
|
|
1679
1944
|
- `OceanColorConfig` (interface): interface OceanColorConfig — ⚠ undocumented
|
|
1680
1945
|
- `OceanConfig` (interface): interface OceanConfig — ⚠ undocumented
|
|
1681
1946
|
- `OceanDirectionVector` (interface): interface OceanDirectionVector — ⚠ undocumented
|
|
@@ -1695,7 +1960,7 @@
|
|
|
1695
1960
|
|
|
1696
1961
|
## @jgengine/shell/water/Ocean
|
|
1697
1962
|
|
|
1698
|
-
- `Ocean` (function): function Ocean({ config, ...meshProps }: OceanProps): React.JSX.Element — ⚠ undocumented
|
|
1963
|
+
- `Ocean` (function): function Ocean({ config, depthAt, ...meshProps }: OceanProps): React.JSX.Element — ⚠ undocumented
|
|
1699
1964
|
- `OceanProps` (interface): interface OceanProps extends Omit<ThreeElements["mesh"], "args" | "children" | "geometry" | "material"> — ⚠ undocumented
|
|
1700
1965
|
|
|
1701
1966
|
## @jgengine/shell/water/OceanConfig
|
|
@@ -1725,8 +1990,8 @@
|
|
|
1725
1990
|
|
|
1726
1991
|
## @jgengine/shell/water/OceanShader
|
|
1727
1992
|
|
|
1728
|
-
- `oceanFragmentShader` (const): const oceanFragmentShader: "\nuniform vec3 uShallowColor;\nuniform vec3 uDeepColor;\nuniform vec3 uCrestColor;\nuniform vec3 uFoamColor;\nuniform float uOpacity;\nuniform float uFresnelStrength;\nuniform float uHorizonBlend;\nuniform float uFoamIntensity;\
|
|
1729
|
-
- `oceanVertexShader` (const): const oceanVertexShader: "\nuniform float uTime;\nuniform vec2 uWaveDirections[6];\nuniform vec4 uWaveParams[6];\nuniform float uChoppiness;\nuniform float uFoamThreshold;\nuniform float uFoamSoftness;\nuniform float uFoamCoverage;\n\
|
|
1993
|
+
- `oceanFragmentShader` (const): const oceanFragmentShader: "\nuniform float uTime;\nuniform vec3 uShallowColor;\nuniform vec3 uDeepColor;\nuniform vec3 uCrestColor;\nuniform vec3 uFoamColor;\nuniform float uOpacity;\nuniform float uFresnelStrength;\nuniform float uHorizonBlend;\nuniform float uFoamIntensity;\nuniform float uDepthR… — ⚠ undocumented
|
|
1994
|
+
- `oceanVertexShader` (const): const oceanVertexShader: "\nuniform float uTime;\nuniform vec2 uWaveDirections[6];\nuniform vec4 uWaveParams[6];\nuniform float uChoppiness;\nuniform float uFoamThreshold;\nuniform float uFoamSoftness;\nuniform float uFoamCoverage;\n\nattribute float aDepth;\n\nvarying vec3 vWorldPosition;\nvarying … — ⚠ undocumented
|
|
1730
1995
|
|
|
1731
1996
|
## @jgengine/shell/weather
|
|
1732
1997
|
|
|
@@ -1820,7 +2085,7 @@
|
|
|
1820
2085
|
- `WorldBarSample` (interface): interface WorldBarSample — ⚠ undocumented
|
|
1821
2086
|
- `WorldEntityBars` (function): function WorldEntityBars({ statId, height = 2.2, roles, resolveRole, maxDistance = 60, }: { statId: string; height?: number; roles?: readonly CatalogEntityRole[]; resolveRole?: (entity: SceneEntity) => CatalogEntityRole | undefined; /** Hide bars for entities farther than this from the player (world… — ⚠ undocumented
|
|
1822
2087
|
- `WorldFloatText` (function): function WorldFloatText({ height = 1.9, lifeMs = 950 }: { height?: number; lifeMs?: number }): React.JSX.Element — ⚠ undocumented
|
|
1823
|
-
- `WorldNameplates` (function): function WorldNameplates({ statId = "health", height = 2.3, roles, resolveRole, maxDistance = 40, tickMs = 120, className, nameplateClassName, nameClassName, barClassName, fillClassName, renderNameplate, }: WorldNameplatesProps): React.JSX.Element — Billboarded name + 78×6px HP bar over every nearby non-local entity that passes `roles`/`maxDistance` — headless (className/data-* slots on every part, `renderNameplate` for a full swap), turned on declaratively via `defineGame({ nameplates })` rather than mounted by hand.
|
|
2088
|
+
- `WorldNameplates` (function): function WorldNameplates({ statId = "health", height = 2.3, roles, resolveRole, maxDistance = 40, tickMs = 120, showHealth = true, className, nameplateClassName, nameClassName, barClassName, fillClassName, renderNameplate, }: WorldNameplatesProps): React.JSX.Element — Billboarded name + 78×6px HP bar over every nearby non-local entity that passes `roles`/`maxDistance` — headless (className/data-* slots on every part, `renderNameplate` for a full swap), turned on declaratively via `defineGame({ nameplates })` rather than mounted by hand.
|
|
1824
2089
|
- `WorldNameplatesProps` (interface): interface WorldNameplatesProps — Props for `WorldNameplates` — entity filter, refresh rate, and headless className/render hooks.
|
|
1825
2090
|
- `WorldObjectHighlights` (function): function WorldObjectHighlights({ color = "#facc15", radius, y = 0.05 }: WorldObjectHighlightsProps): React.JSX.Element — Ground ring over every `ctx.scene.object.selection`-ed placed object — the object-layer counterpart to `WorldEntityBars`/`WorldNameplates`. Mount it once in the game's scene (headless: no defaults are imposed beyond a visible ring) instead of hand-rolling a selection highlight through `WorldOverlay` against external state.
|
|
1826
2091
|
- `WorldObjectHighlightsProps` (interface): interface WorldObjectHighlightsProps — Props for {@link WorldObjectHighlights}.
|