@jgengine/react 0.14.0 → 0.15.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.
Files changed (96) hide show
  1. package/CHANGELOG.md +500 -1
  2. package/dist/accessibility.d.ts +39 -0
  3. package/dist/accessibility.js +61 -0
  4. package/dist/achievements.d.ts +50 -0
  5. package/dist/achievements.js +94 -0
  6. package/dist/cameraShake.d.ts +52 -0
  7. package/dist/cameraShake.js +53 -0
  8. package/dist/coachMarks.d.ts +72 -0
  9. package/dist/coachMarks.js +136 -0
  10. package/dist/codex.d.ts +25 -0
  11. package/dist/codex.js +62 -0
  12. package/dist/comboMeter.d.ts +63 -0
  13. package/dist/comboMeter.js +93 -0
  14. package/dist/components.js +4 -3
  15. package/dist/creditsScreen.d.ts +19 -0
  16. package/dist/creditsScreen.js +31 -0
  17. package/dist/cutscene.d.ts +66 -0
  18. package/dist/cutscene.js +132 -0
  19. package/dist/damageDirection.d.ts +51 -0
  20. package/dist/damageDirection.js +103 -0
  21. package/dist/dialogueView.d.ts +69 -0
  22. package/dist/dialogueView.js +111 -0
  23. package/dist/entityFrames.d.ts +114 -0
  24. package/dist/entityFrames.js +55 -0
  25. package/dist/fastTravel.d.ts +36 -0
  26. package/dist/fastTravel.js +103 -0
  27. package/dist/floatingText.d.ts +84 -0
  28. package/dist/floatingText.js +61 -0
  29. package/dist/gameViewport.js +8 -12
  30. package/dist/hooks.d.ts +42 -0
  31. package/dist/hooks.js +85 -0
  32. package/dist/hudTheme.d.ts +104 -7
  33. package/dist/hudTheme.js +300 -2
  34. package/dist/i18n.d.ts +29 -0
  35. package/dist/i18n.js +44 -0
  36. package/dist/index.d.ts +34 -0
  37. package/dist/index.js +34 -0
  38. package/dist/interactionPrompt.d.ts +80 -0
  39. package/dist/interactionPrompt.js +112 -0
  40. package/dist/keybindingMenu.d.ts +59 -0
  41. package/dist/keybindingMenu.js +146 -0
  42. package/dist/killFeed.d.ts +63 -0
  43. package/dist/killFeed.js +88 -0
  44. package/dist/map.d.ts +123 -2
  45. package/dist/map.js +239 -36
  46. package/dist/menuRouter.d.ts +51 -0
  47. package/dist/menuRouter.js +49 -0
  48. package/dist/modals.d.ts +131 -0
  49. package/dist/modals.js +168 -0
  50. package/dist/notifications.d.ts +39 -0
  51. package/dist/notifications.js +111 -0
  52. package/dist/objectiveBanner.d.ts +62 -0
  53. package/dist/objectiveBanner.js +129 -0
  54. package/dist/photoMode.d.ts +21 -0
  55. package/dist/photoMode.js +39 -0
  56. package/dist/previewFixtures.d.ts +30 -0
  57. package/dist/previewFixtures.js +46 -0
  58. package/dist/questTracker.d.ts +24 -0
  59. package/dist/questTracker.js +31 -0
  60. package/dist/quickMenu.d.ts +39 -0
  61. package/dist/quickMenu.js +79 -0
  62. package/dist/radialMenu.d.ts +50 -0
  63. package/dist/radialMenu.js +69 -0
  64. package/dist/saveSlots.d.ts +81 -0
  65. package/dist/saveSlots.js +138 -0
  66. package/dist/scoreboard.d.ts +67 -0
  67. package/dist/scoreboard.js +71 -0
  68. package/dist/settings.d.ts +9 -3
  69. package/dist/settings.js +10 -4
  70. package/dist/shopGrid.d.ts +70 -0
  71. package/dist/shopGrid.js +129 -0
  72. package/dist/statusEffectBar.d.ts +52 -0
  73. package/dist/statusEffectBar.js +57 -0
  74. package/dist/streetGeometryPreview.d.ts +7 -0
  75. package/dist/streetGeometryPreview.js +119 -0
  76. package/dist/talentTree.d.ts +60 -0
  77. package/dist/talentTree.js +217 -0
  78. package/dist/timerReadout.d.ts +90 -0
  79. package/dist/timerReadout.js +111 -0
  80. package/dist/useDebouncedCommit.d.ts +54 -0
  81. package/dist/useDebouncedCommit.js +81 -0
  82. package/dist/waveHud.d.ts +49 -0
  83. package/dist/waveHud.js +53 -0
  84. package/dist/waypointMarkers.d.ts +80 -0
  85. package/dist/waypointMarkers.js +116 -0
  86. package/package.json +3 -3
  87. package/skills/ce-handoff/SKILL.md +149 -0
  88. package/skills/jgengine/SKILL.md +3 -1
  89. package/skills/jgengine/api.md +17 -7
  90. package/skills/jgengine/capabilities.md +12 -0
  91. package/skills/jgengine/recipes/minimal-game.md +7 -4
  92. package/skills/jgengine-ui/SKILL.md +5 -3
  93. package/skills/jgengine-ui/api.md +708 -19
  94. package/skills/jgengine-ui/capabilities.md +362 -1
  95. package/skills/jgengine-ui/recipes/overhead-entity-frames.md +136 -0
  96. package/skills/jgengine-ui/reference.md +7 -4
@@ -4,6 +4,22 @@
4
4
 
5
5
  Reach for these before hand-rolling. Each row is *the thing you need* → *the primitive that already does it*.
6
6
 
7
+ ## accessibility-provider — apply accessibility preferences to a subtree — text-scale CSS var, reduced-motion/high-contrast/colorblind/captions data attrs, and the colorblind color-matrix filter
8
+
9
+ - `AccessibilityProvider` (function) · `import { AccessibilityProvider } from "@jgengine/react"`
10
+
11
+ ## accessibility-store — serializable, observable accessibility preferences (reduced motion, high contrast, text scale, colorblind mode, captions) a game binds to its settings and presentation
12
+
13
+ - `createAccessibilityStore` (function) · `import { createAccessibilityStore } from "@jgengine/core/ui"`
14
+
15
+ ## achievement-gallery — responsive achievement/trophy grid with unlocked/locked state, counter progress bars, secret masking, and a completion/score header
16
+
17
+ - `AchievementGallery` (function) · `import { AchievementGallery } from "@jgengine/react"`
18
+
19
+ ## achievement-toast — unlock-moment banner (icon, heading, name, points) for an achievement toast queue
20
+
21
+ - `AchievementToast` (function) · `import { AchievementToast } from "@jgengine/react"`
22
+
7
23
  ## action-bar — optional skinned action-bar composition over the headless model — games own chrome
8
24
 
9
25
  - `ActionBar` (function) · `import { ActionBar } from "@jgengine/react"`
@@ -28,10 +44,22 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
28
44
 
29
45
  - `ActionTooltip` (function) · `import { ActionTooltip } from "@jgengine/react"`
30
46
 
47
+ ## auto-scroll — pin a log/chat/console panel to its newest line as entries arrive — no hand-rolled scrollTop effects
48
+
49
+ - `useAutoScroll` (function) · `import { useAutoScroll } from "@jgengine/react"`
50
+
51
+ ## camera-shake-meter — HUD readout for a core camera-shake controller — a trauma meter plus current impact-kind label, reskinnable and kind-labelled
52
+
53
+ - `CameraShakeMeter` (function) · `import { CameraShakeMeter } from "@jgengine/react"`
54
+
31
55
  ## camera-transparent-decor — let author decor pass through the orbit spring-arm; a child opts back in with jgCameraCollide
32
56
 
33
57
  - `isCameraOccluderTransparent` (function) · `import { isCameraOccluderTransparent } from "@jgengine/shell/camera"`
34
58
 
59
+ ## capture-canvas — read the live R3F frame to a PNG data URL (needs preserveDrawingBuffer)
60
+
61
+ - `captureCanvas` (function) · `import { captureCanvas } from "@jgengine/shell/render/sceneCapture"`
62
+
35
63
  ## character-paperdoll — equip-slot paperdoll — flanking columns around a portrait, activatable slots
36
64
 
37
65
  - `Paperdoll` (function) · `import { Paperdoll } from "@jgengine/react"`
@@ -49,18 +77,94 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
49
77
  - `formatDelta` (function) · `import { formatDelta } from "@jgengine/core/ui"`
50
78
  - `formatDuration` (function) · `import { formatDuration } from "@jgengine/core/ui"`
51
79
 
80
+ ## coach-mark — single onboarding callout — title/body, N-of-M counter, Next + Skip controls, theme-reskinnable
81
+
82
+ - `CoachMark` (function) · `import { CoachMark } from "@jgengine/react"`
83
+
84
+ ## coach-mark-host — full-screen onboarding coach-mark host — anchored/centered callout, dimmed spotlight backdrop, Next/Skip wired to the sequence
85
+
86
+ - `CoachMarkHost` (function) · `import { CoachMarkHost } from "@jgengine/react"`
87
+
88
+ ## coach-marks — ordered, gated, persist-once onboarding coach-marks/tutorial callouts — anchored or centered steps with a seen set and Next/Skip
89
+
90
+ - `createCoachMarkSequence` (function) · `import { createCoachMarkSequence } from "@jgengine/core/ui"`
91
+
92
+ ## codex-gallery — codex/bestiary gallery with category tabs, discovered/locked cards, secret masking, and a completion header
93
+
94
+ - `Codex` (function) · `import { Codex } from "@jgengine/react"`
95
+
96
+ ## colorblind-filters — SVG feColorMatrix defs (protanopia/deuteranopia/tritanopia/grayscale) referenced by the accessibility colorblind filter
97
+
98
+ - `ColorblindFilters` (function) · `import { ColorblindFilters } from "@jgengine/react"`
99
+
100
+ ## combo-meter-hud — drop-in HUD for a core combo meter — big live count, free-string tier label, derived multiplier, and a draining decay-window bar, per-tier colored from a caller map and HudTheme-token skinnable
101
+
102
+ - `ComboMeterHud` (function) · `import { ComboMeterHud } from "@jgengine/react"`
103
+
104
+ ## confirm-dialog — generic themeable confirm/cancel dialog — title, body, two buttons, danger styling
105
+
106
+ - `ConfirmDialog` (function) · `import { ConfirmDialog } from "@jgengine/react"`
107
+
108
+ ## controller-camera-shake — R3F consumer that applies a core camera-shake controller's pooled per-frame offset to the active camera (translation + pitch/yaw/roll) so the view visibly shakes
109
+
110
+ - `ControllerCameraShake` (function) · `import { ControllerCameraShake } from "@jgengine/shell/camera"`
111
+
52
112
  ## controls-list — keybind-derived control legend that hides on touch
53
113
 
54
114
  - `ControlsList` (function) · `import { ControlsList } from "@jgengine/react"`
55
115
 
116
+ ## credits-screen — drop-in credits view over a CreditsDocument — headed sections, optional links, HudTheme-skinned
117
+
118
+ - `CreditsScreen` (function) · `import { CreditsScreen } from "@jgengine/react/creditsScreen"`
119
+
120
+ ## cutscene-letterbox — reskinnable cinematic letterbox + skip overlay for a cutscene — animated bars, caption/dialogue slot, progress line, Skip button
121
+
122
+ - `CutsceneLetterbox` (function) · `import { CutsceneLetterbox } from "@jgengine/react"`
123
+
124
+ ## damage-direction-overlay — drop-in hit-from damage-direction overlay — SVG arcs flaring around a center reticle toward each recent hit and fading over time, colored per `kind`/HudTheme, pointer-events none
125
+
126
+ - `DamageDirectionOverlay` (function) · `import { DamageDirectionOverlay } from "@jgengine/react"`
127
+
128
+ ## day-night-sky — drop-in R3F presenter that drives the engine's existing sky dome and lights from a serializable day-night cycle for a moving, color-graded day-night look
129
+
130
+ - `DayNightSky` (function) · `import { DayNightSky } from "@jgengine/shell/environment"`
131
+
132
+ ## debounced-commit — bind a slider/number/color control to an expensive commit path (scene-document patch, settings persist) — instant local mirror, one trailing commit per pause, flush on release/blur/unmount; no raw onChange→patch wiring
133
+
134
+ - `useDebouncedCommit` (function) · `import { useDebouncedCommit } from "@jgengine/react"`
135
+
56
136
  ## default-look — one field that lights a scene like a shipped game (opt out with "flat")
57
137
 
58
138
  - `LookPreset` (type) · `import { LookPreset } from "@jgengine/core/ui"`
59
139
 
140
+ ## default-walk-codes — stock WASD + jump key codes for the shell walk controller
141
+
142
+ - `DEFAULT_WALK_CODES` (const) · `import { DEFAULT_WALK_CODES } from "@jgengine/shell/shellMovement"`
143
+
144
+ ## dialogue-view — drop-in branching conversation UI — speaker + portrait slot, current line, clickable response choices that advance a DialogueRun
145
+
146
+ - `DialogueView` (function) · `import { DialogueView } from "@jgengine/react"`
147
+
148
+ ## disposable-resource — memoize a three.js GPU resource (or tuple) with automatic dispose on change/unmount — no hand-rolled useMemo + dispose-effect pairs
149
+
150
+ - `useDisposable` (function) · `import { useDisposable } from "@jgengine/shell/render/useDisposable"`
151
+
60
152
  ## distance-format — render meters as m or km for HUD stats, telemetry, and range readouts
61
153
 
62
154
  - `formatDistance` (function) · `import { formatDistance } from "@jgengine/core/ui"`
63
155
 
156
+ ## dom-event — attach a window/document/element event listener with automatic cleanup and a stable handler ref — no hand-rolled addEventListener effects
157
+
158
+ - `useDomEvent` (function) · `import { useDomEvent } from "@jgengine/react"`
159
+
160
+ ## entity-frames — overlay that renders caller-composed frames over on-screen entities
161
+
162
+ - `EntityFrames` (function) · `import { EntityFrames } from "@jgengine/react"`
163
+ - `EntityScreenProjection` (interface) · `import { EntityScreenProjection } from "@jgengine/react"`
164
+ - `WorldEntityFrames` (function) · `import { WorldEntityFrames } from "@jgengine/shell/world/WorldEntityFrames"`
165
+ - `projectWorldToScreen` (function) · `import { projectWorldToScreen } from "@jgengine/shell/world/WorldEntityFrames"`
166
+ - `useWorldProjection` (function) · `import { useWorldProjection } from "@jgengine/shell/world/WorldEntityFrames"`
167
+
64
168
  ## entity-portrait — selectable entity portrait tile with vitals and selected/focus states
65
169
 
66
170
  - `EntityPortrait` (function) · `import { EntityPortrait } from "@jgengine/react"`
@@ -81,6 +185,22 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
81
185
 
82
186
  - `useEventMeter` (function) · `import { useEventMeter } from "@jgengine/react"`
83
187
 
188
+ ## fast-travel-menu — discovered-destinations picker grouped by region with distances, a discovery counter, and a travel callback
189
+
190
+ - `FastTravelMenu` (function) · `import { FastTravelMenu } from "@jgengine/react"`
191
+
192
+ ## floating-text — overlay that renders on-screen floating combat text with per-kind color, alpha, and pop-in scale
193
+
194
+ - `FloatingText` (function) · `import { FloatingText } from "@jgengine/react"`
195
+ - `FloatingTextPlacement` (interface) · `import { FloatingTextPlacement } from "@jgengine/react"`
196
+ - `WorldFloatingText` (function) · `import { WorldFloatingText } from "@jgengine/shell/vfx/WorldFloatingText"`
197
+ - `createFloatingTextField` (function) · `import { createFloatingTextField } from "@jgengine/core/ui/floatingText"`
198
+ - `layoutFloatingText` (function) · `import { layoutFloatingText } from "@jgengine/react"`
199
+
200
+ ## fullscreen-map — fullscreen pan/zoom world-map overlay over WorldMapSurface — wheel-zoom, drag-pan, click-to-place, and a freehand draw tool (onStrokeComplete)
201
+
202
+ - `FullscreenMap` (function) · `import { FullscreenMap } from "@jgengine/react"`
203
+
84
204
  ## game-context-bridge — re-provide the GameContext across a nested Canvas/reconciler boundary
85
205
 
86
206
  - `GameContextBridge` (function) · `import { GameContextBridge } from "@jgengine/react"`
@@ -137,27 +257,67 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
137
257
 
138
258
  - `StatBar` (function) · `import { StatBar } from "@jgengine/react"`
139
259
 
140
- ## hud-theme — game-authored token object for bars, frames, slots, and minimap ring
260
+ ## hud-theme — game-authored token object covering bars, frames, slots, chrome, text, status colors, fonts, and rarity
141
261
 
142
262
  - `HudThemePalette` (interface) · `import { HudThemePalette } from "@jgengine/react"`
143
263
 
264
+ ## hud-theme-author — fill a full HudTheme from per-group partial overrides
265
+
266
+ - `hudTheme` (function) · `import { hudTheme } from "@jgengine/react"`
267
+
268
+ ## hud-theme-derive — build a full HudTheme from an accent + surface seed pair
269
+
270
+ - `deriveHudTheme` (function) · `import { deriveHudTheme } from "@jgengine/react"`
271
+
272
+ ## hud-ticker — re-render a HUD element at a steady hz for time-derived readouts (cooldowns, cast/swing bars) — no hand-rolled setInterval effects
273
+
274
+ - `useTicker` (function) · `import { useTicker } from "@jgengine/react"`
275
+
144
276
  ## hud-vitals — atomic purpose-named vitals bars (token-themed parts, not a finished HUD)
145
277
 
146
278
  - `BarTokens` (interface) · `import { BarTokens } from "@jgengine/react"`
147
279
  - `barTokens` (function) · `import { barTokens } from "@jgengine/react"`
148
280
 
281
+ ## i18n — translate a message catalog with fallback-locale lookup, `{param}` interpolation, and Intl pluralization; observable active-locale switching
282
+
283
+ - `createI18n` (function) · `import { createI18n } from "@jgengine/core/ui"`
284
+
285
+ ## interaction-prompt-host — screen-anchored "press E to…" callout rendering a prompt registry's active interactable — keybind cap+label, gauge hold bar, or plain label, theme- and per-prompt-accent skinnable
286
+
287
+ - `InteractionPrompt` (function) · `import { InteractionPrompt } from "@jgengine/react"`
288
+
149
289
  ## key-hint — keyboard/mouse control hint that hides itself on touch
150
290
 
151
291
  - `KeyHint` (function) · `import { KeyHint } from "@jgengine/react"`
152
292
 
293
+ ## keybinding-menu — drop-in controls-settings surface over a rebind session — click-to-capture rows with key glyphs, conflict badges, per-row and reset-all, HudTheme-skinnable
294
+
295
+ - `KeybindingMenu` (function) · `import { KeybindingMenu } from "@jgengine/react"`
296
+
153
297
  ## keycap — styled keyboard/mouse key cap for control hints
154
298
 
155
299
  - `Keycap` (function) · `import { Keycap } from "@jgengine/react"`
156
300
 
301
+ ## kill-feed — vertical event/kill-feed ticker rendering a core event-ticker as a fading, newest-on-top stack of per-kind iconned, accent-colored rows over HudTheme tokens
302
+
303
+ - `KillFeed` (function) · `import { KillFeed } from "@jgengine/react"`
304
+
157
305
  ## live-markers — a self-ticking MarkerSet kept in sync from the live scene each HUD tick — pass a rebuild(markers, ctx) that clears+repopulates, no hand-rolled setInterval
158
306
 
159
307
  - `useLiveMarkers` (function) · `import { useLiveMarkers } from "@jgengine/react"`
160
308
 
309
+ ## map-legend — marker-kind key (glyph + color + label per kind) sharing the map's kindStyles
310
+
311
+ - `MapLegend` (function) · `import { MapLegend } from "@jgengine/react"`
312
+
313
+ ## menu-router — screen stack for a game front-end — push/back/replace/reset with optional Escape-to-back
314
+
315
+ - `useMenuRouter` (function) · `import { useMenuRouter } from "@jgengine/react/menuRouter"`
316
+
317
+ ## menu-stack-reducer — pure push/back/replace/reset transitions for a menu screen stack
318
+
319
+ - `menuStackReducer` (function) · `import { menuStackReducer } from "@jgengine/react/menuRouter"`
320
+
161
321
  ## minimap — framed circular minimap with terrain bake, fog, markers, and facing arrow
162
322
 
163
323
  - `Minimap` (function) · `import { Minimap } from "@jgengine/react"`
@@ -174,10 +334,39 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
174
334
 
175
335
  - `MinimapTrack` (function) · `import { MinimapTrack } from "@jgengine/react"`
176
336
 
337
+ ## modal-host — full-screen modal/dialog host over a modal stack — dimmed backdrop, focus trap, Esc/backdrop-to-cancel, aria-modal dialog
338
+
339
+ - `ModalHost` (function) · `import { ModalHost } from "@jgengine/react"`
340
+
341
+ ## modal-stack — serializable, observable stack of opaque modal/dialog records — push/pop/resolve blocking overlays (pause menu, confirm dialog) with optional auto-dismiss; never interprets kind or result
342
+
343
+ - `createModalStack` (function) · `import { createModalStack } from "@jgengine/core/ui"`
344
+
177
345
  ## nameplates — billboarded name + HP bar over nearby entities
178
346
 
179
347
  - `WorldNameplates` (function) · `import { WorldNameplates } from "@jgengine/shell/world/WorldHud"`
180
348
 
349
+ ## notification-bell — icon button with a live unread-count badge over a notification store
350
+
351
+ - `NotificationBell` (function) · `import { NotificationBell } from "@jgengine/react"`
352
+
353
+ ## notification-center-panel — scrollable notification log with kind markers, read tracking, relative time, and mark-all-read/clear
354
+
355
+ - `NotificationCenter` (function) · `import { NotificationCenter } from "@jgengine/react"`
356
+
357
+ ## objective-banner — serializable, clock-driven stage/objective banner queue — flies a big transient centered title + optional subtitle in, holds, and fades out one at a time, with phase + progress for animation, free-string kinds the game styles, and snapshot/restore
358
+
359
+ - `createObjectiveBanner` (function) · `import { createObjectiveBanner } from "@jgengine/core/ui"`
360
+
361
+ ## objective-banner-host — full-screen overlay that renders a core objective-banner controller as a fly-in / hold / fade-out centered title + subtitle stamp, theme- and per-kind-skinnable
362
+
363
+ - `ObjectiveBannerHost` (function) · `import { ObjectiveBannerHost } from "@jgengine/react"`
364
+
365
+ ## offscreen-markers — serializable waypoint tracker + pure edge-clamp/bearing math for on-screen pins and off-screen directional arrows with distance
366
+
367
+ - `createWaypointTracker` (function) · `import { createWaypointTracker } from "@jgengine/core/ui"`
368
+ - `layoutScreenMarker` (function) · `import { layoutScreenMarker } from "@jgengine/core/ui"`
369
+
181
370
  ## ordinal-format — format a placement number as 1st/2nd/3rd for HUD ranks
182
371
 
183
372
  - `formatOrdinal` (function) · `import { formatOrdinal } from "@jgengine/core/ui"`
@@ -222,6 +411,22 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
222
411
 
223
412
  - `togglePanel` (function) · `import { togglePanel } from "@jgengine/core/ui"`
224
413
 
414
+ ## particle-field — render a core particle system as a soft-point GPU cloud with per-particle size, color, and alpha
415
+
416
+ - `ParticleField` (function) · `import { ParticleField } from "@jgengine/shell/vfx/ParticleField"`
417
+
418
+ ## pause-menu — reskinnable pause-menu building block — Resume plus a game-filled Settings/Quit slot list, HudTheme-driven
419
+
420
+ - `PauseMenu` (function) · `import { PauseMenu } from "@jgengine/react"`
421
+
422
+ ## photo-mode — observable photo-mode state (active + hide-HUD) a game binds its screenshot/camera flow to
423
+
424
+ - `createPhotoModeStore` (function) · `import { createPhotoModeStore } from "@jgengine/core/ui"`
425
+
426
+ ## photo-mode-controls — photo-mode toolbar (hide-HUD toggle, capture, exit) bound to a photo-mode store
427
+
428
+ - `PhotoModeControls` (function) · `import { PhotoModeControls } from "@jgengine/react"`
429
+
225
430
  ## placement-ghost — render valid/invalid placement preview mesh
226
431
 
227
432
  - `PlacementGhost` (function) · `import { PlacementGhost } from "@jgengine/shell/structures"`
@@ -230,10 +435,46 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
230
435
 
231
436
  - `Popover` (function) · `import { Popover } from "@jgengine/react"`
232
437
 
438
+ ## quest-tracker — compact quest/objective HUD tracker — titles + labelled objective progress from describeTrackedQuest views
439
+
440
+ - `QuestTracker` (function) · `import { QuestTracker } from "@jgengine/react"`
441
+
442
+ ## quick-menu — multi-form quick menu (radial / arc / list / grid) over one item model with hotkeys, badges, cooldowns, sections, and nested submenus
443
+
444
+ - `QuickMenu` (function) · `import { QuickMenu } from "@jgengine/react"`
445
+
446
+ ## radial-menu — pointer/stick-driven radial or arc quick menu (weapon/emote wheel) — angular slice selection with hotkeys, badges, cooldowns, and a neutral hub
447
+
448
+ - `RadialMenu` (function) · `import { RadialMenu } from "@jgengine/react"`
449
+
450
+ ## radial-select — map a pointer/stick vector to a radial-menu slice index, with a neutral dead zone and optional arc bounds
451
+
452
+ - `radialIndexFromVector` (function) · `import { radialIndexFromVector } from "@jgengine/core/ui"`
453
+
454
+ ## raf-loop — run a cancellable requestAnimationFrame loop for DOM-side animation with delta seconds — no hand-rolled RAF effects
455
+
456
+ - `useRafLoop` (function) · `import { useRafLoop } from "@jgengine/react"`
457
+
233
458
  ## resolve-game-look — expand a look preset into concrete lighting/backdrop/post knobs
234
459
 
235
460
  - `resolveGameLook` (function) · `import { resolveGameLook } from "@jgengine/core/ui"`
236
461
 
462
+ ## save-slot-menu — drop-in save-select / profile menu that renders a core save-slots index as New / Continue / Load / Delete cards with free-string meta chips and relative save times, theme-skinnable
463
+
464
+ - `SaveSlotMenu` (function) · `import { SaveSlotMenu } from "@jgengine/react"`
465
+
466
+ ## scene-capture-binding — expose the in-Canvas scene-capture function to outside-Canvas HUD (photo mode)
467
+
468
+ - `SceneCaptureBinding` (function) · `import { SceneCaptureBinding } from "@jgengine/shell/render/sceneCapture"`
469
+
470
+ ## scoreboard-table — reskinnable ranked-score / leaderboard table over the rankLeaderboard selector — medal-colored podium, local-row highlight, HudTheme-token driven
471
+
472
+ - `Scoreboard` (function) · `import { Scoreboard } from "@jgengine/react"`
473
+
474
+ ## screen-effects-overlay — shell DOM overlay that renders a core screen-effects controller as full-screen flash / edge-vignette / low-health-pulse color-grade layers
475
+
476
+ - `ScreenEffectsOverlay` (function) · `import { ScreenEffectsOverlay } from "@jgengine/shell/postfx/ScreenEffectsOverlay"`
477
+
237
478
  ## selection-collection — accessible portrait-strip / group-chip renderer over a selection model
238
479
 
239
480
  - `SelectionCollectionChrome` (function) · `import { SelectionCollectionChrome } from "@jgengine/react"`
@@ -250,6 +491,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
250
491
 
251
492
  - `SelectionPanel` (function) · `import { SelectionPanel } from "@jgengine/react"`
252
493
 
494
+ ## shop-grid-host — drop-in vendor/shop grid over a caller-owned wallet — item cards with icon/price/stock, afford-aware Buy, optional Sell, and a balance readout, token-themed
495
+
496
+ - `ShopGrid` (function) · `import { ShopGrid } from "@jgengine/react"`
497
+
253
498
  ## speed-format — render a m/s speed as km/h, mph, knots, or m/s for speedometers and telemetry HUDs
254
499
 
255
500
  - `formatSpeed` (function) · `import { formatSpeed } from "@jgengine/core/ui"`
@@ -258,26 +503,142 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
258
503
 
259
504
  - `StartScreen` (function) · `import { StartScreen } from "@jgengine/react"`
260
505
 
506
+ ## status-effect-bar — timeline HUD row of active statuses — icon + radial countdown ring + stack badge, driven off the status model, HudTheme-skinned
507
+
508
+ - `StatusEffectBar` (function) · `import { StatusEffectBar } from "@jgengine/react"`
509
+
261
510
  ## studio-stage — cinematic lighting rig + backdrop + turntable for parametric studios
262
511
 
263
512
  - `StudioStage` (function) · `import { StudioStage } from "@jgengine/shell/scene/StudioStage"`
264
513
 
514
+ ## talent-tree — drop-in skill/talent/upgrade-tree widget — pass `nodes`+`tree` for point-spend or a precomputed `view` for any unlock rule; branch/tier layout, SVG prerequisite edges, learned/available/locked/maxed styling, icon + rank, onLearn
515
+
516
+ - `TalentTree` (function) · `import { TalentTree } from "@jgengine/react"`
517
+
518
+ ## timer-readout — live digital mm:ss/m:ss.d timer readout bound to a TimerSet
519
+
520
+ - `TimerReadout` (function) · `import { TimerReadout } from "@jgengine/react"`
521
+
522
+ ## timer-readout-format — format milliseconds as digital timer text (mm:ss / m:ss.d / ss.d)
523
+
524
+ - `formatTimerMs` (function) · `import { formatTimerMs } from "@jgengine/react"`
525
+
526
+ ## timer-ring — radial SVG charge/cooldown ring bound to a TimerSet's progress
527
+
528
+ - `TimerRing` (function) · `import { TimerRing } from "@jgengine/react"`
529
+
530
+ ## trans — inline translated-message component bound to the active locale
531
+
532
+ - `Trans` (function) · `import { Trans } from "@jgengine/react"`
533
+
265
534
  ## transform-gizmo — in-game select/move/rotate/scale gizmo
266
535
 
267
536
  - `TransformGizmo` (const) · `import { TransformGizmo } from "@jgengine/shell/structures"`
268
537
 
538
+ ## use-camera-shake — React hook binding a camera-shake controller — subscribes for live trauma/kind and can self-drive its decay on a frame loop
539
+
540
+ - `useCameraShake` (function) · `import { useCameraShake } from "@jgengine/react"`
541
+
542
+ ## use-coach-marks — React hook binding a coach-mark sequence to a component — re-renders on advance/skip/gate changes
543
+
544
+ - `useCoachMarks` (function) · `import { useCoachMarks } from "@jgengine/react"`
545
+
546
+ ## use-combo-meter — React hook binding a combo meter — re-renders per frame so the decay-window bar drains live and returns the current combo view
547
+
548
+ - `useComboMeter` (function) · `import { useComboMeter } from "@jgengine/react"`
549
+
550
+ ## use-damage-direction — React hook that animates a damage-direction tracker's fade with requestAnimationFrame and re-renders its live indicators
551
+
552
+ - `useDamageDirection` (function) · `import { useDamageDirection } from "@jgengine/react"`
553
+
554
+ ## use-dialogue-run — React hook binding a branching dialogue run to a component — re-renders as the player advances the conversation
555
+
556
+ - `useDialogueRun` (function) · `import { useDialogueRun } from "@jgengine/react"`
557
+
558
+ ## use-event-ticker — React hook binding an event-ticker — re-renders per frame so entries fade and drop live, returning the current newest-first views
559
+
560
+ - `useEventTicker` (function) · `import { useEventTicker } from "@jgengine/react"`
561
+
562
+ ## use-fast-travel — re-render a component when a fast-travel network's discovery state changes
563
+
564
+ - `useFastTravel` (function) · `import { useFastTravel } from "@jgengine/react"`
565
+
566
+ ## use-interaction-prompt — React hook binding a prompt registry to a moving player — resolves the nearest interactable prompt and returns the active one
567
+
568
+ - `useInteractionPrompt` (function) · `import { useInteractionPrompt } from "@jgengine/react"`
569
+
570
+ ## use-modal-stack — React hook binding a modal stack to a component — re-renders on push/pop/resolve
571
+
572
+ - `useModalStack` (function) · `import { useModalStack } from "@jgengine/react"`
573
+
574
+ ## use-objective-banner — React hook binding an objective-banner controller — advances its clock per frame and returns the current banner view
575
+
576
+ - `useObjectiveBanner` (function) · `import { useObjectiveBanner } from "@jgengine/react"`
577
+
269
578
  ## use-panels — headless toggleable-window manager with keybind + ESC handling over the core panel model
270
579
 
271
580
  - `usePanels` (function) · `import { usePanels } from "@jgengine/react"`
272
581
 
582
+ ## use-rebind-session — React hook that re-renders a component whenever a rebind session changes
583
+
584
+ - `useRebindSession` (function) · `import { useRebindSession } from "@jgengine/react"`
585
+
586
+ ## use-save-slots — React hook binding a save-slots metadata index — re-renders on change and returns the ordered slot list
587
+
588
+ - `useSaveSlots` (function) · `import { useSaveSlots } from "@jgengine/react"`
589
+
590
+ ## use-sequence-director — React hook that drives a cutscene director's per-frame tick loop and exposes playhead/progress + play/pause/skip controls
591
+
592
+ - `useSequenceDirector` (function) · `import { useSequenceDirector } from "@jgengine/react"`
593
+
594
+ ## use-shop-stock — React hook binding a shop-stock model — re-renders on any stock change and returns the entry list
595
+
596
+ - `useShopStock` (function) · `import { useShopStock } from "@jgengine/react"`
597
+
598
+ ## use-timer — React hook binding one timer to a component with a per-frame re-read
599
+
600
+ - `useTimerRead` (function) · `import { useTimerRead } from "@jgengine/react"`
601
+
602
+ ## use-translate — live `t(key, params)` translator bound to the active locale, re-rendering on locale change
603
+
604
+ - `useT` (function) · `import { useT } from "@jgengine/react"`
605
+
606
+ ## use-wave-runner — React hook that subscribes to a wave runner and returns its pooled current-wave view
607
+
608
+ - `useWaveRunner` (function) · `import { useWaveRunner } from "@jgengine/react"`
609
+
610
+ ## use-waypoints — React binding that returns a waypoint tracker's live list (or a passthrough array)
611
+
612
+ - `useWaypoints` (function) · `import { useWaypoints } from "@jgengine/react"`
613
+
273
614
  ## vital-bar — compact current/max vital meter for an entity summary
274
615
 
275
616
  - `VitalBar` (function) · `import { VitalBar } from "@jgengine/react"`
276
617
 
618
+ ## wave-hud — drop-in wave/spawn HUD over a wave runner — big WAVE N label, wave-progress bar, spawned/total + budget + alert readouts, theme-skinnable
619
+
620
+ - `WaveHud` (function) · `import { WaveHud } from "@jgengine/react"`
621
+
622
+ ## waypoint-arrow — on-screen HUD guide arrow to a tracked waypoint, rotated by facing-relative bearing with a distance readout
623
+
624
+ - `WaypointArrow` (function) · `import { WaypointArrow } from "@jgengine/react"`
625
+
626
+ ## waypoint-markers — overlay rendering world waypoints as on-screen pins and off-screen edge-clamped directional arrows with distance, colored per game-owned kind
627
+
628
+ - `WaypointMarkers` (function) · `import { WaypointMarkers } from "@jgengine/react"`
629
+
277
630
  ## window — standalone draggable, closable window primitive over HudFrame — no manager required
278
631
 
279
632
  - `Window` (function) · `import { Window } from "@jgengine/react"`
280
633
 
634
+ ## world-intersections — inspect turns and junction meshes in a deterministic preview fixture
635
+
636
+ - `StreetGeometryPreview` (function) · `import { StreetGeometryPreview } from "@jgengine/react"`
637
+
281
638
  ## world-object-highlights — ground-ring highlight over every selected placed object
282
639
 
283
640
  - `WorldObjectHighlights` (function) · `import { WorldObjectHighlights } from "@jgengine/shell/world/WorldHud"`
641
+
642
+ ## world-pings — in-scene ping markers — a bobbing downward arrowhead, ground ring, and billboarded callout per marker, colored by kind and fading over the marker's lifetime
643
+
644
+ - `WorldPings` (function) · `import { WorldPings } from "@jgengine/shell/world/WorldPings"`
@@ -0,0 +1,136 @@
1
+ # Overhead enemy nameplates and health bars
2
+
3
+ Use this recipe when a game needs floating world-anchored frames over entities —
4
+ enemy nameplates with a health bar, interaction prompts, objective pips. The
5
+ game keeps owning its entities; JGengine owns only the reusable behavior:
6
+ projecting a world position to the screen, offsetting above the head, culling
7
+ frames that are off-screen or behind the camera, and stacking nearer frames over
8
+ farther ones. You compose the frame markup itself from the shipped bars, so the
9
+ look is the game's, not a prefab.
10
+
11
+ The seam is data-first and caller-owned: pass an array of
12
+ `{ id, worldPosition, ... }` and a projector. Nothing is mirrored into a store.
13
+
14
+ ## Install
15
+
16
+ ```sh
17
+ bun add @jgengine/core @jgengine/react
18
+ # @jgengine/shell only for the R3F projection convenience below
19
+ bun add @jgengine/shell
20
+ ```
21
+
22
+ `@jgengine/react/entityFrames` imports neither Three.js nor React Three Fiber and
23
+ needs no `GameProvider`. The `@jgengine/shell` piece is a thin R3F convenience.
24
+
25
+ ## R3F game: one component from your own entity array
26
+
27
+ `WorldEntityFrames` mounts inside the R3F scene, samples the live camera each
28
+ frame, and renders the frames through a fullscreen overlay. Pass the entities you
29
+ already have and a `renderFrame` that composes the shipped `HealthBar` plus a
30
+ name. Projection, culling, and stacking come for free.
31
+
32
+ ```tsx
33
+ import { WorldEntityFrames } from "@jgengine/shell/world/WorldEntityFrames";
34
+ import { HealthBar, barTokens } from "@jgengine/react/bars";
35
+
36
+ interface Enemy {
37
+ id: string;
38
+ name: string;
39
+ position: [number, number, number];
40
+ hp: number;
41
+ maxHp: number;
42
+ }
43
+
44
+ export function EnemyNameplates({ enemies }: { enemies: readonly Enemy[] }) {
45
+ const entries = enemies.map((e) => ({
46
+ id: e.id,
47
+ // Anchor over the head: lift the world Y by the entity's height.
48
+ worldPosition: [e.position[0], e.position[1] + 2.2, e.position[2]] as const,
49
+ enemy: e,
50
+ }));
51
+
52
+ return (
53
+ <WorldEntityFrames
54
+ entries={entries}
55
+ maxCount={24} // keep the nearest 24 when a crowd is on screen
56
+ renderFrame={({ enemy }) => (
57
+ <div style={{ ...barTokens({ health: "#e5484d" }), textAlign: "center" }}>
58
+ <span
59
+ style={{
60
+ fontSize: 12,
61
+ fontWeight: 700,
62
+ color: "#f1f5f9",
63
+ textShadow: "0 1px 3px rgba(0,0,0,0.9)",
64
+ whiteSpace: "nowrap",
65
+ }}
66
+ >
67
+ {enemy.name}
68
+ </span>
69
+ <HealthBar value={enemy.hp} max={enemy.maxHp} width={78} showValue={false} shape="pill" />
70
+ </div>
71
+ )}
72
+ />
73
+ );
74
+ }
75
+ ```
76
+
77
+ Reskin the whole set with one `HudTheme`/`barTokens` object on an ancestor —
78
+ health color, frame material, radius, and glow flow to every plate's `HealthBar`.
79
+ The `enemy` payload rides along on each entry, so `renderFrame` reads live values
80
+ without a second lookup.
81
+
82
+ ## Non-R3F game: bring your own projector
83
+
84
+ Outside R3F (a 2D or custom-renderer game), use the headless
85
+ `EntityFrames` directly and pass a `project` that maps a world position to a
86
+ screen point — return `null`, or `{ behind: true }`, to cull an entry. `depth`
87
+ (larger = farther) drives stacking.
88
+
89
+ ```tsx
90
+ import { EntityFrames, type ProjectEntity } from "@jgengine/react/entityFrames";
91
+ import { HealthBar } from "@jgengine/react/bars";
92
+
93
+ const project: ProjectEntity = (world) => {
94
+ const screen = myCamera.worldToScreen(world); // your renderer's projection
95
+ if (screen === null) return null; // outside the frustum → culled
96
+ return { x: screen.x, y: screen.y, depth: screen.distance, behind: screen.behind };
97
+ };
98
+
99
+ export function Nameplates({ enemies }: { enemies: readonly Enemy[] }) {
100
+ return (
101
+ <EntityFrames
102
+ entries={enemies.map((e) => ({ id: e.id, worldPosition: e.position, enemy: e }))}
103
+ project={project}
104
+ offsetY={-24}
105
+ viewport={{ width: window.innerWidth, height: window.innerHeight }}
106
+ renderFrame={({ enemy }) => (
107
+ <HealthBar value={enemy.hp} max={enemy.maxHp} width={78} showValue={false} />
108
+ )}
109
+ />
110
+ );
111
+ }
112
+ ```
113
+
114
+ Mount either component inside `HudCanvas` (or any positioned ancestor) so the
115
+ overlay is bounded to the viewport.
116
+
117
+ ## Ownership
118
+
119
+ The game still owns its entities, their positions, health, updates, camera, and
120
+ the render cadence. JGengine owns the projection→offset→cull→stack behavior
121
+ (`layoutEntityFrames`, unit-tested) and, for R3F, the camera→screen projector
122
+ (`useWorldProjection` / `projectWorldToScreen`). The frame markup is yours.
123
+
124
+ ## Common traps
125
+
126
+ - Pass a fresh `entries` array each frame (or memo it on your live data). The
127
+ component re-projects on the R3F frame loop; the pure `EntityFrames` re-projects
128
+ whenever it re-renders.
129
+ - Lift `worldPosition` by the entity's height for an overhead anchor — the seam
130
+ does not guess a height.
131
+ - Set `maxCount` for crowds so a battlefield of entities does not render hundreds
132
+ of plates; the nearest are kept.
133
+ - Do not mirror entities into a `GameProvider`/entity store to use this. If the
134
+ game *does* run the JGengine entity store, `WorldNameplates`
135
+ (`@jgengine/shell/world/WorldHud`) is the store-driven counterpart.
136
+ - Keep `renderFrame` cheap — it runs per visible entity per refresh.