@jgengine/shell 0.13.0 → 0.15.0-next.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 +529 -1
- package/dist/CombatPresentation.js +2 -1
- package/dist/GamePlayerShell.js +25 -5
- package/dist/Shell3dPresentation.d.ts +6 -6
- package/dist/Shell3dPresentation.js +4 -4
- package/dist/camera/ControllerCameraShake.d.ts +31 -0
- package/dist/camera/ControllerCameraShake.js +34 -0
- package/dist/camera/GameCameraRig.js +10 -5
- package/dist/camera/GameOrbitCamera.js +1 -10
- package/dist/camera/cameraRigs.js +16 -4
- package/dist/camera/index.d.ts +1 -0
- package/dist/camera/index.js +1 -0
- package/dist/camera/rigMath.d.ts +2 -0
- package/dist/camera/rigMath.js +7 -0
- package/dist/devtools/CollisionDebugWorld.js +15 -1
- package/dist/devtools/DevtoolsOverlay.js +2 -0
- package/dist/devtools/collisionDebugMath.d.ts +8 -0
- package/dist/devtools/collisionDebugMath.js +14 -5
- package/dist/drivers/FrameDriver.d.ts +4 -1
- package/dist/drivers/FrameDriver.js +5 -3
- package/dist/environment/DayNightSky.d.ts +33 -0
- package/dist/environment/DayNightSky.js +51 -0
- package/dist/environment/Daylight.d.ts +3 -1
- package/dist/environment/Daylight.js +7 -3
- package/dist/environment/EnvironmentScene.js +6 -6
- package/dist/environment/RoadJunctions.d.ts +8 -4
- package/dist/environment/RoadJunctions.js +16 -15
- package/dist/environment/RoadRibbons.d.ts +42 -6
- package/dist/environment/RoadRibbons.js +150 -27
- package/dist/environment/VolumetricClouds.js +3 -3
- package/dist/environment/index.d.ts +1 -0
- package/dist/environment/index.js +1 -0
- package/dist/gameKit.d.ts +7 -4
- package/dist/gameKit.js +8 -5
- package/dist/inputSink.js +14 -0
- package/dist/materialOverride.js +30 -0
- package/dist/postfx/PostProcessing.d.ts +3 -2
- package/dist/postfx/PostProcessing.js +38 -5
- package/dist/postfx/ScreenEffectsOverlay.d.ts +32 -0
- package/dist/postfx/ScreenEffectsOverlay.js +70 -0
- package/dist/postfx/postfxOverlay.d.ts +24 -0
- package/dist/postfx/postfxOverlay.js +35 -0
- package/dist/presentationResolve.d.ts +3 -2
- package/dist/presentationResolve.js +11 -6
- package/dist/render/CascadedShadows.d.ts +13 -0
- package/dist/render/CascadedShadows.js +96 -0
- package/dist/render/EntityPreview.d.ts +53 -0
- package/dist/render/EntityPreview.js +23 -0
- package/dist/render/EnvironmentLighting.d.ts +23 -7
- package/dist/render/EnvironmentLighting.js +69 -10
- package/dist/render/PartMotion.js +4 -4
- package/dist/render/SceneLighting.js +7 -0
- package/dist/render/SceneModels.d.ts +37 -1
- package/dist/render/SceneModels.js +52 -10
- package/dist/render/measureBounds.js +4 -0
- package/dist/render/measureCollisionMesh.d.ts +26 -0
- package/dist/render/measureCollisionMesh.js +108 -0
- package/dist/render/modelLoad.d.ts +41 -5
- package/dist/render/modelLoad.js +85 -18
- package/dist/render/sceneCapture.d.ts +27 -0
- package/dist/render/sceneCapture.js +43 -0
- package/dist/render/useDisposable.d.ts +16 -0
- package/dist/render/useDisposable.js +24 -0
- package/dist/render/useModelAnimation.js +47 -4
- package/dist/scene/AuthoredScene.js +14 -24
- package/dist/scene/CityRenderer.js +103 -36
- package/dist/scene/GrassFieldRenderer.js +4 -1
- package/dist/scene/PoleLineRenderer.js +7 -16
- package/dist/settings/QuickControls.js +5 -3
- package/dist/settings/SettingsMenu.js +6 -3
- package/dist/settings/appliedSettings.d.ts +3 -1
- package/dist/settings/appliedSettings.js +17 -5
- package/dist/settings/settingsController.js +11 -5
- package/dist/shellMovement.d.ts +15 -1
- package/dist/shellMovement.js +15 -1
- package/dist/structures/GeneratedBuilding.js +4 -5
- package/dist/structures/TransformGizmo.js +6 -5
- package/dist/terrain/CarvedTerrain.js +3 -7
- package/dist/terrain/GrassField.js +2 -2
- package/dist/terrain/ProceduralGround.js +3 -5
- package/dist/terrain/grassMaterial.d.ts +8 -2
- package/dist/terrain/grassMaterial.js +24 -5
- package/dist/terrain/index.d.ts +1 -1
- package/dist/terrain/terrainDetailMaterial.js +11 -2
- package/dist/terrain/terrainMath.d.ts +38 -1
- package/dist/terrain/terrainMath.js +86 -64
- package/dist/touch/TouchControlsOverlay.d.ts +6 -2
- package/dist/touch/TouchControlsOverlay.js +136 -17
- package/dist/vfx/ParticleField.d.ts +32 -0
- package/dist/vfx/ParticleField.js +91 -0
- package/dist/vfx/WorldFloatingText.d.ts +32 -0
- package/dist/vfx/WorldFloatingText.js +32 -0
- package/dist/water/Ocean.js +3 -6
- package/dist/weather/LightningStrike.js +3 -9
- package/dist/weather/RainField.js +3 -7
- package/dist/weather/SnowField.js +3 -7
- package/dist/world/DataObjects.js +3 -6
- package/dist/world/GridWorldScene.js +3 -6
- package/dist/world/InstancedBodies.js +3 -6
- package/dist/world/InstancedJoints.js +2 -2
- package/dist/world/SpriteBatch.js +3 -6
- package/dist/world/WorldEntityFrames.d.ts +47 -0
- package/dist/world/WorldEntityFrames.js +75 -0
- package/dist/world/WorldHud.js +7 -5
- package/dist/world/WorldPings.d.ts +26 -0
- package/dist/world/WorldPings.js +68 -0
- package/dist/world/WorldScene.js +9 -4
- package/dist/world/pingPulse.d.ts +21 -0
- package/dist/world/pingPulse.js +17 -0
- package/package.json +5 -5
- package/skills/ce-handoff/SKILL.md +149 -0
- package/skills/game-design/SKILL.md +2 -0
- package/skills/jgengine/SKILL.md +7 -3
- package/skills/jgengine/api.md +17 -7
- package/skills/jgengine/capabilities.md +12 -0
- package/skills/jgengine/recipes/minimal-game.md +7 -4
- package/skills/jgengine-ui/SKILL.md +8 -3
- package/skills/jgengine-ui/api.md +732 -23
- package/skills/jgengine-ui/capabilities.md +371 -2
- package/skills/jgengine-ui/recipes/overhead-entity-frames.md +136 -0
- package/skills/jgengine-ui/reference.md +7 -4
- package/skills/jgengine-world/api.md +408 -12
- package/skills/jgengine-world/capabilities.md +127 -2
- package/skills/jgengine-world/reference.md +15 -1
|
@@ -22,6 +22,17 @@
|
|
|
22
22
|
- `SpeedUnit` (type): type SpeedUnit = "kmh" | "mph" | "knots" | "ms" — Target unit for {@link formatSpeed}: km/h, mph, knots, or raw m/s.
|
|
23
23
|
- `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.
|
|
24
24
|
|
|
25
|
+
## @jgengine/core/i18n/i18n
|
|
26
|
+
|
|
27
|
+
- `Catalog` (type): type Catalog = Readonly<Record<Locale, Messages>> — All locales' message tables, keyed by locale.
|
|
28
|
+
- `I18n` (interface): interface I18n — Runtime translator over a message {@link Catalog} — active locale, lookup with fallback, interpolation, and pluralization.
|
|
29
|
+
- `I18nOptions` (interface): interface I18nOptions — Configuration for {@link createI18n}.
|
|
30
|
+
- `Locale` (type): type Locale = string — A locale tag (e.g. `"en"`, `"es"`, `"ja"`) — a key into a {@link Catalog}.
|
|
31
|
+
- `Messages` (type): type Messages = Readonly<Record<string, string>> — Flat message table for one locale: key → template string with `{param}` slots.
|
|
32
|
+
- `TParams` (type): type TParams = Readonly<Record<string, string | number>> — Interpolation values for a message template.
|
|
33
|
+
- `createI18n` (function): function createI18n(options: I18nOptions): I18n — Create a translator over a message catalog: active-locale lookup with a fallback-locale chain, `{param}` interpolation, and `Intl.PluralRules`-based pluralization. Observable (`subscribe`) so React re-renders on `setLocale`; the catalog is caller-owned static data, the locale is the only state.
|
|
34
|
+
- `interpolate` (function): function interpolate(template: string, params?: TParams): string — Replace `{name}` placeholders in `template` with `params[name]`. Unknown placeholders are left intact. Pure and locale-independent.
|
|
35
|
+
|
|
25
36
|
## @jgengine/core/render/lookPreset
|
|
26
37
|
|
|
27
38
|
- `CINEMATIC_POST_PROCESSING` (const): const CINEMATIC_POST_PROCESSING: PostProcessingConfig — Tuned tone-map + bloom + gentle SSAO + vignette/grade stack — the shipped-game post look.
|
|
@@ -37,7 +48,8 @@
|
|
|
37
48
|
- `BloomConfig` (interface): interface BloomConfig — UnrealBloom stage — soft HDR glow around bright pixels (sun, glints, emissive).
|
|
38
49
|
- `DofConfig` (interface): interface DofConfig — Depth-of-field (bokeh) stage — throws the fore/background out of focus around a focus distance.
|
|
39
50
|
- `GradeConfig` (interface): interface GradeConfig — Final colour-grade stage: lift/gain/gamma, saturation, vignette, film grain — applied in display space after tone mapping.
|
|
40
|
-
- `
|
|
51
|
+
- `PostAaMode` (type): type PostAaMode = "smaa" | "msaa" | false — Edge antialiasing for the post chain. SMAA runs in linear-sRGB before the output tone-map and cleans alpha-tested foliage/particles that MSAA samples alone leave crawling. `"msaa"` keeps only the render-target multisample resolve; `false` disables AA stages.
|
|
52
|
+
- `PostProcessingConfig` (interface): interface PostProcessingConfig — Declarative post-processing chain (RenderPass → AO → Bloom → SMAA → tone-map output → Grade). Present on a game means the shell mounts an `EffectComposer` and owns the render; absent means the renderer draws directly (unchanged). Each stage is a config object, `false` to skip, or omitted for its default. Pure data — no three.js types leak into core.
|
|
41
53
|
- `STUDIO_STAGE_POST` (const): const STUDIO_STAGE_POST: PostProcessingConfig — A cinematic "product shot" post preset — the full chain on (contact-AO, soft bloom, a warm film grade with vignette + a touch of grain + chromatic aberration). Meant for a `StudioStage` where a single parametric asset is framed on a backdrop, so every studio reads shipped, not intern-tier. DoF is left off by default (it needs a per-scene focus distance); set `dof` to enable it.
|
|
42
54
|
- `ToneMappingMode` (type): type ToneMappingMode = "aces" | "agx" | "reinhard" | "cineon" | "linear" | "none" — Renderer tone-mapping curve applied by the post chain's output stage.
|
|
43
55
|
|
|
@@ -55,7 +67,7 @@
|
|
|
55
67
|
- `GameSettingsConfig` (interface): interface GameSettingsConfig — ⚠ undocumented
|
|
56
68
|
- `GraphicsQuality` (type): type GraphicsQuality = "low" | "medium" | "high" — ⚠ undocumented
|
|
57
69
|
- `SETTINGS_STORAGE_PREFIX` (const): const SETTINGS_STORAGE_PREFIX: "jgengine:setting:" — ⚠ undocumented
|
|
58
|
-
- `SETTING_IDS` (const): const SETTING_IDS: { readonly masterVolume: "sound.master"; readonly graphicsQuality: "graphics.quality"; readonly graphicsShadows: "graphics.shadows"; readonly graphicsUiScale: "graphics.uiScale"; readonly touchStyle: "controls.touchStyle"; } — ⚠ undocumented
|
|
70
|
+
- `SETTING_IDS` (const): const SETTING_IDS: { readonly masterVolume: "sound.master"; readonly graphicsQuality: "graphics.quality"; readonly graphicsShadows: "graphics.shadows"; readonly graphicsUiScale: "graphics.uiScale"; readonly touchStyle: "controls.touchStyle"; readonly touchJoystick: "controls.touchJoystick"; } — ⚠ undocumented
|
|
59
71
|
- `SettingCategory` (type): type SettingCategory = BuiltInSettingCategory | (string & {}) — Built-in category ids keep autocomplete; any other string makes a fresh category.
|
|
60
72
|
- `SettingCategoryDef` (interface): interface SettingCategoryDef — Declares or relabels/reorders a category tab; use it for a custom category or to reshape the built-ins.
|
|
61
73
|
- `SettingKind` (type): type SettingKind = "slider" | "toggle" | "select" — ⚠ undocumented
|
|
@@ -75,14 +87,27 @@
|
|
|
75
87
|
|
|
76
88
|
## @jgengine/core/ui
|
|
77
89
|
|
|
90
|
+
- `AccessibilityState` (interface): interface AccessibilityState — Serializable accessibility preferences a game reads to adapt its presentation.
|
|
91
|
+
- `AccessibilityStore` (interface): interface AccessibilityStore — Observable, serializable accessibility-preferences store.
|
|
78
92
|
- `ActionCooldown` (interface): interface ActionCooldown — Cooldown state for an action, expressed so a radial sweep or countdown can render directly.
|
|
79
93
|
- `ActionCost` (interface): interface ActionCost — Headless view model for a contextual action collection — the data layer behind an RTS command card, an ability action bar, a build menu, or a radial. It carries *what the buttons mean* (label, hotkey, cost, cooldown, disabled reasons, toggle state) with zero rendering opinion, so a game keeps layout, dimensions, hotkeys, catalog-id mapping, renderer, and chrome caller-owned. The React renderers in `@jgengine/react/actionHud` consume this; a game can swap either without forking the logic here.
|
|
80
94
|
- `ActionDef` (interface): interface ActionDef — A caller-authored contextual action — the DATA input to the model. Every field except `id` is optional so a build button, a stance toggle, and a cooldown ability all use the same shape. Catalog-id mapping (turning `icon`/`label` into art and copy) stays caller-owned.
|
|
81
95
|
- `ActionReason` (interface): interface ActionReason — A single blocking reason: a stable machine `code` plus caller-facing `message`.
|
|
82
96
|
- `BUILT_IN_SETTING_CATEGORIES` (const): const BUILT_IN_SETTING_CATEGORIES: readonly BuiltInSettingCategory[] — ⚠ undocumented
|
|
97
|
+
- `COLORBLIND_MATRICES` (const): const COLORBLIND_MATRICES: Record<ColorblindMode, string | null> — `feColorMatrix` `values` strings for each colorblind mode — simulate how a viewer with that condition perceives color (and a grayscale mode). `"none"` maps to `null` (no filter). Consumed by the React `ColorblindFilters` defs.
|
|
98
|
+
- `Catalog` (type): type Catalog = Readonly<Record<Locale, Messages>> — All locales' message tables, keyed by locale.
|
|
99
|
+
- `CoachMarkPlacement` (type): type CoachMarkPlacement = "top" | "bottom" | "left" | "right" | "center" — Where a coach-mark callout sits relative to its anchor (or `"center"` for an unanchored callout).
|
|
100
|
+
- `CoachMarkSequence` (interface): interface CoachMarkSequence — An ordered, observable, serializable onboarding coach-mark run.
|
|
101
|
+
- `CoachMarkSequenceOptions` (interface): interface CoachMarkSequenceOptions — Options for {@link createCoachMarkSequence}.
|
|
102
|
+
- `CoachMarkSnapshot` (interface): interface CoachMarkSnapshot — Serializable persisted state — the seen set (with timestamps) and satisfied triggers.
|
|
103
|
+
- `CoachMarkStep` (interface): interface CoachMarkStep — One onboarding hint: an ordered, optionally-anchored, optionally-gated callout.
|
|
104
|
+
- `CoachMarkView` (interface): interface CoachMarkView — The active step plus its position, returned by {@link CoachMarkSequence.current}.
|
|
105
|
+
- `ColorblindMode` (type): type ColorblindMode = "none" | "protanopia" | "deuteranopia" | "tritanopia" | "grayscale" — Colorblind simulation/daltonization modes the engine ships matrices for.
|
|
106
|
+
- `DEFAULT_ACCESSIBILITY` (const): const DEFAULT_ACCESSIBILITY: AccessibilityState — The out-of-the-box accessibility state (all assistance off, `textScale` 1).
|
|
83
107
|
- `DEFAULT_GRAPHICS_QUALITY` (const): const DEFAULT_GRAPHICS_QUALITY: GraphicsQuality — ⚠ undocumented
|
|
84
108
|
- `DEFAULT_GRAPHICS_SHADOWS` (const): const DEFAULT_GRAPHICS_SHADOWS: true — ⚠ undocumented
|
|
85
109
|
- `DEFAULT_MASTER_VOLUME` (const): const DEFAULT_MASTER_VOLUME: 1 — ⚠ undocumented
|
|
110
|
+
- `DEFAULT_PHOTO_MODE` (const): const DEFAULT_PHOTO_MODE: PhotoModeState — The out-of-the-box photo-mode state: not active, HUD hidden when it engages.
|
|
86
111
|
- `DEFAULT_UI_SCALE` (const): const DEFAULT_UI_SCALE: 1 — Player-controlled multiplier on the HUD's computed fit scale — one lever on desktop and mobile alike.
|
|
87
112
|
- `EditorUiDocument` (interface): interface EditorUiDocument — Scene-document HUD section: panel id → layout. Single source of truth for placement.
|
|
88
113
|
- `EditorUiPanelLayout` (interface): interface EditorUiPanelLayout — Authored layout for one HUD panel inside `editor.scene.json` → `ui.panels`.
|
|
@@ -107,24 +132,52 @@
|
|
|
107
132
|
- `HudResizeAxes` (type): type HudResizeAxes = "none" | "x" | "y" | "both" — Which axes a panel type may grow when resized in canvas mode. Resize is semantic — content reflows (longer track, more rows) — never a CSS scale of the whole panel.
|
|
108
133
|
- `HudSize` (interface): interface HudSize — ⚠ undocumented
|
|
109
134
|
- `HudViewportConfig` (interface): interface HudViewportConfig extends HudFitConfig — Per-game HUD viewport declaration carried on `PlayableGame.hudFit`; `mobile` overrides the fit on compact displays so the owner can tune the phone layout separately.
|
|
135
|
+
- `I18n` (interface): interface I18n — Runtime translator over a message {@link Catalog} — active locale, lookup with fallback, interpolation, and pluralization.
|
|
136
|
+
- `I18nOptions` (interface): interface I18nOptions — Configuration for {@link createI18n}.
|
|
110
137
|
- `Insets` (interface): interface Insets — Edge insets in CSS pixels (safe areas, reservations).
|
|
111
138
|
- `LayoutCollision` (interface): interface LayoutCollision — One detected forbidden/warned overlap between two regions.
|
|
112
139
|
- `LayoutCollisionPolicy` (type): type LayoutCollisionPolicy = "forbid" | "allow" | "warn" — How a region participates in collision reporting.
|
|
113
140
|
- `LayoutOrientation` (type): type LayoutOrientation = "portrait" | "landscape" — A concrete device orientation.
|
|
114
141
|
- `LayoutRect` (interface): interface LayoutRect — Axis-aligned rectangle in CSS pixels (origin top-left). Structurally compatible with a `DOMRect`'s edge fields.
|
|
115
142
|
- `LayoutRegion` (interface): interface LayoutRegion — A physical rectangle a UI subsystem occupies, published to the shared registry.
|
|
143
|
+
- `Locale` (type): type Locale = string — A locale tag (e.g. `"en"`, `"es"`, `"ja"`) — a key into a {@link Catalog}.
|
|
116
144
|
- `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.
|
|
145
|
+
- `MODAL_CANCEL` (const): const MODAL_CANCEL: "cancel" — Conventional cancel/dismiss result (also the default auto-dismiss and pop result).
|
|
146
|
+
- `MODAL_CONFIRM` (const): const MODAL_CONFIRM: "confirm" — Conventional confirm result for a two-button dialog — a shared string, not model behavior.
|
|
147
|
+
- `Messages` (type): type Messages = Readonly<Record<string, string>> — Flat message table for one locale: key → template string with `{param}` slots.
|
|
117
148
|
- `MobileHudBehavior` (type): type MobileHudBehavior = | "persistent" | "compact" | "icon" | "transient" | "hidden" | "sheet" | "modal" — How a HUD element adapts on phones.
|
|
149
|
+
- `ModalInput` (type): type ModalInput = Omit<ModalRecord, "id"> & { id?: string } — A modal to push — {@link ModalRecord} with an optional id (auto-assigned when absent).
|
|
150
|
+
- `ModalRecord` (interface): interface ModalRecord — Headless, serializable model for a stack of modal dialogs — the data layer behind a pause menu, a "quit to menu?" confirmation, a level-up popup, or any blocking overlay a game raises over its scene. It carries an ordered stack of opaque {@link ModalRecord}s (push to open, pop/resolve to close) and nothing about how they look: the model NEVER interprets a record's `kind` or a resolution's `result` string — those are free-form game vocabulary the React chrome in `@jgengine/react` renders. Observable ({@link ModalStack.subscribe}) and round-trips through a save ({@link ModalStack.snapshot}/{@link ModalStack.restore}). An injected clock powers optional per-modal auto-dismiss timers; leave those unset and the model is pure and clockless.
|
|
151
|
+
- `ModalResolution` (interface): interface ModalResolution — The outcome of closing a modal via {@link ModalStack.resolve} (or an auto-dismiss) — the closed record's identity plus the free-form `result` string the caller chose. Delivered to the `onResolve` option and stashed as {@link ModalStack.lastResolution}.
|
|
152
|
+
- `ModalStack` (interface): interface ModalStack — An observable, serializable stack of modal dialogs. See {@link createModalStack}.
|
|
153
|
+
- `ModalStackEntry` (interface): interface ModalStackEntry — A serialized stack entry: the opaque record plus the clock time it opened (for timer restore).
|
|
154
|
+
- `ModalStackOptions` (interface): interface ModalStackOptions — Options for {@link createModalStack}.
|
|
155
|
+
- `ModalStackSnapshot` (interface): interface ModalStackSnapshot — Serializable state — the ordered entries (bottom-first) and the id counter. Plain JSON.
|
|
156
|
+
- `ObjectiveBannerAnnouncement` (interface): interface ObjectiveBannerAnnouncement — One announcement request handed to {@link ObjectiveBannerController.announce}.
|
|
157
|
+
- `ObjectiveBannerController` (interface): interface ObjectiveBannerController — A live, clock-driven objective/stage banner controller.
|
|
158
|
+
- `ObjectiveBannerOptions` (interface): interface ObjectiveBannerOptions — Options for {@link createObjectiveBanner}.
|
|
159
|
+
- `ObjectiveBannerPhase` (type): type ObjectiveBannerPhase = "in" | "hold" | "out" — Which part of its life a banner is in: flying `"in"`, holding centered, or fading `"out"`. Progress `0..1` (see {@link ObjectiveBannerView.progress}) runs within whichever phase is active — the renderer maps phase + progress to opacity/scale/translate however it likes.
|
|
160
|
+
- `ObjectiveBannerSnapshot` (interface): interface ObjectiveBannerSnapshot — Serializable state of the queue and the active banner, for save/restore.
|
|
161
|
+
- `ObjectiveBannerView` (interface): interface ObjectiveBannerView — The banner to draw right now: its content, the game-owned `kind`, the current {@link ObjectiveBannerPhase}, and `progress` `0..1` through that phase. This object is pooled and overwritten on the next {@link ObjectiveBannerController.current} call — read it, don't retain it.
|
|
118
162
|
- `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
163
|
- `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
164
|
- `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.
|
|
165
|
+
- `PhotoModeState` (interface): interface PhotoModeState — Serializable photo-mode preferences a game reads to compose its capture UI.
|
|
166
|
+
- `PhotoModeStore` (interface): interface PhotoModeStore — Observable photo-mode store — genre-agnostic state a game binds its capture flow to.
|
|
121
167
|
- `PopoverOptions` (interface): interface PopoverOptions — Options for {@link placePopover}.
|
|
122
168
|
- `PopoverPlacement` (interface): interface PopoverPlacement — The resolved popover position — the side it actually opened on and its clamped top-left.
|
|
123
169
|
- `PopoverSide` (type): type PopoverSide = "top" | "bottom" | "left" | "right" — Which side of its anchor a popover opens toward.
|
|
124
|
-
- `PostProcessingConfig` (interface): interface PostProcessingConfig — Declarative post-processing chain (RenderPass → AO → Bloom → tone-map output → Grade). Present on a game means the shell mounts an `EffectComposer` and owns the render; absent means the renderer draws directly (unchanged). Each stage is a config object, `false` to skip, or omitted for its default. Pure data — no three.js types leak into core.
|
|
170
|
+
- `PostProcessingConfig` (interface): interface PostProcessingConfig — Declarative post-processing chain (RenderPass → AO → Bloom → SMAA → tone-map output → Grade). Present on a game means the shell mounts an `EffectComposer` and owns the render; absent means the renderer draws directly (unchanged). Each stage is a config object, `false` to skip, or omitted for its default. Pure data — no three.js types leak into core.
|
|
171
|
+
- `RadialArc` (interface): interface RadialArc — Arc the slices span. Omit for a full wheel (index 0 at the top). A partial `sweep` (e.g. `Math.PI` for a bottom half, `Math.PI / 2` for a quarter) packs the slices evenly inside `[startAngle, startAngle + sweep]` — the arc/quick-bar forms. Angles are radians from "up" (−Y), clockwise.
|
|
172
|
+
- `RadialSlice` (interface): interface RadialSlice — One wedge of a radial menu — geometry for rendering a slice. Angles are radians from "up" (−Y), clockwise.
|
|
173
|
+
- `RadialVectorOptions` (interface): interface RadialVectorOptions extends RadialArc — Options for {@link radialIndexFromVector}.
|
|
125
174
|
- `ResolvedAction` (interface): interface ResolvedAction — A resolved action view model — availability computed once from cooldown, cost, `disabled`, and any caller reasons. `enabled` is the single truth a renderer gates interaction on; `reasons` is the ordered explanation (cooldown, then unmet costs, then caller reasons, then a generic disable).
|
|
126
|
-
- `SETTING_IDS` (const): const SETTING_IDS: { readonly masterVolume: "sound.master"; readonly graphicsQuality: "graphics.quality"; readonly graphicsShadows: "graphics.shadows"; readonly graphicsUiScale: "graphics.uiScale"; readonly touchStyle: "controls.touchStyle"; } — ⚠ undocumented
|
|
175
|
+
- `SETTING_IDS` (const): const SETTING_IDS: { readonly masterVolume: "sound.master"; readonly graphicsQuality: "graphics.quality"; readonly graphicsShadows: "graphics.shadows"; readonly graphicsUiScale: "graphics.uiScale"; readonly touchStyle: "controls.touchStyle"; readonly touchJoystick: "controls.touchJoystick"; } — ⚠ undocumented
|
|
127
176
|
- `STUDIO_STAGE_POST` (const): const STUDIO_STAGE_POST: PostProcessingConfig — A cinematic "product shot" post preset — the full chain on (contact-AO, soft bloom, a warm film grade with vignette + a touch of grain + chromatic aberration). Meant for a `StudioStage` where a single parametric asset is framed on a backdrop, so every studio reads shipped, not intern-tier. DoF is left off by default (it needs a per-scene focus distance); set `dof` to enable it.
|
|
177
|
+
- `ScreenMarkerLayout` (interface): interface ScreenMarkerLayout — Where and how to draw one marker, from {@link layoutScreenMarker}.
|
|
178
|
+
- `ScreenMarkerOptions` (interface): interface ScreenMarkerOptions — Options for {@link layoutScreenMarker}.
|
|
179
|
+
- `ScreenMarkerViewport` (interface): interface ScreenMarkerViewport — The `{ width, height }` of the viewport the marker is laid out within (CSS px).
|
|
180
|
+
- `ScreenProjection` (interface): interface ScreenProjection — A world position projected to screen space by the caller's camera. This is the minimal shape {@link layoutScreenMarker} consumes — deliberately a structural subset of `@jgengine/react`'s `EntityScreenProjection` (and what its `ProjectEntity`/`useWorldProjection` produce), mirrored here because `core` imports nothing higher. Feed it straight from a world→screen projector.
|
|
128
181
|
- `SelectionFocusDirection` (type): type SelectionFocusDirection = "next" | "prev" | "first" | "last" — A 1-D focus move within the selection member strip.
|
|
129
182
|
- `SelectionGroup` (interface): interface SelectionGroup — A bucket of same-`kind` entities in a large selection — the RTS "12 Marines" control chip.
|
|
130
183
|
- `SelectionView` (interface): interface SelectionView — A resolved multi-selection view model. `primary` is the focused entity's full detail; `members` is the stable-order strip; `groups` buckets members by kind (count-desc, then label) for the portrait-overflow case; `grouped` is the hint that the selection is large enough to prefer groups over per-member portraits.
|
|
@@ -138,24 +191,39 @@
|
|
|
138
191
|
- `SettingsStore` (interface): interface SettingsStore — ⚠ undocumented
|
|
139
192
|
- `SettingsSurface` (type): type SettingsSurface = "quick" — `quick` shows compact on-screen volume/graphics buttons; `false` (default) mounts no engine trigger — open the menu from your own UI with `<SettingsTrigger>` or `useSettings().open()`.
|
|
140
193
|
- `SettingsVariant` (type): type SettingsVariant = "panel" | "sheet" | "sidebar" | "fullscreen" — The four themed settings layouts, chosen with `defineGame({ settings: { variant } })`. All read the game's `--jg-*` theme tokens.
|
|
194
|
+
- `StoredObjectiveBanner` (interface): interface StoredObjectiveBanner — A persisted banner record — all announcement fields resolved, plus id and schedule.
|
|
141
195
|
- `SummarizeSelectionOptions` (interface): interface SummarizeSelectionOptions — Options for {@link summarizeSelection}.
|
|
142
196
|
- `SwingTargetInput` (interface): interface SwingTargetInput — The current target, or the fields the bar needs from it.
|
|
197
|
+
- `TEXT_SCALE_MAX` (const): const TEXT_SCALE_MAX: 2 — Maximum UI text scale.
|
|
198
|
+
- `TEXT_SCALE_MIN` (const): const TEXT_SCALE_MIN: 0.75 — Minimum UI text scale.
|
|
199
|
+
- `TParams` (type): type TParams = Readonly<Record<string, string | number>> — Interpolation values for a message template.
|
|
143
200
|
- `ToneMappingMode` (type): type ToneMappingMode = "aces" | "agx" | "reinhard" | "cineon" | "linear" | "none" — Renderer tone-mapping curve applied by the post chain's output stage.
|
|
144
201
|
- `TooltipContent` (interface): interface TooltipContent — Structured tooltip content — a renderer lays these fields out; the model owns what is shown.
|
|
145
202
|
- `UI_SCALE_MAX` (const): const UI_SCALE_MAX: 1.5 — ⚠ undocumented
|
|
146
203
|
- `UI_SCALE_MIN` (const): const UI_SCALE_MIN: 0.5 — ⚠ undocumented
|
|
147
204
|
- `UiRect` (interface): interface UiRect — A positioned rectangle (viewport/anchor space, top-left origin, pixels).
|
|
148
205
|
- `UiSize` (interface): interface UiSize — A width/height pair (pixels).
|
|
206
|
+
- `Waypoint` (interface): interface Waypoint — A tracked objective/waypoint the game wants a screen marker for.
|
|
207
|
+
- `WaypointSnapshot` (interface): interface WaypointSnapshot — Serializable state of a {@link WaypointTracker}, for save/restore.
|
|
208
|
+
- `WaypointTracker` (interface): interface WaypointTracker — An observable, serializable set of world waypoints keyed by id.
|
|
149
209
|
- `actionByHotkey` (function): function actionByHotkey(actions: readonly ResolvedAction[], key: string): string | null — Find the action whose `hotkey` matches `key`, case-insensitively — the keyboard-shortcut router for an action bar. Returns the first match's id, or null. Matching by hotkey does not consider `enabled`; the caller decides whether to fire a disabled action's feedback.
|
|
150
210
|
- `actionCooldown` (function): function actionCooldown(remainingMs: number, totalMs: number): ActionCooldown — Build an {@link ActionCooldown} from remaining/total milliseconds. `ready` when nothing remains.
|
|
151
211
|
- `actionCooldownFromFraction` (function): function actionCooldownFromFraction(remainingMs: number, fraction: number): ActionCooldown — Build an {@link ActionCooldown} from remaining milliseconds and a known remaining fraction — the shape adapters get from sources (like an ability snapshot) that report a fraction but not a total.
|
|
152
212
|
- `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`.
|
|
153
213
|
- `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.
|
|
154
214
|
- `busVolumeSettingId` (function): function busVolumeSettingId(busId: string): string — ⚠ undocumented
|
|
215
|
+
- `clampTextScale` (function): function clampTextScale(scale: number): number — Clamp a text-scale multiplier into the supported `[TEXT_SCALE_MIN, TEXT_SCALE_MAX]` range.
|
|
155
216
|
- `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
217
|
- `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.
|
|
218
|
+
- `createAccessibilityStore` (function): function createAccessibilityStore(initial: Partial<AccessibilityState> = {}): AccessibilityStore — Serializable, observable store of accessibility preferences (reduced motion, high contrast, text scale, colorblind mode, captions). Genre-agnostic plumbing like input rebinding — a game binds these to its settings UI and adapts its presentation; `snapshot`/`restore` round-trip through a save or settings blob.
|
|
219
|
+
- `createCoachMarkSequence` (function): function createCoachMarkSequence(options: CoachMarkSequenceOptions): CoachMarkSequence — An onboarding coach-mark run: an ordered sequence of hint steps, each shown as a centered callout or anchored to a UI element, with a persisted "seen" set so completed onboarding stays done across sessions, and data-first condition gating so a step waits until its trigger id is satisfied. Advance/skip/dismiss drive it; `snapshot`/`restore` round-trip the seen set through a save. Purely a model — a React host renders `current()`.
|
|
220
|
+
- `createI18n` (function): function createI18n(options: I18nOptions): I18n — Create a translator over a message catalog: active-locale lookup with a fallback-locale chain, `{param}` interpolation, and `Intl.PluralRules`-based pluralization. Observable (`subscribe`) so React re-renders on `setLocale`; the catalog is caller-owned static data, the locale is the only state.
|
|
221
|
+
- `createModalStack` (function): function createModalStack(options: ModalStackOptions = {}): ModalStack — A stack of modal dialogs: push opaque records to open blocking overlays (a pause menu, a confirm prompt, a reward popup), pop or resolve them with a free-form result to close, and query the top / open / depth to gate game input. The model is deliberately vocabulary-free — it never reads a record's `kind` or a resolution's `result`, so a game owns every dialog style — and fully serializable, with an optional injected clock driving per-modal auto-dismiss. A React host renders `top()`; `subscribe` re-renders it, `snapshot`/`restore` round-trip it through a save.
|
|
222
|
+
- `createObjectiveBanner` (function): function createObjectiveBanner(options: ObjectiveBannerOptions = {}): ObjectiveBannerController — A serializable, clock-driven stage/objective banner controller: the classic transient centered title stamp ("WAVE 3", "VICTORY", "OBJECTIVE COMPLETE"). A game calls `announce({ title, subtitle?, kind? })` and the controller queues it, flies it in, holds it, and fades it out on an injected clock — one banner at a time — exposing the current banner plus its phase (in/hold/out) and `progress` `0..1` for a renderer to animate opacity/scale/translate. Nothing here is genre-specific: `kind` is a free label the game owns and styles, and all timings are parameters. Call `advance()` each frame; `current()` returns the pooled view to draw; `snapshot`/`restore` round-trips the queue through a save.
|
|
157
223
|
- `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.
|
|
224
|
+
- `createPhotoModeStore` (function): function createPhotoModeStore(initial: Partial<PhotoModeState> = {}): PhotoModeStore — Serializable, observable photo-mode state (active + hide-HUD). Genre-agnostic plumbing — a game engages it to free its camera and hide gameplay chrome for a clean capture, and reads `hideHud` to conditionally render its HUD. Pair with React `PhotoModeControls` and shell `captureCanvas`.
|
|
158
225
|
- `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.
|
|
226
|
+
- `createWaypointTracker` (function): function createWaypointTracker(): WaypointTracker — A serializable, observable tracker of world waypoints — the objective/point-of- interest half of offscreen markers. A game `set`s waypoints by id (each an `{ id, position, kind, label? }`, where `kind` is a free string the game styles and the model never branches on), and a React host projects each to screen space and lays it out with {@link layoutScreenMarker}: an on-screen pin, or an off-screen directional arrow clamped to the viewport edge with a distance the caller computes. Purely a model — no camera, projection, or renderer here. `snapshot`/`restore` round-trips the set through a save.
|
|
159
227
|
- `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.
|
|
160
228
|
- `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.
|
|
161
229
|
- `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"`.
|
|
@@ -163,7 +231,9 @@
|
|
|
163
231
|
- `formatOrdinal` (function): function formatOrdinal(value: number): string — English ordinal for a placement number: 1 → "1st", 2 → "2nd", 3 → "3rd", 11 → "11th".
|
|
164
232
|
- `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.
|
|
165
233
|
- `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.
|
|
234
|
+
- `interpolate` (function): function interpolate(template: string, params?: TParams): string — Replace `{name}` placeholders in `template` with `params[name]`. Unknown placeholders are left intact. Pure and locale-independent.
|
|
166
235
|
- `isOpen` (function): function isOpen(state: PanelState, id: string): boolean — Whether panel `id` is currently open.
|
|
236
|
+
- `layoutScreenMarker` (function): function layoutScreenMarker(projection: ScreenProjection, viewport: ScreenMarkerViewport, options: ScreenMarkerOptions = {}): ScreenMarkerLayout — Pure, allocation-aware screen-marker math: given a projected target point, the viewport, and a `margin`, decide whether the target is on-screen and where to draw its marker. An on-screen point passes straight through (`onScreen: true`). An off-screen — or behind-camera — point is CLAMPED to the viewport edge (inset by `margin`) with `angle` set to the bearing from screen center toward the target, so a caller can pin an arrow to the frame edge and rotate it to point the way. Behind-camera projections have mirrored coordinates, so the bearing is flipped to face the true direction. This is the edge-clamp/arrow half that `layoutEntityFrames` lacks (it culls off-screen entries instead). No allocation when an `out` object is supplied — reuse one across a whole frame's waypoints.
|
|
167
237
|
- `listHudPanelTypes` (function): function listHudPanelTypes(): HudPanelTypeDef[] — Every registered panel type, sorted by id — editor palette / agent listing.
|
|
168
238
|
- `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
239
|
- `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.
|
|
@@ -172,9 +242,14 @@
|
|
|
172
242
|
- `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.
|
|
173
243
|
- `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.
|
|
174
244
|
- `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.
|
|
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.
|
|
245
|
+
- `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. A rect is only reported when it is partly visible *and* crosses an edge; a fully off-screen (closed/hidden) surface is skipped, so parked drawers and unopened menus never raise a false alarm.
|
|
176
246
|
- `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.
|
|
177
247
|
- `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.
|
|
248
|
+
- `radialIndexFromAngle` (function): function radialIndexFromAngle(angle: number, count: number, arc?: RadialArc): number — Map an angle to a slice index; returns -1 when the angle falls outside a partial `arc`.
|
|
249
|
+
- `radialIndexFromVector` (function): function radialIndexFromVector(dx: number, dy: number, count: number, options: RadialVectorOptions = {}): number | null — Pick the slice a pointer/stick vector points at. `dx`/`dy` are screen-space (y down): up is `(0, -1)`. Returns null inside `deadZone` or (for a partial `arc`) outside the arc, so a centered stick or a click off the arc selects nothing.
|
|
250
|
+
- `radialSlicePosition` (function): function radialSlicePosition(index: number, count: number, radius: number, arc?: RadialArc): { x: number; y: number } — Unit-circle position of a slice center (up = `(0, -1)`), scaled by `radius` — where to place a wedge's icon/label.
|
|
251
|
+
- `radialSlices` (function): function radialSlices(count: number, arc?: RadialArc): RadialSlice[] — Divide a ring (or `arc`) into `count` wedges — the geometry a radial/quick menu (weapon wheel, emote arc, ping bar) renders. A full wheel centers index 0 at the top; a partial `arc` packs the slices inside its sweep.
|
|
252
|
+
- `reducedMotionDuration` (function): function reducedMotionDuration(state: AccessibilityState, ms: number, reduced = 0): number — Return `ms` when motion is allowed, or `reduced` (default 0) when `reducedMotion` is set — the animation-duration gate.
|
|
178
253
|
- `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.
|
|
179
254
|
- `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).
|
|
180
255
|
- `resolveAction` (function): function resolveAction(def: ActionDef): ResolvedAction — Resolve one {@link ActionDef} into a {@link ResolvedAction}: normalize label, compute `enabled`, and order the blocking `reasons`. Pure — the same input always yields the same view model.
|
|
@@ -188,6 +263,19 @@
|
|
|
188
263
|
- `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
264
|
- `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.
|
|
190
265
|
|
|
266
|
+
## @jgengine/core/ui/accessibility
|
|
267
|
+
|
|
268
|
+
- `AccessibilityState` (interface): interface AccessibilityState — Serializable accessibility preferences a game reads to adapt its presentation.
|
|
269
|
+
- `AccessibilityStore` (interface): interface AccessibilityStore — Observable, serializable accessibility-preferences store.
|
|
270
|
+
- `COLORBLIND_MATRICES` (const): const COLORBLIND_MATRICES: Record<ColorblindMode, string | null> — `feColorMatrix` `values` strings for each colorblind mode — simulate how a viewer with that condition perceives color (and a grayscale mode). `"none"` maps to `null` (no filter). Consumed by the React `ColorblindFilters` defs.
|
|
271
|
+
- `ColorblindMode` (type): type ColorblindMode = "none" | "protanopia" | "deuteranopia" | "tritanopia" | "grayscale" — Colorblind simulation/daltonization modes the engine ships matrices for.
|
|
272
|
+
- `DEFAULT_ACCESSIBILITY` (const): const DEFAULT_ACCESSIBILITY: AccessibilityState — The out-of-the-box accessibility state (all assistance off, `textScale` 1).
|
|
273
|
+
- `TEXT_SCALE_MAX` (const): const TEXT_SCALE_MAX: 2 — Maximum UI text scale.
|
|
274
|
+
- `TEXT_SCALE_MIN` (const): const TEXT_SCALE_MIN: 0.75 — Minimum UI text scale.
|
|
275
|
+
- `clampTextScale` (function): function clampTextScale(scale: number): number — Clamp a text-scale multiplier into the supported `[TEXT_SCALE_MIN, TEXT_SCALE_MAX]` range.
|
|
276
|
+
- `createAccessibilityStore` (function): function createAccessibilityStore(initial: Partial<AccessibilityState> = {}): AccessibilityStore — Serializable, observable store of accessibility preferences (reduced motion, high contrast, text scale, colorblind mode, captions). Genre-agnostic plumbing like input rebinding — a game binds these to its settings UI and adapts its presentation; `snapshot`/`restore` round-trip through a save or settings blob.
|
|
277
|
+
- `reducedMotionDuration` (function): function reducedMotionDuration(state: AccessibilityState, ms: number, reduced = 0): number — Return `ms` when motion is allowed, or `reduced` (default 0) when `reducedMotion` is set — the animation-duration gate.
|
|
278
|
+
|
|
191
279
|
## @jgengine/core/ui/actionModel
|
|
192
280
|
|
|
193
281
|
- `ActionCooldown` (interface): interface ActionCooldown — Cooldown state for an action, expressed so a radial sweep or countdown can render directly.
|
|
@@ -205,6 +293,26 @@
|
|
|
205
293
|
- `resolveAction` (function): function resolveAction(def: ActionDef): ResolvedAction — Resolve one {@link ActionDef} into a {@link ResolvedAction}: normalize label, compute `enabled`, and order the blocking `reasons`. Pure — the same input always yields the same view model.
|
|
206
294
|
- `resolveActionCollection` (function): function resolveActionCollection(defs: readonly ActionDef[]): ResolvedAction[] — Resolve an ordered list of actions, preserving input order.
|
|
207
295
|
|
|
296
|
+
## @jgengine/core/ui/coachMarks
|
|
297
|
+
|
|
298
|
+
- `CoachMarkPlacement` (type): type CoachMarkPlacement = "top" | "bottom" | "left" | "right" | "center" — Where a coach-mark callout sits relative to its anchor (or `"center"` for an unanchored callout).
|
|
299
|
+
- `CoachMarkSequence` (interface): interface CoachMarkSequence — An ordered, observable, serializable onboarding coach-mark run.
|
|
300
|
+
- `CoachMarkSequenceOptions` (interface): interface CoachMarkSequenceOptions — Options for {@link createCoachMarkSequence}.
|
|
301
|
+
- `CoachMarkSnapshot` (interface): interface CoachMarkSnapshot — Serializable persisted state — the seen set (with timestamps) and satisfied triggers.
|
|
302
|
+
- `CoachMarkStep` (interface): interface CoachMarkStep — One onboarding hint: an ordered, optionally-anchored, optionally-gated callout.
|
|
303
|
+
- `CoachMarkView` (interface): interface CoachMarkView — The active step plus its position, returned by {@link CoachMarkSequence.current}.
|
|
304
|
+
- `createCoachMarkSequence` (function): function createCoachMarkSequence(options: CoachMarkSequenceOptions): CoachMarkSequence — An onboarding coach-mark run: an ordered sequence of hint steps, each shown as a centered callout or anchored to a UI element, with a persisted "seen" set so completed onboarding stays done across sessions, and data-first condition gating so a step waits until its trigger id is satisfied. Advance/skip/dismiss drive it; `snapshot`/`restore` round-trip the seen set through a save. Purely a model — a React host renders `current()`.
|
|
305
|
+
|
|
306
|
+
## @jgengine/core/ui/floatingText
|
|
307
|
+
|
|
308
|
+
- `FloatingTextDef` (interface): interface FloatingTextDef — One text pop to spawn: what to say, where in the world, and how it moves and fades. Everything but `position` and `text` is optional and falls back to the field's defaults. `kind` is a free-form tag (`"damage"`, `"heal"`, `"crit"`, `"xp"`, `"gold"`, `"bark"`, …) the presentation layer styles — the model never interprets it, so nothing here is combat- or genre-specific.
|
|
309
|
+
- `FloatingTextField` (interface): interface FloatingTextField — A live, dt-driven field of world-anchored floating text.
|
|
310
|
+
- `FloatingTextFieldConfig` (interface): interface FloatingTextFieldConfig — Construction options for {@link createFloatingTextField}.
|
|
311
|
+
- `FloatingTextPosition` (type): type FloatingTextPosition = readonly [number, number, number] — A world-space anchor `[x, y, z]` a floating-text entry rises from.
|
|
312
|
+
- `FloatingTextSnapshot` (interface): interface FloatingTextSnapshot — Serializable state for save/restore and deterministic replay.
|
|
313
|
+
- `FloatingTextView` (interface): interface FloatingTextView — A live entry resolved for rendering: current world position and fade/scale over life.
|
|
314
|
+
- `createFloatingTextField` (function): function createFloatingTextField(config: FloatingTextFieldConfig = {}): FloatingTextField — A generic, allocation-aware field of world-anchored floating text: damage numbers, heals, crits, XP/gold gains, status pops, dialogue barks — anything a game wants to say at a point in the world for a moment. It is dt-driven (call `update(dt)` each frame) and deterministic: the only randomness is the horizontal drift jitter, which flows from the injected `seed`, so the same seed and the same emit/update sequence reproduce identical motion, and `snapshot`/`restore` round-trips the live pool. The model owns only the spawn → rise/drift → fade → reap lifecycle: `kind` is a free string and `color` a passthrough hint, so nothing here couples to combat or any genre. Presentation (projecting each entry to the screen and styling it per `kind`) lives in `@jgengine/react`'s `FloatingText`.
|
|
315
|
+
|
|
208
316
|
## @jgengine/core/ui/gameLayout
|
|
209
317
|
|
|
210
318
|
- `DetectCollisionsOptions` (interface): interface DetectCollisionsOptions — Options for `detectLayoutCollisions`.
|
|
@@ -256,10 +364,34 @@
|
|
|
256
364
|
- `HudPlatform` (type): type HudPlatform = "web" | "mobile" — Where a game is meant to be played. `"web"` alone keeps today's desktop-first HUD; adding `"mobile"` turns on design-resolution fit scaling on compact displays.
|
|
257
365
|
- `HudViewportConfig` (interface): interface HudViewportConfig extends HudFitConfig — Per-game HUD viewport declaration carried on `PlayableGame.hudFit`; `mobile` overrides the fit on compact displays so the owner can tune the phone layout separately.
|
|
258
366
|
- `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.
|
|
259
|
-
- `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.
|
|
367
|
+
- `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. A rect is only reported when it is partly visible *and* crosses an edge; a fully off-screen (closed/hidden) surface is skipped, so parked drawers and unopened menus never raise a false alarm.
|
|
260
368
|
- `rectOverflow` (function): function rectOverflow(rect: HudRect, viewport: HudSize, tolerance = 1.5): Omit<HudOverflow, "id"> | null — Non-null when any edge of `rect` falls outside `viewport` by more than `tolerance` px; each field is the overflow distance past that edge (0 when inside).
|
|
261
369
|
- `resolveHudFit` (function): function resolveHudFit(config: HudViewportConfig | undefined, mobile: boolean): Required<HudFitConfig> — ⚠ undocumented
|
|
262
370
|
|
|
371
|
+
## @jgengine/core/ui/modalStack
|
|
372
|
+
|
|
373
|
+
- `MODAL_CANCEL` (const): const MODAL_CANCEL: "cancel" — Conventional cancel/dismiss result (also the default auto-dismiss and pop result).
|
|
374
|
+
- `MODAL_CONFIRM` (const): const MODAL_CONFIRM: "confirm" — Conventional confirm result for a two-button dialog — a shared string, not model behavior.
|
|
375
|
+
- `ModalInput` (type): type ModalInput = Omit<ModalRecord, "id"> & { id?: string } — A modal to push — {@link ModalRecord} with an optional id (auto-assigned when absent).
|
|
376
|
+
- `ModalRecord` (interface): interface ModalRecord — Headless, serializable model for a stack of modal dialogs — the data layer behind a pause menu, a "quit to menu?" confirmation, a level-up popup, or any blocking overlay a game raises over its scene. It carries an ordered stack of opaque {@link ModalRecord}s (push to open, pop/resolve to close) and nothing about how they look: the model NEVER interprets a record's `kind` or a resolution's `result` string — those are free-form game vocabulary the React chrome in `@jgengine/react` renders. Observable ({@link ModalStack.subscribe}) and round-trips through a save ({@link ModalStack.snapshot}/{@link ModalStack.restore}). An injected clock powers optional per-modal auto-dismiss timers; leave those unset and the model is pure and clockless.
|
|
377
|
+
- `ModalResolution` (interface): interface ModalResolution — The outcome of closing a modal via {@link ModalStack.resolve} (or an auto-dismiss) — the closed record's identity plus the free-form `result` string the caller chose. Delivered to the `onResolve` option and stashed as {@link ModalStack.lastResolution}.
|
|
378
|
+
- `ModalStack` (interface): interface ModalStack — An observable, serializable stack of modal dialogs. See {@link createModalStack}.
|
|
379
|
+
- `ModalStackEntry` (interface): interface ModalStackEntry — A serialized stack entry: the opaque record plus the clock time it opened (for timer restore).
|
|
380
|
+
- `ModalStackOptions` (interface): interface ModalStackOptions — Options for {@link createModalStack}.
|
|
381
|
+
- `ModalStackSnapshot` (interface): interface ModalStackSnapshot — Serializable state — the ordered entries (bottom-first) and the id counter. Plain JSON.
|
|
382
|
+
- `createModalStack` (function): function createModalStack(options: ModalStackOptions = {}): ModalStack — A stack of modal dialogs: push opaque records to open blocking overlays (a pause menu, a confirm prompt, a reward popup), pop or resolve them with a free-form result to close, and query the top / open / depth to gate game input. The model is deliberately vocabulary-free — it never reads a record's `kind` or a resolution's `result`, so a game owns every dialog style — and fully serializable, with an optional injected clock driving per-modal auto-dismiss. A React host renders `top()`; `subscribe` re-renders it, `snapshot`/`restore` round-trip it through a save.
|
|
383
|
+
|
|
384
|
+
## @jgengine/core/ui/objectiveBanner
|
|
385
|
+
|
|
386
|
+
- `ObjectiveBannerAnnouncement` (interface): interface ObjectiveBannerAnnouncement — One announcement request handed to {@link ObjectiveBannerController.announce}.
|
|
387
|
+
- `ObjectiveBannerController` (interface): interface ObjectiveBannerController — A live, clock-driven objective/stage banner controller.
|
|
388
|
+
- `ObjectiveBannerOptions` (interface): interface ObjectiveBannerOptions — Options for {@link createObjectiveBanner}.
|
|
389
|
+
- `ObjectiveBannerPhase` (type): type ObjectiveBannerPhase = "in" | "hold" | "out" — Which part of its life a banner is in: flying `"in"`, holding centered, or fading `"out"`. Progress `0..1` (see {@link ObjectiveBannerView.progress}) runs within whichever phase is active — the renderer maps phase + progress to opacity/scale/translate however it likes.
|
|
390
|
+
- `ObjectiveBannerSnapshot` (interface): interface ObjectiveBannerSnapshot — Serializable state of the queue and the active banner, for save/restore.
|
|
391
|
+
- `ObjectiveBannerView` (interface): interface ObjectiveBannerView — The banner to draw right now: its content, the game-owned `kind`, the current {@link ObjectiveBannerPhase}, and `progress` `0..1` through that phase. This object is pooled and overwritten on the next {@link ObjectiveBannerController.current} call — read it, don't retain it.
|
|
392
|
+
- `StoredObjectiveBanner` (interface): interface StoredObjectiveBanner — A persisted banner record — all announcement fields resolved, plus id and schedule.
|
|
393
|
+
- `createObjectiveBanner` (function): function createObjectiveBanner(options: ObjectiveBannerOptions = {}): ObjectiveBannerController — A serializable, clock-driven stage/objective banner controller: the classic transient centered title stamp ("WAVE 3", "VICTORY", "OBJECTIVE COMPLETE"). A game calls `announce({ title, subtitle?, kind? })` and the controller queues it, flies it in, holds it, and fades it out on an injected clock — one banner at a time — exposing the current banner plus its phase (in/hold/out) and `progress` `0..1` for a renderer to animate opacity/scale/translate. Nothing here is genre-specific: `kind` is a free label the game owns and styles, and all timings are parameters. Call `advance()` each frame; `current()` returns the pooled view to draw; `snapshot`/`restore` round-trips the queue through a save.
|
|
394
|
+
|
|
263
395
|
## @jgengine/core/ui/orientation
|
|
264
396
|
|
|
265
397
|
- `GameOrientation` (type): type GameOrientation = "landscape" | "portrait" | GameOrientationConfig — The `orientation` field of a game definition. Legacy shorthand `"landscape"` / `"portrait"` stays advisory (a dismissible rotate hint, never a gate). The object form `{ mobile: "landscape-required" }` is the strict contract that blocks gameplay behind the rotate screen until the device is turned.
|
|
@@ -288,6 +420,35 @@
|
|
|
288
420
|
- `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
421
|
- `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
422
|
|
|
423
|
+
## @jgengine/core/ui/photoMode
|
|
424
|
+
|
|
425
|
+
- `DEFAULT_PHOTO_MODE` (const): const DEFAULT_PHOTO_MODE: PhotoModeState — The out-of-the-box photo-mode state: not active, HUD hidden when it engages.
|
|
426
|
+
- `PhotoModeState` (interface): interface PhotoModeState — Serializable photo-mode preferences a game reads to compose its capture UI.
|
|
427
|
+
- `PhotoModeStore` (interface): interface PhotoModeStore — Observable photo-mode store — genre-agnostic state a game binds its capture flow to.
|
|
428
|
+
- `createPhotoModeStore` (function): function createPhotoModeStore(initial: Partial<PhotoModeState> = {}): PhotoModeStore — Serializable, observable photo-mode state (active + hide-HUD). Genre-agnostic plumbing — a game engages it to free its camera and hide gameplay chrome for a clean capture, and reads `hideHud` to conditionally render its HUD. Pair with React `PhotoModeControls` and shell `captureCanvas`.
|
|
429
|
+
|
|
430
|
+
## @jgengine/core/ui/radialMenu
|
|
431
|
+
|
|
432
|
+
- `RadialArc` (interface): interface RadialArc — Arc the slices span. Omit for a full wheel (index 0 at the top). A partial `sweep` (e.g. `Math.PI` for a bottom half, `Math.PI / 2` for a quarter) packs the slices evenly inside `[startAngle, startAngle + sweep]` — the arc/quick-bar forms. Angles are radians from "up" (−Y), clockwise.
|
|
433
|
+
- `RadialSlice` (interface): interface RadialSlice — One wedge of a radial menu — geometry for rendering a slice. Angles are radians from "up" (−Y), clockwise.
|
|
434
|
+
- `RadialVectorOptions` (interface): interface RadialVectorOptions extends RadialArc — Options for {@link radialIndexFromVector}.
|
|
435
|
+
- `radialIndexFromAngle` (function): function radialIndexFromAngle(angle: number, count: number, arc?: RadialArc): number — Map an angle to a slice index; returns -1 when the angle falls outside a partial `arc`.
|
|
436
|
+
- `radialIndexFromVector` (function): function radialIndexFromVector(dx: number, dy: number, count: number, options: RadialVectorOptions = {}): number | null — Pick the slice a pointer/stick vector points at. `dx`/`dy` are screen-space (y down): up is `(0, -1)`. Returns null inside `deadZone` or (for a partial `arc`) outside the arc, so a centered stick or a click off the arc selects nothing.
|
|
437
|
+
- `radialSlicePosition` (function): function radialSlicePosition(index: number, count: number, radius: number, arc?: RadialArc): { x: number; y: number } — Unit-circle position of a slice center (up = `(0, -1)`), scaled by `radius` — where to place a wedge's icon/label.
|
|
438
|
+
- `radialSlices` (function): function radialSlices(count: number, arc?: RadialArc): RadialSlice[] — Divide a ring (or `arc`) into `count` wedges — the geometry a radial/quick menu (weapon wheel, emote arc, ping bar) renders. A full wheel centers index 0 at the top; a partial `arc` packs the slices inside its sweep.
|
|
439
|
+
|
|
440
|
+
## @jgengine/core/ui/screenMarkers
|
|
441
|
+
|
|
442
|
+
- `ScreenMarkerLayout` (interface): interface ScreenMarkerLayout — Where and how to draw one marker, from {@link layoutScreenMarker}.
|
|
443
|
+
- `ScreenMarkerOptions` (interface): interface ScreenMarkerOptions — Options for {@link layoutScreenMarker}.
|
|
444
|
+
- `ScreenMarkerViewport` (interface): interface ScreenMarkerViewport — The `{ width, height }` of the viewport the marker is laid out within (CSS px).
|
|
445
|
+
- `ScreenProjection` (interface): interface ScreenProjection — A world position projected to screen space by the caller's camera. This is the minimal shape {@link layoutScreenMarker} consumes — deliberately a structural subset of `@jgengine/react`'s `EntityScreenProjection` (and what its `ProjectEntity`/`useWorldProjection` produce), mirrored here because `core` imports nothing higher. Feed it straight from a world→screen projector.
|
|
446
|
+
- `Waypoint` (interface): interface Waypoint — A tracked objective/waypoint the game wants a screen marker for.
|
|
447
|
+
- `WaypointSnapshot` (interface): interface WaypointSnapshot — Serializable state of a {@link WaypointTracker}, for save/restore.
|
|
448
|
+
- `WaypointTracker` (interface): interface WaypointTracker — An observable, serializable set of world waypoints keyed by id.
|
|
449
|
+
- `createWaypointTracker` (function): function createWaypointTracker(): WaypointTracker — A serializable, observable tracker of world waypoints — the objective/point-of- interest half of offscreen markers. A game `set`s waypoints by id (each an `{ id, position, kind, label? }`, where `kind` is a free string the game styles and the model never branches on), and a React host projects each to screen space and lays it out with {@link layoutScreenMarker}: an on-screen pin, or an off-screen directional arrow clamped to the viewport edge with a distance the caller computes. Purely a model — no camera, projection, or renderer here. `snapshot`/`restore` round-trips the set through a save.
|
|
450
|
+
- `layoutScreenMarker` (function): function layoutScreenMarker(projection: ScreenProjection, viewport: ScreenMarkerViewport, options: ScreenMarkerOptions = {}): ScreenMarkerLayout — Pure, allocation-aware screen-marker math: given a projected target point, the viewport, and a `margin`, decide whether the target is on-screen and where to draw its marker. An on-screen point passes straight through (`onScreen: true`). An off-screen — or behind-camera — point is CLAMPED to the viewport edge (inset by `margin`) with `angle` set to the bearing from screen center toward the target, so a caller can pin an arrow to the frame edge and rotate it to point the way. Behind-camera projections have mirrored coordinates, so the bearing is flipped to face the true direction. This is the edge-clamp/arrow half that `layoutEntityFrames` lacks (it culls off-screen entries instead). No allocation when an `out` object is supplied — reuse one across a whole frame's waypoints.
|
|
451
|
+
|
|
291
452
|
## @jgengine/core/ui/selectionModel
|
|
292
453
|
|
|
293
454
|
- `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.
|
|
@@ -324,6 +485,11 @@
|
|
|
324
485
|
## @jgengine/react
|
|
325
486
|
|
|
326
487
|
- `AbilitySlotBindingOptions` (interface): interface AbilitySlotBindingOptions — ⚠ undocumented
|
|
488
|
+
- `AccessibilityProvider` (function): function AccessibilityProvider({ store, children, className, style, }: { store: AccessibilityStore; children: ReactNode; className?: string; style?: CSSProperties; }): ReactNode — Apply accessibility preferences to a subtree: exposes `--jg-text-scale` for text to scale off, sets `data-reduced-motion` / `data-high-contrast` / `data-colorblind` / `data-captions` for CSS to respond to, and wraps the tree in the selected colorblind `feColorMatrix` filter. Reads a `createAccessibilityStore` and re-renders on change; provides the state to `useAccessibility`.
|
|
489
|
+
- `AchievementGallery` (function): function AchievementGallery({ achievements, title = "Achievements", maskSecrets = true, renderIcon, columns = 2, emptyLabel = "No achievements yet.", className, style, }: AchievementGalleryProps): ReactNode — Achievement/trophy gallery — a responsive grid of cards showing unlocked vs. locked state, a progress bar for counter achievements, and a header summary of completion and score. Secret+locked entries mask their name/description. Feed it `useAchievements(tracker)`.
|
|
490
|
+
- `AchievementGalleryProps` (interface): interface AchievementGalleryProps — Props for {@link AchievementGallery}.
|
|
491
|
+
- `AchievementToast` (function): function AchievementToast({ name, description, icon, points, heading = "Achievement Unlocked", className, style, }: AchievementToastProps): ReactNode — The unlock-moment banner — icon, "Achievement Unlocked" heading, name, and optional points. Purely presentational; pair the game's `onUnlock` seam with a toast queue and render one of these per entry.
|
|
492
|
+
- `AchievementToastProps` (interface): interface AchievementToastProps — Props for {@link AchievementToast}.
|
|
327
493
|
- `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.
|
|
328
494
|
- `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.
|
|
329
495
|
- `ActionBarKeyResult` (interface): interface ActionBarKeyResult — The intent a key press resolves to over an action bar: move focus, activate, or ignore.
|
|
@@ -342,6 +508,9 @@
|
|
|
342
508
|
- `BetterAuthSessionState` (interface): interface BetterAuthSessionState — ⚠ undocumented
|
|
343
509
|
- `BetterAuthUserShape` (interface): interface BetterAuthUserShape — ⚠ undocumented
|
|
344
510
|
- `BossBar` (function): function BossBar(props: AtomicBarProps & { name?: string }): React.JSX.Element — A wide encounter/boss health bar with the boss name at the start.
|
|
511
|
+
- `CameraShakeMeter` (function): function CameraShakeMeter({ controller, animate = false, title = "CAMERA SHAKE", kindLabels, variation = "glass", className, style, }: CameraShakeMeterProps): ReactNode — A drop-in HUD panel that visualizes a core {@link CameraShakeController}: a trauma meter (reusing the shared {@link StaminaBar} building block) plus a live percentage and the current impact `kind` label. Presentation only — it reads the controller and never interprets `kind`, mapping it through `kindLabels` for display. A shell component applies the same controller's `offset()` to the camera; this panel is the on-screen readout of how much shake is in flight.
|
|
512
|
+
- `CameraShakeMeterProps` (interface): interface CameraShakeMeterProps — Props for {@link CameraShakeMeter}.
|
|
513
|
+
- `CameraShakeReadout` (interface): interface CameraShakeReadout — A live read of a camera-shake controller: current trauma `0..1` and the last game-owned `kind`.
|
|
345
514
|
- `CaptureOdds` (function): function CaptureOdds({ chance, className, fillClassName, }: { chance: number; className?: string; fillClassName?: string; }): React.JSX.Element — ⚠ undocumented
|
|
346
515
|
- `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`.
|
|
347
516
|
- `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`.
|
|
@@ -356,22 +525,47 @@
|
|
|
356
525
|
- `ClerkUserShape` (interface): interface ClerkUserShape — ⚠ undocumented
|
|
357
526
|
- `ClerkUserState` (interface): interface ClerkUserState — ⚠ undocumented
|
|
358
527
|
- `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.
|
|
528
|
+
- `CoachMark` (function): function CoachMark({ view, positionStyle, onNext, onSkip, nextLabel = "Next", doneLabel = "Got it", skipLabel = "Skip tour", theme, className, style, }: CoachMarkProps): ReactNode — A single coach-mark callout — title, body, an "N of M" counter, a Next/Got-it button, and a Skip-tour link. Presentation-only; position it with `positionStyle` or drop it into {@link CoachMarkHost}. Reskin via {@link CoachMarkTheme}.
|
|
529
|
+
- `CoachMarkHost` (function): function CoachMarkHost({ sequence, resolveAnchor, showBackdrop = true, onComplete, nextLabel, doneLabel, skipLabel, theme, className, style, }: CoachMarkHostProps): ReactNode — Full-screen coach-mark host: watches a sequence, positions the current step's callout beside its anchored element (or centered when unanchored) via `getBoundingClientRect`, and draws an optional dimmed backdrop with a spotlight cutout around the anchor. Next advances, Skip ends the tour — both persist so hints never re-show. Reskin with {@link CoachMarkTheme}.
|
|
530
|
+
- `CoachMarkHostProps` (interface): interface CoachMarkHostProps — Props for {@link CoachMarkHost}.
|
|
531
|
+
- `CoachMarkProps` (interface): interface CoachMarkProps — Props for {@link CoachMark}.
|
|
532
|
+
- `CoachMarkTheme` (interface): interface CoachMarkTheme — Reskin tokens for {@link CoachMarkHost} / {@link CoachMark}.
|
|
533
|
+
- `Codex` (function): function Codex({ entries, title = "Codex", columns = 3, maskSecrets = true, renderIcon, onSelect, emptyLabel = "Nothing discovered yet.", className, style, }: CodexProps): ReactNode — Codex / bestiary gallery — category tabs, a responsive grid of entry cards (discovered vs. locked, secret entries masked until found), and a header summarizing completion. Feed it `codex.list()`; wire `onSelect` to a detail pane.
|
|
534
|
+
- `CodexProps` (interface): interface CodexProps — Props for {@link Codex}.
|
|
359
535
|
- `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`. *
|
|
536
|
+
- `ColorblindFilters` (function): function ColorblindFilters(): ReactNode — Hidden SVG `<defs>` holding the `feColorMatrix` colorblind filters that `AccessibilityProvider` references by `filter: url(#jg-cb-<mode>)`. Rendered automatically inside the provider; export standalone for custom roots.
|
|
537
|
+
- `ComboMeterHud` (function): function ComboMeterHud({ meter, tierColors, theme, animate = true, hideWhenEmpty = true, barWidth = 220, className, style, }: ComboMeterHudProps): ReactNode — A drop-in HUD for a core {@link ComboMeter}: the big live combo count ("×12"), the current free-string tier label, the derived score multiplier, and a draining window bar (reusing the shared atomic bar) that empties as the decay window runs out and re-fills on every hit. The active tier's color — supplied by the game via `tierColors`, keyed on the free-string tier id the model never interprets — drives the count glow, the label, and the bar fill, so a game reskins the escalation ("good" → "great" → "savage") without the engine hardcoding any tier meaning. Presentation only: all counting, timing, tiers, and the multiplier live in the core model.
|
|
538
|
+
- `ComboMeterHudProps` (interface): interface ComboMeterHudProps — Props for {@link ComboMeterHud}.
|
|
539
|
+
- `ComboMeterTheme` (interface): interface ComboMeterTheme — Reskin tokens for {@link ComboMeterHud}.
|
|
360
540
|
- `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`.
|
|
361
541
|
- `CompassProps` (interface): interface CompassProps — ⚠ undocumented
|
|
542
|
+
- `ConfirmDialog` (function): function ConfirmDialog({ title, body, confirmLabel = "Confirm", cancelLabel = "Cancel", onConfirm, onCancel, danger = false, width = 360, className, style, }: ConfirmDialogProps): ReactNode — A generic two-button confirmation dialog — title, optional body, and Cancel / Confirm buttons over a `HudTheme`-token-driven {@link HudFrame}. Presentation-only: wire `onConfirm`/`onCancel` to a modal stack's `resolve` (typically inside a {@link ModalHost} render callback) and reskin via `HudTheme` tokens or `danger` for a destructive action. It interprets nothing — the game supplies the copy.
|
|
543
|
+
- `ConfirmDialogProps` (interface): interface ConfirmDialogProps — Props for {@link ConfirmDialog}.
|
|
362
544
|
- `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.
|
|
363
545
|
- `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.
|
|
364
546
|
- `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.
|
|
365
547
|
- `CurrencyPill` (function): function CurrencyPill({ currencyId, className }: { currencyId: string; className?: string }): React.JSX.Element — ⚠ undocumented
|
|
548
|
+
- `CutsceneLetterbox` (function): function CutsceneLetterbox({ active, caption, onSkip, skipLabel = "Skip", progress, theme, className, style, }: CutsceneLetterboxProps): ReactNode — A drop-in cinematic letterbox overlay: black bars slide in top and bottom while a cutscene is `active`, an optional caption/dialogue line sits above the lower bar with an optional progress line, and a Skip button rides the top bar. Presentation only — it never touches the director; wire `active`/`caption`/`progress`/`onSkip` from {@link useSequenceDirector} and your `onCue` handler. Reskin via {@link CutsceneLetterboxTheme}.
|
|
549
|
+
- `CutsceneLetterboxProps` (interface): interface CutsceneLetterboxProps — Props for {@link CutsceneLetterbox}.
|
|
550
|
+
- `CutsceneLetterboxTheme` (interface): interface CutsceneLetterboxTheme — Reskin tokens for {@link CutsceneLetterbox}.
|
|
366
551
|
- `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.
|
|
552
|
+
- `DamageDirectionOverlay` (function): function DamageDirectionOverlay({ tracker, colors, showReticle = true, theme, className, style, }: DamageDirectionOverlayProps): ReactNode — A drop-in "hit-from" overlay: transient red (by default) arcs that flare around a center reticle in the direction each recent hit came from and fade out over time, driven entirely by a {@link DamageDirectionTracker}. Opacity and outward push scale with each indicator's eased intensity; color comes from the hit's `kind` (via `colors`) or the theme's danger color. Renders full-screen, `pointer-events: none`, so it never intercepts input — a game drops it into its HUD and calls `tracker.registerHit(...)` on damage. Reskin via {@link DamageDirectionTheme}.
|
|
553
|
+
- `DamageDirectionOverlayProps` (interface): interface DamageDirectionOverlayProps — Props for {@link DamageDirectionOverlay}.
|
|
554
|
+
- `DamageDirectionTheme` (interface): interface DamageDirectionTheme — Reskin tokens for {@link DamageDirectionOverlay}.
|
|
367
555
|
- `DeathScreen` (function): function DeathScreen({ statId = "health", open, className, children, }: { statId?: string; open?: boolean; className?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
556
|
+
- `DebounceTimer` (interface): interface DebounceTimer — Injectable timer seam so the controller is testable with a manual clock.
|
|
557
|
+
- `DebouncedCommit` (interface): interface DebouncedCommit<T> — Live-mirrored, trailing-debounced commit binding for a single control value.
|
|
368
558
|
- `DefaultEquipSlotId` (type): type DefaultEquipSlotId = | "head" | "chest" | "hands" | "legs" | "feet" | "mainHand" | "offHand" | "ring1" | "ring2" | "trinket" — Slot ids used by {@link defaultEquipLayout}'s convenience arrangement.
|
|
369
559
|
- `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
|
|
370
560
|
- `DialogueCheck` (interface): interface DialogueCheck — ⚠ undocumented
|
|
371
561
|
- `DialogueChoice` (interface): interface DialogueChoice — ⚠ undocumented
|
|
372
562
|
- `DialogueDef` (interface): interface DialogueDef — ⚠ undocumented
|
|
373
563
|
- `DialogueLine` (type): type DialogueLine = { speaker: string; text: string } | { choices: readonly DialogueChoice[] } — ⚠ undocumented
|
|
564
|
+
- `DialogueView` (function): function DialogueView({ run, renderPortrait, onChoose, onClose, closeLabel = "Close", theme, className, style, speakerClassName, textClassName, choicesClassName, choiceClassName, }: DialogueViewProps): ReactNode — A drop-in branching-conversation view over a {@link DialogueRun}: renders the current node's speaker name (+ an optional portrait slot), the line, and a list of clickable response choices that advance the conversation — the game passes its dialogue graph and gets working node traversal and choice state with no hand-rolled walk. A choice with a destination advances the run; a terminal choice (or the Close control on a choiceless node) fires `onClose`. Speaker/choice `kind` are free strings surfaced as `data-*` attributes for the game to style; the view never interprets them. HudTheme-skinned via `--jg-*` tokens; reskin further with {@link DialogueViewTheme}.
|
|
565
|
+
- `DialogueViewProps` (interface): interface DialogueViewProps — Props for {@link DialogueView}.
|
|
566
|
+
- `DialogueViewTheme` (interface): interface DialogueViewTheme — Reskin tokens for {@link DialogueView}. Each defaults to a HudTheme `--jg-*` token.
|
|
374
567
|
- `DisplayProfile` (interface): interface DisplayProfile — ⚠ undocumented
|
|
568
|
+
- `DomEventTarget` (interface): interface DomEventTarget — Minimal add/removeEventListener surface accepted by useDomEvent (window, document, elements).
|
|
375
569
|
- `DragGhost` (function): function DragGhost<T>({ layer, className, style, children, }: { layer: DragLayer<T>; className?: string; style?: CSSProperties; children?: (payload: DragPayload<T>) => ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
376
570
|
- `DragLayer` (interface): interface DragLayer<T> — ⚠ undocumented
|
|
377
571
|
- `DragPayload` (interface): interface DragPayload<T> — ⚠ undocumented
|
|
@@ -380,7 +574,13 @@
|
|
|
380
574
|
- `DropInfo` (interface): interface DropInfo<T> — ⚠ undocumented
|
|
381
575
|
- `DropZone` (function): function DropZone<T>({ id, layer, className, activeClassName, cellSize, children, }: { id: string; layer: DragLayer<T>; className?: string; activeClassName?: string; cellSize?: number; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
382
576
|
- `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
|
|
577
|
+
- `EntityFrameEntry` (interface): interface EntityFrameEntry — The minimum an entry must carry; games extend it with their own display data.
|
|
578
|
+
- `EntityFrameLayoutOptions` (interface): interface EntityFrameLayoutOptions — Anchoring, culling, and stacking options shared by the layout core and component.
|
|
579
|
+
- `EntityFramePlacement` (interface): interface EntityFramePlacement<E extends EntityFrameEntry> — One entry resolved to a screen placement, ready to render.
|
|
580
|
+
- `EntityFrames` (function): function EntityFrames<E extends EntityFrameEntry>({ entries, project, renderFrame, className, style, anchorTransform = "translate(-50%, -100%)", ...layout }: EntityFramesProps<E>): React.JSX.Element — Absolutely-positioned overlay that renders a caller-composed frame over every on-screen entry. Drop it inside `HudCanvas` (or any positioned ancestor) and feed it fresh `entries`/`project` each frame. Every part carries `data-*` hooks (`data-entity-frames`, `data-entity-frame="<id>"`) for tests and skins.
|
|
581
|
+
- `EntityFramesProps` (interface): interface EntityFramesProps<E extends EntityFrameEntry> extends EntityFrameLayoutOptions — Props for {@link EntityFrames}.
|
|
383
582
|
- `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.
|
|
583
|
+
- `EntityScreenProjection` (interface): interface EntityScreenProjection — World-anchored entity frames — a data-first seam for floating overhead UI (enemy nameplates + health bars, interaction prompts, objective pips) that tracks entities in the 3D world. The game keeps owning its entities: it passes a plain array of `{ id, worldPosition }` entries and a `project` function that turns a world position into a screen point, and composes each frame's markup itself (typically the shipped {@link ./bars!HealthBar} plus a name) reskinned through `HudTheme`/`barTokens`. This primitive owns only the reusable behavior: projecting, offsetting, culling entries that are off-screen or behind the camera, and stacking nearer entities above farther ones.
|
|
384
584
|
- `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
585
|
- `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
586
|
- `EquipSlotLayout` (type): type EquipSlotLayout = readonly EquipSlot[] — An ordered set of equip slots that make up a paperdoll. Caller-supplied; see {@link defaultEquipLayout}.
|
|
@@ -389,16 +589,25 @@
|
|
|
389
589
|
- `EventMeterView` (interface): interface EventMeterView — A rendered snapshot of an {@link EventMeter}: current value, fill fraction, active tier, and ready-to-consume flag.
|
|
390
590
|
- `EventfulEngineStore` (interface): interface EventfulEngineStore<TEventMap extends object> — ⚠ undocumented
|
|
391
591
|
- `ExperienceBar` (const): const ExperienceBar: (props: AtomicBarProps) => React.JSX.Element — Level progress / experience.
|
|
592
|
+
- `FastTravelMenu` (function): function FastTravelMenu<TMeta = unknown>({ network, from, onTravel, currentId, title = "Fast Travel", emptyLabel = "No destinations discovered yet.", onClose, className, style, }: FastTravelMenuProps<TMeta>): ReactNode — Fast-travel menu — the discovered-destinations list players pick from: points grouped by region, distance-sorted from `from`, each showing icon, name, and distance, with a header counting discovered vs. total. Selecting a row calls `onTravel`; the current location is flagged and not travelable. Bind it to a `createFastTravelNetwork`.
|
|
593
|
+
- `FastTravelMenuProps` (interface): interface FastTravelMenuProps<TMeta = unknown> — Props for {@link FastTravelMenu}.
|
|
594
|
+
- `FloatingText` (function): function FloatingText({ entries, project, styleFor, fontSizePx = 20, className, style, renderEntry, ...layout }: FloatingTextProps): React.JSX.Element — Absolutely-positioned overlay that renders every on-screen floating-text entry as text with its color, current alpha, and pop-in scale. Drop it inside a positioned ancestor (e.g. an `<Html fullscreen>` overlay or `HudCanvas`) and feed it fresh `entries`/`project` each frame. Every part carries `data-*` hooks (`data-floating-text`, `data-floating-text-entry="<id>"`, `data-kind="<kind>"`) for tests and skins.
|
|
595
|
+
- `FloatingTextLayoutOptions` (interface): interface FloatingTextLayoutOptions — Anchoring and culling options shared by the layout core and the component.
|
|
596
|
+
- `FloatingTextPlacement` (interface): interface FloatingTextPlacement — World-anchored floating text — the presentation half of the data-first `@jgengine/core/ui/floatingText` seam. The game keeps owning the simulation: it passes the field's `active()` views plus a `project` function (world → screen), exactly the transport {@link ./entityFrames!EntityFrames} uses, so an R3F game gets it for free from `useWorldProjection`. This component owns only the reusable presentation: projecting each entry, culling ones behind the camera or off-screen, and rendering absolutely-positioned text with the entry's color, current alpha, and pop-in scale — reskinnable per `kind` through `styleFor`.
|
|
597
|
+
- `FloatingTextProps` (interface): interface FloatingTextProps extends FloatingTextLayoutOptions — Props for {@link FloatingText}.
|
|
392
598
|
- `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
|
|
393
599
|
- `FriendRow` (function): function FriendRow({ friend, className, dotClassName, children, }: { friend: FriendEntry; className?: string; dotClassName?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
394
600
|
- `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
|
|
601
|
+
- `FullscreenMap` (function): function FullscreenMap({ open = true, bounds, contentWidth = 900, minScale = 0.5, maxScale = 8, title = "Map", onClose, onWorldClick, tool = "pan", onStrokeComplete, drawTone = "info", drawWidth = 3, children, overlayClassName, overlayStyle, ...surfaceProps }: FullscreenMapProps): ReactNode — Fullscreen pan/zoom world-map overlay — the enlarged "press M" map. Wheel to zoom (toward the cursor), drag to pan, and click to place (wire `onWorldClick` to a waypoint/annotation store). Switch `tool` to `"draw"` to freehand-draw strokes committed to `onStrokeComplete` (wire to `createAnnotationLayer`). Reuses {@link WorldMapSurface} for rendering, so terrain bake, fog, routes, zones, markers, and the player arrow all appear; a drag never fires `onWorldClick`. Compose a {@link MapLegend} or tool palette via `children`.
|
|
602
|
+
- `FullscreenMapProps` (interface): interface FullscreenMapProps extends Omit<WorldMapSurfaceProps, "canvasWidth" | "canvasHeight" | "viewport" | "width" | "height" | "style"> — Props for {@link FullscreenMap}.
|
|
603
|
+
- `GameContextBridge` (function): function GameContextBridge({ context, children, }: { context: GameContext | null; children?: ReactNode; }): React.JSX.Element — Re-provide a captured {@link GameContext} across a nested React reconciler boundary. The `<Canvas>` of `@react-three/fiber` renders its children in a *separate* React root, so a `GameProvider` in the outer tree does NOT reach inside it — hooks like `useGameContext` / `useEntityRenderCues` throw. The fix the shell already uses internally: capture the context outside the boundary (with {@link useOptionalGameContext}) and wrap the inner tree in `GameContextBridge`. A `null` context renders children unchanged, so the same code works in showcases with no running game. This is the seam behind `EntityPreview` — reach for it directly when building a bespoke nested canvas.
|
|
395
604
|
- `GameIdentityProvider` (function): function GameIdentityProvider({ source, children, }: { source: IdentitySource; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
396
605
|
- `GamePreviewComponent` (type): type GamePreviewComponent = ComponentType<GamePreviewProps> — ⚠ undocumented
|
|
397
606
|
- `GamePreviewProps` (type): type GamePreviewProps = { className?: string; } — ⚠ undocumented
|
|
398
607
|
- `GamePreviewStates` (type): type GamePreviewStates = Record<string, GamePreviewComponent> — ⚠ undocumented
|
|
399
608
|
- `GameProvider` (function): function GameProvider({ context, children }: { context: GameContext; children?: ReactNode }): React.JSX.Element — ⚠ undocumented
|
|
400
609
|
- `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.
|
|
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.
|
|
610
|
+
- `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; ember: HudTheme; synthwave: HudTheme; fieldkit: HudTheme; } — Built-in theme presets for demos/scaffold only — not product identity; games author their own theme.
|
|
402
611
|
- `HealthBar` (const): const HealthBar: (props: AtomicBarProps) => React.JSX.Element — Player/enemy health — danger-flashes to `--jg-health-low` below a quarter full.
|
|
403
612
|
- `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.
|
|
404
613
|
- `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.
|
|
@@ -411,20 +620,31 @@
|
|
|
411
620
|
- `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
621
|
- `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.
|
|
413
622
|
- `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.
|
|
623
|
+
- `HudTheme` (interface): interface HudTheme — A full HUD theme. Author one with {@link hudTheme} or {@link deriveHudTheme}.
|
|
415
624
|
- `HudThemeBar` (interface): interface HudThemeBar — Framed-trough tokens shared by every atomic bar.
|
|
625
|
+
- `HudThemeFont` (interface): interface HudThemeFont — Typography roles. Any CSS `font-family` list.
|
|
416
626
|
- `HudThemeFrame` (interface): interface HudThemeFrame — Frame material + shape tokens (panels, `HudFrame variation="themed"`).
|
|
417
|
-
- `
|
|
627
|
+
- `HudThemeOverrides` (interface): interface HudThemeOverrides — Per-group partial overrides accepted by {@link hudTheme}.
|
|
628
|
+
- `HudThemePalette` (interface): interface HudThemePalette — `HudTheme` (#1034, #1573): one token object that restyles every shared token-driven building block at once — the atomic bars (#1033), frames, slots, the minimap ring, and the chrome the registry blocks read (surfaces, edges, text, status colors, fonts, rarity). `hudThemeVars(theme)` emits the whole `--jg-*` vocabulary, so setting a **game-authored** theme on any HUD ancestor re-skins `packages/react` primitives and `registry/jgengine` components together. 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
629
|
- `HudThemePreset` (type): type HudThemePreset = keyof typeof HUD_THEME_PRESETS — Built-in demo/scaffold theme preset name — not a game identity.
|
|
419
630
|
- `HudThemePreview` (function): function HudThemePreview({ className }: { className?: string }): React.JSX.Element — Renders the default theme plus every genre preset as a deterministic matrix.
|
|
631
|
+
- `HudThemeRarity` (interface): interface HudThemeRarity — Item-rarity coloring shared by loot cards, tooltips, and inventory slots.
|
|
632
|
+
- `HudThemeSeed` (interface): interface HudThemeSeed — Seed colors for {@link deriveHudTheme}. Only `accent` and `surface` are required.
|
|
420
633
|
- `HudThemeSlot` (interface): interface HudThemeSlot — Action/inventory slot tokens.
|
|
634
|
+
- `HudThemeStatus` (interface): interface HudThemeStatus — Semantic status colors — outcome, threat, and relationship coloring.
|
|
635
|
+
- `HudThemeSurface` (interface): interface HudThemeSurface — Chrome surfaces, edges, and text — what panels, overlays, and menus are built out of.
|
|
421
636
|
- `HudViewportContextValue` (interface): interface HudViewportContextValue — ⚠ undocumented
|
|
422
637
|
- `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.
|
|
638
|
+
- `I18nProvider` (function): function I18nProvider({ i18n, children }: { i18n: I18n; children: ReactNode }): ReactNode — Provide an {@link I18n} instance to the tree so `useT`/`useLocale` can read it.
|
|
423
639
|
- `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
640
|
- `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
641
|
- `IconTreatmentProps` (interface): interface IconTreatmentProps — Props for {@link IconTreatment}.
|
|
426
642
|
- `IconsPreview` (function): function IconsPreview({ className }: { className?: string }): React.JSX.Element — Renders the school-gradient row and a treated-icon hotbar — the deterministic #1035 fixture.
|
|
427
643
|
- `IdentitySource` (interface): interface IdentitySource — ⚠ undocumented
|
|
644
|
+
- `InteractionPrompt` (function): function InteractionPrompt({ registry, playerPosition, theme, accentFor, keyFor, gaugeProgress, anchor = "bottom-center", zIndex = 40, className, style, }: InteractionPromptProps): ReactNode — A screen-anchored "Press E to …" interaction callout that renders the active prompt of a {@link PromptRegistry}. It subscribes to the registry and — when given `playerPosition` — re-resolves as the hero moves, showing the nearest in-range interactable and switching to a closer/higher-priority one as they cross radii. Each display kind renders as itself: a `keybind` shows a key cap plus its label ("Press [E] Open"), a `gauge` shows a hold bar filling with `gaugeProgress`, and a `label` shows plain text. Presentation only — the registry never branches on a prompt's meaning; the game colors each via `accentFor` and maps action ids to key glyphs via `keyFor`. HudTheme-skinnable through `--jg-accent` and {@link InteractionPromptTheme}.
|
|
645
|
+
- `InteractionPromptAnchor` (type): type InteractionPromptAnchor = "bottom-center" | "top-center" | "center" — Where the callout sits over the scene.
|
|
646
|
+
- `InteractionPromptProps` (interface): interface InteractionPromptProps — Props for {@link InteractionPrompt}.
|
|
647
|
+
- `InteractionPromptTheme` (interface): interface InteractionPromptTheme — Reskin tokens for {@link InteractionPrompt}.
|
|
428
648
|
- `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
649
|
- `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
650
|
- `InventoryGridProps` (interface): interface InventoryGridProps — Props for {@link InventoryGrid}.
|
|
@@ -432,12 +652,23 @@
|
|
|
432
652
|
- `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
|
|
433
653
|
- `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.
|
|
434
654
|
- `KeybindRow` (function): function KeybindRow({ action, keys, className, }: { action: string; keys: readonly string[]; className?: string; }): React.JSX.Element — ⚠ undocumented
|
|
655
|
+
- `KeybindingMenu` (function): function KeybindingMenu({ session, theme, title = "Controls", resetAllLabel = "Reset All", capturePrompt = "Press a key…", onChange, className, style, }: KeybindingMenuProps): ReactNode — A drop-in controls-settings surface for a {@link RebindSession}: one row per action showing its label and current key glyph. Clicking a row arms capture ("Press a key…") and a window `keydown` listener feeds the pressed `event.code` to `session.capture`; rows that collide with another action show a conflict badge; each row has a Reset button and the panel has a Reset-all button. Presentation only — all conflict/capture/reset logic lives in the core session, and action ids/labels are the game's free strings. Reskin via {@link KeybindingMenuTheme} or ambient HudTheme tokens. A game owns its overall settings layout; this is the reusable controls block it drops in.
|
|
656
|
+
- `KeybindingMenuProps` (interface): interface KeybindingMenuProps — Props for {@link KeybindingMenu}.
|
|
657
|
+
- `KeybindingMenuTheme` (interface): interface KeybindingMenuTheme — Reskin tokens for {@link KeybindingMenu}. All fall back to HudTheme `--jg-*` vars.
|
|
435
658
|
- `Keycap` (function): function Keycap({ children, className, style, }: { children: ReactNode; className?: string; style?: CSSProperties; }): React.JSX.Element — A single keyboard/mouse key rendered as a cap. Tagged `data-jg-kbd` so tooling can find it; on its own it stays visible (hiding a lone cap would strand its label). Wrap keys + their meaning in `KeyHint` to make the whole hint vanish on touch.
|
|
659
|
+
- `KillFeed` (function): function KillFeed({ ticker, kindStyles, theme, iconSize = 18, animate = true, zIndex = 40, className, style, }: KillFeedProps): ReactNode — A vertical event/kill-feed ticker: renders an {@link EventTicker}'s recent entries as a stack of rows, newest on top, each with its `fade` `0..1` mapped to opacity so entries dim and drop as they age out. Each row shows an optional per-kind (or per-entry) {@link GameIcon} and a per-kind accent color from `kindStyles`, styled with HudTheme tokens. Presentation only: all capping/timing lives in the core ticker, and the free-string `kind`/`text`/`icon` are never interpreted here — a game colors and icons each variant via `kindStyles`.
|
|
660
|
+
- `KillFeedKindStyle` (interface): interface KillFeedKindStyle — Per-`kind` styling for a kill-feed row — accent color and an optional icon.
|
|
661
|
+
- `KillFeedProps` (interface): interface KillFeedProps — Props for {@link KillFeed}.
|
|
662
|
+
- `KillFeedTheme` (interface): interface KillFeedTheme — Reskin tokens for {@link KillFeed}.
|
|
436
663
|
- `LayoutRegionSpec` (type): type LayoutRegionSpec = Omit<LayoutRegion, "rect"> — A region descriptor without its measured rectangle — the caller supplies geometry through `useRegisterLayoutRegion`.
|
|
437
664
|
- `LeavePartyButton` (function): function LeavePartyButton({ className, children, }: { className?: string; children?: ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
438
665
|
- `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
666
|
- `ManaBar` (const): const ManaBar: (props: AtomicBarProps) => React.JSX.Element — Spell/energy resource pool.
|
|
440
667
|
- `MapBounds` (interface): interface MapBounds — ⚠ undocumented
|
|
668
|
+
- `MapLegend` (function): function MapLegend({ kinds, labels, kindStyles = DEFAULT_MARKER_KINDS, title = "Legend", className, style, }: MapLegendProps): ReactNode — Marker-kind key for a map/minimap — glyph + color swatch per kind, labelled. Reads the same `kindStyles` the map renders with, so the legend can never drift from the pins.
|
|
669
|
+
- `MapLegendProps` (interface): interface MapLegendProps — Props for {@link MapLegend}.
|
|
670
|
+
- `MapViewport` (interface): interface MapViewport — Pan/zoom transform applied to a {@link WorldMapSurface}'s content group.
|
|
671
|
+
- `MedalToken` (type): type MedalToken = "gold" | "silver" | "bronze" — The medal tokens {@link medalFor} emits for the podium.
|
|
441
672
|
- `MicToggle` (function): function MicToggle({ voice, className, mutedLabel, unmutedLabel, }: { voice: VoiceState; className?: string; mutedLabel?: ReactNode; unmutedLabel?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
442
673
|
- `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`.
|
|
443
674
|
- `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.
|
|
@@ -450,7 +681,19 @@
|
|
|
450
681
|
- `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
682
|
- `MinimapTrackProps` (interface): interface MinimapTrackProps — Props for {@link MinimapTrack}.
|
|
452
683
|
- `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
|
-
- `
|
|
684
|
+
- `ModalControls` (interface): interface ModalControls — Stack-bound controls handed to a {@link ModalHost} render callback.
|
|
685
|
+
- `ModalHost` (function): function ModalHost({ stack, children, showBackdrop = true, backdrop, closeOnBackdrop = true, closeOnEsc = true, zIndexBase = 80, className, style, }: ModalHostProps): ReactNode — Full-screen modal host: watches a stack, renders only the topmost modal centered over a dimmed backdrop, and manages accessibility — the panel is a `role="dialog" aria-modal`, focus moves into it on open and is trapped with Tab/Shift+Tab cycling, Escape and (optionally) a backdrop click cancel the top modal, and focus returns to the previously focused element on close. It renders nothing when the stack is empty. Skin the panel and backdrop via `HudTheme` tokens.
|
|
686
|
+
- `ModalHostProps` (interface): interface ModalHostProps — Props for {@link ModalHost}.
|
|
687
|
+
- `ModalStackView` (interface): interface ModalStackView — React chrome over the headless modal stack (`@jgengine/core/ui/modalStack`) — the blocking-overlay layer a game raises over its scene: a pause menu, a "quit to menu?" confirm, a reward popup. {@link useModalStack} is the DATA/HOOK layer (subscribe + the active record), {@link ModalHost} renders the top modal with a backdrop, focus trap, and Esc-to-cancel, and {@link ConfirmDialog} / {@link PauseMenu} are ready-to-wire, HudTheme-token-driven building blocks. All unskinned and game-owned: the model never interprets a modal's `kind`, so a game switches on it to pick which of these (or its own) content to show, and reskins everything via `HudTheme` tokens and the frame.
|
|
688
|
+
- `NotificationBell` (function): function NotificationBell({ store, onClick, icon = "🔔", className, style }: NotificationBellProps): ReactNode — Notification bell — an icon button with an unread-count badge, bound to a notification store. Toggle a {@link NotificationCenter} panel from its click.
|
|
689
|
+
- `NotificationBellProps` (interface): interface NotificationBellProps — Props for {@link NotificationBell}.
|
|
690
|
+
- `NotificationCenter` (function): function NotificationCenter({ store, title = "Notifications", emptyLabel = "You're all caught up.", onClose, formatTime, className, style, }: NotificationCenterProps): ReactNode — Notification center panel — the scrollable log toasts don't provide: newest notifications with a kind-colored marker, title/body, relative time, and an unread highlight; a header with the unread count, mark-all-read, and clear. Clicking an entry marks it read. Bind it to a `createNotificationCenter`.
|
|
691
|
+
- `NotificationCenterProps` (interface): interface NotificationCenterProps — Props for {@link NotificationCenter}.
|
|
692
|
+
- `ObjectiveBannerHost` (function): function ObjectiveBannerHost({ controller, theme, kindThemes, animate = true, dismissOnClick = false, zIndex = 50, className, style, }: ObjectiveBannerHostProps): ReactNode — A full-screen overlay that renders an {@link ObjectiveBannerController} as the classic transient centered title stamp — "WAVE 3", "VICTORY", "OBJECTIVE COMPLETE" — flying in, holding, and fading out. It subscribes to the model, drives `advance()` on an animation frame (unless the game ticks it), and maps the current banner's phase + progress to opacity/scale/translate. Reskin the base look with {@link ObjectiveBannerTheme} and color each variant via `kindThemes` keyed on the game-owned `kind`. Presentation only: all timing and queueing live in the core model, and `kind` is never interpreted here.
|
|
693
|
+
- `ObjectiveBannerHostProps` (interface): interface ObjectiveBannerHostProps — Props for {@link ObjectiveBannerHost}.
|
|
694
|
+
- `ObjectiveBannerTheme` (interface): interface ObjectiveBannerTheme — Reskin tokens for {@link ObjectiveBannerHost}. Per-`kind` overrides layer on top.
|
|
695
|
+
- `PREVIEW_FIXTURES` (const): const PREVIEW_FIXTURES: Record<string, PreviewFixture> — Registry of deterministic, engine-level preview fixtures — the *real* exported `@jgengine/react` components (`HudThemePreview`, `BarsPreview`, `IconsPreview`, …) that render identically every time from static values, so they can be screenshotted as regression evidence without booting a game.
|
|
696
|
+
- `PanelHost` (function): function PanelHost({ manager, render, panels, variation, shape, width, zIndexBase = 40, className, windowClassName, windowStyle, bodyStyle, }: { manager: PanelsManager; /** Content for a panel by id. Takes precedence over `panels`. */ render?: (id: string) => ReactNode; /** Static content map by pan… — 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
697
|
- `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
698
|
- `PanelsManager` (interface): interface PanelsManager — The live panel manager returned by {@link usePanels} and consumed by {@link PanelHost}.
|
|
456
699
|
- `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.
|
|
@@ -458,28 +701,52 @@
|
|
|
458
701
|
- `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
|
|
459
702
|
- `PartyInviteToast` (function): function PartyInviteToast({ className, acceptClassName, declineClassName, renderInvite, }: { className?: string; acceptClassName?: string; declineClassName?: string; renderInvite?: (invite: PartyInviteEntry) => ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
460
703
|
- `PartyMemberRow` (function): function PartyMemberRow({ member, className, dotClassName, children, }: { member: PartyMemberEntry; className?: string; dotClassName?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
704
|
+
- `PauseMenu` (function): function PauseMenu({ title = "Paused", onResume, resumeLabel = "Resume", items = [], width = 300, className, style, }: PauseMenuProps): ReactNode — A reskinnable pause-menu building block: a primary Resume button plus a game-filled list of slot items (Settings, Save, Quit, …), stacked in a `HudTheme`-token-driven {@link HudFrame}. It ships the common shape every game's pause screen needs and nothing genre-specific — the game supplies the title, item labels/order, and destructive styling, and reskins with `HudTheme` tokens. Drop it into a {@link ModalHost} keyed on a `"pause"` modal, or render it standalone.
|
|
705
|
+
- `PauseMenuItem` (interface): interface PauseMenuItem — One selectable row in a {@link PauseMenu}'s slot list (Settings, Save, Quit, …).
|
|
706
|
+
- `PauseMenuProps` (interface): interface PauseMenuProps — Props for {@link PauseMenu}.
|
|
707
|
+
- `PhotoModeControls` (function): function PhotoModeControls({ store, onCapture, className, style }: PhotoModeControlsProps): ReactNode — Photo-mode toolbar — a hide/show-HUD toggle, a capture button, and an exit button, bound to a `createPhotoModeStore`. Presentation-only: the game wires `onCapture` to shell `captureCanvas`/`downloadImage` and reads `hideHud` to drop its gameplay HUD.
|
|
708
|
+
- `PhotoModeControlsProps` (interface): interface PhotoModeControlsProps — Props for {@link PhotoModeControls}.
|
|
461
709
|
- `PlayingCard` (interface): interface PlayingCard — A single card in a stack: an id plus its face and orientation.
|
|
462
710
|
- `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
711
|
- `PotionSlots` (function): function PotionSlots(props: SlotGridProps): React.JSX.Element — Consumable (health/shield potion) slots.
|
|
464
712
|
- `PresenceDot` (function): function PresenceDot({ userId, className }: { userId: string; className?: string }): React.JSX.Element — ⚠ undocumented
|
|
713
|
+
- `PreviewFixture` (interface): interface PreviewFixture — One entry in the engine preview-fixture registry: a deterministic, engine-level preview component keyed by a stable id.
|
|
714
|
+
- `ProjectEntity` (type): type ProjectEntity = ( worldPosition: readonly [number, number, number], ) => EntityScreenProjection | null — Projects a world position to a screen point, or returns `null` to cull the entry entirely (e.g. outside the frustum). Caller-owned so this seam never depends on a specific camera or renderer.
|
|
465
715
|
- `ProximityPrompt` (function): function ProximityPrompt({ prompt, className, }: { prompt: ProximityPromptDef; className?: string; }): React.JSX.Element — ⚠ undocumented
|
|
466
716
|
- `PushToTalkButton` (function): function PushToTalkButton({ voice, className, children, }: { voice: VoiceState; className?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
467
717
|
- `QteTrack` (function): function QteTrack({ steps, startedAt, className, stepClassName, activeClassName, doneClassName, }: { steps: readonly QteStep[]; startedAt: number; className?: string; stepClassName?: string; activeClassName?: string; doneClassName?: string; }): React.JSX.Element — ⚠ undocumented
|
|
718
|
+
- `QuestTracker` (function): function QuestTracker({ quests, title = "Quests", emptyLabel = "No active quests.", maxObjectives, accent = "var(--jg-accent, #facc15)", className, style, }: QuestTrackerProps): ReactNode — Quest / objective tracker HUD — a compact panel of active quests with a title and labelled, progress-barred objectives (checked + struck when complete). Presentation-only over `describeTrackedQuest(def, instance)` views, so it stays decoupled from the `QuestJournal` runtime.
|
|
719
|
+
- `QuestTrackerProps` (interface): interface QuestTrackerProps — Props for {@link QuestTracker}.
|
|
468
720
|
- `QuickMatchButton` (function): function QuickMatchButton({ listings, onJoin, onNoMatch, filter, className, children, }: { listings: readonly SessionListing[]; onJoin: (listing: SessionListing) => void; onNoMatch?: () => void; filter?: MatchFilter; className?: string; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
721
|
+
- `QuickMenu` (function): function QuickMenu({ items, layout = "list", onSelect, onClose, title, columns = 3, arc = { startAngle: Math.PI / 2, sweep: Math.PI }, radialSize = 300, accent = "var(--jg-accent, #38bdf8)", className, style, }: QuickMenuProps): ReactNode — Versatile quick menu that takes many forms — a `radial` wheel, a partial `arc`, a vertical `list`, or a `grid` — over one item model with icons, labels, hotkeys, count badges, cooldowns, section headers, and nested submenus (drill in / back). Radial and arc forms reuse {@link RadialMenu}; list and grid render sectioned rows/tiles. The game supplies content and skin.
|
|
722
|
+
- `QuickMenuItem` (interface): interface QuickMenuItem extends RadialMenuOption — An entry on a {@link QuickMenu}: a leaf action, or (with `children`) a submenu.
|
|
723
|
+
- `QuickMenuLayout` (type): type QuickMenuLayout = "radial" | "arc" | "list" | "grid" — The forms a {@link QuickMenu} can take.
|
|
724
|
+
- `QuickMenuProps` (interface): interface QuickMenuProps — Props for {@link QuickMenu}.
|
|
469
725
|
- `RANKS` (const): const RANKS: readonly Rank[] — Ranks in ascending order, ace low.
|
|
726
|
+
- `RadialMenu` (function): function RadialMenu({ options, open = true, onSelect, onClose, size = 300, innerRadius = 52, arc, highlightIndex, accent = "var(--jg-accent, #38bdf8)", className, style, }: RadialMenuProps): ReactNode — Radial / quick menu (weapon or emote wheel) — a ring or partial `arc` of selectable wedges the player points at with the mouse (or a stick). Pointer angle drives the highlight via core `radialIndexFromVector`; click/confirm fires `onSelect`, the neutral hub closes. Options carry optional hotkeys, count badges, cooldowns, and submenu markers. The game supplies icons/labels and skins it.
|
|
727
|
+
- `RadialMenuOption` (interface): interface RadialMenuOption — One selectable entry on a radial/quick menu (weapon or emote wheel).
|
|
728
|
+
- `RadialMenuProps` (interface): interface RadialMenuProps — Props for {@link RadialMenu}.
|
|
470
729
|
- `Rank` (type): type Rank = "A" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "J" | "Q" | "K" — A playing-card rank, ace through king.
|
|
471
730
|
- `ReadableEngineStore` (interface): interface ReadableEngineStore<TState> — ⚠ undocumented
|
|
472
731
|
- `RegionRecord` (interface): interface RegionRecord extends LayoutRegion — A region registration: the full `LayoutRegion` plus the live element (dev outlining), rect measured by the shell/react side.
|
|
473
732
|
- `RequireSession` (function): function RequireSession({ fallback, loading, children, }: { fallback?: ReactNode; loading?: ReactNode; children?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
474
733
|
- `RotateDeviceScreen` (function): function RotateDeviceScreen({ title = "Turn your device", description, requiredOrientation = "landscape", accent = "var(--jg-accent, #8ea2ff)", icon, className, style, }: { /** Short headline. */ title?: string; /** One concise explanatory line. Defaults from `requiredOrientation`. */ description?: … — Full-viewport, non-dismissible rotate-device gate shown when a game requires an orientation the device isn't in.
|
|
734
|
+
- `SETTINGS_TRIGGER_CLASSNAME` (const): const SETTINGS_TRIGGER_CLASSNAME: "pointer-events-auto flex h-8 w-8 items-center justify-center rounded-md border border-[var(--jg-edge-bright)] bg-[var(--jg-surface)]/80 text-base text-[var(--jg-text-dim)] shadow-[0_1px_2px_rgba(0,0,0,0.6)] transition hover:bg-[var(--jg-surface-deep)] hover:text-[v… — Default HudTheme-token skin for {@link SettingsTrigger} — the 8×8 chrome button games re-authored seven times. Pass your own `className` only to override placement or brand chrome; the gear glyph already scales with `text-base` / `1em`.
|
|
475
735
|
- `SUITS` (const): const SUITS: readonly Suit[] — Suits in canonical order (clubs, diamonds, hearts, spades).
|
|
736
|
+
- `SaveSlotMenu` (function): function SaveSlotMenu({ model, onLoad, onNew, onDelete, onContinue, title = "Select Save", theme, now = Date.now, metaIcons, className, style, }: SaveSlotMenuProps): ReactNode — A drop-in save-select / profile menu that renders a {@link SaveSlots} index as a column of cards. A filled slot shows its name, the free-string `meta` the game supplied as chips, and a relative "saved" time, with Load and Delete actions; an empty slot shows a "New Game" affordance. A top-level Continue button targets the newest save (`model.mostRecent()`). This is a starting-point game-front-end building block — the game owns final art, wording, and layout; reskin it with {@link SaveSlotMenuTheme} or HudTheme CSS vars. Presentation only: all state lives in the core model, and `meta` keys are never interpreted.
|
|
737
|
+
- `SaveSlotMenuProps` (interface): interface SaveSlotMenuProps — Props for {@link SaveSlotMenu}.
|
|
738
|
+
- `SaveSlotMenuTheme` (interface): interface SaveSlotMenuTheme — Reskin tokens for {@link SaveSlotMenu}. All optional — each falls back to a HudTheme var then a neutral default.
|
|
476
739
|
- `SaveStoreView` (interface): interface SaveStoreView<T> — The reactive slice of a {@link SaveStore} returned by {@link useSaveStore} — the live value plus bound save actions, all re-rendering on change.
|
|
740
|
+
- `Scoreboard` (function): function Scoreboard({ entries, rows, options, title, scoreLabel = "Score", nameFor, formatScore, medalIcon, theme, className, style, }: ScoreboardProps): ReactNode — A reskinnable ranked-score table for the {@link rankLeaderboard} selector: a rank column (medal icon/color for the top three via {@link medalFor}, otherwise the number), a name column, and a score column. The local player's row (`isLocal`) is washed and accented so "you" stands out. Feed it already-ranked `entries`, or raw `rows` plus `options` and it ranks them for you. All colors and spacing come from {@link ScoreboardTheme} / HudTheme `--jg-*` tokens — the component reads the model and never styles by game meaning.
|
|
741
|
+
- `ScoreboardProps` (interface): interface ScoreboardProps — Props for {@link Scoreboard}. Pass either `entries` (already ranked) or `rows` + `options`.
|
|
742
|
+
- `ScoreboardTheme` (interface): interface ScoreboardTheme — Reskin tokens for {@link Scoreboard}. Every color/spacing value reads a `--jg-*` token first.
|
|
477
743
|
- `Screen` (function): function Screen({ id, open = true, className, children, }: { id: string; open?: boolean; className?: string; children?: ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
478
744
|
- `SelectionCollectionChrome` (function): function SelectionCollectionChrome({ model, itemSize = 44, gap = 4, windowSize, scroll = 0, ariaLabel = "Selection", renderMember, renderGroup, onGroupSelect, className, style, }: { model: SelectionModel; itemSize?: number; gap?: number; /** Cap the mounted portraits; the model virtualizes past this… — The composable RENDERER for the member collection: a portrait strip for a small selection, or the same-kind group chips once the model is `grouped`. Roving tabindex + arrow-key focus. Swap `renderMember`/`renderGroup` for custom chrome, or read the model and lay it out yourself. No panel skin — a behavior/accessibility layer only.
|
|
479
745
|
- `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`.
|
|
480
746
|
- `SelectionKeyEvent` (interface): interface SelectionKeyEvent — A minimal keyboard-event shape — a real `KeyboardEvent`/React synthetic satisfies it.
|
|
481
747
|
- `SelectionModel` (interface): interface SelectionModel — The live selection model returned by {@link useSelectionView}.
|
|
482
748
|
- `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.
|
|
749
|
+
- `SequenceDirectorBinding` (interface): interface SequenceDirectorBinding extends SequenceState — The live playback state plus bound controls returned by {@link useSequenceDirector}.
|
|
483
750
|
- `SettingsActionView` (interface): interface SettingsActionView — A resolved game-state action — `run` is already bound to the game context and closes the menu.
|
|
484
751
|
- `SettingsCategoryView` (interface): interface SettingsCategoryView — A settings menu category with its rows and keybinds, ready to render.
|
|
485
752
|
- `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.
|
|
@@ -487,8 +754,11 @@
|
|
|
487
754
|
- `SettingsKeybindRow` (interface): interface SettingsKeybindRow — One rebindable action row rendered in the controls settings category.
|
|
488
755
|
- `SettingsProvider` (function): function SettingsProvider({ store, children }: { store: SettingsStore; children: ReactNode }): React.JSX.Element — ⚠ undocumented
|
|
489
756
|
- `SettingsRow` (interface): interface SettingsRow — One editable setting rendered in a settings menu category.
|
|
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`
|
|
757
|
+
- `SettingsTrigger` (function): function SettingsTrigger({ className = SETTINGS_TRIGGER_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` only when overriding the default HudTheme skin; pass `children` to replace the gear glyph. Renders nothing when the game has no settings to show, so it never leaves a dead button behind.
|
|
491
758
|
- `ShieldBar` (const): const ShieldBar: (props: AtomicBarProps) => React.JSX.Element — Absorb/armor shield overlay.
|
|
759
|
+
- `ShopGrid` (function): function ShopGrid({ shop, wallet, onWalletChange, theme, currencyIcons, iconFor, showSell = false, walletCurrencies, title = "Shop", labelFor, minCardWidth = "140px", className, style, }: ShopGridProps): ReactNode — A drop-in vendor/shop grid: item cards (icon, name, price with a currency glyph, stock count or "∞") over a caller-owned wallet, plus a wallet balance readout. Each card's Buy button disables when the wallet cannot afford it (`shop.canAfford`) or the item is sold out; an optional Sell button appears for entries with a `sellPrice`. Buying/selling routes through the core shop model and hands the debited/credited wallet back via `onWalletChange` — the component never owns the wallet. Purely token-driven presentation (shared `--jg-*` HudTheme tokens, reskinnable via {@link ShopGridTheme}); `kind` and `currency` are free strings the game styles, never interpreted.
|
|
760
|
+
- `ShopGridProps` (interface): interface ShopGridProps — Props for {@link ShopGrid}.
|
|
761
|
+
- `ShopGridTheme` (interface): interface ShopGridTheme — Reskin tokens for {@link ShopGrid}. Falls back to shared `--jg-*` HudTheme tokens, then neutral defaults.
|
|
492
762
|
- `SignOutButton` (function): function SignOutButton({ className, children, }: { className?: string; children?: ReactNode; }): React.JSX.Element | null — ⚠ undocumented
|
|
493
763
|
- `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
|
|
494
764
|
- `SlotGrid` (function): function SlotGrid({ inventoryId, className, renderSlot, }: { inventoryId: string; className?: string; renderSlot?: (slot: InventorySlot, index: number) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
@@ -507,8 +777,22 @@
|
|
|
507
777
|
- `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
778
|
- `StatRow` (interface): interface StatRow — One derived-stat row. `group` optionally buckets rows under a small header.
|
|
509
779
|
- `StatTone` (type): type StatTone = keyof typeof TONES — A stat tone — picks the bar's color ramp.
|
|
780
|
+
- `StatusEffectBar` (function): function StatusEffectBar({ effects, size = 44, gap = 8, iconFor, colorFor, schoolFor, labelFor, showTimer = true, ringWidth = 3, className, style, }: StatusEffectBarProps): ReactNode — A horizontal timeline of active status effects — one countdown-ring icon per effect. Presentation only and pure over its `effects` prop, so it renders straight off the status model's snapshot. `kind` is a free string the game styles (icon / color / label); the component never interprets buff-vs-debuff semantics. Ring, track, and frame read `HudTheme` tokens, so a theme change reskins the whole row.
|
|
781
|
+
- `StatusEffectBarProps` (interface): interface StatusEffectBarProps — Props for {@link StatusEffectBar}.
|
|
782
|
+
- `StatusIconResolver` (type): type StatusIconResolver = (kind: string) => GameIconName | ReactNode | null — `StatusEffectBar` (#status-effect-hud): a drop-in timeline HUD row that renders active buffs/debuffs as painted icons, each wrapped in a radial countdown ring and a stack-count badge, driven straight off the engine's existing status model (`StatusInstance` → `StatusEffectView`). A game passes its live effect views and gets a polished, reskinnable effect bar — no re-deriving ring math or timers. `kind` is a free string the game styles: the component never interprets buff-vs-debuff semantics, it only maps `kind` to an icon/color/label the game can fully override. Ring, track, and frame read `HudTheme` tokens (`--jg-accent`, `--jg-slot-*`), so a theme change reskins the whole row.
|
|
783
|
+
- `StreetGeometryPreview` (function): function StreetGeometryPreview({ className }: { className?: string }): React.JSX.Element — Deterministic close-up gallery of the shared road/junction mesh seam.
|
|
510
784
|
- `Suit` (type): type Suit = "clubs" | "diamonds" | "hearts" | "spades" — The four French-deck suits.
|
|
785
|
+
- `TalentIcon` (type): type TalentIcon = GameIconName | ReactNode | null — How a node id resolves to display art: a built-in {@link GameIconName}, any node, or `null` for the default.
|
|
786
|
+
- `TalentTree` (function): function TalentTree<TStat extends string = string>({ view: viewProp, nodes, tree, onLearn, icon, label, branchLabel, title = "Talents", variation = "themed", nodeSize = 54, columnGap = 30, tierGap = 46, showPoints = true, className, style, }: TalentTreeProps<TStat>): ReactNode — Drop-in talent / skill-tree widget over the existing progression model (`@jgengine/core/game/talents` + its `talentTreeView` selector). The game passes its node definitions and a live `createTalentTree` instance; the widget lays nodes out by branch column and prerequisite-depth tier, draws SVG prerequisite edges, styles each node learned/available/locked/maxed, shows an icon + rank badge, and calls `onLearn(nodeId)` when the player clicks a node that is currently allocatable. All layout, edge-drawing, and eligibility come from the model/selector — the widget never re-derives topology. Unskinned and HudTheme-token driven; node ids/branches are opaque game data the game supplies icons and labels for.
|
|
787
|
+
- `TalentTreeProps` (interface): interface TalentTreeProps<TStat extends string = string> — Props for {@link TalentTree}.
|
|
788
|
+
- `TimerFormat` (type): type TimerFormat = "mm:ss" | "m:ss.d" | "ss.d" — Digital text format for a timer readout.
|
|
789
|
+
- `TimerReadout` (function): function TimerReadout({ timer, id, source = "auto", format = "mm:ss", placeholder = "--:--", active = true, className, style, }: TimerReadoutProps): ReactNode — A live digital timer readout (mm:ss / m:ss.d) driven off a {@link TimerSet}. It re-reads every frame and formats remaining or elapsed time — a round clock, a respawn countdown, or an ability charge, all the same widget. HudTheme-skinned via `--jg-bar-text`; reskin with `style` or the theme tokens.
|
|
790
|
+
- `TimerReadoutProps` (interface): interface TimerReadoutProps — Props for {@link TimerReadout}.
|
|
791
|
+
- `TimerReadoutSource` (type): type TimerReadoutSource = "auto" | "remaining" | "elapsed" — Which value a readout leads with. `"auto"` follows the timer's direction — remaining for a countdown, elapsed for a countup charge.
|
|
792
|
+
- `TimerRing` (function): function TimerRing({ timer, id, size = 72, thickness = 8, mode = "fill", color = "var(--jg-accent, #38bdf8)", trackColor = "var(--jg-bar-track, rgba(148,163,184,0.25))", children, active = true, className, style, }: TimerRingProps): ReactNode — A radial charge/cooldown ring driven off a {@link TimerSet}'s `progress01`. Re-reads every frame and sweeps an SVG arc as the timer advances — ability charge, cooldown wipe, respawn ring, capture progress, all the same widget. `mode` chooses filling vs. draining; center `children` can hold a readout. HudTheme-skinned via `--jg-accent` / `--jg-bar-track`.
|
|
793
|
+
- `TimerRingProps` (interface): interface TimerRingProps — Props for {@link TimerRing}.
|
|
511
794
|
- `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.
|
|
795
|
+
- `Trans` (function): function Trans({ k, params }: { k: string; params?: TParams }): ReactNode — Render a translated message inline: `<Trans k="hud.score" params={{ value }} />`.
|
|
512
796
|
- `UseActionBarOptions` (interface): interface UseActionBarOptions — Options for {@link useActionBar}.
|
|
513
797
|
- `UseAxisChannelResult` (interface): interface UseAxisChannelResult — ⚠ undocumented
|
|
514
798
|
- `UsePanelsOptions` (interface): interface UsePanelsOptions — Options for {@link usePanels}.
|
|
@@ -520,13 +804,23 @@
|
|
|
520
804
|
- `VoiceRoster` (function): function VoiceRoster({ voice, className, participantClassName, renderParticipant, }: { voice: VoiceState; className?: string; participantClassName?: string; renderParticipant?: (participant: VoiceParticipant, gain: number) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
521
805
|
- `VoiceState` (interface): interface VoiceState — ⚠ undocumented
|
|
522
806
|
- `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.
|
|
807
|
+
- `WaveHud` (function): function WaveHud({ runner, theme, variation = "plate", width = 260, className, style }: WaveHudProps): ReactNode — A drop-in wave/spawn HUD panel over a {@link WaveRunner}: a big "WAVE N" label, a wave-progress bar (the shared {@link ExperienceBar}), and the live spawned / total, budget, and alert readouts — the visible face of "the brain behind WAVE 3". It subscribes to the runner and re-renders on change; the game drives the runner's clock. Reskin with {@link WaveHudTheme} and the shared HudTheme bar tokens. When the final wave finishes it shows a "WAVES CLEARED" state. Presentation only: the schedule, budget, and RNG live in the core model, and spawn `kind`s are never read.
|
|
808
|
+
- `WaveHudProps` (interface): interface WaveHudProps — Props for {@link WaveHud}.
|
|
809
|
+
- `WaveHudTheme` (interface): interface WaveHudTheme — Reskin tokens for {@link WaveHud}. All optional; each falls back to a sensible default.
|
|
810
|
+
- `WaypointArrow` (function): function WaypointArrow({ relative, distance, label, formatDistance = (value) => `${Math.round(value)}m`, size = 44, color = "#f59e0b", className, style, }: WaypointArrowProps): ReactNode — On-screen guide arrow to the tracked waypoint — a HUD compass needle rotated by the facing-relative bearing, with an optional label and distance readout. Pair with `WaypointStore.guidance(playerXZ, facingYaw)`.
|
|
811
|
+
- `WaypointArrowProps` (interface): interface WaypointArrowProps — Props for {@link WaypointArrow}.
|
|
812
|
+
- `WaypointMarkerTheme` (interface): interface WaypointMarkerTheme — Reskin tokens for {@link WaypointMarkers}. Per-`kind` color layers on top via `kindColors`.
|
|
813
|
+
- `WaypointMarkers` (function): function WaypointMarkers({ entries, project, viewport, distanceOf, distanceFormat, theme, kindColors, margin = 28, showPinLabels = true, className, style, }: WaypointMarkersProps): ReactNode — Off-screen objective / waypoint markers: an absolutely-positioned overlay that turns a set of world waypoints into on-screen pins and off-screen directional arrows. For each waypoint it calls the caller's `project` to get a screen point, then {@link layoutScreenMarker} to decide: an in-view target renders a pin (and optional label) at its projected spot; an off-screen or behind-camera target renders an arrow clamped to the viewport edge, rotated to point the way, with an optional distance label from `distanceOf`. Color comes from `theme` plus a per-`kind` `kindColors` map the game owns — the model never interprets `kind`. Presentation only: tracking, projection, and distance are all caller-supplied.
|
|
814
|
+
- `WaypointMarkersProps` (interface): interface WaypointMarkersProps — Props for {@link WaypointMarkers}.
|
|
523
815
|
- `WeaponSlots` (function): function WeaponSlots(props: SlotGridProps): React.JSX.Element — Weapon loadout slots.
|
|
524
816
|
- `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.
|
|
525
817
|
- `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
|
|
526
818
|
- `WorldBrowserState` (interface): interface WorldBrowserState — ⚠ undocumented
|
|
527
819
|
- `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
|
|
528
|
-
- `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`.
|
|
820
|
+
- `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`. Framed panel wrapper over {@link WorldMapSurface}.
|
|
529
821
|
- `WorldMapProps` (interface): interface WorldMapProps — ⚠ undocumented
|
|
822
|
+
- `WorldMapSurface` (function): function WorldMapSurface({ markers, bounds, player, facingYaw = 0, fog, background, width = 520, height, kindStyles = DEFAULT_MARKER_KINDS, routes, zones, cellStates, onWorldClick, canvasWidth, canvasHeight, viewport = IDENTITY_VIEWPORT, style, }: WorldMapSurfaceProps): ReactNode — The bare top-down map `<svg>` shared by {@link WorldMap} (framed panel) and {@link FullscreenMap} (pan/zoom overlay): baked terrain background, fog, map layers, markers with labels, and the player arrow, drawn under an optional viewport transform. Rectangular linear projection over the world `bounds`.
|
|
823
|
+
- `WorldMapSurfaceProps` (interface): interface WorldMapSurfaceProps — Props for {@link WorldMapSurface}.
|
|
530
824
|
- `abilityKitNeedsHeartbeat` (function): function abilityKitNeedsHeartbeat(kit: AbilityKit, resourceAvailable?: number): boolean — ⚠ undocumented
|
|
531
825
|
- `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.
|
|
532
826
|
- `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.
|
|
@@ -537,16 +831,24 @@
|
|
|
537
831
|
- `createHeldKeyTracker` (function): function createHeldKeyTracker(target: HeldKeyEventTarget): { isDown: (code: string) => boolean; dispose: () => void; } — ⚠ undocumented
|
|
538
832
|
- `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
833
|
- `defaultHudTheme` (const): const defaultHudTheme: HudTheme — Default theme tokens for previews/scaffold — not a finished game look; author a custom theme.
|
|
834
|
+
- `deriveHudTheme` (function): function deriveHudTheme(seed: HudThemeSeed): HudTheme — Derives a coherent full theme from an accent/surface pair — shades, edges, dim text, frames, bar troughs, and slots all fall out of the seed, so a game gets one consistent look across the `packages/react` primitives and the `registry/jgengine` blocks without naming 50 tokens. Hex seeds only (`#rgb` or `#rrggbb`).
|
|
540
835
|
- `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.
|
|
836
|
+
- `formatTimerMs` (function): function formatTimerMs(ms: number, format: TimerFormat = "mm:ss"): string — Format a millisecond duration as digital timer text — `mm:ss` (default), `m:ss.d` (with tenths), or `ss.d` (seconds + tenths). Negative inputs clamp to zero. No genre meaning: the same helper serves a round clock, a respawn countdown, or an ability charge readout.
|
|
541
837
|
- `guestIdentity` (function): function guestIdentity(seed?: string): IdentitySource — ⚠ undocumented
|
|
838
|
+
- `hudTheme` (function): function hudTheme(overrides: HudThemeOverrides): HudTheme — Builds a full {@link HudTheme} from per-group partials, filling the rest from {@link defaultHudTheme}. Reach for this when a game wants to name exact values; use {@link deriveHudTheme} when a seed color pair is enough.
|
|
542
839
|
- `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.
|
|
543
840
|
- `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).
|
|
544
841
|
- `isRedSuit` (function): function isRedSuit(suit: Suit): boolean — True for the red suits (hearts, diamonds).
|
|
545
842
|
- `latestChatBubbles` (function): function latestChatBubbles(messages: readonly ChatMessage[], nowMs: number, ttlMs: number): ChatBubble[] — ⚠ undocumented
|
|
843
|
+
- `layoutEntityFrames` (function): function layoutEntityFrames<E extends EntityFrameEntry>(entries: readonly E[], project: ProjectEntity, options: EntityFrameLayoutOptions = {}): EntityFramePlacement<E>[] — Pure layout core: projects each entry, drops the ones behind the camera, off-screen (when `viewport` is set), or beyond `maxCount`, and returns the survivors sorted farthest-first so nearer frames render last (on top). Stable for equal depths via `id`. No React, no DOM — unit-testable in isolation.
|
|
844
|
+
- `layoutFloatingText` (function): function layoutFloatingText(views: readonly FloatingTextView[], project: ProjectEntity, options: FloatingTextLayoutOptions = {}): FloatingTextPlacement[] — Pure layout core: projects each view, drops the ones behind the camera or (when `viewport` is set) off-screen, and returns the survivors sorted farthest-first so nearer text paints on top. No React, no DOM — unit-testable.
|
|
546
845
|
- `localPlayerEntity` (function): function localPlayerEntity(ctx: GameContext): SceneEntity | null — ⚠ undocumented
|
|
547
846
|
- `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.
|
|
847
|
+
- `previewFixtureNames` (function): function previewFixtureNames(): string[] — Sorted list of registered fixture names, for discovery/listing.
|
|
848
|
+
- `relativeSavedAt` (function): function relativeSavedAt(savedAt: number, nowMs = Date.now()): string — Turn a `savedAt` timestamp into a compact relative label ("just now", "4m ago", "2d ago"). Presentation-only helper — the model stores raw ms.
|
|
548
849
|
- `resolveDialogueInvoke` (function): function resolveDialogueInvoke(choice: DialogueChoice, result: CheckResult | null): { command: string; args?: unknown } | null — ⚠ undocumented
|
|
549
850
|
- `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.
|
|
851
|
+
- `resolvePreviewFixture` (function): function resolvePreviewFixture(name: string): PreviewFixture | undefined — Resolve a fixture by name, or `undefined` when it is not registered.
|
|
550
852
|
- `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
853
|
- `schoolForAction` (function): function schoolForAction(action: string): IconSchool — Infers an {@link IconSchool} from an action id (keyword match); `neutral` when nothing matches.
|
|
552
854
|
- `schoolForItem` (function): function schoolForItem(itemId: string): IconSchool — Infers an {@link IconSchool} from an item id (keyword match); `neutral` when nothing matches.
|
|
@@ -554,17 +856,29 @@
|
|
|
554
856
|
- `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.
|
|
555
857
|
- `useAbilitySlot` (function): function useAbilitySlot(kit: AbilityKit, slotId: string, resourceAvailable?: number, options?: AbilitySlotBindingOptions): AbilitySlotSnapshot | null — ⚠ undocumented
|
|
556
858
|
- `useAbilitySlots` (function): function useAbilitySlots(kit: AbilityKit, resourceAvailable?: number, options?: AbilitySlotBindingOptions): AbilitySlotSnapshot[] — ⚠ undocumented
|
|
859
|
+
- `useAccessibility` (function): function useAccessibility(): AccessibilityContextValue — Read the live accessibility state + its store; throws without an {@link AccessibilityProvider} above.
|
|
860
|
+
- `useAchievements` (function): function useAchievements(tracker: AchievementTracker): readonly AchievementView[] — Subscribe a component to an achievement tracker's live view list. The list keeps a stable identity between changes, so this re-renders only on unlock or progress — not every frame.
|
|
557
861
|
- `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.
|
|
558
862
|
- `useActivePrompt` (function): function useActivePrompt<T extends PositionedPrompt>(prompts?: readonly T[]): T | null — ⚠ undocumented
|
|
559
863
|
- `useAuthedPlayer` (function): function useAuthedPlayer(options?: { guestSeed?: string }): PlayerIdentity | null — ⚠ undocumented
|
|
864
|
+
- `useAutoScroll` (function): function useAutoScroll<T extends HTMLElement>(dep: unknown): React.RefObject<T | null> — Pin a scrollable element to its bottom whenever `dep` changes (typically a length or the list itself). Attach the returned ref to the scroll container. Owns the log/chat/console scroll-to-bottom effect so panels don't hand-roll it.
|
|
560
865
|
- `useAxisChannel` (function): function useAxisChannel(config: AxisChannelConfig): UseAxisChannelResult — Wires useHeldKeys into a fresh AxisChannel, ready for a per-frame `channel.sample(dt, isDown)`. The channel is recreated when `config` identity changes, so pass a stable config (useMemo/module constant at the call site) unless a rebind is intended.
|
|
866
|
+
- `useCameraShake` (function): function useCameraShake(controller: CameraShakeController, animate = true): CameraShakeReadout — Subscribe to a camera-shake controller and re-render on every change (add / decay / clear). Optionally drives `update()` on an animation frame so the trauma meter bleeds down live even when no game loop ticks the controller. Returns the current trauma + kind for a HUD readout.
|
|
561
867
|
- `useChat` (function): function useChat(channelId: string, options?: { limit?: number }): ChatMessage[] — ⚠ undocumented
|
|
562
868
|
- `useChatBubbles` (function): function useChatBubbles(options?: ChatBubblesOptions): readonly ChatBubble[] — ⚠ undocumented
|
|
869
|
+
- `useCoachMarks` (function): function useCoachMarks(sequence: CoachMarkSequence): CoachMarkView | null — Subscribe to a coach-mark sequence and re-render on every change, returning the current step view (or `null` when the tour is complete or waiting on a gate).
|
|
870
|
+
- `useComboMeter` (function): function useComboMeter(meter: ComboMeter, animate = true): ComboMeterView — Subscribe to a combo meter and re-render it each animation frame so the decay window bar drains live, returning the pooled view to draw right now. Reading the view each frame advances the meter's clock and fires window expiry, so a combo that times out visibly drops even with no further hits. The returned object is the model's pooled view — read its fields immediately, do not retain it.
|
|
563
871
|
- `useCurrency` (function): function useCurrency(currencyId: string): number — ⚠ undocumented
|
|
872
|
+
- `useDamageDirection` (function): function useDamageDirection(tracker: DamageDirectionTracker): readonly DamageIndicator[] — Subscribe to a damage-direction tracker and animate. Because indicators fade continuously on a clock (not just on discrete events), this drives a `requestAnimationFrame` loop while any indicator is live and stops when the screen is clear, then wakes again on the next hit. Returns the tracker's current `active()` array (reused between frames — copy if you retain it).
|
|
873
|
+
- `useDebouncedCommit` (function): function useDebouncedCommit<T>(value: T, commit: (value: T) => void, delayMs = 180): DebouncedCommit<T> — See {@link DebouncedCommit}. `commit` and `delayMs` may change between renders (kept in refs); the binding identity stays stable except when `value` (the local mirror) changes.
|
|
874
|
+
- `useDialogueRun` (function): function useDialogueRun(run: DialogueRun): DialogueGraphView | null — Subscribe to a {@link DialogueRun} and re-render on every advance / jump / reset, returning the current node view (or `null` if the run's node id is unknown).
|
|
875
|
+
- `useDomEvent` (function): function useDomEvent<E>(resolveTarget: () => DomEventTarget | null, type: string, handler: (event: E) => void, options?: { capture?: boolean; passive?: boolean }): void — Attach a DOM event listener with automatic cleanup. `resolveTarget` runs inside the effect, so `() => window` and ref-reading resolvers are SSR-safe; return null to skip attaching. The handler is kept in a ref, so a fresh closure per render never re-binds the listener. Re-binds only when `type` or `options.capture`/`options.passive` change.
|
|
564
876
|
- `useDragLayer` (function): function useDragLayer<T>(options?: { onDrop?: (info: DropInfo<T>) => void; }): DragLayer<T> — ⚠ undocumented
|
|
565
877
|
- `useEntityChatBubble` (function): function useEntityChatBubble(instanceId: string, options?: ChatBubblesOptions): ChatBubble | null — ⚠ undocumented
|
|
566
878
|
- `useEntityStat` (function): function useEntityStat(instanceId: string, statId: string): StatValue | null — ⚠ undocumented
|
|
567
879
|
- `useEventMeter` (function): function useEventMeter(meter: EventMeter, options?: AbilitySlotBindingOptions): EventMeterView — Bind a `createEventMeter` (`@jgengine/core/stats/eventMeter`) heat/streak gauge to a component — the react-render half of the ult/adrenaline and streak/combo meters (`event-meter` capability) that lets a HUD gauge re-render on tick without the game hand-rolling a `useEffect`/`setInterval` heartbeat around `meter.value()`.
|
|
880
|
+
- `useEventTicker` (function): function useEventTicker(ticker: EventTicker, animate = true): EventTickerView[] — Subscribe to an event ticker and re-render it on an animation frame (unless the game already ticks it), returning the live entries newest-first with `fade` applied. Driving the frame loop is what makes entries visibly fade and drop as they age out.
|
|
881
|
+
- `useFastTravel` (function): function useFastTravel<TMeta = unknown>(network: FastTravelNetwork<TMeta>): FastTravelNetwork<TMeta> — Subscribe a component to a fast-travel network's discovery changes. Returns the network unchanged; the hook only forces a re-render when a point is discovered or the network is restored, so callers can read `destinations`/`list` in render.
|
|
568
882
|
- `useFeed` (function): function useFeed({ action, limit }: { action: string; limit?: number }): FeedEntry[] — ⚠ undocumented
|
|
569
883
|
- `useFog` (function): function useFog(fog: FogField): ReturnType<FogField["cells"]> — ⚠ undocumented
|
|
570
884
|
- `useFriendRequests` (function): function useFriendRequests(): FriendRequestEntry[] — ⚠ undocumented
|
|
@@ -583,6 +897,8 @@
|
|
|
583
897
|
- `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
898
|
- `useHudLayoutPersist` (function): function useHudLayoutPersist(): HudLayoutPersist | null — Injected panel-commit port, or `null` when no host has provided one.
|
|
585
899
|
- `useHudViewport` (function): function useHudViewport(): HudViewportContextValue | null — ⚠ undocumented
|
|
900
|
+
- `useI18n` (function): function useI18n(): I18n — Read the current {@link I18n} from context; throws when no {@link I18nProvider} is above.
|
|
901
|
+
- `useInteractionPrompt` (function): function useInteractionPrompt(registry: PromptRegistry, playerPosition: PromptPoint): PositionedPrompt | null — Subscribe to a {@link PromptRegistry} and re-`resolve` it whenever the player moves, returning the prompt to draw right now — or `null` when the player is out of range of every interactable. The registry notifies only on active-prompt *changes*, so this re-renders on transitions rather than every frame the hero moves. Feed it the player's `{ x, z }` position each frame; identical positions do no work.
|
|
586
902
|
- `useInventory` (function): function useInventory(inventoryId: string): readonly InventorySlot[] — ⚠ undocumented
|
|
587
903
|
- `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).
|
|
588
904
|
- `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)`.
|
|
@@ -590,38 +906,70 @@
|
|
|
590
906
|
- `useLeaderboard` (function): function useLeaderboard(stat: string, options: { scope: LeaderboardScope; limit?: number }): { userId: string; value: number }[] — ⚠ undocumented
|
|
591
907
|
- `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.
|
|
592
908
|
- `useLocalPlayerDead` (function): function useLocalPlayerDead(healthStatId = "health"): boolean — ⚠ undocumented
|
|
909
|
+
- `useLocale` (function): function useLocale(): Locale — Subscribe to the active locale — re-renders on `setLocale`.
|
|
593
910
|
- `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.
|
|
911
|
+
- `useModalStack` (function): function useModalStack(stack: ModalStack): ModalStackView — Subscribe to a modal stack and re-render on every change, returning the active modal and depth.
|
|
594
912
|
- `useNearestWorldItem` (function): function useNearestWorldItem(radius: number): WorldItemRecord | null — Nearest ground item within `radius` of the local player — drives a pickup prompt/highlight.
|
|
913
|
+
- `useNotifications` (function): function useNotifications<TMeta = unknown>(store: NotificationStore<TMeta>): readonly NotificationEntry<TMeta>[] — Subscribe to a notification store's live list.
|
|
914
|
+
- `useObjectiveBanner` (function): function useObjectiveBanner(controller: ObjectiveBannerController, animate = true): ObjectiveBannerView | null — Subscribe to a banner controller, drive its clock on an animation frame (unless the game already ticks it), and return the banner to draw right now — or `null` when idle. Re-renders every frame while a banner is animating.
|
|
595
915
|
- `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.
|
|
596
916
|
- `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).
|
|
597
917
|
- `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
918
|
- `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.
|
|
599
919
|
- `useParty` (function): function useParty(): PartyMemberEntry[] — ⚠ undocumented
|
|
600
920
|
- `usePartyInvites` (function): function usePartyInvites(): PartyInviteEntry[] — ⚠ undocumented
|
|
921
|
+
- `usePhotoMode` (function): function usePhotoMode(store: PhotoModeStore): PhotoModeState — Subscribe to a photo-mode store's live state.
|
|
601
922
|
- `usePlayer` (function): function usePlayer(): { userId: string; isNew: boolean } — ⚠ undocumented
|
|
923
|
+
- `usePlural` (function): function usePlural(): (key: string, count: number, params?: TParams) => string — Return the plural-aware translator bound to the current locale.
|
|
924
|
+
- `usePrefersReducedMotion` (function): function usePrefersReducedMotion(): boolean — OS "reduce motion" preference (`prefers-reduced-motion: reduce`) as a live boolean — SSR-safe (defaults false). Use it to seed an accessibility store's `reducedMotion` default.
|
|
602
925
|
- `usePresence` (function): function usePresence(userId: string): PresenceInfo — ⚠ undocumented
|
|
603
926
|
- `useQuestJournal` (function): function useQuestJournal(): QuestInstance[] — ⚠ undocumented
|
|
927
|
+
- `useRafLoop` (function): function useRafLoop(onFrame: (deltaSeconds: number) => void, active = true): void — Run a requestAnimationFrame loop while `active`, calling `onFrame(deltaSeconds)` each frame. The callback is kept in a ref so re-renders never restart the loop; cleanup cancels the pending frame. For scene-graph work inside a canvas prefer R3F's useFrame — this is for DOM-side animation outside the renderer.
|
|
928
|
+
- `useRebindSession` (function): function useRebindSession(session: RebindSession): RebindSession — Subscribe to a rebind session and re-render on every change (capture, reset, arm/disarm, restore). Returns the session unchanged for convenient inline use.
|
|
604
929
|
- `useRegisterLayoutRegion` (function): function useRegisterLayoutRegion(spec: LayoutRegionSpec, ref: RefObject<HTMLElement | null>, enabled = true): void — Register the element behind `ref` as a layout region and keep its measured rectangle live (ResizeObserver + viewport changes). No-op outside a `GameViewportProvider`, so a component using it still works in isolation.
|
|
605
930
|
- `useReservedControlZones` (function): function useReservedControlZones(): readonly LayoutRect[] — Rectangles reserved by touch controls and system UI — HUD placement should avoid these.
|
|
606
931
|
- `useRoster` (function): function useRoster(userId?: string): readonly RosterEntry[] — ⚠ undocumented
|
|
932
|
+
- `useSaveSlots` (function): function useSaveSlots(model: SaveSlots): SaveSlotMeta[] — Subscribe to a {@link SaveSlots} index and re-render on any change (write, clear, rename, restore). Returns the live list of slots in menu order. Wire it into a save-select screen and mutate the model in event handlers — the menu re-renders itself.
|
|
607
933
|
- `useSaveStore` (function): function useSaveStore<T>(store: SaveStore<T>, options?: { load?: boolean }): SaveStoreView<T> — Bind a {@link SaveStore} to React: returns the live `value` and `status` and re-renders whenever either changes. By default it calls `load()` once on mount (pass `{ load: false }` to hydrate yourself). The same hook works for offline (localStorage) and cloud (Convex/DB) saves — only the store's backend differs.
|
|
608
934
|
- `useSceneEntities` (function): function useSceneEntities(): readonly SceneEntity[] — ⚠ undocumented
|
|
609
935
|
- `useSceneEntityIds` (function): function useSceneEntityIds(): readonly string[] — Membership-only entity id list: the returned array keeps a stable identity across per-frame pose writes and only changes when an entity spawns, despawns, or the store is hydrated (#625). A marker mapped from these ids reads its own live pose imperatively (useFrame), so the actor tree no longer re-reconciles every frame. Prefer this over {@link useSceneEntities} for large scenes.
|
|
610
936
|
- `useSceneObjectIds` (function): function useSceneObjectIds(): readonly string[] — Membership-only object id list — the object counterpart of {@link useSceneEntityIds}; stable across move/rotate/setVisual, changes only on place/remove.
|
|
611
937
|
- `useSceneObjects` (function): function useSceneObjects(): readonly SceneObject[] — ⚠ undocumented
|
|
612
938
|
- `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.
|
|
939
|
+
- `useSequenceDirector` (function): function useSequenceDirector(director: SequenceDirector): SequenceDirectorBinding — Bind a {@link SequenceDirector} to a component: subscribe to its state, and while it is playing run a `requestAnimationFrame` loop that ticks the director each frame off the same injected clock — so a game drops in one hook and the cutscene advances itself. Returns the current playback state (playhead, progress, playing/done) plus bound `play`/`pause`/`skip`/`seek`/`stop`. Cue side effects belong on `director.onCue`, not here — the hook never interprets a cue.
|
|
613
940
|
- `useSession` (function): function useSession(): IdentitySource — ⚠ undocumented
|
|
614
941
|
- `useSetting` (function): function useSetting<T extends SettingValue>(id: string, fallback: T): readonly [T, (value: SettingValue) => void] — Read + write one persisted setting; re-renders when the value changes anywhere.
|
|
615
942
|
- `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.
|
|
616
943
|
- `useSettingsStore` (function): function useSettingsStore(): SettingsStore — The shared settings store, or a standalone one when no provider is mounted (game code read outside the shell).
|
|
944
|
+
- `useShopStock` (function): function useShopStock(shop: ShopStock): ShopStockEntry[] — Subscribe to a shop's stock and re-render whenever it changes (buy, sell, restock, price, add, remove, restore). Returns the current entry list — a detached snapshot safe to map over.
|
|
617
945
|
- `useStore` (function): function useStore<T>(handle: StoreHandle<T>): T — Subscribe a component to a typed store slot defined with `defineStore`. Returns the current value (or the definition's initial before any write), re-rendering only when the slot changes — the cast-free, boilerplate-free replacement for a hand-written `useGameStore((ctx) => ctx.game.store.get(KEY) as T)`.
|
|
946
|
+
- `useT` (function): function useT(): (key: string, params?: TParams) => string — Return the translator bound to the current locale; the component re-renders when `setLocale` is called, so returned strings stay live.
|
|
618
947
|
- `useTarget` (function): function useTarget(fromInstanceId: string): string | null — ⚠ undocumented
|
|
948
|
+
- `useTicker` (function): function useTicker(hz = 10): number — Re-render at a steady rate. Returns a monotonically increasing tick count driven by a setInterval, for HUD elements that display wall-clock-derived values (cooldowns, cast bars, swing timers) without an engine subscription to hang off. `hz <= 0` disables the ticker.
|
|
949
|
+
- `useTimerRead` (function): function useTimerRead(timer: TimerSet, id: string, active = true): TimerRead | null — Subscribe to a single timer and re-read it every animation frame while mounted, so a HUD readout stays live without the game hand-rolling interval math. Reuses one read object (allocation-aware). Returns `null` for an unknown id. Pass `active={false}` to freeze the per-frame tick (e.g. an off-screen HUD).
|
|
619
950
|
- `useViewportMetrics` (function): function useViewportMetrics(): ViewportMetrics — Live visible viewport, tracking `window.visualViewport` (mobile browser chrome, pinch-zoom) with a layout-viewport fallback.
|
|
620
951
|
- `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.
|
|
952
|
+
- `useWaveRunner` (function): function useWaveRunner(runner: WaveRunner): WaveView — Subscribe to a {@link WaveRunner} and re-render whenever it notifies (wave, budget, spawns, alert change). Returns the runner's pooled {@link WaveView}. The runner is driven by the game/demo (call `runner.update(dt)`), not by this hook.
|
|
953
|
+
- `useWaypoints` (function): function useWaypoints(source: WaypointTracker | readonly Waypoint[]): readonly Waypoint[] — Subscribe to a {@link WaypointTracker} and re-render on every change, returning its current waypoints. Pass a plain array instead and it is returned as-is (no subscription), so a game can drive the host from a tracker or from its own derived state.
|
|
621
954
|
- `useWorldBrowser` (function): function useWorldBrowser(options: { fetchSessions: () => Promise<readonly SessionListing[]>; filter?: MatchFilter; limit?: number; refreshMs?: number; }): WorldBrowserState — Polls a host-supplied session fetcher (e.g. createWsBackend().browse) and filters through matchmaking's browseSessions. fetchSessions must be identity-stable (wrap in useCallback at the call site) or every render refetches.
|
|
622
955
|
- `useWorldInvites` (function): function useWorldInvites(): WorldInvite[] — ⚠ undocumented
|
|
623
956
|
- `useWorldItems` (function): function useWorldItems(): readonly WorldItemRecord[] — ⚠ undocumented
|
|
624
957
|
|
|
958
|
+
## @jgengine/react/accessibility
|
|
959
|
+
|
|
960
|
+
- `AccessibilityProvider` (function): function AccessibilityProvider({ store, children, className, style, }: { store: AccessibilityStore; children: ReactNode; className?: string; style?: CSSProperties; }): ReactNode — Apply accessibility preferences to a subtree: exposes `--jg-text-scale` for text to scale off, sets `data-reduced-motion` / `data-high-contrast` / `data-colorblind` / `data-captions` for CSS to respond to, and wraps the tree in the selected colorblind `feColorMatrix` filter. Reads a `createAccessibilityStore` and re-renders on change; provides the state to `useAccessibility`.
|
|
961
|
+
- `ColorblindFilters` (function): function ColorblindFilters(): ReactNode — Hidden SVG `<defs>` holding the `feColorMatrix` colorblind filters that `AccessibilityProvider` references by `filter: url(#jg-cb-<mode>)`. Rendered automatically inside the provider; export standalone for custom roots.
|
|
962
|
+
- `useAccessibility` (function): function useAccessibility(): AccessibilityContextValue — Read the live accessibility state + its store; throws without an {@link AccessibilityProvider} above.
|
|
963
|
+
- `usePrefersReducedMotion` (function): function usePrefersReducedMotion(): boolean — OS "reduce motion" preference (`prefers-reduced-motion: reduce`) as a live boolean — SSR-safe (defaults false). Use it to seed an accessibility store's `reducedMotion` default.
|
|
964
|
+
|
|
965
|
+
## @jgengine/react/achievements
|
|
966
|
+
|
|
967
|
+
- `AchievementGallery` (function): function AchievementGallery({ achievements, title = "Achievements", maskSecrets = true, renderIcon, columns = 2, emptyLabel = "No achievements yet.", className, style, }: AchievementGalleryProps): ReactNode — Achievement/trophy gallery — a responsive grid of cards showing unlocked vs. locked state, a progress bar for counter achievements, and a header summary of completion and score. Secret+locked entries mask their name/description. Feed it `useAchievements(tracker)`.
|
|
968
|
+
- `AchievementGalleryProps` (interface): interface AchievementGalleryProps — Props for {@link AchievementGallery}.
|
|
969
|
+
- `AchievementToast` (function): function AchievementToast({ name, description, icon, points, heading = "Achievement Unlocked", className, style, }: AchievementToastProps): ReactNode — The unlock-moment banner — icon, "Achievement Unlocked" heading, name, and optional points. Purely presentational; pair the game's `onUnlock` seam with a toast queue and render one of these per entry.
|
|
970
|
+
- `AchievementToastProps` (interface): interface AchievementToastProps — Props for {@link AchievementToast}.
|
|
971
|
+
- `useAchievements` (function): function useAchievements(tracker: AchievementTracker): readonly AchievementView[] — Subscribe a component to an achievement tracker's live view list. The list keeps a stable identity between changes, so this re-renders only on unlock or progress — not every frame.
|
|
972
|
+
|
|
625
973
|
## @jgengine/react/actionHud
|
|
626
974
|
|
|
627
975
|
- `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.
|
|
@@ -658,6 +1006,13 @@
|
|
|
658
1006
|
|
|
659
1007
|
- `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
1008
|
|
|
1009
|
+
## @jgengine/react/cameraShake
|
|
1010
|
+
|
|
1011
|
+
- `CameraShakeMeter` (function): function CameraShakeMeter({ controller, animate = false, title = "CAMERA SHAKE", kindLabels, variation = "glass", className, style, }: CameraShakeMeterProps): ReactNode — A drop-in HUD panel that visualizes a core {@link CameraShakeController}: a trauma meter (reusing the shared {@link StaminaBar} building block) plus a live percentage and the current impact `kind` label. Presentation only — it reads the controller and never interprets `kind`, mapping it through `kindLabels` for display. A shell component applies the same controller's `offset()` to the camera; this panel is the on-screen readout of how much shake is in flight.
|
|
1012
|
+
- `CameraShakeMeterProps` (interface): interface CameraShakeMeterProps — Props for {@link CameraShakeMeter}.
|
|
1013
|
+
- `CameraShakeReadout` (interface): interface CameraShakeReadout — A live read of a camera-shake controller: current trauma `0..1` and the last game-owned `kind`.
|
|
1014
|
+
- `useCameraShake` (function): function useCameraShake(controller: CameraShakeController, animate = true): CameraShakeReadout — Subscribe to a camera-shake controller and re-render on every change (add / decay / clear). Optionally drives `update()` on an animation frame so the trauma meter bleeds down live even when no game loop ticks the controller. Returns the current trauma + kind for a HUD readout.
|
|
1015
|
+
|
|
661
1016
|
## @jgengine/react/cards
|
|
662
1017
|
|
|
663
1018
|
- `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`.
|
|
@@ -701,6 +1056,27 @@
|
|
|
701
1056
|
- `useChatBubbles` (function): function useChatBubbles(options?: ChatBubblesOptions): readonly ChatBubble[] — ⚠ undocumented
|
|
702
1057
|
- `useEntityChatBubble` (function): function useEntityChatBubble(instanceId: string, options?: ChatBubblesOptions): ChatBubble | null — ⚠ undocumented
|
|
703
1058
|
|
|
1059
|
+
## @jgengine/react/coachMarks
|
|
1060
|
+
|
|
1061
|
+
- `CoachMark` (function): function CoachMark({ view, positionStyle, onNext, onSkip, nextLabel = "Next", doneLabel = "Got it", skipLabel = "Skip tour", theme, className, style, }: CoachMarkProps): ReactNode — A single coach-mark callout — title, body, an "N of M" counter, a Next/Got-it button, and a Skip-tour link. Presentation-only; position it with `positionStyle` or drop it into {@link CoachMarkHost}. Reskin via {@link CoachMarkTheme}.
|
|
1062
|
+
- `CoachMarkHost` (function): function CoachMarkHost({ sequence, resolveAnchor, showBackdrop = true, onComplete, nextLabel, doneLabel, skipLabel, theme, className, style, }: CoachMarkHostProps): ReactNode — Full-screen coach-mark host: watches a sequence, positions the current step's callout beside its anchored element (or centered when unanchored) via `getBoundingClientRect`, and draws an optional dimmed backdrop with a spotlight cutout around the anchor. Next advances, Skip ends the tour — both persist so hints never re-show. Reskin with {@link CoachMarkTheme}.
|
|
1063
|
+
- `CoachMarkHostProps` (interface): interface CoachMarkHostProps — Props for {@link CoachMarkHost}.
|
|
1064
|
+
- `CoachMarkProps` (interface): interface CoachMarkProps — Props for {@link CoachMark}.
|
|
1065
|
+
- `CoachMarkTheme` (interface): interface CoachMarkTheme — Reskin tokens for {@link CoachMarkHost} / {@link CoachMark}.
|
|
1066
|
+
- `useCoachMarks` (function): function useCoachMarks(sequence: CoachMarkSequence): CoachMarkView | null — Subscribe to a coach-mark sequence and re-render on every change, returning the current step view (or `null` when the tour is complete or waiting on a gate).
|
|
1067
|
+
|
|
1068
|
+
## @jgengine/react/codex
|
|
1069
|
+
|
|
1070
|
+
- `Codex` (function): function Codex({ entries, title = "Codex", columns = 3, maskSecrets = true, renderIcon, onSelect, emptyLabel = "Nothing discovered yet.", className, style, }: CodexProps): ReactNode — Codex / bestiary gallery — category tabs, a responsive grid of entry cards (discovered vs. locked, secret entries masked until found), and a header summarizing completion. Feed it `codex.list()`; wire `onSelect` to a detail pane.
|
|
1071
|
+
- `CodexProps` (interface): interface CodexProps — Props for {@link Codex}.
|
|
1072
|
+
|
|
1073
|
+
## @jgengine/react/comboMeter
|
|
1074
|
+
|
|
1075
|
+
- `ComboMeterHud` (function): function ComboMeterHud({ meter, tierColors, theme, animate = true, hideWhenEmpty = true, barWidth = 220, className, style, }: ComboMeterHudProps): ReactNode — A drop-in HUD for a core {@link ComboMeter}: the big live combo count ("×12"), the current free-string tier label, the derived score multiplier, and a draining window bar (reusing the shared atomic bar) that empties as the decay window runs out and re-fills on every hit. The active tier's color — supplied by the game via `tierColors`, keyed on the free-string tier id the model never interprets — drives the count glow, the label, and the bar fill, so a game reskins the escalation ("good" → "great" → "savage") without the engine hardcoding any tier meaning. Presentation only: all counting, timing, tiers, and the multiplier live in the core model.
|
|
1076
|
+
- `ComboMeterHudProps` (interface): interface ComboMeterHudProps — Props for {@link ComboMeterHud}.
|
|
1077
|
+
- `ComboMeterTheme` (interface): interface ComboMeterTheme — Reskin tokens for {@link ComboMeterHud}.
|
|
1078
|
+
- `useComboMeter` (function): function useComboMeter(meter: ComboMeter, animate = true): ComboMeterView — Subscribe to a combo meter and re-render it each animation frame so the decay window bar drains live, returning the pooled view to draw right now. Reading the view each frame advances the meter's clock and fires window expiry, so a combo that times out visibly drops even with no further hits. The returned object is the model's pooled view — read its fields immediately, do not retain it.
|
|
1079
|
+
|
|
704
1080
|
## @jgengine/react/components
|
|
705
1081
|
|
|
706
1082
|
- `CaptureOdds` (function): function CaptureOdds({ chance, className, fillClassName, }: { chance: number; className?: string; fillClassName?: string; }): React.JSX.Element — ⚠ undocumented
|
|
@@ -724,6 +1100,32 @@
|
|
|
724
1100
|
- `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`.
|
|
725
1101
|
- `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.
|
|
726
1102
|
|
|
1103
|
+
## @jgengine/react/creditsScreen
|
|
1104
|
+
|
|
1105
|
+
- `CreditsScreen` (function): function CreditsScreen({ document, className, style, renderEntry, }: { document: CreditsDocument; className?: string; style?: CSSProperties; renderEntry?: (entry: CreditsEntry, index: number) => ReactNode; }): ReactNode — Renders a {@link CreditsDocument} as headed sections of credited lines. Skinned entirely through the `--jg-*` HudTheme tokens, so it inherits the game's look from the surrounding theme block; pass `renderEntry` to art-direct the line itself. Links render only when an entry carries `href`, and always open in a new tab with `noreferrer`.
|
|
1106
|
+
|
|
1107
|
+
## @jgengine/react/cutscene
|
|
1108
|
+
|
|
1109
|
+
- `CutsceneLetterbox` (function): function CutsceneLetterbox({ active, caption, onSkip, skipLabel = "Skip", progress, theme, className, style, }: CutsceneLetterboxProps): ReactNode — A drop-in cinematic letterbox overlay: black bars slide in top and bottom while a cutscene is `active`, an optional caption/dialogue line sits above the lower bar with an optional progress line, and a Skip button rides the top bar. Presentation only — it never touches the director; wire `active`/`caption`/`progress`/`onSkip` from {@link useSequenceDirector} and your `onCue` handler. Reskin via {@link CutsceneLetterboxTheme}.
|
|
1110
|
+
- `CutsceneLetterboxProps` (interface): interface CutsceneLetterboxProps — Props for {@link CutsceneLetterbox}.
|
|
1111
|
+
- `CutsceneLetterboxTheme` (interface): interface CutsceneLetterboxTheme — Reskin tokens for {@link CutsceneLetterbox}.
|
|
1112
|
+
- `SequenceDirectorBinding` (interface): interface SequenceDirectorBinding extends SequenceState — The live playback state plus bound controls returned by {@link useSequenceDirector}.
|
|
1113
|
+
- `useSequenceDirector` (function): function useSequenceDirector(director: SequenceDirector): SequenceDirectorBinding — Bind a {@link SequenceDirector} to a component: subscribe to its state, and while it is playing run a `requestAnimationFrame` loop that ticks the director each frame off the same injected clock — so a game drops in one hook and the cutscene advances itself. Returns the current playback state (playhead, progress, playing/done) plus bound `play`/`pause`/`skip`/`seek`/`stop`. Cue side effects belong on `director.onCue`, not here — the hook never interprets a cue.
|
|
1114
|
+
|
|
1115
|
+
## @jgengine/react/damageDirection
|
|
1116
|
+
|
|
1117
|
+
- `DamageDirectionOverlay` (function): function DamageDirectionOverlay({ tracker, colors, showReticle = true, theme, className, style, }: DamageDirectionOverlayProps): ReactNode — A drop-in "hit-from" overlay: transient red (by default) arcs that flare around a center reticle in the direction each recent hit came from and fade out over time, driven entirely by a {@link DamageDirectionTracker}. Opacity and outward push scale with each indicator's eased intensity; color comes from the hit's `kind` (via `colors`) or the theme's danger color. Renders full-screen, `pointer-events: none`, so it never intercepts input — a game drops it into its HUD and calls `tracker.registerHit(...)` on damage. Reskin via {@link DamageDirectionTheme}.
|
|
1118
|
+
- `DamageDirectionOverlayProps` (interface): interface DamageDirectionOverlayProps — Props for {@link DamageDirectionOverlay}.
|
|
1119
|
+
- `DamageDirectionTheme` (interface): interface DamageDirectionTheme — Reskin tokens for {@link DamageDirectionOverlay}.
|
|
1120
|
+
- `useDamageDirection` (function): function useDamageDirection(tracker: DamageDirectionTracker): readonly DamageIndicator[] — Subscribe to a damage-direction tracker and animate. Because indicators fade continuously on a clock (not just on discrete events), this drives a `requestAnimationFrame` loop while any indicator is live and stops when the screen is clear, then wakes again on the next hit. Returns the tracker's current `active()` array (reused between frames — copy if you retain it).
|
|
1121
|
+
|
|
1122
|
+
## @jgengine/react/dialogueView
|
|
1123
|
+
|
|
1124
|
+
- `DialogueView` (function): function DialogueView({ run, renderPortrait, onChoose, onClose, closeLabel = "Close", theme, className, style, speakerClassName, textClassName, choicesClassName, choiceClassName, }: DialogueViewProps): ReactNode — A drop-in branching-conversation view over a {@link DialogueRun}: renders the current node's speaker name (+ an optional portrait slot), the line, and a list of clickable response choices that advance the conversation — the game passes its dialogue graph and gets working node traversal and choice state with no hand-rolled walk. A choice with a destination advances the run; a terminal choice (or the Close control on a choiceless node) fires `onClose`. Speaker/choice `kind` are free strings surfaced as `data-*` attributes for the game to style; the view never interprets them. HudTheme-skinned via `--jg-*` tokens; reskin further with {@link DialogueViewTheme}.
|
|
1125
|
+
- `DialogueViewProps` (interface): interface DialogueViewProps — Props for {@link DialogueView}.
|
|
1126
|
+
- `DialogueViewTheme` (interface): interface DialogueViewTheme — Reskin tokens for {@link DialogueView}. Each defaults to a HudTheme `--jg-*` token.
|
|
1127
|
+
- `useDialogueRun` (function): function useDialogueRun(run: DialogueRun): DialogueGraphView | null — Subscribe to a {@link DialogueRun} and re-render on every advance / jump / reset, returning the current node view (or `null` if the run's node id is unknown).
|
|
1128
|
+
|
|
727
1129
|
## @jgengine/react/display
|
|
728
1130
|
|
|
729
1131
|
- `DisplayProfile` (interface): interface DisplayProfile — ⚠ undocumented
|
|
@@ -744,6 +1146,31 @@
|
|
|
744
1146
|
- `EventfulEngineStore` (interface): interface EventfulEngineStore<TEventMap extends object> — ⚠ undocumented
|
|
745
1147
|
- `ReadableEngineStore` (interface): interface ReadableEngineStore<TState> — ⚠ undocumented
|
|
746
1148
|
|
|
1149
|
+
## @jgengine/react/entityFrames
|
|
1150
|
+
|
|
1151
|
+
- `EntityFrameEntry` (interface): interface EntityFrameEntry — The minimum an entry must carry; games extend it with their own display data.
|
|
1152
|
+
- `EntityFrameLayoutOptions` (interface): interface EntityFrameLayoutOptions — Anchoring, culling, and stacking options shared by the layout core and component.
|
|
1153
|
+
- `EntityFramePlacement` (interface): interface EntityFramePlacement<E extends EntityFrameEntry> — One entry resolved to a screen placement, ready to render.
|
|
1154
|
+
- `EntityFrames` (function): function EntityFrames<E extends EntityFrameEntry>({ entries, project, renderFrame, className, style, anchorTransform = "translate(-50%, -100%)", ...layout }: EntityFramesProps<E>): React.JSX.Element — Absolutely-positioned overlay that renders a caller-composed frame over every on-screen entry. Drop it inside `HudCanvas` (or any positioned ancestor) and feed it fresh `entries`/`project` each frame. Every part carries `data-*` hooks (`data-entity-frames`, `data-entity-frame="<id>"`) for tests and skins.
|
|
1155
|
+
- `EntityFramesProps` (interface): interface EntityFramesProps<E extends EntityFrameEntry> extends EntityFrameLayoutOptions — Props for {@link EntityFrames}.
|
|
1156
|
+
- `EntityScreenProjection` (interface): interface EntityScreenProjection — World-anchored entity frames — a data-first seam for floating overhead UI (enemy nameplates + health bars, interaction prompts, objective pips) that tracks entities in the 3D world. The game keeps owning its entities: it passes a plain array of `{ id, worldPosition }` entries and a `project` function that turns a world position into a screen point, and composes each frame's markup itself (typically the shipped {@link ./bars!HealthBar} plus a name) reskinned through `HudTheme`/`barTokens`. This primitive owns only the reusable behavior: projecting, offsetting, culling entries that are off-screen or behind the camera, and stacking nearer entities above farther ones.
|
|
1157
|
+
- `ProjectEntity` (type): type ProjectEntity = ( worldPosition: readonly [number, number, number], ) => EntityScreenProjection | null — Projects a world position to a screen point, or returns `null` to cull the entry entirely (e.g. outside the frustum). Caller-owned so this seam never depends on a specific camera or renderer.
|
|
1158
|
+
- `layoutEntityFrames` (function): function layoutEntityFrames<E extends EntityFrameEntry>(entries: readonly E[], project: ProjectEntity, options: EntityFrameLayoutOptions = {}): EntityFramePlacement<E>[] — Pure layout core: projects each entry, drops the ones behind the camera, off-screen (when `viewport` is set), or beyond `maxCount`, and returns the survivors sorted farthest-first so nearer frames render last (on top). Stable for equal depths via `id`. No React, no DOM — unit-testable in isolation.
|
|
1159
|
+
|
|
1160
|
+
## @jgengine/react/fastTravel
|
|
1161
|
+
|
|
1162
|
+
- `FastTravelMenu` (function): function FastTravelMenu<TMeta = unknown>({ network, from, onTravel, currentId, title = "Fast Travel", emptyLabel = "No destinations discovered yet.", onClose, className, style, }: FastTravelMenuProps<TMeta>): ReactNode — Fast-travel menu — the discovered-destinations list players pick from: points grouped by region, distance-sorted from `from`, each showing icon, name, and distance, with a header counting discovered vs. total. Selecting a row calls `onTravel`; the current location is flagged and not travelable. Bind it to a `createFastTravelNetwork`.
|
|
1163
|
+
- `FastTravelMenuProps` (interface): interface FastTravelMenuProps<TMeta = unknown> — Props for {@link FastTravelMenu}.
|
|
1164
|
+
- `useFastTravel` (function): function useFastTravel<TMeta = unknown>(network: FastTravelNetwork<TMeta>): FastTravelNetwork<TMeta> — Subscribe a component to a fast-travel network's discovery changes. Returns the network unchanged; the hook only forces a re-render when a point is discovered or the network is restored, so callers can read `destinations`/`list` in render.
|
|
1165
|
+
|
|
1166
|
+
## @jgengine/react/floatingText
|
|
1167
|
+
|
|
1168
|
+
- `FloatingText` (function): function FloatingText({ entries, project, styleFor, fontSizePx = 20, className, style, renderEntry, ...layout }: FloatingTextProps): React.JSX.Element — Absolutely-positioned overlay that renders every on-screen floating-text entry as text with its color, current alpha, and pop-in scale. Drop it inside a positioned ancestor (e.g. an `<Html fullscreen>` overlay or `HudCanvas`) and feed it fresh `entries`/`project` each frame. Every part carries `data-*` hooks (`data-floating-text`, `data-floating-text-entry="<id>"`, `data-kind="<kind>"`) for tests and skins.
|
|
1169
|
+
- `FloatingTextLayoutOptions` (interface): interface FloatingTextLayoutOptions — Anchoring and culling options shared by the layout core and the component.
|
|
1170
|
+
- `FloatingTextPlacement` (interface): interface FloatingTextPlacement — World-anchored floating text — the presentation half of the data-first `@jgengine/core/ui/floatingText` seam. The game keeps owning the simulation: it passes the field's `active()` views plus a `project` function (world → screen), exactly the transport {@link ./entityFrames!EntityFrames} uses, so an R3F game gets it for free from `useWorldProjection`. This component owns only the reusable presentation: projecting each entry, culling ones behind the camera or off-screen, and rendering absolutely-positioned text with the entry's color, current alpha, and pop-in scale — reskinnable per `kind` through `styleFor`.
|
|
1171
|
+
- `FloatingTextProps` (interface): interface FloatingTextProps extends FloatingTextLayoutOptions — Props for {@link FloatingText}.
|
|
1172
|
+
- `layoutFloatingText` (function): function layoutFloatingText(views: readonly FloatingTextView[], project: ProjectEntity, options: FloatingTextLayoutOptions = {}): FloatingTextPlacement[] — Pure layout core: projects each view, drops the ones behind the camera or (when `viewport` is set) off-screen, and returns the survivors sorted farthest-first so nearer text paints on top. No React, no DOM — unit-testable.
|
|
1173
|
+
|
|
747
1174
|
## @jgengine/react/fogOverlay
|
|
748
1175
|
|
|
749
1176
|
- `FogCellRect` (interface): interface FogCellRect — ⚠ undocumented
|
|
@@ -775,6 +1202,7 @@
|
|
|
775
1202
|
## @jgengine/react/hooks
|
|
776
1203
|
|
|
777
1204
|
- `AbilitySlotBindingOptions` (interface): interface AbilitySlotBindingOptions — ⚠ undocumented
|
|
1205
|
+
- `DomEventTarget` (interface): interface DomEventTarget — Minimal add/removeEventListener surface accepted by useDomEvent (window, document, elements).
|
|
778
1206
|
- `EventMeterView` (interface): interface EventMeterView — A rendered snapshot of an {@link EventMeter}: current value, fill fraction, active tier, and ready-to-consume flag.
|
|
779
1207
|
- `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.
|
|
780
1208
|
- `UseAxisChannelResult` (interface): interface UseAxisChannelResult — ⚠ undocumented
|
|
@@ -786,9 +1214,11 @@
|
|
|
786
1214
|
- `useAbilitySlot` (function): function useAbilitySlot(kit: AbilityKit, slotId: string, resourceAvailable?: number, options?: AbilitySlotBindingOptions): AbilitySlotSnapshot | null — ⚠ undocumented
|
|
787
1215
|
- `useAbilitySlots` (function): function useAbilitySlots(kit: AbilityKit, resourceAvailable?: number, options?: AbilitySlotBindingOptions): AbilitySlotSnapshot[] — ⚠ undocumented
|
|
788
1216
|
- `useActivePrompt` (function): function useActivePrompt<T extends PositionedPrompt>(prompts?: readonly T[]): T | null — ⚠ undocumented
|
|
1217
|
+
- `useAutoScroll` (function): function useAutoScroll<T extends HTMLElement>(dep: unknown): React.RefObject<T | null> — Pin a scrollable element to its bottom whenever `dep` changes (typically a length or the list itself). Attach the returned ref to the scroll container. Owns the log/chat/console scroll-to-bottom effect so panels don't hand-roll it.
|
|
789
1218
|
- `useAxisChannel` (function): function useAxisChannel(config: AxisChannelConfig): UseAxisChannelResult — Wires useHeldKeys into a fresh AxisChannel, ready for a per-frame `channel.sample(dt, isDown)`. The channel is recreated when `config` identity changes, so pass a stable config (useMemo/module constant at the call site) unless a rebind is intended.
|
|
790
1219
|
- `useChat` (function): function useChat(channelId: string, options?: { limit?: number }): ChatMessage[] — ⚠ undocumented
|
|
791
1220
|
- `useCurrency` (function): function useCurrency(currencyId: string): number — ⚠ undocumented
|
|
1221
|
+
- `useDomEvent` (function): function useDomEvent<E>(resolveTarget: () => DomEventTarget | null, type: string, handler: (event: E) => void, options?: { capture?: boolean; passive?: boolean }): void — Attach a DOM event listener with automatic cleanup. `resolveTarget` runs inside the effect, so `() => window` and ref-reading resolvers are SSR-safe; return null to skip attaching. The handler is kept in a ref, so a fresh closure per render never re-binds the listener. Re-binds only when `type` or `options.capture`/`options.passive` change.
|
|
792
1222
|
- `useEntityStat` (function): function useEntityStat(instanceId: string, statId: string): StatValue | null — ⚠ undocumented
|
|
793
1223
|
- `useEventMeter` (function): function useEventMeter(meter: EventMeter, options?: AbilitySlotBindingOptions): EventMeterView — Bind a `createEventMeter` (`@jgengine/core/stats/eventMeter`) heat/streak gauge to a component — the react-render half of the ult/adrenaline and streak/combo meters (`event-meter` capability) that lets a HUD gauge re-render on tick without the game hand-rolling a `useEffect`/`setInterval` heartbeat around `meter.value()`.
|
|
794
1224
|
- `useFeed` (function): function useFeed({ action, limit }: { action: string; limit?: number }): FeedEntry[] — ⚠ undocumented
|
|
@@ -812,12 +1242,14 @@
|
|
|
812
1242
|
- `usePlayer` (function): function usePlayer(): { userId: string; isNew: boolean } — ⚠ undocumented
|
|
813
1243
|
- `usePresence` (function): function usePresence(userId: string): PresenceInfo — ⚠ undocumented
|
|
814
1244
|
- `useQuestJournal` (function): function useQuestJournal(): QuestInstance[] — ⚠ undocumented
|
|
1245
|
+
- `useRafLoop` (function): function useRafLoop(onFrame: (deltaSeconds: number) => void, active = true): void — Run a requestAnimationFrame loop while `active`, calling `onFrame(deltaSeconds)` each frame. The callback is kept in a ref so re-renders never restart the loop; cleanup cancels the pending frame. For scene-graph work inside a canvas prefer R3F's useFrame — this is for DOM-side animation outside the renderer.
|
|
815
1246
|
- `useRoster` (function): function useRoster(userId?: string): readonly RosterEntry[] — ⚠ undocumented
|
|
816
1247
|
- `useSceneEntities` (function): function useSceneEntities(): readonly SceneEntity[] — ⚠ undocumented
|
|
817
1248
|
- `useSceneEntityIds` (function): function useSceneEntityIds(): readonly string[] — Membership-only entity id list: the returned array keeps a stable identity across per-frame pose writes and only changes when an entity spawns, despawns, or the store is hydrated (#625). A marker mapped from these ids reads its own live pose imperatively (useFrame), so the actor tree no longer re-reconciles every frame. Prefer this over {@link useSceneEntities} for large scenes.
|
|
818
1249
|
- `useSceneObjectIds` (function): function useSceneObjectIds(): readonly string[] — Membership-only object id list — the object counterpart of {@link useSceneEntityIds}; stable across move/rotate/setVisual, changes only on place/remove.
|
|
819
1250
|
- `useSceneObjects` (function): function useSceneObjects(): readonly SceneObject[] — ⚠ undocumented
|
|
820
1251
|
- `useTarget` (function): function useTarget(fromInstanceId: string): string | null — ⚠ undocumented
|
|
1252
|
+
- `useTicker` (function): function useTicker(hz = 10): number — Re-render at a steady rate. Returns a monotonically increasing tick count driven by a setInterval, for HUD elements that display wall-clock-derived values (cooldowns, cast bars, swing timers) without an engine subscription to hang off. `hz <= 0` disables the ticker.
|
|
821
1253
|
- `useWorldBrowser` (function): function useWorldBrowser(options: { fetchSessions: () => Promise<readonly SessionListing[]>; filter?: MatchFilter; limit?: number; refreshMs?: number; }): WorldBrowserState — Polls a host-supplied session fetcher (e.g. createWsBackend().browse) and filters through matchmaking's browseSessions. fetchSessions must be identity-stable (wrap in useCallback at the call site) or every render refetches.
|
|
822
1254
|
- `useWorldInvites` (function): function useWorldInvites(): WorldInvite[] — ⚠ undocumented
|
|
823
1255
|
- `useWorldItems` (function): function useWorldItems(): readonly WorldItemRecord[] — ⚠ undocumented
|
|
@@ -857,14 +1289,22 @@
|
|
|
857
1289
|
|
|
858
1290
|
## @jgengine/react/hudTheme
|
|
859
1291
|
|
|
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.
|
|
1292
|
+
- `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; ember: HudTheme; synthwave: HudTheme; fieldkit: HudTheme; } — Built-in theme presets for demos/scaffold only — not product identity; games author their own theme.
|
|
1293
|
+
- `HudTheme` (interface): interface HudTheme — A full HUD theme. Author one with {@link hudTheme} or {@link deriveHudTheme}.
|
|
862
1294
|
- `HudThemeBar` (interface): interface HudThemeBar — Framed-trough tokens shared by every atomic bar.
|
|
1295
|
+
- `HudThemeFont` (interface): interface HudThemeFont — Typography roles. Any CSS `font-family` list.
|
|
863
1296
|
- `HudThemeFrame` (interface): interface HudThemeFrame — Frame material + shape tokens (panels, `HudFrame variation="themed"`).
|
|
864
|
-
- `
|
|
1297
|
+
- `HudThemeOverrides` (interface): interface HudThemeOverrides — Per-group partial overrides accepted by {@link hudTheme}.
|
|
1298
|
+
- `HudThemePalette` (interface): interface HudThemePalette — `HudTheme` (#1034, #1573): one token object that restyles every shared token-driven building block at once — the atomic bars (#1033), frames, slots, the minimap ring, and the chrome the registry blocks read (surfaces, edges, text, status colors, fonts, rarity). `hudThemeVars(theme)` emits the whole `--jg-*` vocabulary, so setting a **game-authored** theme on any HUD ancestor re-skins `packages/react` primitives and `registry/jgengine` components together. 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
1299
|
- `HudThemePreset` (type): type HudThemePreset = keyof typeof HUD_THEME_PRESETS — Built-in demo/scaffold theme preset name — not a game identity.
|
|
1300
|
+
- `HudThemeRarity` (interface): interface HudThemeRarity — Item-rarity coloring shared by loot cards, tooltips, and inventory slots.
|
|
1301
|
+
- `HudThemeSeed` (interface): interface HudThemeSeed — Seed colors for {@link deriveHudTheme}. Only `accent` and `surface` are required.
|
|
866
1302
|
- `HudThemeSlot` (interface): interface HudThemeSlot — Action/inventory slot tokens.
|
|
1303
|
+
- `HudThemeStatus` (interface): interface HudThemeStatus — Semantic status colors — outcome, threat, and relationship coloring.
|
|
1304
|
+
- `HudThemeSurface` (interface): interface HudThemeSurface — Chrome surfaces, edges, and text — what panels, overlays, and menus are built out of.
|
|
867
1305
|
- `defaultHudTheme` (const): const defaultHudTheme: HudTheme — Default theme tokens for previews/scaffold — not a finished game look; author a custom theme.
|
|
1306
|
+
- `deriveHudTheme` (function): function deriveHudTheme(seed: HudThemeSeed): HudTheme — Derives a coherent full theme from an accent/surface pair — shades, edges, dim text, frames, bar troughs, and slots all fall out of the seed, so a game gets one consistent look across the `packages/react` primitives and the `registry/jgengine` blocks without naming 50 tokens. Hex seeds only (`#rgb` or `#rrggbb`).
|
|
1307
|
+
- `hudTheme` (function): function hudTheme(overrides: HudThemeOverrides): HudTheme — Builds a full {@link HudTheme} from per-group partials, filling the rest from {@link defaultHudTheme}. Reach for this when a game wants to name exact values; use {@link deriveHudTheme} when a seed color pair is enough.
|
|
868
1308
|
- `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
1309
|
- `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
1310
|
|
|
@@ -878,6 +1318,15 @@
|
|
|
878
1318
|
- `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.
|
|
879
1319
|
- `useHudViewport` (function): function useHudViewport(): HudViewportContextValue | null — ⚠ undocumented
|
|
880
1320
|
|
|
1321
|
+
## @jgengine/react/i18n
|
|
1322
|
+
|
|
1323
|
+
- `I18nProvider` (function): function I18nProvider({ i18n, children }: { i18n: I18n; children: ReactNode }): ReactNode — Provide an {@link I18n} instance to the tree so `useT`/`useLocale` can read it.
|
|
1324
|
+
- `Trans` (function): function Trans({ k, params }: { k: string; params?: TParams }): ReactNode — Render a translated message inline: `<Trans k="hud.score" params={{ value }} />`.
|
|
1325
|
+
- `useI18n` (function): function useI18n(): I18n — Read the current {@link I18n} from context; throws when no {@link I18nProvider} is above.
|
|
1326
|
+
- `useLocale` (function): function useLocale(): Locale — Subscribe to the active locale — re-renders on `setLocale`.
|
|
1327
|
+
- `usePlural` (function): function usePlural(): (key: string, count: number, params?: TParams) => string — Return the plural-aware translator bound to the current locale.
|
|
1328
|
+
- `useT` (function): function useT(): (key: string, params?: TParams) => string — Return the translator bound to the current locale; the component re-renders when `setLocale` is called, so returned strings stay live.
|
|
1329
|
+
|
|
881
1330
|
## @jgengine/react/iconTreatment
|
|
882
1331
|
|
|
883
1332
|
- `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.
|
|
@@ -909,6 +1358,14 @@
|
|
|
909
1358
|
- `useAuthedPlayer` (function): function useAuthedPlayer(options?: { guestSeed?: string }): PlayerIdentity | null — ⚠ undocumented
|
|
910
1359
|
- `useSession` (function): function useSession(): IdentitySource — ⚠ undocumented
|
|
911
1360
|
|
|
1361
|
+
## @jgengine/react/interactionPrompt
|
|
1362
|
+
|
|
1363
|
+
- `InteractionPrompt` (function): function InteractionPrompt({ registry, playerPosition, theme, accentFor, keyFor, gaugeProgress, anchor = "bottom-center", zIndex = 40, className, style, }: InteractionPromptProps): ReactNode — A screen-anchored "Press E to …" interaction callout that renders the active prompt of a {@link PromptRegistry}. It subscribes to the registry and — when given `playerPosition` — re-resolves as the hero moves, showing the nearest in-range interactable and switching to a closer/higher-priority one as they cross radii. Each display kind renders as itself: a `keybind` shows a key cap plus its label ("Press [E] Open"), a `gauge` shows a hold bar filling with `gaugeProgress`, and a `label` shows plain text. Presentation only — the registry never branches on a prompt's meaning; the game colors each via `accentFor` and maps action ids to key glyphs via `keyFor`. HudTheme-skinnable through `--jg-accent` and {@link InteractionPromptTheme}.
|
|
1364
|
+
- `InteractionPromptAnchor` (type): type InteractionPromptAnchor = "bottom-center" | "top-center" | "center" — Where the callout sits over the scene.
|
|
1365
|
+
- `InteractionPromptProps` (interface): interface InteractionPromptProps — Props for {@link InteractionPrompt}.
|
|
1366
|
+
- `InteractionPromptTheme` (interface): interface InteractionPromptTheme — Reskin tokens for {@link InteractionPrompt}.
|
|
1367
|
+
- `useInteractionPrompt` (function): function useInteractionPrompt(registry: PromptRegistry, playerPosition: PromptPoint): PositionedPrompt | null — Subscribe to a {@link PromptRegistry} and re-`resolve` it whenever the player moves, returning the prompt to draw right now — or `null` when the player is out of range of every interactable. The registry notifies only on active-prompt *changes*, so this re-renders on transitions rather than every frame the hero moves. Feed it the player's `{ x, z }` position each frame; identical positions do no work.
|
|
1368
|
+
|
|
912
1369
|
## @jgengine/react/inventoryGrid
|
|
913
1370
|
|
|
914
1371
|
- `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`.
|
|
@@ -919,6 +1376,21 @@
|
|
|
919
1376
|
- `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.
|
|
920
1377
|
- `Keycap` (function): function Keycap({ children, className, style, }: { children: ReactNode; className?: string; style?: CSSProperties; }): React.JSX.Element — A single keyboard/mouse key rendered as a cap. Tagged `data-jg-kbd` so tooling can find it; on its own it stays visible (hiding a lone cap would strand its label). Wrap keys + their meaning in `KeyHint` to make the whole hint vanish on touch.
|
|
921
1378
|
|
|
1379
|
+
## @jgengine/react/keybindingMenu
|
|
1380
|
+
|
|
1381
|
+
- `KeybindingMenu` (function): function KeybindingMenu({ session, theme, title = "Controls", resetAllLabel = "Reset All", capturePrompt = "Press a key…", onChange, className, style, }: KeybindingMenuProps): ReactNode — A drop-in controls-settings surface for a {@link RebindSession}: one row per action showing its label and current key glyph. Clicking a row arms capture ("Press a key…") and a window `keydown` listener feeds the pressed `event.code` to `session.capture`; rows that collide with another action show a conflict badge; each row has a Reset button and the panel has a Reset-all button. Presentation only — all conflict/capture/reset logic lives in the core session, and action ids/labels are the game's free strings. Reskin via {@link KeybindingMenuTheme} or ambient HudTheme tokens. A game owns its overall settings layout; this is the reusable controls block it drops in.
|
|
1382
|
+
- `KeybindingMenuProps` (interface): interface KeybindingMenuProps — Props for {@link KeybindingMenu}.
|
|
1383
|
+
- `KeybindingMenuTheme` (interface): interface KeybindingMenuTheme — Reskin tokens for {@link KeybindingMenu}. All fall back to HudTheme `--jg-*` vars.
|
|
1384
|
+
- `useRebindSession` (function): function useRebindSession(session: RebindSession): RebindSession — Subscribe to a rebind session and re-render on every change (capture, reset, arm/disarm, restore). Returns the session unchanged for convenient inline use.
|
|
1385
|
+
|
|
1386
|
+
## @jgengine/react/killFeed
|
|
1387
|
+
|
|
1388
|
+
- `KillFeed` (function): function KillFeed({ ticker, kindStyles, theme, iconSize = 18, animate = true, zIndex = 40, className, style, }: KillFeedProps): ReactNode — A vertical event/kill-feed ticker: renders an {@link EventTicker}'s recent entries as a stack of rows, newest on top, each with its `fade` `0..1` mapped to opacity so entries dim and drop as they age out. Each row shows an optional per-kind (or per-entry) {@link GameIcon} and a per-kind accent color from `kindStyles`, styled with HudTheme tokens. Presentation only: all capping/timing lives in the core ticker, and the free-string `kind`/`text`/`icon` are never interpreted here — a game colors and icons each variant via `kindStyles`.
|
|
1389
|
+
- `KillFeedKindStyle` (interface): interface KillFeedKindStyle — Per-`kind` styling for a kill-feed row — accent color and an optional icon.
|
|
1390
|
+
- `KillFeedProps` (interface): interface KillFeedProps — Props for {@link KillFeed}.
|
|
1391
|
+
- `KillFeedTheme` (interface): interface KillFeedTheme — Reskin tokens for {@link KillFeed}.
|
|
1392
|
+
- `useEventTicker` (function): function useEventTicker(ticker: EventTicker, animate = true): EventTickerView[] — Subscribe to an event ticker and re-render it on an animation frame (unless the game already ticks it), returning the live entries newest-first with `fade` applied. Driving the frame loop is what makes entries visibly fade and drop as they age out.
|
|
1393
|
+
|
|
922
1394
|
## @jgengine/react/liveBind
|
|
923
1395
|
|
|
924
1396
|
- `LiveText` (function): function LiveText({ get, format, className, style, }: { get: () => number | string; format?: (value: number | string) => string; className?: string; style?: CSSProperties; }): React.JSX.Element — ⚠ undocumented
|
|
@@ -930,7 +1402,12 @@
|
|
|
930
1402
|
|
|
931
1403
|
- `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`.
|
|
932
1404
|
- `CompassProps` (interface): interface CompassProps — ⚠ undocumented
|
|
1405
|
+
- `FullscreenMap` (function): function FullscreenMap({ open = true, bounds, contentWidth = 900, minScale = 0.5, maxScale = 8, title = "Map", onClose, onWorldClick, tool = "pan", onStrokeComplete, drawTone = "info", drawWidth = 3, children, overlayClassName, overlayStyle, ...surfaceProps }: FullscreenMapProps): ReactNode — Fullscreen pan/zoom world-map overlay — the enlarged "press M" map. Wheel to zoom (toward the cursor), drag to pan, and click to place (wire `onWorldClick` to a waypoint/annotation store). Switch `tool` to `"draw"` to freehand-draw strokes committed to `onStrokeComplete` (wire to `createAnnotationLayer`). Reuses {@link WorldMapSurface} for rendering, so terrain bake, fog, routes, zones, markers, and the player arrow all appear; a drag never fires `onWorldClick`. Compose a {@link MapLegend} or tool palette via `children`.
|
|
1406
|
+
- `FullscreenMapProps` (interface): interface FullscreenMapProps extends Omit<WorldMapSurfaceProps, "canvasWidth" | "canvasHeight" | "viewport" | "width" | "height" | "style"> — Props for {@link FullscreenMap}.
|
|
933
1407
|
- `MapBounds` (interface): interface MapBounds — ⚠ undocumented
|
|
1408
|
+
- `MapLegend` (function): function MapLegend({ kinds, labels, kindStyles = DEFAULT_MARKER_KINDS, title = "Legend", className, style, }: MapLegendProps): ReactNode — Marker-kind key for a map/minimap — glyph + color swatch per kind, labelled. Reads the same `kindStyles` the map renders with, so the legend can never drift from the pins.
|
|
1409
|
+
- `MapLegendProps` (interface): interface MapLegendProps — Props for {@link MapLegend}.
|
|
1410
|
+
- `MapViewport` (interface): interface MapViewport — Pan/zoom transform applied to a {@link WorldMapSurface}'s content group.
|
|
934
1411
|
- `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`.
|
|
935
1412
|
- `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.
|
|
936
1413
|
- `MinimapChromeMarker` (interface): interface MinimapChromeMarker — One dot (or, with `heading`, a rotated arrow) drawn by `MinimapChrome`.
|
|
@@ -942,14 +1419,53 @@
|
|
|
942
1419
|
- `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
1420
|
- `MinimapTrackProps` (interface): interface MinimapTrackProps — Props for {@link MinimapTrack}.
|
|
944
1421
|
- `MinimapTrackSpan` (interface): interface MinimapTrackSpan — A colored span across the {@link MinimapTrack} rail, given by 0..1 `start`/`end` fractions (e.g. from core `trackFraction`).
|
|
945
|
-
- `
|
|
1422
|
+
- `WaypointArrow` (function): function WaypointArrow({ relative, distance, label, formatDistance = (value) => `${Math.round(value)}m`, size = 44, color = "#f59e0b", className, style, }: WaypointArrowProps): ReactNode — On-screen guide arrow to the tracked waypoint — a HUD compass needle rotated by the facing-relative bearing, with an optional label and distance readout. Pair with `WaypointStore.guidance(playerXZ, facingYaw)`.
|
|
1423
|
+
- `WaypointArrowProps` (interface): interface WaypointArrowProps — Props for {@link WaypointArrow}.
|
|
1424
|
+
- `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`. Framed panel wrapper over {@link WorldMapSurface}.
|
|
946
1425
|
- `WorldMapProps` (interface): interface WorldMapProps — ⚠ undocumented
|
|
1426
|
+
- `WorldMapSurface` (function): function WorldMapSurface({ markers, bounds, player, facingYaw = 0, fog, background, width = 520, height, kindStyles = DEFAULT_MARKER_KINDS, routes, zones, cellStates, onWorldClick, canvasWidth, canvasHeight, viewport = IDENTITY_VIEWPORT, style, }: WorldMapSurfaceProps): ReactNode — The bare top-down map `<svg>` shared by {@link WorldMap} (framed panel) and {@link FullscreenMap} (pan/zoom overlay): baked terrain background, fog, map layers, markers with labels, and the player arrow, drawn under an optional viewport transform. Rectangular linear projection over the world `bounds`.
|
|
1427
|
+
- `WorldMapSurfaceProps` (interface): interface WorldMapSurfaceProps — Props for {@link WorldMapSurface}.
|
|
947
1428
|
- `useFog` (function): function useFog(fog: FogField): ReturnType<FogField["cells"]> — ⚠ undocumented
|
|
948
1429
|
- `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
1430
|
|
|
1431
|
+
## @jgengine/react/menuRouter
|
|
1432
|
+
|
|
1433
|
+
- `MenuRouter` (interface): interface MenuRouter<Id extends string> — A menu screen stack: where you are, how you got there, and how to go back.
|
|
1434
|
+
- `MenuStackAction` (type): type MenuStackAction<Id extends string> = | { type: "open"; id: Id } | { type: "back" } | { type: "replace"; id: Id } | { type: "reset"; id?: Id } — A screen-stack transition. `reset` without an id collapses to the router's original root.
|
|
1435
|
+
- `menuStackReducer` (function): function menuStackReducer<Id extends string>(path: readonly Id[], action: MenuStackAction<Id>, root: Id): readonly Id[] — The pure screen-stack transition behind {@link useMenuRouter}. Exported so a game can drive the same navigation from its own store or a replayable command log instead of React state.
|
|
1436
|
+
- `useMenuRouter` (function): function useMenuRouter<Id extends string>(root: Id, options: { escapeToBack?: boolean } = {}): MenuRouter<Id> — The screen stack behind a game front-end: title → save select → settings → credits, and Escape back out. Every game menu needs this and none of it is game-specific, so it ships here rather than being re-derived per game. Holds no content and imposes no look — the game decides what each screen id renders.
|
|
1437
|
+
|
|
1438
|
+
## @jgengine/react/modals
|
|
1439
|
+
|
|
1440
|
+
- `ConfirmDialog` (function): function ConfirmDialog({ title, body, confirmLabel = "Confirm", cancelLabel = "Cancel", onConfirm, onCancel, danger = false, width = 360, className, style, }: ConfirmDialogProps): ReactNode — A generic two-button confirmation dialog — title, optional body, and Cancel / Confirm buttons over a `HudTheme`-token-driven {@link HudFrame}. Presentation-only: wire `onConfirm`/`onCancel` to a modal stack's `resolve` (typically inside a {@link ModalHost} render callback) and reskin via `HudTheme` tokens or `danger` for a destructive action. It interprets nothing — the game supplies the copy.
|
|
1441
|
+
- `ConfirmDialogProps` (interface): interface ConfirmDialogProps — Props for {@link ConfirmDialog}.
|
|
1442
|
+
- `ModalControls` (interface): interface ModalControls — Stack-bound controls handed to a {@link ModalHost} render callback.
|
|
1443
|
+
- `ModalHost` (function): function ModalHost({ stack, children, showBackdrop = true, backdrop, closeOnBackdrop = true, closeOnEsc = true, zIndexBase = 80, className, style, }: ModalHostProps): ReactNode — Full-screen modal host: watches a stack, renders only the topmost modal centered over a dimmed backdrop, and manages accessibility — the panel is a `role="dialog" aria-modal`, focus moves into it on open and is trapped with Tab/Shift+Tab cycling, Escape and (optionally) a backdrop click cancel the top modal, and focus returns to the previously focused element on close. It renders nothing when the stack is empty. Skin the panel and backdrop via `HudTheme` tokens.
|
|
1444
|
+
- `ModalHostProps` (interface): interface ModalHostProps — Props for {@link ModalHost}.
|
|
1445
|
+
- `ModalStackView` (interface): interface ModalStackView — React chrome over the headless modal stack (`@jgengine/core/ui/modalStack`) — the blocking-overlay layer a game raises over its scene: a pause menu, a "quit to menu?" confirm, a reward popup. {@link useModalStack} is the DATA/HOOK layer (subscribe + the active record), {@link ModalHost} renders the top modal with a backdrop, focus trap, and Esc-to-cancel, and {@link ConfirmDialog} / {@link PauseMenu} are ready-to-wire, HudTheme-token-driven building blocks. All unskinned and game-owned: the model never interprets a modal's `kind`, so a game switches on it to pick which of these (or its own) content to show, and reskins everything via `HudTheme` tokens and the frame.
|
|
1446
|
+
- `PauseMenu` (function): function PauseMenu({ title = "Paused", onResume, resumeLabel = "Resume", items = [], width = 300, className, style, }: PauseMenuProps): ReactNode — A reskinnable pause-menu building block: a primary Resume button plus a game-filled list of slot items (Settings, Save, Quit, …), stacked in a `HudTheme`-token-driven {@link HudFrame}. It ships the common shape every game's pause screen needs and nothing genre-specific — the game supplies the title, item labels/order, and destructive styling, and reskins with `HudTheme` tokens. Drop it into a {@link ModalHost} keyed on a `"pause"` modal, or render it standalone.
|
|
1447
|
+
- `PauseMenuItem` (interface): interface PauseMenuItem — One selectable row in a {@link PauseMenu}'s slot list (Settings, Save, Quit, …).
|
|
1448
|
+
- `PauseMenuProps` (interface): interface PauseMenuProps — Props for {@link PauseMenu}.
|
|
1449
|
+
- `useModalStack` (function): function useModalStack(stack: ModalStack): ModalStackView — Subscribe to a modal stack and re-render on every change, returning the active modal and depth.
|
|
1450
|
+
|
|
1451
|
+
## @jgengine/react/notifications
|
|
1452
|
+
|
|
1453
|
+
- `NotificationBell` (function): function NotificationBell({ store, onClick, icon = "🔔", className, style }: NotificationBellProps): ReactNode — Notification bell — an icon button with an unread-count badge, bound to a notification store. Toggle a {@link NotificationCenter} panel from its click.
|
|
1454
|
+
- `NotificationBellProps` (interface): interface NotificationBellProps — Props for {@link NotificationBell}.
|
|
1455
|
+
- `NotificationCenter` (function): function NotificationCenter({ store, title = "Notifications", emptyLabel = "You're all caught up.", onClose, formatTime, className, style, }: NotificationCenterProps): ReactNode — Notification center panel — the scrollable log toasts don't provide: newest notifications with a kind-colored marker, title/body, relative time, and an unread highlight; a header with the unread count, mark-all-read, and clear. Clicking an entry marks it read. Bind it to a `createNotificationCenter`.
|
|
1456
|
+
- `NotificationCenterProps` (interface): interface NotificationCenterProps — Props for {@link NotificationCenter}.
|
|
1457
|
+
- `useNotifications` (function): function useNotifications<TMeta = unknown>(store: NotificationStore<TMeta>): readonly NotificationEntry<TMeta>[] — Subscribe to a notification store's live list.
|
|
1458
|
+
|
|
1459
|
+
## @jgengine/react/objectiveBanner
|
|
1460
|
+
|
|
1461
|
+
- `ObjectiveBannerHost` (function): function ObjectiveBannerHost({ controller, theme, kindThemes, animate = true, dismissOnClick = false, zIndex = 50, className, style, }: ObjectiveBannerHostProps): ReactNode — A full-screen overlay that renders an {@link ObjectiveBannerController} as the classic transient centered title stamp — "WAVE 3", "VICTORY", "OBJECTIVE COMPLETE" — flying in, holding, and fading out. It subscribes to the model, drives `advance()` on an animation frame (unless the game ticks it), and maps the current banner's phase + progress to opacity/scale/translate. Reskin the base look with {@link ObjectiveBannerTheme} and color each variant via `kindThemes` keyed on the game-owned `kind`. Presentation only: all timing and queueing live in the core model, and `kind` is never interpreted here.
|
|
1462
|
+
- `ObjectiveBannerHostProps` (interface): interface ObjectiveBannerHostProps — Props for {@link ObjectiveBannerHost}.
|
|
1463
|
+
- `ObjectiveBannerTheme` (interface): interface ObjectiveBannerTheme — Reskin tokens for {@link ObjectiveBannerHost}. Per-`kind` overrides layer on top.
|
|
1464
|
+
- `useObjectiveBanner` (function): function useObjectiveBanner(controller: ObjectiveBannerController, animate = true): ObjectiveBannerView | null — Subscribe to a banner controller, drive its clock on an animation frame (unless the game already ticks it), and return the banner to draw right now — or `null` when idle. Re-renders every frame while a banner is animating.
|
|
1465
|
+
|
|
950
1466
|
## @jgengine/react/panels
|
|
951
1467
|
|
|
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
|
|
1468
|
+
- `PanelHost` (function): function PanelHost({ manager, render, panels, variation, shape, width, zIndexBase = 40, className, windowClassName, windowStyle, bodyStyle, }: { manager: PanelsManager; /** Content for a panel by id. Takes precedence over `panels`. */ render?: (id: string) => ReactNode; /** Static content map by pan… — 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
1469
|
- `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
1470
|
- `PanelsManager` (interface): interface PanelsManager — The live panel manager returned by {@link usePanels} and consumed by {@link PanelHost}.
|
|
955
1471
|
- `UsePanelsOptions` (interface): interface UsePanelsOptions — Options for {@link usePanels}.
|
|
@@ -957,18 +1473,50 @@
|
|
|
957
1473
|
- `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
1474
|
- `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.
|
|
959
1475
|
|
|
1476
|
+
## @jgengine/react/photoMode
|
|
1477
|
+
|
|
1478
|
+
- `PhotoModeControls` (function): function PhotoModeControls({ store, onCapture, className, style }: PhotoModeControlsProps): ReactNode — Photo-mode toolbar — a hide/show-HUD toggle, a capture button, and an exit button, bound to a `createPhotoModeStore`. Presentation-only: the game wires `onCapture` to shell `captureCanvas`/`downloadImage` and reads `hideHud` to drop its gameplay HUD.
|
|
1479
|
+
- `PhotoModeControlsProps` (interface): interface PhotoModeControlsProps — Props for {@link PhotoModeControls}.
|
|
1480
|
+
- `usePhotoMode` (function): function usePhotoMode(store: PhotoModeStore): PhotoModeState — Subscribe to a photo-mode store's live state.
|
|
1481
|
+
|
|
960
1482
|
## @jgengine/react/preview
|
|
961
1483
|
|
|
962
1484
|
- `GamePreviewComponent` (type): type GamePreviewComponent = ComponentType<GamePreviewProps> — ⚠ undocumented
|
|
963
1485
|
- `GamePreviewProps` (type): type GamePreviewProps = { className?: string; } — ⚠ undocumented
|
|
964
1486
|
- `GamePreviewStates` (type): type GamePreviewStates = Record<string, GamePreviewComponent> — ⚠ undocumented
|
|
965
1487
|
|
|
1488
|
+
## @jgengine/react/previewFixtures
|
|
1489
|
+
|
|
1490
|
+
- `PREVIEW_FIXTURES` (const): const PREVIEW_FIXTURES: Record<string, PreviewFixture> — Registry of deterministic, engine-level preview fixtures — the *real* exported `@jgengine/react` components (`HudThemePreview`, `BarsPreview`, `IconsPreview`, …) that render identically every time from static values, so they can be screenshotted as regression evidence without booting a game.
|
|
1491
|
+
- `PreviewFixture` (interface): interface PreviewFixture — One entry in the engine preview-fixture registry: a deterministic, engine-level preview component keyed by a stable id.
|
|
1492
|
+
- `previewFixtureNames` (function): function previewFixtureNames(): string[] — Sorted list of registered fixture names, for discovery/listing.
|
|
1493
|
+
- `resolvePreviewFixture` (function): function resolvePreviewFixture(name: string): PreviewFixture | undefined — Resolve a fixture by name, or `undefined` when it is not registered.
|
|
1494
|
+
|
|
966
1495
|
## @jgengine/react/provider
|
|
967
1496
|
|
|
1497
|
+
- `GameContextBridge` (function): function GameContextBridge({ context, children, }: { context: GameContext | null; children?: ReactNode; }): React.JSX.Element — Re-provide a captured {@link GameContext} across a nested React reconciler boundary. The `<Canvas>` of `@react-three/fiber` renders its children in a *separate* React root, so a `GameProvider` in the outer tree does NOT reach inside it — hooks like `useGameContext` / `useEntityRenderCues` throw. The fix the shell already uses internally: capture the context outside the boundary (with {@link useOptionalGameContext}) and wrap the inner tree in `GameContextBridge`. A `null` context renders children unchanged, so the same code works in showcases with no running game. This is the seam behind `EntityPreview` — reach for it directly when building a bespoke nested canvas.
|
|
968
1498
|
- `GameProvider` (function): function GameProvider({ context, children }: { context: GameContext; children?: ReactNode }): React.JSX.Element — ⚠ undocumented
|
|
969
1499
|
- `useGameContext` (function): function useGameContext(): GameContext — ⚠ undocumented
|
|
970
1500
|
- `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).
|
|
971
1501
|
|
|
1502
|
+
## @jgengine/react/questTracker
|
|
1503
|
+
|
|
1504
|
+
- `QuestTracker` (function): function QuestTracker({ quests, title = "Quests", emptyLabel = "No active quests.", maxObjectives, accent = "var(--jg-accent, #facc15)", className, style, }: QuestTrackerProps): ReactNode — Quest / objective tracker HUD — a compact panel of active quests with a title and labelled, progress-barred objectives (checked + struck when complete). Presentation-only over `describeTrackedQuest(def, instance)` views, so it stays decoupled from the `QuestJournal` runtime.
|
|
1505
|
+
- `QuestTrackerProps` (interface): interface QuestTrackerProps — Props for {@link QuestTracker}.
|
|
1506
|
+
|
|
1507
|
+
## @jgengine/react/quickMenu
|
|
1508
|
+
|
|
1509
|
+
- `QuickMenu` (function): function QuickMenu({ items, layout = "list", onSelect, onClose, title, columns = 3, arc = { startAngle: Math.PI / 2, sweep: Math.PI }, radialSize = 300, accent = "var(--jg-accent, #38bdf8)", className, style, }: QuickMenuProps): ReactNode — Versatile quick menu that takes many forms — a `radial` wheel, a partial `arc`, a vertical `list`, or a `grid` — over one item model with icons, labels, hotkeys, count badges, cooldowns, section headers, and nested submenus (drill in / back). Radial and arc forms reuse {@link RadialMenu}; list and grid render sectioned rows/tiles. The game supplies content and skin.
|
|
1510
|
+
- `QuickMenuItem` (interface): interface QuickMenuItem extends RadialMenuOption — An entry on a {@link QuickMenu}: a leaf action, or (with `children`) a submenu.
|
|
1511
|
+
- `QuickMenuLayout` (type): type QuickMenuLayout = "radial" | "arc" | "list" | "grid" — The forms a {@link QuickMenu} can take.
|
|
1512
|
+
- `QuickMenuProps` (interface): interface QuickMenuProps — Props for {@link QuickMenu}.
|
|
1513
|
+
|
|
1514
|
+
## @jgengine/react/radialMenu
|
|
1515
|
+
|
|
1516
|
+
- `RadialMenu` (function): function RadialMenu({ options, open = true, onSelect, onClose, size = 300, innerRadius = 52, arc, highlightIndex, accent = "var(--jg-accent, #38bdf8)", className, style, }: RadialMenuProps): ReactNode — Radial / quick menu (weapon or emote wheel) — a ring or partial `arc` of selectable wedges the player points at with the mouse (or a stick). Pointer angle drives the highlight via core `radialIndexFromVector`; click/confirm fires `onSelect`, the neutral hub closes. Options carry optional hotkeys, count badges, cooldowns, and submenu markers. The game supplies icons/labels and skins it.
|
|
1517
|
+
- `RadialMenuOption` (interface): interface RadialMenuOption — One selectable entry on a radial/quick menu (weapon or emote wheel).
|
|
1518
|
+
- `RadialMenuProps` (interface): interface RadialMenuProps — Props for {@link RadialMenu}.
|
|
1519
|
+
|
|
972
1520
|
## @jgengine/react/rotateDevice
|
|
973
1521
|
|
|
974
1522
|
- `RotateDeviceScreen` (function): function RotateDeviceScreen({ title = "Turn your device", description, requiredOrientation = "landscape", accent = "var(--jg-accent, #8ea2ff)", icon, className, style, }: { /** Short headline. */ title?: string; /** One concise explanatory line. Defaults from `requiredOrientation`. */ description?: … — Full-viewport, non-dismissible rotate-device gate shown when a game requires an orientation the device isn't in.
|
|
@@ -978,6 +1526,21 @@
|
|
|
978
1526
|
- `SaveStoreView` (interface): interface SaveStoreView<T> — The reactive slice of a {@link SaveStore} returned by {@link useSaveStore} — the live value plus bound save actions, all re-rendering on change.
|
|
979
1527
|
- `useSaveStore` (function): function useSaveStore<T>(store: SaveStore<T>, options?: { load?: boolean }): SaveStoreView<T> — Bind a {@link SaveStore} to React: returns the live `value` and `status` and re-renders whenever either changes. By default it calls `load()` once on mount (pass `{ load: false }` to hydrate yourself). The same hook works for offline (localStorage) and cloud (Convex/DB) saves — only the store's backend differs.
|
|
980
1528
|
|
|
1529
|
+
## @jgengine/react/saveSlots
|
|
1530
|
+
|
|
1531
|
+
- `SaveSlotMenu` (function): function SaveSlotMenu({ model, onLoad, onNew, onDelete, onContinue, title = "Select Save", theme, now = Date.now, metaIcons, className, style, }: SaveSlotMenuProps): ReactNode — A drop-in save-select / profile menu that renders a {@link SaveSlots} index as a column of cards. A filled slot shows its name, the free-string `meta` the game supplied as chips, and a relative "saved" time, with Load and Delete actions; an empty slot shows a "New Game" affordance. A top-level Continue button targets the newest save (`model.mostRecent()`). This is a starting-point game-front-end building block — the game owns final art, wording, and layout; reskin it with {@link SaveSlotMenuTheme} or HudTheme CSS vars. Presentation only: all state lives in the core model, and `meta` keys are never interpreted.
|
|
1532
|
+
- `SaveSlotMenuProps` (interface): interface SaveSlotMenuProps — Props for {@link SaveSlotMenu}.
|
|
1533
|
+
- `SaveSlotMenuTheme` (interface): interface SaveSlotMenuTheme — Reskin tokens for {@link SaveSlotMenu}. All optional — each falls back to a HudTheme var then a neutral default.
|
|
1534
|
+
- `relativeSavedAt` (function): function relativeSavedAt(savedAt: number, nowMs = Date.now()): string — Turn a `savedAt` timestamp into a compact relative label ("just now", "4m ago", "2d ago"). Presentation-only helper — the model stores raw ms.
|
|
1535
|
+
- `useSaveSlots` (function): function useSaveSlots(model: SaveSlots): SaveSlotMeta[] — Subscribe to a {@link SaveSlots} index and re-render on any change (write, clear, rename, restore). Returns the live list of slots in menu order. Wire it into a save-select screen and mutate the model in event handlers — the menu re-renders itself.
|
|
1536
|
+
|
|
1537
|
+
## @jgengine/react/scoreboard
|
|
1538
|
+
|
|
1539
|
+
- `MedalToken` (type): type MedalToken = "gold" | "silver" | "bronze" — The medal tokens {@link medalFor} emits for the podium.
|
|
1540
|
+
- `Scoreboard` (function): function Scoreboard({ entries, rows, options, title, scoreLabel = "Score", nameFor, formatScore, medalIcon, theme, className, style, }: ScoreboardProps): ReactNode — A reskinnable ranked-score table for the {@link rankLeaderboard} selector: a rank column (medal icon/color for the top three via {@link medalFor}, otherwise the number), a name column, and a score column. The local player's row (`isLocal`) is washed and accented so "you" stands out. Feed it already-ranked `entries`, or raw `rows` plus `options` and it ranks them for you. All colors and spacing come from {@link ScoreboardTheme} / HudTheme `--jg-*` tokens — the component reads the model and never styles by game meaning.
|
|
1541
|
+
- `ScoreboardProps` (interface): interface ScoreboardProps — Props for {@link Scoreboard}. Pass either `entries` (already ranked) or `rows` + `options`.
|
|
1542
|
+
- `ScoreboardTheme` (interface): interface ScoreboardTheme — Reskin tokens for {@link Scoreboard}. Every color/spacing value reads a `--jg-*` token first.
|
|
1543
|
+
|
|
981
1544
|
## @jgengine/react/selectSnapshot
|
|
982
1545
|
|
|
983
1546
|
- `SelectCache` (type): type SelectCache<TSnapshot, TSelected> = { ready: boolean; snapshot: TSnapshot; value: TSelected; } — ⚠ undocumented
|
|
@@ -997,6 +1560,7 @@
|
|
|
997
1560
|
|
|
998
1561
|
## @jgengine/react/settings
|
|
999
1562
|
|
|
1563
|
+
- `SETTINGS_TRIGGER_CLASSNAME` (const): const SETTINGS_TRIGGER_CLASSNAME: "pointer-events-auto flex h-8 w-8 items-center justify-center rounded-md border border-[var(--jg-edge-bright)] bg-[var(--jg-surface)]/80 text-base text-[var(--jg-text-dim)] shadow-[0_1px_2px_rgba(0,0,0,0.6)] transition hover:bg-[var(--jg-surface-deep)] hover:text-[v… — Default HudTheme-token skin for {@link SettingsTrigger} — the 8×8 chrome button games re-authored seven times. Pass your own `className` only to override placement or brand chrome; the gear glyph already scales with `text-base` / `1em`.
|
|
1000
1564
|
- `SettingsActionView` (interface): interface SettingsActionView — A resolved game-state action — `run` is already bound to the game context and closes the menu.
|
|
1001
1565
|
- `SettingsCategoryView` (interface): interface SettingsCategoryView — A settings menu category with its rows and keybinds, ready to render.
|
|
1002
1566
|
- `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.
|
|
@@ -1004,12 +1568,19 @@
|
|
|
1004
1568
|
- `SettingsKeybindRow` (interface): interface SettingsKeybindRow — One rebindable action row rendered in the controls settings category.
|
|
1005
1569
|
- `SettingsProvider` (function): function SettingsProvider({ store, children }: { store: SettingsStore; children: ReactNode }): React.JSX.Element — ⚠ undocumented
|
|
1006
1570
|
- `SettingsRow` (interface): interface SettingsRow — One editable setting rendered in a settings menu category.
|
|
1007
|
-
- `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`
|
|
1571
|
+
- `SettingsTrigger` (function): function SettingsTrigger({ className = SETTINGS_TRIGGER_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` only when overriding the default HudTheme skin; pass `children` to replace the gear glyph. Renders nothing when the game has no settings to show, so it never leaves a dead button behind.
|
|
1008
1572
|
- `useHasSettings` (function): function useHasSettings(): boolean — True when the game has any setting or game-action to show — gate your own settings entry on it.
|
|
1009
1573
|
- `useSetting` (function): function useSetting<T extends SettingValue>(id: string, fallback: T): readonly [T, (value: SettingValue) => void] — Read + write one persisted setting; re-renders when the value changes anywhere.
|
|
1010
1574
|
- `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.
|
|
1011
1575
|
- `useSettingsStore` (function): function useSettingsStore(): SettingsStore — The shared settings store, or a standalone one when no provider is mounted (game code read outside the shell).
|
|
1012
1576
|
|
|
1577
|
+
## @jgengine/react/shopGrid
|
|
1578
|
+
|
|
1579
|
+
- `ShopGrid` (function): function ShopGrid({ shop, wallet, onWalletChange, theme, currencyIcons, iconFor, showSell = false, walletCurrencies, title = "Shop", labelFor, minCardWidth = "140px", className, style, }: ShopGridProps): ReactNode — A drop-in vendor/shop grid: item cards (icon, name, price with a currency glyph, stock count or "∞") over a caller-owned wallet, plus a wallet balance readout. Each card's Buy button disables when the wallet cannot afford it (`shop.canAfford`) or the item is sold out; an optional Sell button appears for entries with a `sellPrice`. Buying/selling routes through the core shop model and hands the debited/credited wallet back via `onWalletChange` — the component never owns the wallet. Purely token-driven presentation (shared `--jg-*` HudTheme tokens, reskinnable via {@link ShopGridTheme}); `kind` and `currency` are free strings the game styles, never interpreted.
|
|
1580
|
+
- `ShopGridProps` (interface): interface ShopGridProps — Props for {@link ShopGrid}.
|
|
1581
|
+
- `ShopGridTheme` (interface): interface ShopGridTheme — Reskin tokens for {@link ShopGrid}. Falls back to shared `--jg-*` HudTheme tokens, then neutral defaults.
|
|
1582
|
+
- `useShopStock` (function): function useShopStock(shop: ShopStock): ShopStockEntry[] — Subscribe to a shop's stock and re-render whenever it changes (buy, sell, restock, price, add, remove, restore). Returns the current entry list — a detached snapshot safe to map over.
|
|
1583
|
+
|
|
1013
1584
|
## @jgengine/react/slots
|
|
1014
1585
|
|
|
1015
1586
|
- `ArmorSlots` (function): function ArmorSlots(props: SlotGridProps): React.JSX.Element — Armor piece slots.
|
|
@@ -1044,11 +1615,44 @@
|
|
|
1044
1615
|
- `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).
|
|
1045
1616
|
- `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.
|
|
1046
1617
|
|
|
1618
|
+
## @jgengine/react/statusEffectBar
|
|
1619
|
+
|
|
1620
|
+
- `StatusEffectBar` (function): function StatusEffectBar({ effects, size = 44, gap = 8, iconFor, colorFor, schoolFor, labelFor, showTimer = true, ringWidth = 3, className, style, }: StatusEffectBarProps): ReactNode — A horizontal timeline of active status effects — one countdown-ring icon per effect. Presentation only and pure over its `effects` prop, so it renders straight off the status model's snapshot. `kind` is a free string the game styles (icon / color / label); the component never interprets buff-vs-debuff semantics. Ring, track, and frame read `HudTheme` tokens, so a theme change reskins the whole row.
|
|
1621
|
+
- `StatusEffectBarProps` (interface): interface StatusEffectBarProps — Props for {@link StatusEffectBar}.
|
|
1622
|
+
- `StatusIconResolver` (type): type StatusIconResolver = (kind: string) => GameIconName | ReactNode | null — `StatusEffectBar` (#status-effect-hud): a drop-in timeline HUD row that renders active buffs/debuffs as painted icons, each wrapped in a radial countdown ring and a stack-count badge, driven straight off the engine's existing status model (`StatusInstance` → `StatusEffectView`). A game passes its live effect views and gets a polished, reskinnable effect bar — no re-deriving ring math or timers. `kind` is a free string the game styles: the component never interprets buff-vs-debuff semantics, it only maps `kind` to an icon/color/label the game can fully override. Ring, track, and frame read `HudTheme` tokens (`--jg-accent`, `--jg-slot-*`), so a theme change reskins the whole row.
|
|
1623
|
+
|
|
1047
1624
|
## @jgengine/react/store
|
|
1048
1625
|
|
|
1049
1626
|
- `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)`.
|
|
1050
1627
|
- `useStore` (function): function useStore<T>(handle: StoreHandle<T>): T — Subscribe a component to a typed store slot defined with `defineStore`. Returns the current value (or the definition's initial before any write), re-rendering only when the slot changes — the cast-free, boilerplate-free replacement for a hand-written `useGameStore((ctx) => ctx.game.store.get(KEY) as T)`.
|
|
1051
1628
|
|
|
1629
|
+
## @jgengine/react/streetGeometryPreview
|
|
1630
|
+
|
|
1631
|
+
- `StreetGeometryPreview` (function): function StreetGeometryPreview({ className }: { className?: string }): React.JSX.Element — Deterministic close-up gallery of the shared road/junction mesh seam.
|
|
1632
|
+
|
|
1633
|
+
## @jgengine/react/talentTree
|
|
1634
|
+
|
|
1635
|
+
- `TalentIcon` (type): type TalentIcon = GameIconName | ReactNode | null — How a node id resolves to display art: a built-in {@link GameIconName}, any node, or `null` for the default.
|
|
1636
|
+
- `TalentTree` (function): function TalentTree<TStat extends string = string>({ view: viewProp, nodes, tree, onLearn, icon, label, branchLabel, title = "Talents", variation = "themed", nodeSize = 54, columnGap = 30, tierGap = 46, showPoints = true, className, style, }: TalentTreeProps<TStat>): ReactNode — Drop-in talent / skill-tree widget over the existing progression model (`@jgengine/core/game/talents` + its `talentTreeView` selector). The game passes its node definitions and a live `createTalentTree` instance; the widget lays nodes out by branch column and prerequisite-depth tier, draws SVG prerequisite edges, styles each node learned/available/locked/maxed, shows an icon + rank badge, and calls `onLearn(nodeId)` when the player clicks a node that is currently allocatable. All layout, edge-drawing, and eligibility come from the model/selector — the widget never re-derives topology. Unskinned and HudTheme-token driven; node ids/branches are opaque game data the game supplies icons and labels for.
|
|
1637
|
+
- `TalentTreeProps` (interface): interface TalentTreeProps<TStat extends string = string> — Props for {@link TalentTree}.
|
|
1638
|
+
|
|
1639
|
+
## @jgengine/react/timerReadout
|
|
1640
|
+
|
|
1641
|
+
- `TimerFormat` (type): type TimerFormat = "mm:ss" | "m:ss.d" | "ss.d" — Digital text format for a timer readout.
|
|
1642
|
+
- `TimerReadout` (function): function TimerReadout({ timer, id, source = "auto", format = "mm:ss", placeholder = "--:--", active = true, className, style, }: TimerReadoutProps): ReactNode — A live digital timer readout (mm:ss / m:ss.d) driven off a {@link TimerSet}. It re-reads every frame and formats remaining or elapsed time — a round clock, a respawn countdown, or an ability charge, all the same widget. HudTheme-skinned via `--jg-bar-text`; reskin with `style` or the theme tokens.
|
|
1643
|
+
- `TimerReadoutProps` (interface): interface TimerReadoutProps — Props for {@link TimerReadout}.
|
|
1644
|
+
- `TimerReadoutSource` (type): type TimerReadoutSource = "auto" | "remaining" | "elapsed" — Which value a readout leads with. `"auto"` follows the timer's direction — remaining for a countdown, elapsed for a countup charge.
|
|
1645
|
+
- `TimerRing` (function): function TimerRing({ timer, id, size = 72, thickness = 8, mode = "fill", color = "var(--jg-accent, #38bdf8)", trackColor = "var(--jg-bar-track, rgba(148,163,184,0.25))", children, active = true, className, style, }: TimerRingProps): ReactNode — A radial charge/cooldown ring driven off a {@link TimerSet}'s `progress01`. Re-reads every frame and sweeps an SVG arc as the timer advances — ability charge, cooldown wipe, respawn ring, capture progress, all the same widget. `mode` chooses filling vs. draining; center `children` can hold a readout. HudTheme-skinned via `--jg-accent` / `--jg-bar-track`.
|
|
1646
|
+
- `TimerRingProps` (interface): interface TimerRingProps — Props for {@link TimerRing}.
|
|
1647
|
+
- `formatTimerMs` (function): function formatTimerMs(ms: number, format: TimerFormat = "mm:ss"): string — Format a millisecond duration as digital timer text — `mm:ss` (default), `m:ss.d` (with tenths), or `ss.d` (seconds + tenths). Negative inputs clamp to zero. No genre meaning: the same helper serves a round clock, a respawn countdown, or an ability charge readout.
|
|
1648
|
+
- `useTimerRead` (function): function useTimerRead(timer: TimerSet, id: string, active = true): TimerRead | null — Subscribe to a single timer and re-read it every animation frame while mounted, so a HUD readout stays live without the game hand-rolling interval math. Reuses one read object (allocation-aware). Returns `null` for an unknown id. Pass `active={false}` to freeze the per-frame tick (e.g. an off-screen HUD).
|
|
1649
|
+
|
|
1650
|
+
## @jgengine/react/useDebouncedCommit
|
|
1651
|
+
|
|
1652
|
+
- `DebounceTimer` (interface): interface DebounceTimer — Injectable timer seam so the controller is testable with a manual clock.
|
|
1653
|
+
- `DebouncedCommit` (interface): interface DebouncedCommit<T> — Live-mirrored, trailing-debounced commit binding for a single control value.
|
|
1654
|
+
- `useDebouncedCommit` (function): function useDebouncedCommit<T>(value: T, commit: (value: T) => void, delayMs = 180): DebouncedCommit<T> — See {@link DebouncedCommit}. `commit` and `delayMs` may change between renders (kept in refs); the binding identity stays stable except when `value` (the local mirror) changes.
|
|
1655
|
+
|
|
1052
1656
|
## @jgengine/react/voice
|
|
1053
1657
|
|
|
1054
1658
|
- `MicToggle` (function): function MicToggle({ voice, className, mutedLabel, unmutedLabel, }: { voice: VoiceState; className?: string; mutedLabel?: ReactNode; unmutedLabel?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
@@ -1059,6 +1663,20 @@
|
|
|
1059
1663
|
- `VoiceState` (interface): interface VoiceState — ⚠ undocumented
|
|
1060
1664
|
- `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.
|
|
1061
1665
|
|
|
1666
|
+
## @jgengine/react/waveHud
|
|
1667
|
+
|
|
1668
|
+
- `WaveHud` (function): function WaveHud({ runner, theme, variation = "plate", width = 260, className, style }: WaveHudProps): ReactNode — A drop-in wave/spawn HUD panel over a {@link WaveRunner}: a big "WAVE N" label, a wave-progress bar (the shared {@link ExperienceBar}), and the live spawned / total, budget, and alert readouts — the visible face of "the brain behind WAVE 3". It subscribes to the runner and re-renders on change; the game drives the runner's clock. Reskin with {@link WaveHudTheme} and the shared HudTheme bar tokens. When the final wave finishes it shows a "WAVES CLEARED" state. Presentation only: the schedule, budget, and RNG live in the core model, and spawn `kind`s are never read.
|
|
1669
|
+
- `WaveHudProps` (interface): interface WaveHudProps — Props for {@link WaveHud}.
|
|
1670
|
+
- `WaveHudTheme` (interface): interface WaveHudTheme — Reskin tokens for {@link WaveHud}. All optional; each falls back to a sensible default.
|
|
1671
|
+
- `useWaveRunner` (function): function useWaveRunner(runner: WaveRunner): WaveView — Subscribe to a {@link WaveRunner} and re-render whenever it notifies (wave, budget, spawns, alert change). Returns the runner's pooled {@link WaveView}. The runner is driven by the game/demo (call `runner.update(dt)`), not by this hook.
|
|
1672
|
+
|
|
1673
|
+
## @jgengine/react/waypointMarkers
|
|
1674
|
+
|
|
1675
|
+
- `WaypointMarkerTheme` (interface): interface WaypointMarkerTheme — Reskin tokens for {@link WaypointMarkers}. Per-`kind` color layers on top via `kindColors`.
|
|
1676
|
+
- `WaypointMarkers` (function): function WaypointMarkers({ entries, project, viewport, distanceOf, distanceFormat, theme, kindColors, margin = 28, showPinLabels = true, className, style, }: WaypointMarkersProps): ReactNode — Off-screen objective / waypoint markers: an absolutely-positioned overlay that turns a set of world waypoints into on-screen pins and off-screen directional arrows. For each waypoint it calls the caller's `project` to get a screen point, then {@link layoutScreenMarker} to decide: an in-view target renders a pin (and optional label) at its projected spot; an off-screen or behind-camera target renders an arrow clamped to the viewport edge, rotated to point the way, with an optional distance label from `distanceOf`. Color comes from `theme` plus a per-`kind` `kindColors` map the game owns — the model never interprets `kind`. Presentation only: tracking, projection, and distance are all caller-supplied.
|
|
1677
|
+
- `WaypointMarkersProps` (interface): interface WaypointMarkersProps — Props for {@link WaypointMarkers}.
|
|
1678
|
+
- `useWaypoints` (function): function useWaypoints(source: WaypointTracker | readonly Waypoint[]): readonly Waypoint[] — Subscribe to a {@link WaypointTracker} and re-render on every change, returning its current waypoints. Pass a plain array instead and it is returned as-is (no subscription), so a game can drive the host from a tracker or from its own derived state.
|
|
1679
|
+
|
|
1062
1680
|
## @jgengine/shell/GamePhaseStamp
|
|
1063
1681
|
|
|
1064
1682
|
- `GamePhaseStamp` (function): function GamePhaseStamp(): null — ⚠ undocumented
|
|
@@ -1125,6 +1743,8 @@
|
|
|
1125
1743
|
- `CameraOccluder` (interface): interface CameraOccluder — Camera spring-arm occlusion filtering.
|
|
1126
1744
|
- `CameraShakeChannel` (interface): interface CameraShakeChannel — ⚠ undocumented
|
|
1127
1745
|
- `CameraShakeContext` (const): const CameraShakeContext: React.Context<CameraShakeChannel> — ⚠ undocumented
|
|
1746
|
+
- `ControllerCameraShake` (function): function ControllerCameraShake({ controller, priority = GAME_SIM_FRAME_PRIORITY, }: ControllerCameraShakeProps): ReactNode — The shell-side consumer of a core {@link CameraShakeController}: each frame it calls `controller.update(delta)` to bleed trauma, reads the pooled `controller.offset()`, and applies it additively to the active camera — a positional kick plus a pitch/yaw/roll rotation — so the view VISIBLY shakes on impacts. It runs after the camera rig (which re-poses the camera to its base every frame), so the shake composes with any rig without a manual save/restore and without fighting the built-in `shakeChannel`. Renders nothing.
|
|
1747
|
+
- `ControllerCameraShakeProps` (interface): interface ControllerCameraShakeProps — Props for {@link ControllerCameraShake}.
|
|
1128
1748
|
- `GAME_SIM_FRAME_PRIORITY` (const): const GAME_SIM_FRAME_PRIORITY: 0 — Run simulation/movement before orbit follow so poses are current.
|
|
1129
1749
|
- `GameCameraRig` (function): function GameCameraRig({ yawRef, pitchRef, config, onDragChange, pointerControls, panKeysEnabled, director, viewmodel, }: GameCameraRigProps): React.JSX.Element — ⚠ undocumented
|
|
1130
1750
|
- `GameCameraRigProps` (interface): interface GameCameraRigProps — ⚠ undocumented
|
|
@@ -1143,6 +1763,11 @@
|
|
|
1143
1763
|
- `readFirstPersonMuzzle` (function): function readFirstPersonMuzzle(target: THREE.Vector3): boolean — World position of the first-person weapon muzzle, or false when no viewmodel is mounted.
|
|
1144
1764
|
- `usePlayerFov` (function): function usePlayerFov(): PlayerFovState — ⚠ undocumented
|
|
1145
1765
|
|
|
1766
|
+
## @jgengine/shell/camera/ControllerCameraShake
|
|
1767
|
+
|
|
1768
|
+
- `ControllerCameraShake` (function): function ControllerCameraShake({ controller, priority = GAME_SIM_FRAME_PRIORITY, }: ControllerCameraShakeProps): ReactNode — The shell-side consumer of a core {@link CameraShakeController}: each frame it calls `controller.update(delta)` to bleed trauma, reads the pooled `controller.offset()`, and applies it additively to the active camera — a positional kick plus a pitch/yaw/roll rotation — so the view VISIBLY shakes on impacts. It runs after the camera rig (which re-poses the camera to its base every frame), so the shake composes with any rig without a manual save/restore and without fighting the built-in `shakeChannel`. Renders nothing.
|
|
1769
|
+
- `ControllerCameraShakeProps` (interface): interface ControllerCameraShakeProps — Props for {@link ControllerCameraShake}.
|
|
1770
|
+
|
|
1146
1771
|
## @jgengine/shell/camera/GameCameraRig
|
|
1147
1772
|
|
|
1148
1773
|
- `GameCameraRig` (function): function GameCameraRig({ yawRef, pitchRef, config, onDragChange, pointerControls, panKeysEnabled, director, viewmodel, }: GameCameraRigProps): React.JSX.Element — ⚠ undocumented
|
|
@@ -1344,7 +1969,7 @@
|
|
|
1344
1969
|
|
|
1345
1970
|
## @jgengine/shell/drivers/FrameDriver
|
|
1346
1971
|
|
|
1347
|
-
- `FrameDriver` (function): function FrameDriver({ ctx, playable, tracker, yawRef, pitchRef, primaryClickRef, pointerAxisRef, gateRef, onRuntimeError, multiplayer, serverIdRef, pointerService, pointerAim, pingCommand, poster, onPosterSettled, }: { ctx: GameContext; playable: PlayableGame; tracker: ActionStateTracker
|
|
1972
|
+
- `FrameDriver` (function): function FrameDriver({ ctx, playable, tracker, yawRef, pitchRef, primaryClickRef, pointerAxisRef, analogRef, gateRef, onRuntimeError, multiplayer, serverIdRef, pointerService, pointerAim, pingCommand, poster, onPosterSettled, }: { ctx: GameContext; playable: PlayableGame; tracker: ActionStateTracker… — ⚠ undocumented
|
|
1348
1973
|
- `POSTER_SETTLE_SECONDS` (const): const POSTER_SETTLE_SECONDS: 1.6 — ⚠ undocumented
|
|
1349
1974
|
|
|
1350
1975
|
## @jgengine/shell/drivers/HudOnlyDriver
|
|
@@ -1353,6 +1978,8 @@
|
|
|
1353
1978
|
|
|
1354
1979
|
## @jgengine/shell/environment
|
|
1355
1980
|
|
|
1981
|
+
- `DayNightSky` (function): function DayNightSky({ cycle, radius, hazeStrength, sunGlowStrength, lights = true, keyLightIntensity = 1.1, ambientIntensity = 0.6, }: DayNightSkyProps): React.JSX.Element — Binds a {@link DayNightCycle} to the engine's existing `SkyDome` shader and a pair of lights: each frame it reads `cycle.sample()` and writes the blended tint into the dome's top/horizon/sun uniforms while the sun's arc comes from the shared `daylightStateAt` geometry. This is the turnkey presentation seam — a game mounts this one component in its scene and gets a moving, color-graded day-night sky from the serializable model, with no hand-rolled per-frame lerp and no new renderer. The cycle's `phase`/color values are free-form and never interpreted here.
|
|
1982
|
+
- `DayNightSkyProps` (interface): interface DayNightSkyProps — Props for {@link DayNightSky}: the cycle to bind plus optional dome shape and light-strength knobs.
|
|
1356
1983
|
- `DaylightCycleConfig` (interface): interface DaylightCycleConfig — ⚠ undocumented
|
|
1357
1984
|
- `DaylightProps` (interface): interface DaylightProps — ⚠ undocumented
|
|
1358
1985
|
- `DaylightState` (interface): interface DaylightState — ⚠ undocumented
|
|
@@ -1367,6 +1994,8 @@
|
|
|
1367
1994
|
|
|
1368
1995
|
## @jgengine/shell/environment
|
|
1369
1996
|
|
|
1997
|
+
- `DayNightSky` (function): function DayNightSky({ cycle, radius, hazeStrength, sunGlowStrength, lights = true, keyLightIntensity = 1.1, ambientIntensity = 0.6, }: DayNightSkyProps): React.JSX.Element — Binds a {@link DayNightCycle} to the engine's existing `SkyDome` shader and a pair of lights: each frame it reads `cycle.sample()` and writes the blended tint into the dome's top/horizon/sun uniforms while the sun's arc comes from the shared `daylightStateAt` geometry. This is the turnkey presentation seam — a game mounts this one component in its scene and gets a moving, color-graded day-night sky from the serializable model, with no hand-rolled per-frame lerp and no new renderer. The cycle's `phase`/color values are free-form and never interpreted here.
|
|
1998
|
+
- `DayNightSkyProps` (interface): interface DayNightSkyProps — Props for {@link DayNightSky}: the cycle to bind plus optional dome shape and light-strength knobs.
|
|
1370
1999
|
- `DaylightCycleConfig` (interface): interface DaylightCycleConfig — ⚠ undocumented
|
|
1371
2000
|
- `DaylightProps` (interface): interface DaylightProps — ⚠ undocumented
|
|
1372
2001
|
- `DaylightState` (interface): interface DaylightState — ⚠ undocumented
|
|
@@ -1379,6 +2008,11 @@
|
|
|
1379
2008
|
- `TimeOfDayDaylightProps` (interface): interface TimeOfDayDaylightProps — ⚠ undocumented
|
|
1380
2009
|
- `VolumetricCloudsProps` (interface): interface VolumetricCloudsProps — Props for {@link VolumetricClouds} — fully-resolved cloud rules plus the shared sun direction.
|
|
1381
2010
|
|
|
2011
|
+
## @jgengine/shell/environment/DayNightSky
|
|
2012
|
+
|
|
2013
|
+
- `DayNightSky` (function): function DayNightSky({ cycle, radius, hazeStrength, sunGlowStrength, lights = true, keyLightIntensity = 1.1, ambientIntensity = 0.6, }: DayNightSkyProps): React.JSX.Element — Binds a {@link DayNightCycle} to the engine's existing `SkyDome` shader and a pair of lights: each frame it reads `cycle.sample()` and writes the blended tint into the dome's top/horizon/sun uniforms while the sun's arc comes from the shared `daylightStateAt` geometry. This is the turnkey presentation seam — a game mounts this one component in its scene and gets a moving, color-graded day-night sky from the serializable model, with no hand-rolled per-frame lerp and no new renderer. The cycle's `phase`/color values are free-form and never interpreted here.
|
|
2014
|
+
- `DayNightSkyProps` (interface): interface DayNightSkyProps — Props for {@link DayNightSky}: the cycle to bind plus optional dome shape and light-strength knobs.
|
|
2015
|
+
|
|
1382
2016
|
## @jgengine/shell/environment/Daylight
|
|
1383
2017
|
|
|
1384
2018
|
- `DaylightProps` (interface): interface DaylightProps — ⚠ undocumented
|
|
@@ -1398,7 +2032,9 @@
|
|
|
1398
2032
|
|
|
1399
2033
|
## @jgengine/shell/environment/RoadRibbons
|
|
1400
2034
|
|
|
1401
|
-
- `
|
|
2035
|
+
- `AuthoredRoadNetwork` (interface): interface AuthoredRoadNetwork — Trimmed ribbons for every road plus the welded surfaces that fill the crossings between them.
|
|
2036
|
+
- `JunctionSurface` (interface): interface JunctionSurface — One welded asphalt junction surface plus the color it should render in.
|
|
2037
|
+
- `RoadRibbons` (function): function RoadRibbons({ road, field, paths, }: { road: RoadEnvironmentDescriptor; field: TerrainField; paths: readonly (readonly RoadPoint[])[]; }): React.JSX.Element | null — Renders one `road()` descriptor from its trimmed centerline sub-paths (cut back at every junction by {@link buildAuthoredRoadNetwork}): an asphalt ribbon, a curb/edge strip along each border, an optional dashed centerline, and optional sidewalks. Because the sub-paths already stop at the junction boundary, every layer naturally ends there — no ribbon ploughs through the crossing and the dashed line no longer needs exclusion circles to skip intersections.
|
|
1402
2038
|
|
|
1403
2039
|
## @jgengine/shell/environment/VolumetricClouds
|
|
1404
2040
|
|
|
@@ -1488,12 +2124,24 @@
|
|
|
1488
2124
|
|
|
1489
2125
|
## @jgengine/shell/postfx/PostProcessing
|
|
1490
2126
|
|
|
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.
|
|
2127
|
+
- `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 → SMAA → OutputPass → Grade. Rendered only when `PlayableGame.postProcessing` is set, so games without it draw unchanged.
|
|
2128
|
+
|
|
2129
|
+
## @jgengine/shell/postfx/ScreenEffectsOverlay
|
|
2130
|
+
|
|
2131
|
+
- `ScreenEffectsOverlay` (function): function ScreenEffectsOverlay({ controller, blendMode = "normal", zIndex = 40, animate = true, }: ScreenEffectsOverlayProps): ReactNode — A DOM overlay that renders a {@link ScreenEffectsController} as full-screen color-grade layers over the game canvas — damage vignettes, heal flashes, a sustained low-health pulse — through the shell's postfx overlay layer, so a game gets screen feedback without hand-rolling shader or overlay timing. It subscribes to the model, drives `advance()` on an animation frame (unless the game ticks it), and paints one absolutely-positioned, pointer-transparent layer per active effect at its eased opacity. Presentation only: all timing and state live in the core model, and `kind` is never interpreted here.
|
|
2132
|
+
- `ScreenEffectsOverlayProps` (interface): interface ScreenEffectsOverlayProps — Reskin tokens for {@link ScreenEffectsOverlay}.
|
|
1492
2133
|
|
|
1493
2134
|
## @jgengine/shell/postfx/gradeShader
|
|
1494
2135
|
|
|
1495
2136
|
- `createGradePass` (function): function createGradePass(config: GradeConfig = {}): ShaderPass — Build the display-space colour-grade pass (lift/gain/gamma, saturation, vignette, grain). Advance `uniforms.uTime.value` each frame to animate the grain.
|
|
1496
2137
|
|
|
2138
|
+
## @jgengine/shell/postfx/postfxOverlay
|
|
2139
|
+
|
|
2140
|
+
- `POSTFX_OVERLAY_USERDATA` (const): const POSTFX_OVERLAY_USERDATA: { readonly jgPostfxOverlay: true } — Spread onto a group's `userData` to mark its subtree as a screen/world overlay effect — additive glows, telegraphs, tracers, debug gizmos — that post-processing scene prepasses (GTAO's normal/depth render, DOF's depth render) must skip. Those prepasses render the scene with `overrideMaterial`, which turns transparent overlay quads into opaque stamps in the AO/DOF buffers (visible as black squares over hit sparks). The shell marks its own combat VFX and collision-debug mounts; games mark custom overlay effects the same way.
|
|
2141
|
+
- `hidePostfxOverlays` (function): function hidePostfxOverlays(scene: THREE.Object3D, out: THREE.Object3D[]): void — Hide every currently visible marked object under `scene`, recording what was hidden into `out` (cleared first, no allocation on the hot path) so {@link restorePostfxOverlays} can undo exactly that set.
|
|
2142
|
+
- `isPostfxOverlay` (function): function isPostfxOverlay(object: { userData?: Record<string, unknown> }): boolean — True when the object opted out of postfx scene prepasses via {@link POSTFX_OVERLAY_USERDATA}.
|
|
2143
|
+
- `restorePostfxOverlays` (function): function restorePostfxOverlays(hidden: THREE.Object3D[]): void — Restore visibility for the objects hidden by {@link hidePostfxOverlays} and clear the list.
|
|
2144
|
+
|
|
1497
2145
|
## @jgengine/shell/registry
|
|
1498
2146
|
|
|
1499
2147
|
- `GameRegistry` (type): type GameRegistry = Record<string, () => Promise<PlayableGame>> — ⚠ undocumented
|
|
@@ -1502,6 +2150,11 @@
|
|
|
1502
2150
|
- `RenderObject` (type): type RenderObject = (object: SceneObject) => ReactNode — ⚠ undocumented
|
|
1503
2151
|
- `resolveGameLoader` (function): function resolveGameLoader(registry: GameRegistry, gameId: string, fallbackGameId?: string): (() => Promise<PlayableGame>) | undefined — ⚠ undocumented
|
|
1504
2152
|
|
|
2153
|
+
## @jgengine/shell/render/EntityPreview
|
|
2154
|
+
|
|
2155
|
+
- `EntityPreview` (function): function EntityPreview({ children, model, instanceId, mood = "studio", backdrop, turntable = 0, faceCamera = false, forward, environment = true, cameraPosition = [0, 1, 3], fov = 35, dpr = [1, 2], className, style, }: EntityPreviewProps): React.JSX.Element — Drop-in live 3D preview of a single entity — the character-screen portrait, unit inspector, or loadout viewer. It owns all the plumbing a game would otherwise re-derive by hand: a nested `<Canvas>`, the {@link GameContextBridge} that carries the running `GameContext` across the R3F reconciler boundary (so the subject's `useEntityRenderCues` / `useGameContext` hooks resolve and it mirrors the live game), a {@link StudioStage} 3-point lighting rig with optional turntable / face-camera, and a capture-friendly GL surface. The game keeps ownership of its `renderEntity`: pass it as `children`, or hand a native `model` (+ `instanceId`) for an engine-composed body. Bound to a live `instanceId`, the portrait walks, flinches, and topples in lockstep with the world instead of a canned spin.
|
|
2156
|
+
- `EntityPreviewProps` (interface): interface EntityPreviewProps — Props for {@link EntityPreview}.
|
|
2157
|
+
|
|
1505
2158
|
## @jgengine/shell/render/PartMotion
|
|
1506
2159
|
|
|
1507
2160
|
- `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).
|
|
@@ -1531,6 +2184,12 @@
|
|
|
1531
2184
|
- `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
2185
|
- `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.
|
|
1533
2186
|
|
|
2187
|
+
## @jgengine/shell/render/measureCollisionMesh
|
|
2188
|
+
|
|
2189
|
+
- `MeasuredCollisionTriangles` (interface): interface MeasuredCollisionTriangles extends CollisionMeshSource — Entity-local triangle soup of the meshes under a measured root, plus the contributing mesh count (same async fill-in detection as measured bounds). Satisfies {@link CollisionMeshSource}.
|
|
2190
|
+
- `measureLocalCollisionTriangles` (function): function measureLocalCollisionTriangles(root: THREE.Object3D, transform?: { scale: number; offset: readonly [number, number, number] }): MeasuredCollisionTriangles | null — Collect the triangle soup of the meshes under `root` in `root`'s own frame — the mesh-accurate counterpart to `measureLocalBounds`, with the same visibility/sprite/{@link MEASURE_EXCLUDE_KEY} exclusions (skinned meshes contribute their bind pose). An optional uniform `scale` + `offset` maps the result into entity-local space when the caller mounts the root scaled/translated (the model-primitive path). Returns `null` when nothing is measurable or the soup exceeds the triangle budget — callers keep their box fallback.
|
|
2191
|
+
- `reportMeasuredCollisionMesh` (function): function reportMeasuredCollisionMesh(ctx: GameContext, target: "entity" | "object", key: string, triangles: MeasuredCollisionTriangles): void — Forward measured triangles into the context (entity kind or object catalog id), deduping repeat reports of the same soup so remounts and multi-instance kinds don't rebuild the BVH.
|
|
2192
|
+
|
|
1534
2193
|
## @jgengine/shell/render/modelRender
|
|
1535
2194
|
|
|
1536
2195
|
- `MaterialCache` (interface): interface MaterialCache — ⚠ undocumented
|
|
@@ -1542,6 +2201,19 @@
|
|
|
1542
2201
|
- `ModelPick` (type): type ModelPick = { model?: string; fallbackModel?: string; style?: Omit<ModelConfig, "url" | "dims">; } — Preferred + optional fallback catalog ids for a single entity/object slot. Soft-resolves through the catalog: when neither id is live (pack not pulled/ reindexed yet), the mapping is omitted and the shell keeps its primitive. Re-home later by fixing ids / pulling packs — no Kenney, no hard throws.
|
|
1543
2202
|
- `ModelResolveContext` (interface): interface ModelResolveContext — ⚠ undocumented
|
|
1544
2203
|
|
|
2204
|
+
## @jgengine/shell/render/sceneCapture
|
|
2205
|
+
|
|
2206
|
+
- `CaptureRenderer` (interface): interface CaptureRenderer — The bit of a WebGL renderer scene capture needs — its backing `<canvas>`.
|
|
2207
|
+
- `SceneCaptureBinding` (function): function SceneCaptureBinding({ bind }: { bind: (capture: () => string | null) => void }): null — In-`<Canvas>` binder that hands the scene-capture function out to HUD code living outside the reconciler (a photo-mode Capture button). Mount it inside the game's `WorldOverlay`; call `bind` receives a `() => string | null` that grabs the current frame. Renders nothing.
|
|
2208
|
+
- `captureCanvas` (function): function captureCanvas(gl: CaptureRenderer): string | null — Read the current frame to a PNG data URL. Requires the R3F `<Canvas>` to have been created with `gl={{ preserveDrawingBuffer: true }}` (the shell's game canvas already is); returns null if the backing canvas can't be read.
|
|
2209
|
+
- `downloadImage` (function): function downloadImage(dataUrl: string, filename = "screenshot.png"): void — Trigger a browser download of an image data URL (the photo-mode "save" action).
|
|
2210
|
+
|
|
2211
|
+
## @jgengine/shell/render/useDisposable
|
|
2212
|
+
|
|
2213
|
+
- `Disposable` (interface): interface Disposable — Anything exposing dispose() — three.js geometries, materials, textures, render targets.
|
|
2214
|
+
- `disposeAll` (function): function disposeAll(value: Disposable | readonly Disposable[]): void — Dispose a single resource or every resource in a tuple.
|
|
2215
|
+
- `useDisposable` (function): function useDisposable<T extends Disposable | readonly Disposable[]>(create: () => T, deps: DependencyList): T — Memoize a three.js resource (or tuple of resources) and dispose it when `deps` change or the component unmounts. Owns the useMemo + dispose-effect pair that otherwise repeats at every GPU-resource call site. The factory must return objects exposing `dispose()` (geometries, materials, textures, render targets).
|
|
2216
|
+
|
|
1545
2217
|
## @jgengine/shell/render/useEntityRenderCues
|
|
1546
2218
|
|
|
1547
2219
|
- `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`.
|
|
@@ -1642,6 +2314,11 @@
|
|
|
1642
2314
|
- `EMPTY_RESERVED` (const): const EMPTY_RESERVED: ReadonlySet<string> — No action names are reserved when no camera rig is active (hud/none presentation): games may bind `turnLeft`/`interact`/etc. as their own.
|
|
1643
2315
|
- `NO_ACTIONS` (const): const NO_ACTIONS: string[] — Empty action list — published while the orientation gate is up to suppress all held input without touching the tracker.
|
|
1644
2316
|
|
|
2317
|
+
## @jgengine/shell/shellMovement
|
|
2318
|
+
|
|
2319
|
+
- `DEFAULT_WALK_CODES` (const): const DEFAULT_WALK_CODES: { readonly moveForward: readonly ["KeyW"]; readonly moveBack: readonly ["KeyS"]; readonly moveLeft: readonly ["KeyA"]; readonly moveRight: readonly ["KeyD"]; readonly jump: readonly ["Space"]; } — Default keyboard codes for the shell walk controller (WASD + Space). Use as the base of `defineGame({ input: { ...DEFAULT_WALK_CODES, interact: ["KeyE"] } })` instead of re-typing the same five bindings in every game.
|
|
2320
|
+
- `SHELL_MOVEMENT_ACTIONS` (const): const SHELL_MOVEMENT_ACTIONS: readonly ["moveForward", "moveBack", "moveLeft", "moveRight", "jump"] — Movement action names the shell drives via the walk controller.
|
|
2321
|
+
|
|
1645
2322
|
## @jgengine/shell/structures
|
|
1646
2323
|
|
|
1647
2324
|
- `BuildingBlock` (function): function BuildingBlock({ part, palette }: BuildingBlockProps): React.JSX.Element — ⚠ undocumented
|
|
@@ -1741,6 +2418,7 @@
|
|
|
1741
2418
|
- `TerrainHeightSampler` (type): type TerrainHeightSampler = (x: number, z: number) => number — ⚠ undocumented
|
|
1742
2419
|
- `TerrainNormal` (type): type TerrainNormal = readonly [number, number, number] — A surface normal vector at a terrain sample point.
|
|
1743
2420
|
- `TerrainSeed` (type): type TerrainSeed = number | string — ⚠ undocumented
|
|
2421
|
+
- `TerrainSurfaceColorOptions` (interface): interface TerrainSurfaceColorOptions — Slope/noise surface shading laid over the height lerp so untextured ground reads like terrain instead of a smooth two-tone gradient. All knobs are optional with sane defaults; every field is a pure function of vertex position (+ `seed`), so the coloring is stable across rebuilds and tests.
|
|
1744
2422
|
- `TerrainVertexColorOptions` (interface): interface TerrainVertexColorOptions — ⚠ undocumented
|
|
1745
2423
|
- `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.
|
|
1746
2424
|
|
|
@@ -1778,6 +2456,7 @@
|
|
|
1778
2456
|
- `TerrainHeightSampler` (type): type TerrainHeightSampler = (x: number, z: number) => number — ⚠ undocumented
|
|
1779
2457
|
- `TerrainNormal` (type): type TerrainNormal = readonly [number, number, number] — A surface normal vector at a terrain sample point.
|
|
1780
2458
|
- `TerrainSeed` (type): type TerrainSeed = number | string — ⚠ undocumented
|
|
2459
|
+
- `TerrainSurfaceColorOptions` (interface): interface TerrainSurfaceColorOptions — Slope/noise surface shading laid over the height lerp so untextured ground reads like terrain instead of a smooth two-tone gradient. All knobs are optional with sane defaults; every field is a pure function of vertex position (+ `seed`), so the coloring is stable across rebuilds and tests.
|
|
1781
2460
|
- `TerrainVertexColorOptions` (interface): interface TerrainVertexColorOptions — ⚠ undocumented
|
|
1782
2461
|
- `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.
|
|
1783
2462
|
|
|
@@ -1824,7 +2503,7 @@
|
|
|
1824
2503
|
|
|
1825
2504
|
## @jgengine/shell/terrain/grassMaterial
|
|
1826
2505
|
|
|
1827
|
-
- `DEFAULT_GRASS_DISTANCE_FADE` (const): const DEFAULT_GRASS_DISTANCE_FADE: Required<GrassDistanceFadeOptions> — Default camera-distance fade band: tufts start thinning at
|
|
2506
|
+
- `DEFAULT_GRASS_DISTANCE_FADE` (const): const DEFAULT_GRASS_DISTANCE_FADE: Required<GrassDistanceFadeOptions> — Default camera-distance fade band: tufts start thinning at 55 m and are gone by 150 m so the meadow reads deep.
|
|
1828
2507
|
- `DEFAULT_GRASS_WIND` (const): const DEFAULT_GRASS_WIND: Required<GrassWindOptions> — ⚠ undocumented
|
|
1829
2508
|
- `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.
|
|
1830
2509
|
- `GrassMaterialHandle` (interface): interface GrassMaterialHandle — ⚠ undocumented
|
|
@@ -1861,6 +2540,7 @@
|
|
|
1861
2540
|
- `TerrainArea` (type): type TerrainArea = number | readonly [width: number, depth: number] — ⚠ undocumented
|
|
1862
2541
|
- `TerrainHeightSampler` (type): type TerrainHeightSampler = (x: number, z: number) => number — ⚠ undocumented
|
|
1863
2542
|
- `TerrainPaletteSampler` (type): type TerrainPaletteSampler = (x: number, z: number) => { low: string; high: string; waterline?: string } — Per-position palette override for multi-biome ground coloring — `createTerrainPaletteSampler` from `@jgengine/core/world/terrain` returns exactly this shape.
|
|
2543
|
+
- `TerrainSurfaceColorOptions` (interface): interface TerrainSurfaceColorOptions — Slope/noise surface shading laid over the height lerp so untextured ground reads like terrain instead of a smooth two-tone gradient. All knobs are optional with sane defaults; every field is a pure function of vertex position (+ `seed`), so the coloring is stable across rebuilds and tests.
|
|
1864
2544
|
- `TerrainVertexColorOptions` (interface): interface TerrainVertexColorOptions — ⚠ undocumented
|
|
1865
2545
|
|
|
1866
2546
|
## @jgengine/shell/touch/OrientationHint
|
|
@@ -1870,7 +2550,7 @@
|
|
|
1870
2550
|
## @jgengine/shell/touch/TouchControlsOverlay
|
|
1871
2551
|
|
|
1872
2552
|
- `TouchCodeSink` (interface): interface TouchCodeSink — ⚠ undocumented
|
|
1873
|
-
- `TouchControlsDock` (function): function TouchControlsDock({ scheme, sink, style, scale = 1, }: { scheme: TouchScheme; sink: TouchCodeSink; /** Player-selected skin; falls back to the scheme's game default. */ style?: TouchStyle; scale?: number;
|
|
2553
|
+
- `TouchControlsDock` (function): function TouchControlsDock({ scheme, sink, style, scale = 1, joystickVariant = "floating", }: { scheme: TouchScheme; sink: TouchCodeSink; /** Player-selected skin; falls back to the scheme's game default. */ style?: TouchStyle; scale?: number; /** Player-selected joystick behavior (Settings → Contro… — ⚠ undocumented
|
|
1874
2554
|
- `TouchPlaySurface` (function): function TouchPlaySurface({ scheme, sink, yawRef, pitchRef, maxPitch, onPrimaryTap, }: { scheme: TouchScheme; sink: TouchCodeSink; yawRef: MutableRefObject<number>; pitchRef: MutableRefObject<number>; maxPitch: number; onPrimaryTap: () => void; }): React.JSX.Element — ⚠ undocumented
|
|
1875
2555
|
- `primaryButtonOffsets` (function): function primaryButtonOffsets(count: number, scale = 1): { right: number; bottom: number }[] | null — Thumb-arc placement for primary buttons around the bottom-right corner: up to three on an inner ring, the rest on an outer ring. Null means too many buttons for an arc — the dock falls back to a wrapping grid.
|
|
1876
2556
|
- `touchDockClearance` (function): function touchDockClearance(scheme: TouchScheme | null, scale = 1): number — Vertical space (px, excluding device safe areas) that *bottom-docked* clusters occupy above the bottom edge. The shell publishes it as `--jg-hud-dock-clearance` so `HudCanvas` regions never collide with touch controls. Side rails and top clusters reserve their own rectangles through the layout registry instead of this scalar.
|
|
@@ -1879,6 +2559,17 @@
|
|
|
1879
2559
|
|
|
1880
2560
|
- `useShellMultiplayerSync` (function): function useShellMultiplayerSync(ctx: GameContext | null, multiplayer: ShellMultiplayer | null, playable: PlayableGame, serverIdRef: { current: string | null }, setRemotePlayers: Dispatch<SetStateAction<PresencePoseRow[]>>): void — Joins the multiplayer server for the live context and wires presence, feed relay, and chat sync until teardown.
|
|
1881
2561
|
|
|
2562
|
+
## @jgengine/shell/vfx/ParticleField
|
|
2563
|
+
|
|
2564
|
+
- `ParticleBlending` (type): type ParticleBlending = "additive" | "normal" — How particle fragments composite: `additive` for fire/sparks/magic glow, `normal` for smoke/dust.
|
|
2565
|
+
- `ParticleField` (function): function ParticleField({ system, advance = true, blending = "additive", scale = 300, depthWrite = false, }: ParticleFieldProps): ReactElement — Renders a core `ParticleSystem` as a GPU point cloud: one draw call, per-particle size / color / alpha via a soft-round shader, and a `drawRange` clamped to the live count so dead particles cost nothing. The simulation stays engine-side and genre-agnostic; this is purely how it reaches the screen. By default it advances the sim with the frame delta — pass `advance={false}` to drive it from your own fixed loop instead.
|
|
2566
|
+
- `ParticleFieldProps` (interface): interface ParticleFieldProps — Props for {@link ParticleField}.
|
|
2567
|
+
|
|
2568
|
+
## @jgengine/shell/vfx/WorldFloatingText
|
|
2569
|
+
|
|
2570
|
+
- `WorldFloatingText` (function): function WorldFloatingText({ field, advance = true, styleFor, fontSizePx, className, ...layout }: WorldFloatingTextProps): React.JSX.Element — R3F one-line drop-in for world-anchored floating text: mounts inside the scene, (optionally) advances a core {@link FloatingTextField} each frame, samples the live camera to project every live entry to the screen, and renders `@jgengine/react`'s {@link FloatingText} through a fullscreen `<Html>` overlay. This is the turnkey way an R3F game gets damage numbers / heal pops / XP gains from its own field without wiring projection by hand — the camera binding, viewport culling, and depth stacking come for free. Skin per `kind` with `styleFor`.
|
|
2571
|
+
- `WorldFloatingTextProps` (interface): interface WorldFloatingTextProps extends FloatingTextLayoutOptions — Props for {@link WorldFloatingText}.
|
|
2572
|
+
|
|
1882
2573
|
## @jgengine/shell/visibility/CullingProvider
|
|
1883
2574
|
|
|
1884
2575
|
- `CullingProvider` (function): function CullingProvider({ config, children }: { config: VisibilityConfig | undefined; children: ReactNode }): ReactNode — Drives automatic frustum + distance culling for every entity and placed object. It reads the live render camera each frame, updates the engine VisibilitySystem, and exposes a predicate the entity/object markers consult to toggle `group.visible` — objects fully outside the view (plus a conservative preload margin) are never submitted to the renderer, without unmounting them or touching gameplay. UI, sky, terrain, and environment live outside this subtree and are unaffected.
|
|
@@ -2076,6 +2767,13 @@
|
|
|
2076
2767
|
- `SpriteBatchInstance` (interface): interface SpriteBatchInstance — ⚠ undocumented
|
|
2077
2768
|
- `SpriteBatchProps` (interface): interface SpriteBatchProps — ⚠ undocumented
|
|
2078
2769
|
|
|
2770
|
+
## @jgengine/shell/world/WorldEntityFrames
|
|
2771
|
+
|
|
2772
|
+
- `WorldEntityFrames` (function): function WorldEntityFrames<E extends EntityFrameEntry>({ entries, renderFrame, tickMs = 0, className, anchorTransform, ...layout }: WorldEntityFramesProps<E>): React.JSX.Element — R3F convenience that mounts inside the scene, samples the live camera each frame (throttled by `tickMs`), and renders `@jgengine/react`'s {@link EntityFrames} through a fullscreen `<Html>` overlay. This is the one-line way an R3F game gets overhead enemy nameplates/health bars from its own entity array without a store: pass `entries` + a `renderFrame` that composes the shipped bars. The projection, viewport culling, and stacking come for free.
|
|
2773
|
+
- `WorldEntityFramesProps` (interface): interface WorldEntityFramesProps<E extends EntityFrameEntry> extends EntityFrameLayoutOptions — Props for {@link WorldEntityFrames}.
|
|
2774
|
+
- `projectWorldToScreen` (function): function projectWorldToScreen(scratch: THREE.Vector3, camera: THREE.Camera, worldPosition: readonly [number, number, number], width: number, height: number): EntityScreenProjection — Pure world→screen projection: NDC via `camera.project`, mapped to CSS pixels. `behind` is set when the point falls outside the near/far clip range (NDC z beyond [-1, 1]), which covers positions behind the camera. Exposed for tests and for callers wiring their own frame loop around a bare THREE camera.
|
|
2775
|
+
- `useWorldProjection` (function): function useWorldProjection(): ProjectEntity — Returns a {@link ProjectEntity} bound to the live R3F camera and canvas size — the world→screen half of the data-first entity-frame seam. Call the returned function with a world position to get a CSS-pixel screen point (or `null`/`behind` when the point is outside the frustum). Reads the camera fresh on every call, so sample it inside a frame loop. Games that already own their entities use this to feed `@jgengine/react`'s `EntityFrames` without mirroring state into a store.
|
|
2776
|
+
|
|
2079
2777
|
## @jgengine/shell/world/WorldHud
|
|
2080
2778
|
|
|
2081
2779
|
- `CombatCameraShake` (function): function CombatCameraShake(): null — ⚠ undocumented
|
|
@@ -2095,6 +2793,11 @@
|
|
|
2095
2793
|
|
|
2096
2794
|
- `WorldItems` (function): function WorldItems({ config }: { config?: WorldItemRenderConfig }): React.JSX.Element — Rarity→beam/color/label render binding + loot-filter overlay (#32/#33) for every dropped `worldItem`.
|
|
2097
2795
|
|
|
2796
|
+
## @jgengine/shell/world/WorldPings
|
|
2797
|
+
|
|
2798
|
+
- `WorldPings` (function): function WorldPings({ markers, kindStyles, pingsOnly = true, height = 2.4, showCallout = true, renderCallout, }: WorldPingsProps): ReactNode — World-space pings — the in-scene side of a ping/marker: a bobbing downward arrowhead pointing at the spot, a ground ring, and a billboarded callout, colored by marker kind and fading in/out over the marker's lifetime. Reads a `MarkerSet` (typically the one a `createPingSystem` writes to), a marker source, or a static array; mount through `PlayableGame.WorldOverlay`.
|
|
2799
|
+
- `WorldPingsProps` (interface): interface WorldPingsProps — Props for {@link WorldPings}.
|
|
2800
|
+
|
|
2098
2801
|
## @jgengine/shell/world/WorldScene
|
|
2099
2802
|
|
|
2100
2803
|
- `RemotePlayers` (function): function RemotePlayers({ rows }: { rows: PresencePoseRow[] }): React.JSX.Element — ⚠ undocumented
|
|
@@ -2110,6 +2813,12 @@
|
|
|
2110
2813
|
- `FloatTextInfo` (interface): interface FloatTextInfo — ⚠ undocumented
|
|
2111
2814
|
- `FloatTextStyle` (interface): interface FloatTextStyle — ⚠ undocumented
|
|
2112
2815
|
|
|
2816
|
+
## @jgengine/shell/world/pingPulse
|
|
2817
|
+
|
|
2818
|
+
- `PingOpacityInput` (interface): interface PingOpacityInput — Inputs to {@link pingOpacity}.
|
|
2819
|
+
- `pingBobOffset` (function): function pingBobOffset(elapsedSeconds: number, amplitude = 0.18, speedHz = 1.1): number — Vertical bob offset (world units) for a hovering ping arrow at `elapsedSeconds`.
|
|
2820
|
+
- `pingOpacity` (function): function pingOpacity(input: PingOpacityInput): number — Alpha for a world ping in `[0, 1]`: ramps up over `fadeInMs` after it appears and ramps back down over `fadeOutMs` before it expires. Pure math so the lifecycle can be unit-tested without an R3F canvas.
|
|
2821
|
+
|
|
2113
2822
|
## @jgengine/shell/world/worldBarSamples
|
|
2114
2823
|
|
|
2115
2824
|
- `NameplateSample` (interface): interface NameplateSample — One entity's projected nameplate: screen `x`/`y`, display `name`, health `percent` (or `null` when statless), and world `distance` from the player.
|