@jgengine/convex 0.55.0 → 0.56.1
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
CHANGED
|
@@ -26,6 +26,171 @@ At publish, rename this heading to the new version and mirror the entries into
|
|
|
26
26
|
`packages/core/src/meta/changelog.ts` (the typed `CHANGELOG` export).
|
|
27
27
|
-->
|
|
28
28
|
|
|
29
|
+
## 0.56.1
|
|
30
|
+
|
|
31
|
+
### Migrate
|
|
32
|
+
|
|
33
|
+
- **Bump lockstep SDK packages to `^0.56.1`:** `@jgengine/{core,rapier,ui,ws,node,sql,convex,shell,editor,assets,navbake}`. CLI `jgengine` is `0.53.1`; `@jgengine/github` is `0.43.1`.
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- scripts/check-npm-trusted.ts refuses a release unless every package it publishes exists on npm and its latest version came through trusted publishing; bun run release runs it before cutting and the Publish workflow before its first npm publish, so a half-published release cannot happen.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- the grass eviction test walks a 600 m field in six settles instead of 2 km in twelve; it took 27-32 s on CI runners against a 30 s limit and blocked the 0.56.0 publish.
|
|
42
|
+
- the engine UI package (packages/ui) publishes as @jgengine/react again. 0.56.0 renamed it @jgengine/ui, a name npm had never seen, so trusted publishing refused it part-way and @jgengine/core@0.56.0 on latest depended on a package that did not exist. Imports, dependencies, jgengine.json engine keys ("react"), scaffold aliases and doctor's @source check all name @jgengine/react; bun run check react-free treats it as the engine's own UI package.
|
|
43
|
+
|
|
44
|
+
## 0.56.0
|
|
45
|
+
|
|
46
|
+
### Migrate
|
|
47
|
+
|
|
48
|
+
- **Bump lockstep SDK packages to `^0.56.0`:** `@jgengine/{core,rapier,ui,ws,node,sql,convex,shell,editor,assets,navbake}`. CLI `jgengine` is `0.53.0`; `@jgengine/github` is `0.43.0`.
|
|
49
|
+
- Native games compose `RuneRoot`, `RuneView`, `RuneLabel`, `RuneAction`, `RuneFor`, `RuneLayers`, `RuneTransient` and `RuneWorldAnchor` from `@jgengine/core/ui/rune/primitives.view`. Theme tokens and native style props replace game CSS; the new API supplies no finished widgets or screens. See the page-sized example in the jgengine-ui skill.
|
|
50
|
+
- `ActionBindingsProvider` and `useActionBindings` move from `ui/kit/uiKitRoot.view` to `input/actionBindings.view`, so native UI reads rebinds without importing a CSS kit. All in-repo imports move with them.
|
|
51
|
+
- `adjustSettingRow` now lives in `@jgengine/core/settings/settingAdjustment`; its arguments and result are unchanged. In-repo settings adopters use the new home.
|
|
52
|
+
- `createHudAwakeClock` and `sameWatched` now live in `@jgengine/core/hud/hudAwakeClock`, shared by the DOM and native HUD renderers.
|
|
53
|
+
- engine and game UI uses @jgengine/core/ui/jsx and @jgengine/react; the website and two framework examples retain their own React host and embed games with mountGamePlayer
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- RuneField native text field (controlled value, submit, autoFocus, focused-key capture, touch keyboard proxy) so native games can take chat, names and passwords.
|
|
58
|
+
- `RuneTextField` (`@jgengine/core/ui/rune/elements.view`): Native Rune-owned text field; edits and submits come back as events.
|
|
59
|
+
- `nativeFieldKey` (`@jgengine/core/ui/rune/nativeSurface.view`): ⚠ undocumented
|
|
60
|
+
- `RuneField` (`@jgengine/core/ui/rune/primitives.view`): Native text entry: Rune owns caret, selection and IME; the game owns the text. Also `RuneFieldProps`.
|
|
61
|
+
- Direct native Rune primitives for the engine JSX runtime, with one typed style set, bound slots/property patches, responsive/safe/world anchoring, keyed collections, native interaction and flow ownership. Set `uiRenderer: "rune"` and compose inside `RuneRoot` to bypass the CSS mirror.
|
|
62
|
+
- A headless native PNG renderer using the production builder, and native bounds/text for the game drive harness.
|
|
63
|
+
- Rune-native UI primitives (RuneRoot, RuneView, RuneLabel, RuneAction, RuneFor, RuneLayers, RuneTransient, RuneWorldAnchor, RuneGlyph) and Deepward rebuilt on them with no CSS or DOM host
|
|
64
|
+
- `ActionBindingsProvider` (`@jgengine/core/input/actionBindings.view`): Provide the game's live bindings, including player rebinds, without a presentation kit. Also `useActionBindings`.
|
|
65
|
+
- `adjustSettingRow` (`@jgengine/core/settings/settingAdjustment`): Step a slider within its bounds, flip a toggle or cycle a selection.
|
|
66
|
+
- `pageHost` (`@jgengine/core/ui/jsx/pageHost.view`): One JSX tree can contain native surfaces and ordinary page tooling, sharing all providers.
|
|
67
|
+
- `RuneActivation` (`@jgengine/core/ui/rune/activation`): Hold activation shared by pointer, touch, keyboard and pad, using an injected clock. Also `runeNextFocus`.
|
|
68
|
+
- `RuneBoundFont` (`@jgengine/core/ui/rune/element`): ⚠ undocumented Also `RuneBoundStyle`, `RuneColor`, `RuneElement`, `RuneElementProps`, `RuneFont`, `RuneGesture`, `RuneSize`, `RuneSpan` and 1 more.
|
|
69
|
+
- `RuneBox` (`@jgengine/core/ui/rune/elements.view`): Native Rune column. Also `RuneButton`, `RuneIcon`, `RuneRow`, `RuneScroll`, `RuneSurface`, `RuneText`, `RuneViewport`, `useRuneViewport`.
|
|
70
|
+
- `registerNativeRuneFont` (`@jgengine/core/ui/rune/nativeSurface.view`): Register native font bytes before the first surface mounts.
|
|
71
|
+
- `RuneNode` (`@jgengine/core/ui/rune/nativeTree`): A native host node; it has no browser element or computed style. Also `NativeWireNode`, `RuneTreeSink`, `nativeEnabled`, `nativeLabel`, `nativeSpec`, `nativeTreeHost`.
|
|
72
|
+
- `bind` (`@jgengine/core/ui/rune/primitives`): Bind any native visual property without scheduling a component render. Also `RuneFlow`, `RuneRoute`, `RuneSource`, `RuneTheme`, `RuneViewportClass`, `createRuneFlow`, `ownRuneFlow`, `runeFormat` and 3 more.
|
|
73
|
+
- `RuneAction` (`@jgengine/core/ui/rune/primitives.view`): Command interaction with native focus, pointer/touch, keyboard, pad, hold and drag/drop. Also `RuneActionProps`, `RuneAnchor`, `RuneFor`, `RuneGlyph`, `RuneLabel`, `RuneLabelProps`, `RuneLayers`, `RuneProjection` and 6 more.
|
|
74
|
+
- native Rune scroll views fade the edge with hidden content; flows can drag and touch
|
|
75
|
+
- one machine-wide limit on rendering browsers (JG_RENDER_SLOTS, sized to the machine; fairshare room for a second). Every Chrome launch takes a slot, a running but slow broker is joined instead of passed by, and devBroker status lists every broker and slot holder
|
|
76
|
+
- `createRunePassThrough` (`@jgengine/core/ui/runePassThrough`): ⚠ undocumented Also `RunePassThrough`.
|
|
77
|
+
- Rune rendering stays opt-in through ?ui=rune; DOM remains the default. The CSS styling path and CSS-to-Rune mirror are temporary while typed Rune-native props replace CSS
|
|
78
|
+
- `uiTour` (`@jgengine/core/play/uiTour`): ⚠ undocumented Also `TourStep`.
|
|
79
|
+
- `Children` (`@jgengine/core/ui/jsx`): ⚠ undocumented Also `ActionDispatch`, `AnyActionArg`, `CSSProperties`, `Component`, `ComponentClass`, `ComponentType`, `Context`, `DependencyList` and 58 more.
|
|
80
|
+
- `createPortal` (`@jgengine/core/ui/jsx/client.view`): ⚠ undocumented Also `Root`, `createRoot`, `flushSync`, `hydrateRoot`.
|
|
81
|
+
- `AllHTMLAttributes` (`@jgengine/core/ui/jsx/dom.view`): Every attribute of every tag, for the tags with no narrower set here. Also `AnchorHTMLAttributes`, `AnimationEvent`, `AnimationEventHandler`, `AriaAttributes`, `Attributes`, `AudioHTMLAttributes`, `ButtonHTMLAttributes`, `CanvasHTMLAttributes` and 56 more.
|
|
82
|
+
- `domHost` (`@jgengine/core/ui/jsx/domHost.view`): The host a DOM root renders through.
|
|
83
|
+
- `Children` (`@jgengine/core/ui/jsx/element`): ⚠ undocumented Also `AnyType`, `ClassInstance`, `ComponentClass`, `ContextType`, `ELEMENT`, `ElementType`, `Fragment`, `FunctionComponent` and 26 more.
|
|
84
|
+
- `Fragment` (`@jgengine/core/ui/jsx/jsx-dev-runtime`): ⚠ undocumented Also `jsx`, `jsxDEV`, `jsxs`.
|
|
85
|
+
- `Fragment` (`@jgengine/core/ui/jsx/jsx-runtime`): ⚠ undocumented Also `jsx`, `jsxDEV`, `jsxs`.
|
|
86
|
+
- `markupHost` (`@jgengine/core/ui/jsx/markup`): ⚠ undocumented Also `MarkupNode`, `renderToStaticMarkup`, `renderToString`, `renderToTree`, `styleText`, `treeToMarkup`.
|
|
87
|
+
- `Component` (`@jgengine/core/ui/jsx/reconciler`): Base class for the few class components (error boundaries). Also `ActionDispatch`, `AnyActionArg`, `Fiber`, `Host`, `PureComponent`, `Root`, `act`, `flushSync` and 17 more.
|
|
88
|
+
- `CSSProperties` (`@jgengine/core/ui/jsx/types`): An inline style object: CSS properties in camelCase, plus `--custom` properties. Also `ComponentClass`, `ComponentType`, `Context`, `DependencyList`, `Dispatch`, `EffectCallback`, `ElementType`, `ErrorInfo` and 19 more.
|
|
89
|
+
- `MirrorReport` (`@jgengine/core/ui/rune/cssMirror.view`): What the mirror could not express, counted by `property: value` and by where it was asked. Also `WireBox`, `boxOfElement`, `elementOf`, `idOf`, `mirrorContents`, `mirrorElement`, `mirrorRoot`, `onPaintResourceLoaded` and 4 more.
|
|
90
|
+
- `stateMatters` (`@jgengine/core/ui/rune/cssStates.view`): Whether marking `element` with the state's attribute would change how it or anything under it is styled. Also `twinStateRules`.
|
|
91
|
+
- `averageOfStops` (`@jgengine/core/ui/rune/cssValues`): The colour a gradient averages to: what a small repeated tile of it reads as. Also `WireDim`, `WireImageLayer`, `WireLayer`, `WireShadow`, `WireTextShadow`, `WireTrack`, `WireTransform`, `colorAlpha` and 17 more.
|
|
92
|
+
- `installRuneMeasure` (`@jgengine/core/ui/rune/domMeasure.view`): Make measurement of Rune-drawn elements answer from Rune's layout. Also `RuneScrollDriver`, `invalidateRuneLayout`, `runeRectOf`, `setRuneRect`, `setRuneScroll`.
|
|
93
|
+
- `compactPatches` (`@jgengine/core/ui/rune/patches`): Keep only attached replacement roots after all changes in one mirror pass.
|
|
94
|
+
- `RuneInput` (`@jgengine/core/ui/rune/runeInput.view`): ⚠ undocumented
|
|
95
|
+
- `RuneLayer` (`@jgengine/core/ui/rune/runeLayer.view`): Draws its children through Rune instead of the page: the elements exist (so styles, refs and events work as written) but the browser never lays them out or paints them; the Rune stage mirrors them onto its canvas over the game. Also `runeUiEnabled`.
|
|
96
|
+
- `RuneStage` (`@jgengine/core/ui/rune/runeStage.view`): ⚠ undocumented Also `registerRuneFont`.
|
|
97
|
+
- `VideoFrameSource` (`@jgengine/core/ui/rune/videoFrames.view`): The browser video methods used by a frame feed.
|
|
98
|
+
- `RuneScrollValues` (`@jgengine/core/ui/runeUi.view`): Scroll offset, viewport and content size in layout pixels.
|
|
99
|
+
- `mountGamePlayer` (`@jgengine/shell/mountGamePlayer`): Run a game inside any page: mounts the registry-driven player into `container` and returns the function that takes it down. Also `MountGamePlayerOptions`.
|
|
100
|
+
- `AccessibilityProvider` (`@jgengine/react`): Apply accessibility preferences to a subtree: exposes `--jg-text-scale` for text to scale off, and sets `data-reduced-motion` / `data-high-contrast` / `data-colorblind` / `data-captions` for CSS to respond to. Also `AbilitySlotBindingOptions`, `AchievementGallery`, `AchievementGalleryProps`, `AchievementToast`, `AchievementToastProps`, `ActionBar`, `ActionBarChrome`, `ActionBarKeyResult` and 626 more.
|
|
101
|
+
- `EventfulEngineStore` (`@jgengine/react/engineStore`): ⚠ undocumented Also `ReadableEngineStore`.
|
|
102
|
+
- `ENGINE_STYLESHEET` (`@jgengine/react/engineStyles`): The engine stylesheet: every `jg-*` keyframe the shared blocks and registry components animate with, the `[data-jg-*]` interaction-state rules behind {@link HudButton} / {@link HudSurface}, the quiet hover/press/focus defaults for plain buttons inside the HUD root, and reduced-motion handling (`prefers-reduced-motion` or `[data-reduced-motion="true"]` zero `--jg-motion-scale`). Also `ensureEngineStyles`, `useEngineStyles`.
|
|
103
|
+
- `PerFrameRenderError` (`@jgengine/react/hooks`): The error a component that re-renders every frame or tick from the store fails with in a dev build or test. Also `AbilitySlotBindingOptions`, `DomEventTarget`, `EventMeterView`, `GameClockControls`, `InventoryGridBinding`, `UseAxisChannelResult`, `WorldBrowserState`, `abilityKitNeedsHeartbeat` and 46 more.
|
|
104
|
+
- `GamePreviewComponent` (`@jgengine/react/preview`): ⚠ undocumented Also `GamePreviewProps`, `GamePreviewStates`.
|
|
105
|
+
- `PREVIEW_FIXTURES` (`@jgengine/react/previewFixtures`): Registry of deterministic, engine-level preview fixtures — the *real* exported `@jgengine/react` components (`HudThemePreview`, `IconsPreview`, …) that render identically every time from static values, so they can be screenshotted as regression evidence without booting a game. Also `PreviewFixture`, `previewFixtureNames`, `resolvePreviewFixture`.
|
|
106
|
+
- `GameContextBridge` (`@jgengine/react/provider`): Re-provide a captured {@link GameContext} across a nested React reconciler boundary. Also `GameProvider`, `useGameContext`, `useOptionalGameContext`.
|
|
107
|
+
- `selectionEqual` (`@jgengine/react/selectSnapshot`): Whether two selections show the same thing: the same value, or arrays and plain objects whose entries are the same all the way down (a record or class instance compares by identity). Also `HotSelectionPace`, `SelectCache`.
|
|
108
|
+
- `useKeyedStore` (`@jgengine/react/store`): Subscribe a component to one owner's slot of a typed keyed-family store defined with `defineKeyedStore`. Also `useStore`.
|
|
109
|
+
- `MENU_THEME_STYLE` (`@jgengine/react/testFixtures`): Menu theme tokens passed through the `style` prop with no cast.
|
|
110
|
+
|
|
111
|
+
### Changed
|
|
112
|
+
|
|
113
|
+
- Reduced repo agent rules and restored Claude loading
|
|
114
|
+
- Removed nested rule files; retained a 2,726-byte root guide and a CLAUDE.md containing only @AGENTS.md
|
|
115
|
+
- Updated game and skill references to the surviving guidance; no runtime code changed
|
|
116
|
+
- Validation: setup and every documented command or its --help passed; skill-doc tests passed; links and the size target passed; verify-fast caught its injected regression
|
|
117
|
+
- Ember Command moves to Rune-native UI primitives and deletes its CSS UI. Engine: native patches before Rune's first frame now queue behind the spec (runeUi.view.test.ts). Verified by fixture tests; no browser drive (Jon's call). Unverified: phone-width browser view, world health bars under the Rune canvas, GPU.
|
|
118
|
+
- Fernwild moves to Rune-native UI primitives and deletes its CSS UI. Verified by fixture tests; no browser drive (Jon's call). Missing primitives worked around in-game: text entry (name list), 3D model preview in UI (body card), shift/double click (x5 button), focus return after native press. Unverified: phone browser view, death/respawn code test, GPU.
|
|
119
|
+
- Verified: cargo test -p jg-ui 33 pass; rune UI TS tests 44 pass (new tests broken once and restored); core, Deepward and Scrap Signal type-checks.
|
|
120
|
+
- Unverified: real typing, IME and the phone keyboard proxy in a browser; the press fix is confirmed by the Harbor Heat tour after this lands.
|
|
121
|
+
- Unverified: real typing, IME and the phone keyboard proxy in a browser.
|
|
122
|
+
- Harbor Heat now draws its whole UI on the Rune-native primitives; its CSS and old UI folder are deleted.
|
|
123
|
+
- Verified: headless play test walks title, settings, credits, a run, HUD, city phone, pause, save and resume at 1280x720 and 390x844 (assertion broken once and restored); 193 tests; type-check.
|
|
124
|
+
- Simplified: 3D portraits on the licence and talk screens are now silhouettes; the courier name uses a key stand-in until it moves to RuneField.
|
|
125
|
+
- Unverified: real mouse, touch and pad input in a browser.
|
|
126
|
+
- LLMville now draws its whole UI on the Rune-native primitives; style.css, Tailwind and shadcn are removed.
|
|
127
|
+
- Verified: headless play test walks sign-in, lab creation, chat, every tablet app's main action, settings and rebind at 1280x720 and 390x844 (assertion broken once and restored); 399 tests; type-check; react-free; template sync.
|
|
128
|
+
- Simplified: /dev workbench routes and an unused create-world screen removed; the map claims cells by tap or drag with no hover price.
|
|
129
|
+
- Unverified: real browser input and the phone keyboard; emoji in player chat render as empty boxes (no emoji font in Rune).
|
|
130
|
+
- Deepward composes its whole HUD, menus, settings, credits and game-specific panels from native Rune primitives. Its stylesheet, CSS kit and old visor composition are removed. Other games keep the temporary mirror during migration.
|
|
131
|
+
- Odd Orbit moves to Rune-native UI primitives and deletes its CSS UI. Unverified: real-click HUD after play starts (software Rune repaint on host), GPU cost.
|
|
132
|
+
- Scrap Signal now draws its whole UI on the Rune-native primitives; its CSS and old UI folder are deleted.
|
|
133
|
+
- Verified: 228 tests, type-check, boot probe and bundle check pass with no ceiling raised; 42 headless native screenshots at 1280x720, 844x390 and 390x844 in games/scrap-signal/proofs/rune-primitives.
|
|
134
|
+
- Unverified: real mouse, touch and pad drives need the PC (no WebGPU in Chrome on the Linux host); the call sign entry is a game-local key stand-in until RuneField lands.
|
|
135
|
+
- A bare wrangler deploy in apps/web now runs the site asset check and refuses a build without game models, LUTs or HDRIs
|
|
136
|
+
- Landing gates run in about half the time: game suites play their proofs across up to four worker threads (fernwild's suite 761 s to 176 s; an engine change's gate 432-599 s to 210-242 s), and verify:fast shares its pass cache and test timings across every worktree of a clone, so a unit another lane proved on the same bytes is not run again
|
|
137
|
+
- A game's README or PLAN edit runs none of its tests or type-checks (was 64 tests)
|
|
138
|
+
- lane:close marks its own draft PR ready and refuses a PR into another base before the gate, not after it; tally's .tally/ reports are ignored, so a rebased landing's re-verify can merge
|
|
139
|
+
- Beacon Bastion draws its whole UI natively through Rune; old CSS UI removed. Engine: clicks on Rune pass through to the 3D field. Tests prove keyboard-typed commander name and the menu confirm cue.
|
|
140
|
+
- Brightway Park draws its UI natively through Rune; CSS UI removed
|
|
141
|
+
- Drift Foundry draws its UI natively through Rune; CSS UI removed
|
|
142
|
+
- vendored Rune updated from dev d751f07 to c92e462 (250 commits). Re-applied 8 jgengine patches upstream still lacks (layout rects, layout_style, web transparency, WOFF fonts, zero-range scroll, canvas wheel, synthetic bold for regular-only game fonts, SVG via the browser) and dropped 10 that served only the removed CSS host. Added a web touch build fix upstream dev needs. Text takes upstream's new WindfoilChromium default on Windows and Linux. jg-ui wasm grows from 7.7 to 10.3 MB (2.9 to 4.9 MB gzipped).
|
|
143
|
+
- Unverified: LLMville main flow needs its local backend; framework-host and website demo browser checks remain pending. Rune fidelity is outside this React-removal landing. Performance was not measured
|
|
144
|
+
|
|
145
|
+
### Fixed
|
|
146
|
+
|
|
147
|
+
- native Rune presses now wake a frame, so a click on a still HUD reaches the game at once instead of waiting for the next input.
|
|
148
|
+
- the rule effect registry test no longer fails when Scrap Signal's perks load first in the same worker.
|
|
149
|
+
- gamepad taps, held input and landing lock checks no longer race host scheduling
|
|
150
|
+
- Deepward's pause menu no longer covers the save-failure, reprint and blocked-record sheets
|
|
151
|
+
- a finger tap on a non-modal Rune control reaches it instead of the game below
|
|
152
|
+
- Deepward sheet titles and item names wrap on phones; the Fitter windup no longer re-renders each frame
|
|
153
|
+
- convert game package declarations and browser fixtures, preserve static form selections, and remove stale React Three Fiber documentation
|
|
154
|
+
|
|
155
|
+
### Removed
|
|
156
|
+
|
|
157
|
+
- `@jgengine/core/settings/settingsBlocks.view` no longer exports `adjustSettingRow`.
|
|
158
|
+
- `@jgengine/core/ui/kit/uiKitRoot.view` no longer exports `ActionBindingsProvider`, `useActionBindings`.
|
|
159
|
+
- `@jgengine/react` no longer exports `ActionBindingsProvider`, `useActionBindings`.
|
|
160
|
+
- verify:fast's rerun of timed-out test files; a timeout stays red and names the file. The bg-tasks exit-event test that timed out under load is quarantined with #3118
|
|
161
|
+
- jg-ui's CSS box host (css.rs, style.rs), its canvas-frame and box patch/scroll exports, and the old widget spec; the Rune wasm takes only native nodes and RuneUi drops patch, patchText, scrollTo, canvasFrame, removeCanvas and rects.
|
|
162
|
+
- the CSS-to-Rune mirror (RuneLayer, ?ui=rune, cssMirror, cssStates, domMeasure, runeInput, patches, boxTransform, videoFrames, cssValues) and the uiTour flow built on it. Every game draws its UI on native Rune surfaces; loadGameFonts now registers fonts with the native surface.
|
|
163
|
+
- `@jgengine/core/play/uiTour` no longer exports `TourStep`, `uiTour`.
|
|
164
|
+
- `@jgengine/core/ui/rune/cssMirror.view` no longer exports `MirrorReport`, `WireBox`, `boxOfElement`, `elementOf`, `idOf`, `mirrorContents`, `mirrorElement`, `mirrorRoot` and 5 more.
|
|
165
|
+
- `@jgengine/core/ui/rune/cssStates.view` no longer exports `stateMatters`, `twinStateRules`.
|
|
166
|
+
- `@jgengine/core/ui/rune/cssValues` no longer exports `WireDim`, `WireImageLayer`, `WireLayer`, `WireShadow`, `WireTextShadow`, `WireTrack`, `WireTransform`, `averageOfStops` and 18 more.
|
|
167
|
+
- `@jgengine/core/ui/rune/domMeasure.view` no longer exports `RuneScrollDriver`, `installRuneMeasure`, `invalidateRuneLayout`, `runeRectOf`, `setRuneRect`, `setRuneScroll`.
|
|
168
|
+
- `@jgengine/core/ui/rune/patches` no longer exports `compactPatches`.
|
|
169
|
+
- `@jgengine/core/ui/rune/runeInput.view` no longer exports `RuneInput`.
|
|
170
|
+
- `@jgengine/core/ui/rune/runeLayer.view` no longer exports `RuneLayer`, `runeUiEnabled`.
|
|
171
|
+
- `@jgengine/core/ui/rune/runeStage.view` no longer exports `RuneStage`, `registerRuneFont`.
|
|
172
|
+
- `@jgengine/core/ui/rune/videoFrames.view` no longer exports `VideoFrameSource`.
|
|
173
|
+
- `@jgengine/react` no longer exports `AbilitySlotBindingOptions`, `AccessibilityProvider`, `AchievementGallery`, `AchievementGalleryProps`, `AchievementToast`, `AchievementToastProps`, `ActionBar`, `ActionBarChrome` and 627 more.
|
|
174
|
+
- `@jgengine/react/engineStore` no longer exports `EventfulEngineStore`, `ReadableEngineStore`.
|
|
175
|
+
- `@jgengine/react/engineStyles` no longer exports `ENGINE_STYLESHEET`, `ensureEngineStyles`, `useEngineStyles`.
|
|
176
|
+
- `@jgengine/react/hooks` no longer exports `AbilitySlotBindingOptions`, `DomEventTarget`, `EventMeterView`, `GameClockControls`, `InventoryGridBinding`, `PerFrameRenderError`, `UseAxisChannelResult`, `WorldBrowserState` and 47 more.
|
|
177
|
+
- `@jgengine/react/preview` no longer exports `GamePreviewComponent`, `GamePreviewProps`, `GamePreviewStates`.
|
|
178
|
+
- `@jgengine/react/previewFixtures` no longer exports `PREVIEW_FIXTURES`, `PreviewFixture`, `previewFixtureNames`, `resolvePreviewFixture`.
|
|
179
|
+
- `@jgengine/react/provider` no longer exports `GameContextBridge`, `GameProvider`, `useGameContext`, `useOptionalGameContext`.
|
|
180
|
+
- `@jgengine/react/selectSnapshot` no longer exports `HotSelectionPace`, `SelectCache`, `selectionEqual`.
|
|
181
|
+
- `@jgengine/react/store` no longer exports `useKeyedStore`, `useStore`.
|
|
182
|
+
- `@jgengine/react/testFixtures` no longer exports `MENU_THEME_STYLE`.
|
|
183
|
+
|
|
184
|
+
## 0.55.1
|
|
185
|
+
|
|
186
|
+
### Migrate
|
|
187
|
+
|
|
188
|
+
- **Bump lockstep SDK packages to `^0.55.1`:** `@jgengine/{core,rapier,react,ws,node,sql,convex,shell,editor,assets,navbake}`. CLI `jgengine` is `0.52.1`; `@jgengine/github` is `0.42.1`.
|
|
189
|
+
|
|
190
|
+
### Fixed
|
|
191
|
+
|
|
192
|
+
- a save whose stored environment (wet surfaces, fires, flocks) no longer fits the game's authored world loads the rest of the save and starts the environment fresh, with a degraded: console line. On 0.55.0 it threw, so Harbor Heat showed a runtime error instead of its menu for anyone holding a save from 0.54.0.
|
|
193
|
+
|
|
29
194
|
## 0.55.0
|
|
30
195
|
|
|
31
196
|
### Migrate
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jgengine/convex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.56.1",
|
|
4
4
|
"description": "Convex adapters for JGengine: game transport, presence transport, and backend wiring over @jgengine/core.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"check-types": "tsgo --noEmit -p tsconfig.json"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@jgengine/core": "^0.
|
|
33
|
+
"@jgengine/core": "^0.56.1"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"convex": "^1.31.2",
|
package/skills/jgengine/SKILL.md
CHANGED
|
@@ -57,8 +57,8 @@ World content is editor-first: anything that adds, moves or restyles something v
|
|
|
57
57
|
2. `npx jgengine recipe <name>` prints a typechecked snippet; `npx jgengine recipe` lists them. [recipes/minimal-game.md](recipes/minimal-game.md) is the whole-game walkthrough; each domain has `recipes/`.
|
|
58
58
|
3. Open `api.md` or a `.d.ts` only for exact signatures, with grep.
|
|
59
59
|
|
|
60
|
-
If nothing fits, name the shared owner first (AGENTS.md
|
|
60
|
+
If nothing fits, name the shared owner first ([AGENTS.md](../../../AGENTS.md#game-changes-improve-the-framework)); report SDK gaps upstream outside this repo.
|
|
61
61
|
|
|
62
62
|
## Finish
|
|
63
63
|
|
|
64
|
-
Declare the game's genres in `jgengine.json` (`suite`) and prove each required player verb with a headless proof; `jgengine suite <game>` is the score ([
|
|
64
|
+
Declare the game's genres in `jgengine.json` (`suite`) and prove each required player verb with a headless proof; `jgengine suite <game>` is the score ([game proofs](../../../games/README.md#design-checklist-and-loop-proofs)). Keep scene coordinates in the editor document, state serializable, randomness injected. A game is not done while its entities and props are box markers: run the asset pass in `jgengine-assets`. Prove it with `jgengine-verify`.
|
package/skills/jgengine/api.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
- `CHANGELOG` (const): const CHANGELOG: Record<string, ChangelogEntry> — Per-version engine changelog keyed by semver string (e.g. `"0.10.0"`).
|
|
8
8
|
- `ChangelogEntry` (interface): interface ChangelogEntry — One release's migrate steps plus added/changed/removed notes (typed mirror of CHANGELOG.md).
|
|
9
|
-
- `VERSION` (const): const VERSION: "0.
|
|
9
|
+
- `VERSION` (const): const VERSION: "0.56.1" — Installed `@jgengine/core` semver - compare against {@link CHANGELOG} keys when migrating.
|
|
10
10
|
|
|
11
11
|
## @jgengine/core/authoring
|
|
12
12
|
|
|
@@ -107,11 +107,11 @@
|
|
|
107
107
|
|
|
108
108
|
## @jgengine/core/devtools/ColPanel.view
|
|
109
109
|
|
|
110
|
-
- `ColPanel` (function): function ColPanel():
|
|
110
|
+
- `ColPanel` (function): function ColPanel(): JSX.Element — ⚠ undocumented
|
|
111
111
|
|
|
112
112
|
## @jgengine/core/devtools/CollisionDebugWorld.draw
|
|
113
113
|
|
|
114
|
-
- `CollisionDebugWorld` (function): function CollisionDebugWorld():
|
|
114
|
+
- `CollisionDebugWorld` (function): function CollisionDebugWorld(): JSX.Element | null — World-space collision debugger. Performs zero scene scans and zero raycasts when every layer is off. Mount only when shell devtools are enabled.
|
|
115
115
|
|
|
116
116
|
## @jgengine/core/devtools/FpsCounter.draw
|
|
117
117
|
|
|
@@ -119,23 +119,23 @@
|
|
|
119
119
|
|
|
120
120
|
## @jgengine/core/devtools/KeysPanel.view
|
|
121
121
|
|
|
122
|
-
- `KeysPanel` (function): function KeysPanel({ input }: { input: ActionCodesMap | undefined }):
|
|
122
|
+
- `KeysPanel` (function): function KeysPanel({ input }: { input: ActionCodesMap | undefined }): JSX.Element — ⚠ undocumented
|
|
123
123
|
|
|
124
124
|
## @jgengine/core/devtools/LogsPanel.view
|
|
125
125
|
|
|
126
|
-
- `LogsPanel` (function): function LogsPanel():
|
|
126
|
+
- `LogsPanel` (function): function LogsPanel(): JSX.Element — ⚠ undocumented
|
|
127
127
|
|
|
128
128
|
## @jgengine/core/devtools/NetPanel.draw
|
|
129
129
|
|
|
130
|
-
- `NetPanel` (function): function NetPanel({ multiplayer }: { multiplayer: ShellMultiplayer | null }):
|
|
130
|
+
- `NetPanel` (function): function NetPanel({ multiplayer }: { multiplayer: ShellMultiplayer | null }): JSX.Element — ⚠ undocumented
|
|
131
131
|
|
|
132
132
|
## @jgengine/core/devtools/PerfPanel.view
|
|
133
133
|
|
|
134
|
-
- `PerfPanel` (function): function PerfPanel({ ctx }: { ctx: GameContext }):
|
|
134
|
+
- `PerfPanel` (function): function PerfPanel({ ctx }: { ctx: GameContext }): JSX.Element — ⚠ undocumented
|
|
135
135
|
|
|
136
136
|
## @jgengine/core/devtools/TunePanel.view
|
|
137
137
|
|
|
138
|
-
- `TunePanel` (function): function TunePanel({ gameName }: { gameName: string }):
|
|
138
|
+
- `TunePanel` (function): function TunePanel({ gameName }: { gameName: string }): JSX.Element — ⚠ undocumented
|
|
139
139
|
- `tuneControlLabels` (function): function tuneControlLabels(name: string): { range: string; number: string } — Accessible names for one tunable's inputs: the number field answers to the control name itself, so `drive --fill "<name>=<value>"` and a screen reader both find it; the range is `<name> slider`.
|
|
140
140
|
|
|
141
141
|
## @jgengine/core/devtools/agentBridge.draw
|
|
@@ -247,8 +247,8 @@
|
|
|
247
247
|
|
|
248
248
|
## @jgengine/core/devtools/diagnosticOverlay.view
|
|
249
249
|
|
|
250
|
-
- `DiagnosticOverlay` (function): function DiagnosticOverlay({ diagnostics, gameName }: { diagnostics: RuntimeDiagnostic[]; gameName: string }):
|
|
251
|
-
- `ErrorReportActions` (function): function ErrorReportActions({ report, issueTitle }: { report: string; issueTitle: string }):
|
|
250
|
+
- `DiagnosticOverlay` (function): function DiagnosticOverlay({ diagnostics, gameName }: { diagnostics: RuntimeDiagnostic[]; gameName: string }): JSX.Element | null — ⚠ undocumented
|
|
251
|
+
- `ErrorReportActions` (function): function ErrorReportActions({ report, issueTitle }: { report: string; issueTitle: string }): JSX.Element — "Copy error" + "File issue" buttons for any error surface. `report` is the full text to copy / prefill.
|
|
252
252
|
- `GameUiErrorBoundary` (class): class GameUiErrorBoundary extends Component< { children: ReactNode; onRuntimeError: (error: unknown, phase: string, componentStack?: string) => void }, { failed: boolean } > — ⚠ undocumented
|
|
253
253
|
- `RuntimeDiagnostic` (interface): interface RuntimeDiagnostic { id: number; phase: string; message: string; stack?: string | undefined; componentStack?: string | undefined; capturedAt: string } — ⚠ undocumented
|
|
254
254
|
- `errorReportContext` (function): function errorReportContext(): string — Standalone error footer text (page, browser, engine) shared by every error surface.
|
|
@@ -335,7 +335,7 @@
|
|
|
335
335
|
|
|
336
336
|
## @jgengine/core/devtools/panelAtoms.view
|
|
337
337
|
|
|
338
|
-
- `SectionLabel` (function): function SectionLabel({ children }: { children: string }):
|
|
338
|
+
- `SectionLabel` (function): function SectionLabel({ children }: { children: string }): JSX.Element — ⚠ undocumented
|
|
339
339
|
- `ms` (function): function ms(value: number): string — ⚠ undocumented
|
|
340
340
|
|
|
341
341
|
## @jgengine/core/devtools/perfDiagnose.view
|
|
@@ -350,11 +350,11 @@
|
|
|
350
350
|
|
|
351
351
|
## @jgengine/core/devtools/renderCounter
|
|
352
352
|
|
|
353
|
-
- `ComponentRenders` (interface): interface ComponentRenders — Which
|
|
353
|
+
- `ComponentRenders` (interface): interface ComponentRenders — Which components rendered, and how often: the evidence that a changing value re-renders only its own leaf. The engine's UI runtime reports every component render and every commit to the counter installed on the page (`bun run drive --renders`) or by the test preload, so a test can count renders of a real game HUD. It can be installed before or after the runtime loads.
|
|
354
354
|
- `RenderCounter` (interface): interface RenderCounter — The installed counter, at `globalThis.__jgRenders`.
|
|
355
355
|
- `RenderCounts` (interface): interface RenderCounts — Every commit and component render since the counter was installed or reset.
|
|
356
|
-
- `installRenderCounter` (function): function installRenderCounter(scope: {
|
|
357
|
-
- `renderCounter` (function): function renderCounter(): RenderCounter | null — The counter the test preload or the page script installed, or null when
|
|
356
|
+
- `installRenderCounter` (function): function installRenderCounter(scope: { __jgRenders?: RenderCounter | undefined; __jgRenderSink?: { render(type: unknown): void; commit(): void } | undefined }): RenderCounter — Install the counter on `scope`: the UI runtime calls its sink once per component render (a component that bailed out is never called) and once per commit. Self-contained, so a harness can ship its source to a page.
|
|
357
|
+
- `renderCounter` (function): function renderCounter(): RenderCounter | null — The counter the test preload or the page script installed, or null when there is none.
|
|
358
358
|
|
|
359
359
|
## @jgengine/core/devtools/report
|
|
360
360
|
|
|
@@ -461,7 +461,7 @@
|
|
|
461
461
|
|
|
462
462
|
- `CHANGELOG` (const): const CHANGELOG: Record<string, ChangelogEntry> — Per-version engine changelog keyed by semver string (e.g. `"0.10.0"`).
|
|
463
463
|
- `ChangelogEntry` (interface): interface ChangelogEntry — One release's migrate steps plus added/changed/removed notes (typed mirror of CHANGELOG.md).
|
|
464
|
-
- `VERSION` (const): const VERSION: "0.
|
|
464
|
+
- `VERSION` (const): const VERSION: "0.56.1" — Installed `@jgengine/core` semver - compare against {@link CHANGELOG} keys when migrating.
|
|
465
465
|
|
|
466
466
|
## @jgengine/core/runtime/adapter
|
|
467
467
|
|
|
@@ -597,7 +597,7 @@
|
|
|
597
597
|
- `HeadlessGameSource` (type): type HeadlessGameSource<TAssetRef extends ModelAssetRef, TMultiplayer> = | { game: HeadlessPlayable; definition?: never; content?: never; loop?: never; movement?: never; collision?: never; } | { definition: GameDefinition<TAssetRef, TMultiplayer>; game?: never; /** Catalog resolvers (`entityById`/`o… — Where a headless run gets its game. Pass the whole playable (`game`, what `defineGame` returns) and the runner reads its content, its phase-synced loop, its movement and collision config and whether the shell walks the player, the way play does. Pass a bare `definition` only for a test that builds a partial game; then content, loop, movement and collision are yours to pass, and passing them alongside `game` is a type error.
|
|
598
598
|
- `HeadlessInput` (interface): interface HeadlessInput — One step's worth of player intent handed to {@link HeadlessRunner.step} — the held-action set and pointer state the shell would otherwise publish from the browser each frame.
|
|
599
599
|
- `HeadlessPlayable` (type): type HeadlessPlayable<TProbe extends ProbeReadings = ProbeReadings> = PlayableGameContract<unknown, unknown, unknown, unknown, unknown, unknown, TProbe> — Any playable game, whatever its UI and render types (what `defineGame` returns); `TProbe` is what its `capture.probe` returns.
|
|
600
|
-
- `HeadlessRunner` (interface): interface HeadlessRunner — A renderer-free driver for a game loop: builds a {@link GameContext} from a game, runs the init hooks, then advances the simulation one step at a time from injected input. No
|
|
600
|
+
- `HeadlessRunner` (interface): interface HeadlessRunner — A renderer-free driver for a game loop: builds a {@link GameContext} from a game, runs the init hooks, then advances the simulation one step at a time from injected input. No UI runtime or three.js — the whole play path (time, input, `onTick`, behaviour nav, player movement) runs from `core` primitives alone, so a non-React host (a server tick, a test, a CLI replay) can play a real game and read its world snapshot. The shell's FrameDriver is one such driver bolted to `useFrame`; this is the same step distilled out of the render tree.
|
|
601
601
|
- `HeadlessRunnerOptions` (type): type HeadlessRunnerOptions<TAssetRef extends ModelAssetRef, TMultiplayer> = HeadlessGameSource<TAssetRef, TMultiplayer> & { /** The single local player; defaults to `{ userId: "player", isNew: true }`. */ player?: { userId: string; isNew: boolean }; /** Wall-clock source for the sim clock — inject a… — ⚠ undocumented
|
|
602
602
|
- `createHeadlessRunner` (function): function createHeadlessRunner<TAssetRef extends ModelAssetRef, TMultiplayer>(options: HeadlessRunnerOptions<TAssetRef, TMultiplayer>): HeadlessRunner — ⚠ undocumented
|
|
603
603
|
|
|
@@ -851,7 +851,7 @@
|
|
|
851
851
|
## @jgengine/shell/GameHost
|
|
852
852
|
|
|
853
853
|
- `EditorSummonModule` (interface): interface EditorSummonModule — Structural shape of the module `GameHost`'s `editor` loader resolves — `import("@jgengine/editor")` satisfies it.
|
|
854
|
-
- `GameHost` (function): function GameHost({ playable, gameId, wsUrl, multiplayer, resolveMultiplayer, editor, creator, creatorOpen = false, onCreatorOpenChange }: GameHostProps):
|
|
854
|
+
- `GameHost` (function): function GameHost({ playable, gameId, wsUrl, multiplayer, resolveMultiplayer, editor, creator, creatorOpen = false, onCreatorOpenChange }: GameHostProps): JSX.Element — The one documented mount: resolves multiplayer for the playable and renders the shell. With the `editor` loader prop it also owns the whole editor summon (F2+E, `?mode=editor`, dev save endpoint).
|
|
855
855
|
- `GameHostProps` (interface): interface GameHostProps — Props for {@link GameHost}: the playable, optional multiplayer overrides, and the optional editor loader that enables the engine-owned F2+E summon.
|
|
856
856
|
|
|
857
857
|
## @jgengine/shell/defineGame
|
|
@@ -861,8 +861,8 @@
|
|
|
861
861
|
|
|
862
862
|
## @jgengine/shell/gameKit
|
|
863
863
|
|
|
864
|
-
- `Clock` (const): const Clock:
|
|
865
|
-
- `Coins` (function): function Coins({ currencyId, icon = "🪙", style, className, }: { currencyId: string; icon?: ReactNode; style?: CSSProperties; className?: string; }):
|
|
864
|
+
- `Clock` (const): const Clock: NamedExoticComponent<{ format?: "24h" | "12h" | undefined; showDay?: boolean | undefined; controls?: boolean | undefined; style?: CSSProperties | undefined; className?: string | undefined; }> — 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.
|
|
865
|
+
- `Coins` (function): function Coins({ currencyId, icon = "🪙", style, className, }: { currencyId: string; icon?: ReactNode; style?: CSSProperties; className?: string; }): JSX.Element — A currency counter — an icon (emoji/char, default a coin) plus the live amount for `currencyId`. *
|
|
866
866
|
- `DEFAULT_DRIVE_CODES` (const): const DEFAULT_DRIVE_CODES: { readonly throttle: readonly ["KeyW", "ArrowUp"]; readonly brake: readonly ["KeyS", "ArrowDown"]; readonly steerLeft: readonly ["KeyA", "ArrowLeft"]; readonly steerRight: readonly ["KeyD", "ArrowRight"]; readonly handbrake: readonly ["Space"]; } — Stock keyboard codes for driving a vehicle: WASD or the arrows for throttle, brake and steering, Space for the handbrake. Spread it as the base of a racing map and override what the game uses differently (`input: { ...DEFAULT_DRIVE_CODES, handbrake: ["KeyX"], hop: ["Space"] }`).
|
|
867
867
|
- `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"]; } — Stock keyboard codes for the shell walk controller: WASD to move, Space to jump. Spread it as the base of a game's map (`input: { ...DEFAULT_WALK_CODES, sprint: ["ShiftLeft"], interact: ["KeyE"] }`) instead of re-typing the same five bindings in every game.
|
|
868
868
|
- `EditorCatalogDefinition` (interface): interface EditorCatalogDefinition — Game-exported catalog definition: a `ParamSchema` plus default entries. Schemas stay in code; entry values merge into `document.catalogs` and are what the editor/RPC edits and saves.
|
|
@@ -871,13 +871,13 @@
|
|
|
871
871
|
- `GameCameraConfig` (interface): interface GameCameraConfig — Camera tuning for the shell's rig stack: pick the rig via `rig`, then tune it through its matching config block. All fields optional — the default is the third-person orbit rig.
|
|
872
872
|
- `GameConfig` (type): type GameConfig<TAssetRef extends ModelAssetRef = ModelAssetRef, TProbe extends ProbeReadings = ProbeReadings> = EngineFields<TAssetRef> & PresentationFields<TProbe> — ⚠ undocumented · used by `defineGame`: The one public authoring entry point: compose engine fields (systems, world, physics, input) and presentation fields (camera, HUD, audio, au…
|
|
873
873
|
- `GameContext` (interface): interface GameContext — The live engine handle a game's loop, systems, commands, and UI read and mutate — entities, objects, the reactive store, opted-in `game.*` subsystems, world queries, and the sim clock. One context = one running world.
|
|
874
|
-
- `GameHost` (function): function GameHost({ playable, gameId, wsUrl, multiplayer, resolveMultiplayer, editor, creator, creatorOpen = false, onCreatorOpenChange }: GameHostProps):
|
|
874
|
+
- `GameHost` (function): function GameHost({ playable, gameId, wsUrl, multiplayer, resolveMultiplayer, editor, creator, creatorOpen = false, onCreatorOpenChange }: GameHostProps): JSX.Element — The one documented mount: resolves multiplayer for the playable and renders the shell. With the `editor` loader prop it also owns the whole editor summon (F2+E, `?mode=editor`, dev save endpoint).
|
|
875
875
|
- `GameHostProps` (interface): interface GameHostProps — Props for {@link GameHost}: the playable, optional multiplayer overrides, and the optional editor loader that enables the engine-owned F2+E summon.
|
|
876
876
|
- `GameLoop` (interface): interface GameLoop<TContext = unknown> — Lifecycle hooks a game implements to drive init, per-tick simulation, and player join/leave.
|
|
877
|
-
- `Hotbar` (const): const Hotbar:
|
|
878
|
-
- `HudCanvas` (const): const HudCanvas:
|
|
879
|
-
- `HudFade` (const): const HudFade:
|
|
880
|
-
- `HudPanel` (const): const HudPanel:
|
|
877
|
+
- `Hotbar` (const): const Hotbar: NamedExoticComponent<{ inventoryId: string; activeSlot?: number | undefined; keys?: readonly string[] | undefined; slotSize?: number | undefined; itemIcon?: ((itemId: string) => UiNode) | undefined; style?: CSSProperties | undefined; className?: string | undefined; }> — 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.
|
|
878
|
+
- `HudCanvas` (const): const HudCanvas: NamedExoticComponent<{ layout: HudLayoutStore; editChord?: false | HudEditChord | undefined; showDuring?: readonly GamePhase[] | undefined; className?: string | undefined; style?: CSSProperties | undefined; children?: UiNode; }> — Full-viewport HUD surface. Each `HudPanel` names an anchor and a priority; the canvas measures every panel and places them all at once so none lands on another, at any screen size. Panels sharing an anchor stack outward from that edge; a panel that would cover a neighbour slides along its edge to the nearest free spot; when the screen is too small, the lowest-priority panels fold into a toggle, and only then does the whole HUD shrink. Device safe areas and every touch control (any region registered as kind `control` or `system`) are kept clear. Games declare panels, never place them per size.
|
|
879
|
+
- `HudFade` (const): const HudFade: NamedExoticComponent<HudFadeProps> — A HUD group that steps back when nothing is happening: it fades after a quiet spell and comes back the moment a watched value changes, so the world fills the screen and the HUD speaks only when it has news. Hovering it also brings it back. It reads `watch` and `hold` every frame and sets its own opacity, so it never re-renders, and neither do its children, for a value it watches.
|
|
880
|
+
- `HudPanel` (const): const HudPanel: NamedExoticComponent<{ id: string; anchor?: HudAnchor | undefined; order?: number | undefined; chip?: string | undefined; interactive?: boolean | undefined; inset?: { x: number; y: number; } | undefined; locked?: boolean | undefined; showDuring?: readonly GamePhase[] | undefined; pri… — A HUD block anchored to a corner, edge or the centre. `HudCanvas` places every panel together: panels sharing an anchor stack outward from the screen edge in ascending `order`, and a panel that would cover another slides to the nearest free spot. When the screen is too small, lower-`priority` panels fold into a toggle first. On fine pointers panels stay draggable through the edit chord; a dragged panel leaves the flow and keeps its custom placement.
|
|
881
881
|
- `HudSlots` (function): function HudSlots({ storageKey, slots = {}, panels = {}, overlay, showDuring = DEFAULT_SLOT_PHASES, className }: HudSlotsProps): ReactNode — The play HUD in one line: a few small panels pinned to the screen's edges, scaled from a 1600x900 design to any window and movable by the player (the layout is remembered per `storageKey`). Keep it to a handful of slots; the world is the picture.
|
|
882
882
|
- `PlayableGame` (type): type PlayableGame<TProbe extends ProbeReadings = ProbeReadings> = PlayableGameContract< ComponentType, ComponentType, RenderEntity, RenderObject, ComponentType<ViewmodelProps>, ComponentType<WorldOverlayProps>, TProbe, ComponentType<RemotePlayersProps> > & { /** HUD theme the shell applies at the `G… — The concrete React-bound playable a shell `defineGame` returns and `GameHost` mounts — the one PlayableGame games handle. `TProbe` is what the game's `capture.probe` returns, so a proof flow over `typeof game` names only real probes.
|
|
883
883
|
- `StoreHandle` (interface): interface StoreHandle<T> — A typed, cast-free handle onto one slot of the reactive game store (`ctx.game.store`). The single type parameter is fixed at definition; `read`/`write`/`update` never widen to `unknown`, so no call site repeats `store.get(key) as T`. Writes flow through the engine store, so they bump `ctx.version()`, serialize into a {@link WorldSnapshot}, and replay under host authority — the same guarantees a hand-rolled `store.get`/`store.set` pair gives up the moment it forks run state into a module-level singleton.
|
|
@@ -249,11 +249,11 @@
|
|
|
249
249
|
- `BetterAuthUserShape` (interface): interface BetterAuthUserShape { id: string; name?: string | null; email?: string | null; image?: string | null } — ⚠ undocumented
|
|
250
250
|
- `ClerkUserShape` (interface): interface ClerkUserShape { id: string; fullName?: string | null; username?: string | null; imageUrl?: string | null; primaryEmailAddress?: {emailAddress: string} | null; createdAt?: Date | null; lastSignInAt?: Date | null } — ⚠ undocumented
|
|
251
251
|
- `ClerkUserState` (interface): interface ClerkUserState { isLoaded: boolean; isSignedIn: boolean | undefined; user: ClerkUserShape | null | undefined } — ⚠ undocumented
|
|
252
|
-
- `GameIdentityProvider` (function): function GameIdentityProvider({ source, children, }: { source: IdentitySource; children?: ReactNode; }):
|
|
252
|
+
- `GameIdentityProvider` (function): function GameIdentityProvider({ source, children, }: { source: IdentitySource; children?: ReactNode; }): JSX.Element — ⚠ undocumented
|
|
253
253
|
- `IdentitySource` (interface): interface IdentitySource { session: AuthSession | null; isLoading: boolean; signOut?: () => void } — ⚠ undocumented
|
|
254
|
-
- `RequireSession` (function): function RequireSession({ fallback, loading, children, }: { fallback?: ReactNode; loading?: ReactNode; children?: ReactNode; }):
|
|
255
|
-
- `SignOutButton` (function): function SignOutButton({ className, children, }: { className?: string; children?: ReactNode; }):
|
|
256
|
-
- `UserBadge` (function): function UserBadge({ className, avatarClassName, nameClassName, renderBadge, }: { className?: string; avatarClassName?: string; nameClassName?: string; renderBadge?: (session: AuthSession) => ReactNode; }):
|
|
254
|
+
- `RequireSession` (function): function RequireSession({ fallback, loading, children, }: { fallback?: ReactNode; loading?: ReactNode; children?: ReactNode; }): JSX.Element — ⚠ undocumented
|
|
255
|
+
- `SignOutButton` (function): function SignOutButton({ className, children, }: { className?: string; children?: ReactNode; }): JSX.Element | null — ⚠ undocumented
|
|
256
|
+
- `UserBadge` (function): function UserBadge({ className, avatarClassName, nameClassName, renderBadge, }: { className?: string; avatarClassName?: string; nameClassName?: string; renderBadge?: (session: AuthSession) => ReactNode; }): JSX.Element | null — ⚠ undocumented
|
|
257
257
|
- `betterAuthIdentity` (function): function betterAuthIdentity(state: BetterAuthSessionState, options?: { signOut?: () => void }): IdentitySource — ⚠ undocumented
|
|
258
258
|
- `clerkIdentity` (function): function clerkIdentity(state: ClerkUserState, options?: { signOut?: () => void }): IdentitySource — ⚠ undocumented
|
|
259
259
|
- `guestIdentity` (function): function guestIdentity(seed?: string): IdentitySource — ⚠ undocumented
|
|
@@ -339,11 +339,11 @@
|
|
|
339
339
|
|
|
340
340
|
## @jgengine/core/multiplayer/voice.view
|
|
341
341
|
|
|
342
|
-
- `MicToggle` (function): function MicToggle({ voice, className, mutedLabel, unmutedLabel, }: { voice: VoiceState; className?: string; mutedLabel?: ReactNode; unmutedLabel?: ReactNode; }):
|
|
343
|
-
- `PushToTalkButton` (function): function PushToTalkButton({ voice, className, children, }: { voice: VoiceState; className?: string; children?: ReactNode; }):
|
|
344
|
-
- `SpeakingIndicator` (function): function SpeakingIndicator({ voice, userId, className, threshold = 0.01, children, }: { voice: VoiceState; userId: string; className?: string; threshold?: number; children?: ReactNode; }):
|
|
342
|
+
- `MicToggle` (function): function MicToggle({ voice, className, mutedLabel, unmutedLabel, }: { voice: VoiceState; className?: string; mutedLabel?: ReactNode; unmutedLabel?: ReactNode; }): JSX.Element — ⚠ undocumented
|
|
343
|
+
- `PushToTalkButton` (function): function PushToTalkButton({ voice, className, children, }: { voice: VoiceState; className?: string; children?: ReactNode; }): JSX.Element — ⚠ undocumented
|
|
344
|
+
- `SpeakingIndicator` (function): function SpeakingIndicator({ voice, userId, className, threshold = 0.01, children, }: { voice: VoiceState; userId: string; className?: string; threshold?: number; children?: ReactNode; }): JSX.Element — ⚠ undocumented
|
|
345
345
|
- `UseVoiceOptions` (interface): interface UseVoiceOptions { transport?: VoiceTransport; channelId?: string; mode?: PushToTalkMode; resolveRoutes?: () => readonly VoiceRoute[]; getUserMedia?: (constraints: MediaStreamConstraints) => Promise<MediaStream> } — ⚠ undocumented · used by `useVoice`: Mic capture + push-to-talk + channel roster over the VoiceTransport signaling seam.
|
|
346
|
-
- `VoiceRoster` (function): function VoiceRoster({ voice, className, participantClassName, renderParticipant, }: { voice: VoiceState; className?: string; participantClassName?: string; renderParticipant?: (participant: VoiceParticipant, gain: number) => ReactNode; }):
|
|
346
|
+
- `VoiceRoster` (function): function VoiceRoster({ voice, className, participantClassName, renderParticipant, }: { voice: VoiceState; className?: string; participantClassName?: string; renderParticipant?: (participant: VoiceParticipant, gain: number) => ReactNode; }): JSX.Element — ⚠ undocumented
|
|
347
347
|
- `VoiceState` (interface): interface VoiceState { supported: boolean; micStream: MediaStream | null; micError: string | null; requestMic(): Promise<boolean>; transmitting: boolean; status: PushToTalkStatus; mode: PushToTalkMode; setMode(mode: PushToTalkMode): void; muted: boolean; setMut… — ⚠ undocumented · used by `useVoice`: Mic capture + push-to-talk + channel roster over the VoiceTransport signaling seam.
|
|
348
348
|
- `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.
|
|
349
349
|
|