@jgengine/shell 0.17.0 → 0.18.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 +130 -2
- package/dist/GamePlayerShell.js +10 -4
- package/dist/JoinGate.d.ts +17 -0
- package/dist/JoinGate.js +14 -0
- package/dist/Shell3dPresentation.d.ts +8 -1
- package/dist/Shell3dPresentation.js +34 -5
- package/dist/ShellChrome.d.ts +2 -0
- package/dist/ShellChrome.js +6 -0
- package/dist/TerritoryOverlay.d.ts +21 -0
- package/dist/TerritoryOverlay.js +9 -0
- package/dist/audio/AudioComponents.js +8 -1
- package/dist/audio/audioEngine.d.ts +7 -1
- package/dist/audio/audioEngine.js +67 -5
- package/dist/camera/cameraRigs.js +7 -0
- package/dist/defineGame.js +21 -6
- package/dist/devtools/KeysPanel.js +3 -3
- package/dist/drivers/FrameDriver.d.ts +5 -1
- package/dist/drivers/FrameDriver.js +61 -24
- package/dist/drivers/HudOnlyDriver.js +9 -4
- package/dist/environment/EnvironmentScene.js +1 -1
- package/dist/input/gamepadMerge.d.ts +10 -0
- package/dist/input/gamepadMerge.js +12 -0
- package/dist/input/gamepadSource.d.ts +12 -0
- package/dist/input/gamepadSource.js +107 -0
- package/dist/materialOverride.d.ts +4 -1
- package/dist/materialOverride.js +10 -1
- package/dist/postfx/PostProcessing.d.ts +10 -7
- package/dist/postfx/PostProcessing.js +33 -15
- package/dist/postfx/gradeShader.js +13 -0
- package/dist/render/CascadedShadows.d.ts +11 -0
- package/dist/render/CascadedShadows.js +19 -8
- package/dist/render/EnvironmentLighting.d.ts +4 -1
- package/dist/render/EnvironmentLighting.js +45 -9
- package/dist/render/SceneLighting.d.ts +16 -2
- package/dist/render/SceneLighting.js +56 -6
- package/dist/render/SceneModels.js +45 -9
- package/dist/render/modelLoad.d.ts +10 -0
- package/dist/render/modelLoad.js +28 -0
- package/dist/render/modelRender.d.ts +3 -0
- package/dist/render/modelRender.js +6 -2
- package/dist/render/testFixtures/proceduralSpriteAtlas.d.ts +15 -0
- package/dist/render/testFixtures/proceduralSpriteAtlas.js +30 -0
- package/dist/render/testFixtures/proceduralTileLayer.d.ts +13 -0
- package/dist/render/testFixtures/proceduralTileLayer.js +30 -0
- package/dist/render/useFootIk.d.ts +9 -0
- package/dist/render/useFootIk.js +89 -0
- package/dist/render/useModelAnimation.d.ts +2 -0
- package/dist/render/useModelAnimation.js +163 -107
- package/dist/scene/CityRenderer.js +661 -236
- package/dist/scene/cityWindowMaterial.d.ts +8 -6
- package/dist/scene/cityWindowMaterial.js +80 -21
- package/dist/settings/appliedSettings.d.ts +3 -1
- package/dist/settings/appliedSettings.js +5 -2
- package/dist/terrain/terrainDetailMaterial.js +7 -3
- package/dist/useShellMultiplayerSync.d.ts +8 -1
- package/dist/useShellMultiplayerSync.js +25 -5
- package/dist/visibility/CullingProvider.d.ts +2 -1
- package/dist/visibility/CullingProvider.js +7 -2
- package/dist/world/GridWorldScene.js +4 -0
- package/dist/world/TileLayerRenderer.d.ts +9 -0
- package/dist/world/TileLayerRenderer.js +64 -0
- package/dist/world/WorldParticles.d.ts +31 -0
- package/dist/world/WorldParticles.js +128 -0
- package/dist/world/WorldScene.d.ts +2 -1
- package/dist/world/WorldScene.js +46 -4
- package/dist/world/entityPose.d.ts +4 -0
- package/dist/world/entityPose.js +9 -0
- package/dist/world/tileLayerInstances.d.ts +11 -0
- package/dist/world/tileLayerInstances.js +28 -0
- package/dist/worldSync.d.ts +5 -1
- package/dist/worldSync.js +25 -4
- package/package.json +4 -4
- package/skills/ce-handoff/SKILL.md +1 -1
- package/skills/game-design/SKILL.md +11 -1
- package/skills/jgengine/SKILL.md +2 -0
- package/skills/jgengine/api.md +98 -22
- package/skills/jgengine/capabilities.md +28 -0
- package/skills/jgengine-ui/SKILL.md +8 -0
- package/skills/jgengine-ui/api.md +127 -16
- package/skills/jgengine-ui/capabilities.md +21 -0
- package/skills/jgengine-ui/reference.md +3 -0
- package/skills/jgengine-world/SKILL.md +6 -0
- package/skills/jgengine-world/api.md +312 -12
- package/skills/jgengine-world/capabilities.md +102 -0
- package/skills/level-design/SKILL.md +1 -1
- package/skills/jgengine-ui/references/visual-scorecard.md +0 -73
|
@@ -12,10 +12,18 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
12
12
|
|
|
13
13
|
- `collectAuthoredTriggers` (function) · `import { collectAuthoredTriggers } from "@jgengine/shell/gameKit"`
|
|
14
14
|
|
|
15
|
+
## client-side — input prediction with replay reconciliation
|
|
16
|
+
|
|
17
|
+
- `createPredictionBuffer` (function) · `import { createPredictionBuffer } from "@jgengine/core/runtime/prediction"`
|
|
18
|
+
|
|
15
19
|
## collider-autofit — hitboxes and physical bodies fit each kind's rendered model bounds automatically — no hand-tuned sizes
|
|
16
20
|
|
|
17
21
|
- `GameContextModels` (interface) · `import { GameContextModels } from "@jgengine/core/runtime/gameContext"`
|
|
18
22
|
|
|
23
|
+
## command-quantity — validate bounded whole-item counts at command boundaries
|
|
24
|
+
|
|
25
|
+
- `readQuantity` (function) · `import { readQuantity } from "@jgengine/core/runtime/commandInput"`
|
|
26
|
+
|
|
19
27
|
## default-walk-codes — stock WASD + jump key codes for the shell walk controller
|
|
20
28
|
|
|
21
29
|
- `DEFAULT_WALK_CODES` (const) · `import { DEFAULT_WALK_CODES } from "@jgengine/shell/gameKit"`
|
|
@@ -84,6 +92,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
84
92
|
|
|
85
93
|
- `StatBar` (function) · `import { StatBar } from "@jgengine/shell/gameKit"`
|
|
86
94
|
|
|
95
|
+
## input-recorder — tick-indexed input log for replay, rollback, and regression tests
|
|
96
|
+
|
|
97
|
+
- `createInputRecorder` (function) · `import { createInputRecorder } from "@jgengine/core/runtime/inputRecorder"`
|
|
98
|
+
|
|
87
99
|
## loot-table — validate a loot table definition for use with the registry
|
|
88
100
|
|
|
89
101
|
- `lootTable` (function) · `import { lootTable } from "@jgengine/core/authoring"`
|
|
@@ -116,6 +128,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
116
128
|
|
|
117
129
|
- `toRuntimeObjectRow` (function) · `import { toRuntimeObjectRow } from "@jgengine/core/runtime/objectRows"`
|
|
118
130
|
|
|
131
|
+
## pose-interpolation — render entity poses between fixed simulation steps without stutter
|
|
132
|
+
|
|
133
|
+
- `createPoseHistory` (function) · `import { createPoseHistory } from "@jgengine/core/runtime/poseInterpolation"`
|
|
134
|
+
|
|
119
135
|
## render-fallback-diagnostics — Enable/disable the dev-only placeholder-fallback probe.
|
|
120
136
|
|
|
121
137
|
- `armFallbackSeams` (function) · `import { armFallbackSeams } from "@jgengine/core/devtools/fallbackSeams"`
|
|
@@ -126,6 +142,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
126
142
|
- `resetTextureErrors` (function) · `import { resetTextureErrors } from "@jgengine/core/devtools/textureErrors"`
|
|
127
143
|
- `textureErrorsSnapshot` (function) · `import { textureErrorsSnapshot } from "@jgengine/core/devtools/textureErrors"`
|
|
128
144
|
|
|
145
|
+
## runtime — snapshot interpolation
|
|
146
|
+
|
|
147
|
+
- `createSnapshotBuffer` (function) · `import { createSnapshotBuffer } from "@jgengine/core/runtime/snapshotBuffer"`
|
|
148
|
+
|
|
129
149
|
## runtime-save — save/load the whole game world through a pluggable backend, autosave or save points
|
|
130
150
|
|
|
131
151
|
- `createRuntimeSave` (function) · `import { createRuntimeSave } from "@jgengine/core/runtime/runtimeSave"`
|
|
@@ -142,6 +162,14 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
142
162
|
|
|
143
163
|
- `seededRng` (function) · `import { seededRng } from "@jgengine/shell/gameKit"`
|
|
144
164
|
|
|
165
|
+
## sim-loop — fixed-step or variable simulation stepping with tick count, catch-up cap, and interpolation alpha
|
|
166
|
+
|
|
167
|
+
- `createSimLoop` (function) · `import { createSimLoop } from "@jgengine/core/runtime/simLoop"`
|
|
168
|
+
|
|
169
|
+
## sim-snapshot — capture and restore whole-simulation state for replay, rollback, and regression tests
|
|
170
|
+
|
|
171
|
+
- `createSimSnapshotRegistry` (function) · `import { createSimSnapshotRegistry } from "@jgengine/core/runtime/simSnapshot"`
|
|
172
|
+
|
|
145
173
|
## typed-keyed-store — a cast-free typed handle onto a per-owner keyed family of reactive game-store slots, replayable and host-authoritative
|
|
146
174
|
|
|
147
175
|
- `defineKeyedStore` (function) · `import { defineKeyedStore } from "@jgengine/shell/gameKit"`
|
|
@@ -39,6 +39,14 @@ Existing React games keep their entity store and use the focused
|
|
|
39
39
|
- Layout and skin remain caller-controlled; shared primitives own reusable behavior, not product look.
|
|
40
40
|
- SSR-visible output is hydration-stable; round computed SVG values at the boundary.
|
|
41
41
|
|
|
42
|
+
## Shared-world interaction rules
|
|
43
|
+
|
|
44
|
+
- Every rejected verb displays its reason on the triggering surface. Use `useServerSession(transport, gameId)` for join lifecycle. Join failure blocks play with `JoinGate` and retry; returning `{ ok: false }` without feedback is incomplete.
|
|
45
|
+
- The first tutorial verb works within 60 seconds from spawn with starting inventory. Land, power, and slots are granted or purchasable in-context; tutorial locks must not hide prerequisites.
|
|
46
|
+
- Placement previews display claim cost and affordability inline with `TerritoryOverlay`.
|
|
47
|
+
- `ChatPanel` owns collapsed/expanded state, own-message styling, Enter focus and Escape blur; standalone hosts pass `messages`, `userId`, and `onSend` (typed `{ ok, reason }`), while context-backed games use channel props. Use native inputs so shell typing-target suspension applies.
|
|
48
|
+
- Register Tailwind `@source` for consumed package files and inspect `bun run shoot <gameId> --mode ui` captures of join, chat, and placement feedback.
|
|
49
|
+
|
|
42
50
|
## Traps
|
|
43
51
|
|
|
44
52
|
- Do not put environment beautification, authored-scene rendering, or world placement here.
|
|
@@ -33,14 +33,21 @@
|
|
|
33
33
|
- `createI18n` (function): function createI18n(options: I18nOptions): I18n — Create a translator over a message catalog: active-locale lookup with a fallback-locale chain, `{param}` interpolation, and `Intl.PluralRules`-based pluralization. Observable (`subscribe`) so React re-renders on `setLocale`; the catalog is caller-owned static data, the locale is the only state.
|
|
34
34
|
- `interpolate` (function): function interpolate(template: string, params?: TParams): string — Replace `{name}` placeholders in `template` with `params[name]`. Unknown placeholders are left intact. Pure and locale-independent.
|
|
35
35
|
|
|
36
|
+
## @jgengine/core/render/environment
|
|
37
|
+
|
|
38
|
+
- `EnvironmentSource` (type): type EnvironmentSource = | { kind: "gradient"; sky: string; ground: string; sun?: string; intensity?: number } /** Equirectangular HDR or EXR environment map loaded from `url`. */ | { kind: "hdri"; url: string; rotation?: number; intensity?: number } /** Six faces of a cube environment map, in three… — A declarative source for image-based scene lighting.
|
|
39
|
+
|
|
36
40
|
## @jgengine/core/render/lookPreset
|
|
37
41
|
|
|
38
42
|
- `CINEMATIC_POST_PROCESSING` (const): const CINEMATIC_POST_PROCESSING: PostProcessingConfig — Tuned tone-map + bloom + gentle SSAO + vignette/grade stack — the shipped-game post look.
|
|
39
43
|
- `CINEMATIC_SKY` (const): const CINEMATIC_SKY: SkyEnvironmentConfig — A static day sky: a real dome plus the shell's view-following shadow-casting sun and hemisphere fill.
|
|
40
44
|
- `GameLookInput` (interface): interface GameLookInput — Explicit graphics knobs a game may set; the preset only fills the ones left undefined.
|
|
41
|
-
- `LookPreset` (type): type LookPreset = "cinematic" | "flat" — Named
|
|
45
|
+
- `LookPreset` (type): type LookPreset = "neutral" | "photoreal" | "toon" | "cinematic" | "flat" — Named look preset composing the existing lighting/sky/fog/post knobs into one field. `"neutral"` (the default when unset) keeps presentation unstyled; `"cinematic"` draws a scene lit like a shipped game — a real day sky with a view-following shadow-casting sun + hemisphere fill, a network-free image-based-lighting environment so PBR surfaces catch soft reflections, and a tuned tone-map/bloom/AO/vignette post stack. `"flat"` opts out of the sky/IBL/post rig to the bare ambient+directional default (pre-#773). The upgraded default primitive materials — tuned roughness/metalness plus subtle procedural surface detail so un-modeled boxes/capsules stop reading as flat plastic — apply under both presets.
|
|
46
|
+
- `NEUTRAL_POST_PROCESSING` (const): const NEUTRAL_POST_PROCESSING: PostProcessingConfig — Unstyled baseline: a stable linear presentation with no genre-specific grading.
|
|
47
|
+
- `PHOTOREAL_POST_PROCESSING` (const): const PHOTOREAL_POST_PROCESSING: PostProcessingConfig — High-contrast physically based presentation for authored HDR environments.
|
|
42
48
|
- `ResolvedGameLook` (interface): interface ResolvedGameLook — Concrete lighting/backdrop/post the shell renders after the preset has filled unset knobs.
|
|
43
|
-
- `
|
|
49
|
+
- `TOON_POST_PROCESSING` (const): const TOON_POST_PROCESSING: PostProcessingConfig — Clean graphic presentation; toon materials remain game-owned while this sets the grade.
|
|
50
|
+
- `resolveGameLook` (function): function resolveGameLook(input: GameLookInput): ResolvedGameLook — Expand a game's `look` into concrete lighting/backdrop/post. The default is `"neutral"`; `"flat"` passes the explicit knobs through untouched. Anything the game authored wins — the preset only fills unset knobs, and it never adds a sky when the world already owns one (so the sky's tuned sun/hemisphere serve as the lighting rig).
|
|
44
51
|
|
|
45
52
|
## @jgengine/core/render/postProcessing
|
|
46
53
|
|
|
@@ -53,6 +60,19 @@
|
|
|
53
60
|
- `STUDIO_STAGE_POST` (const): const STUDIO_STAGE_POST: PostProcessingConfig — A cinematic "product shot" post preset — the full chain on (contact-AO, soft bloom, a warm film grade with vignette + a touch of grain + chromatic aberration). Meant for a `StudioStage` where a single parametric asset is framed on a backdrop, so every studio reads shipped, not intern-tier. DoF is left off by default (it needs a per-scene focus distance); set `dof` to enable it.
|
|
54
61
|
- `ToneMappingMode` (type): type ToneMappingMode = "aces" | "agx" | "reinhard" | "cineon" | "linear" | "none" — Renderer tone-mapping curve applied by the post chain's output stage.
|
|
55
62
|
|
|
63
|
+
## @jgengine/core/render/sprite2d
|
|
64
|
+
|
|
65
|
+
- `SortingLayers` (const): const SortingLayers: readonly ["background", "world", "actors", "effects", "foreground", "ui"] — Canonical layers used by 2D presentations.
|
|
66
|
+
- `SpriteClipState` (interface): interface SpriteClipState — Serializable playback position for a named sprite animation.
|
|
67
|
+
- `createSpriteClipPlayer` (function): function createSpriteClipPlayer(atlas: SpriteAtlas): { play(name: string): void; advance(dt: number): void; frame: () => { x: number; y: number; w: number; h: number; pivot?: [number, number] | undefined; } | undefined; snapshot: () => { animation: string; frameIndex: number; elapsed: number; done: … — Create a renderer-independent sprite animation player.
|
|
68
|
+
- `sortingOrder` (function): function sortingOrder(layers: readonly string[], layer: string, offset = 0): number — Resolve a layer name and local offset into a stable render order.
|
|
69
|
+
|
|
70
|
+
## @jgengine/core/settings/graphicsProfile
|
|
71
|
+
|
|
72
|
+
- `DEFAULT_GRAPHICS_PROFILES` (const): const DEFAULT_GRAPHICS_PROFILES: Record<GraphicsQuality, GraphicsProfile> — Conservative defaults that preserve the existing high-quality shell behavior.
|
|
73
|
+
- `GraphicsProfile` (interface): interface GraphicsProfile — Serializable renderer budget selected by the player's graphics tier.
|
|
74
|
+
- `resolveGraphicsProfile` (function): function resolveGraphicsProfile(quality: GraphicsQuality, overrides?: Partial<GraphicsProfile>): GraphicsProfile — Resolve one tier and apply game-authored field and post-stage overrides.
|
|
75
|
+
|
|
56
76
|
## @jgengine/core/settings/settingsModel
|
|
57
77
|
|
|
58
78
|
- `BUILT_IN_SETTING_CATEGORIES` (const): const BUILT_IN_SETTING_CATEGORIES: readonly BuiltInSettingCategory[] — ⚠ undocumented
|
|
@@ -141,7 +161,7 @@
|
|
|
141
161
|
- `LayoutRect` (interface): interface LayoutRect — Axis-aligned rectangle in CSS pixels (origin top-left). Structurally compatible with a `DOMRect`'s edge fields.
|
|
142
162
|
- `LayoutRegion` (interface): interface LayoutRegion — A physical rectangle a UI subsystem occupies, published to the shared registry.
|
|
143
163
|
- `Locale` (type): type Locale = string — A locale tag (e.g. `"en"`, `"es"`, `"ja"`) — a key into a {@link Catalog}.
|
|
144
|
-
- `LookPreset` (type): type LookPreset = "cinematic" | "flat" — Named
|
|
164
|
+
- `LookPreset` (type): type LookPreset = "neutral" | "photoreal" | "toon" | "cinematic" | "flat" — Named look preset composing the existing lighting/sky/fog/post knobs into one field. `"neutral"` (the default when unset) keeps presentation unstyled; `"cinematic"` draws a scene lit like a shipped game — a real day sky with a view-following shadow-casting sun + hemisphere fill, a network-free image-based-lighting environment so PBR surfaces catch soft reflections, and a tuned tone-map/bloom/AO/vignette post stack. `"flat"` opts out of the sky/IBL/post rig to the bare ambient+directional default (pre-#773). The upgraded default primitive materials — tuned roughness/metalness plus subtle procedural surface detail so un-modeled boxes/capsules stop reading as flat plastic — apply under both presets.
|
|
145
165
|
- `MODAL_CANCEL` (const): const MODAL_CANCEL: "cancel" — Conventional cancel/dismiss result (also the default auto-dismiss and pop result).
|
|
146
166
|
- `MODAL_CONFIRM` (const): const MODAL_CONFIRM: "confirm" — Conventional confirm result for a two-button dialog — a shared string, not model behavior.
|
|
147
167
|
- `Messages` (type): type Messages = Readonly<Record<string, string>> — Flat message table for one locale: key → template string with `{param}` slots.
|
|
@@ -254,7 +274,7 @@
|
|
|
254
274
|
- `resizePanelSize` (function): function resizePanelSize(current: HudSize, delta: { dw: number; dh: number }, axes: HudResizeAxes, limits?: { minWidth?: number; maxWidth?: number; minHeight?: number; maxHeight?: number; }): HudSize — Semantic resize: apply pixel deltas only on growable axes, clamped to min/max. Never scales content — callers reflow layout size (track length, list rows).
|
|
255
275
|
- `resolveAction` (function): function resolveAction(def: ActionDef): ResolvedAction — Resolve one {@link ActionDef} into a {@link ResolvedAction}: normalize label, compute `enabled`, and order the blocking `reasons`. Pure — the same input always yields the same view model.
|
|
256
276
|
- `resolveActionCollection` (function): function resolveActionCollection(defs: readonly ActionDef[]): ResolvedAction[] — Resolve an ordered list of actions, preserving input order.
|
|
257
|
-
- `resolveGameLook` (function): function resolveGameLook(input: GameLookInput): ResolvedGameLook — Expand a game's `look` into concrete lighting/backdrop/post. The default is `"
|
|
277
|
+
- `resolveGameLook` (function): function resolveGameLook(input: GameLookInput): ResolvedGameLook — Expand a game's `look` into concrete lighting/backdrop/post. The default is `"neutral"`; `"flat"` passes the explicit knobs through untouched. Anything the game authored wins — the preset only fills unset knobs, and it never adds a sky when the world already owns one (so the sky's tuned sun/hemisphere serve as the lighting rig).
|
|
258
278
|
- `resolveHudFit` (function): function resolveHudFit(config: HudViewportConfig | undefined, mobile: boolean): Required<HudFitConfig> — ⚠ undocumented
|
|
259
279
|
- `resolveHudPanelLayout` (function): function resolveHudPanelLayout(docPanel: EditorUiPanelLayout | undefined, fallback: HudPanelFallback): ResolvedHudPanelLayout — Resolve a panel's layout: document entry wins field-by-field over TSX fallback. TSX props are fallback-only — the scene document is the source of truth once authored.
|
|
260
280
|
- `resolveOrientationRequirement` (function): function resolveOrientationRequirement(orientation: GameOrientation | undefined, platform: "mobile" | "desktop"): OrientationRequirement — Resolve the game's orientation declaration into a concrete requirement for a platform. Desktop is always unconstrained.
|
|
@@ -520,8 +540,8 @@
|
|
|
520
540
|
- `ChatBubble` (interface): interface ChatBubble — ⚠ undocumented
|
|
521
541
|
- `ChatBubblesOptions` (interface): interface ChatBubblesOptions — ⚠ undocumented
|
|
522
542
|
- `ChatInput` (function): function ChatInput({ channelId, className, inputClassName, buttonClassName, placeholder, sendLabel, onSent, onRejected, }: { channelId: string; className?: string; inputClassName?: string; buttonClassName?: string; placeholder?: string; sendLabel?: ReactNode; onSent?: (message: ChatMessage) => void;… — ⚠ undocumented
|
|
523
|
-
- `ChatLog` (function): function ChatLog({ channelId, limit, className, messageClassName, renderMessage, }: { channelId: string; limit?: number; className?: string; messageClassName?: string; renderMessage?: (message: ChatMessage) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
524
|
-
- `ChatPanel` (function): function ChatPanel
|
|
543
|
+
- `ChatLog` (function): function ChatLog({ channelId, limit, className, messageClassName, ownMessageClassName, renderMessage, }: { channelId: string; limit?: number; className?: string; messageClassName?: string; ownMessageClassName?: string; renderMessage?: (message: ChatMessage) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
544
|
+
- `ChatPanel` (function): function ChatPanel<T extends ChatMessage = ChatMessage>(props: Parameters<typeof ContextChatPanel>[0] | StandaloneChatPanelProps<T>): React.JSX.Element — Chat behavior over a game context or externally supplied server messages.
|
|
525
545
|
- `ClerkUserShape` (interface): interface ClerkUserShape — ⚠ undocumented
|
|
526
546
|
- `ClerkUserState` (interface): interface ClerkUserState — ⚠ undocumented
|
|
527
547
|
- `Clock` (function): function Clock({ format = "24h", showDay = true, controls = false, style, className, }: { format?: "24h" | "12h"; showDay?: boolean; controls?: boolean; style?: CSSProperties; className?: string; }): React.JSX.Element — A time-of-day clock reading the sim calendar — `Day N · HH:MM`, 24h or 12h. `controls` adds pause + the game's speed multipliers as clickable pills (the "fast-forward" bar), off by default so a game opts into letting the player scrub time.
|
|
@@ -620,6 +640,9 @@
|
|
|
620
640
|
- `HudLayoutPersist` (type): type HudLayoutPersist = (id: string, panel: EditorUiPanelLayout) => void — Host-owned callback that commits one HUD panel layout into the scene document (typically an undoable `setUiPanel` dispatch). Injected by the editor so product UI never reaches for editor globals.
|
|
621
641
|
- `HudLayoutPersistProvider` (function): function HudLayoutPersistProvider({ onPanelCommit, children, }: { onPanelCommit: HudLayoutPersist; children?: ReactNode; }): React.JSX.Element — Provides {@link HudLayoutPersist} / `onPanelCommit` to descendant `useHudLayout` calls. Mount around game UI when a host can accept document UI patches (editor). Absent provider → canvas moves/resizes are no-ops for document writes.
|
|
622
642
|
- `HudPanel` (function): function HudPanel({ id, anchor = "top-left", order, compact: compactMode = "keep", chip, interactive, inset, locked, showDuring, priority, mobileBehavior, allowOverlapWith, collisionGroup, region = true, width, height, type, className, style, children, }: { id: string; anchor?: HudAnchor; /** Stack … — A HUD block that lives in one of the nine anchor regions. Panels sharing a region stack outward from the screen edge in ascending `order`. On fine pointers panels stay draggable through the edit chord; a dragged panel leaves the flow and keeps its custom placement. On compact displays custom placements are ignored and the `compact` behavior applies.
|
|
643
|
+
- `HudSkin` (interface): interface HudSkin — A game-authored visual skin layered over a {@link HudTheme}.
|
|
644
|
+
- `HudSkinMaterial` (interface): interface HudSkinMaterial — Optional raster-backed materials for shared HUD chrome.
|
|
645
|
+
- `HudSkinPreview` (function): function HudSkinPreview({ className }: { className?: string }): React.JSX.Element — Procedural two-skin fixture for visual regression captures.
|
|
623
646
|
- `HudTheme` (interface): interface HudTheme — A full HUD theme. Author one with {@link hudTheme} or {@link deriveHudTheme}.
|
|
624
647
|
- `HudThemeBar` (interface): interface HudThemeBar — Framed-trough tokens shared by every atomic bar.
|
|
625
648
|
- `HudThemeFont` (interface): interface HudThemeFont — Typography roles. Any CSS `font-family` list.
|
|
@@ -835,6 +858,7 @@
|
|
|
835
858
|
- `eventMeterNeedsHeartbeat` (function): function eventMeterNeedsHeartbeat(meter: EventMeter, previous: EventMeterView | null): boolean — True when `meter`'s value/fraction/tier/ready diverge from `previous` — the re-render check `useEventMeter` polls on its heartbeat.
|
|
836
859
|
- `formatTimerMs` (function): function formatTimerMs(ms: number, format: TimerFormat = "mm:ss"): string — Format a millisecond duration as digital timer text — `mm:ss` (default), `m:ss.d` (with tenths), or `ss.d` (seconds + tenths). Negative inputs clamp to zero. No genre meaning: the same helper serves a round clock, a respawn countdown, or an ability charge readout.
|
|
837
860
|
- `guestIdentity` (function): function guestIdentity(seed?: string): IdentitySource — ⚠ undocumented
|
|
861
|
+
- `hudSkinVars` (function): function hudSkinVars(skin?: HudSkin): CSSProperties — Converts a skin into the CSS variables consumed by shared HUD components.
|
|
838
862
|
- `hudTheme` (function): function hudTheme(overrides: HudThemeOverrides): HudTheme — Builds a full {@link HudTheme} from per-group partials, filling the rest from {@link defaultHudTheme}. Reach for this when a game wants to name exact values; use {@link deriveHudTheme} when a seed color pair is enough.
|
|
839
863
|
- `hudThemeVars` (function): function hudThemeVars(theme: HudTheme): CSSProperties — Emits the CSS custom properties for a theme — spread onto any HUD ancestor to re-skin the subtree.
|
|
840
864
|
- `hudVisibleInPhase` (function): function hudVisibleInPhase(showDuring: readonly GamePhase[] | undefined, phase: GamePhase): boolean — Whether a HUD element opted into `showDuring` is visible in the current phase; `undefined` = always visible (default).
|
|
@@ -894,6 +918,7 @@
|
|
|
894
918
|
- `useGameViewportLayout` (function): function useGameViewportLayout(): GameViewportLayout — The live shared viewport layout. Returns a neutral default outside a `GameViewportProvider` so it never throws in previews.
|
|
895
919
|
- `useHasSettings` (function): function useHasSettings(): boolean — True when the game has any setting or game-action to show — gate your own settings entry on it.
|
|
896
920
|
- `useHeldKeys` (function): function useHeldKeys(): (code: string) => boolean — Held-key predicate backed by window keydown/keyup/blur listeners (blur clears held state so a released-off-window key doesn't stick). SSR-safe: listeners attach in an effect, never at module scope. The returned predicate is stable across renders.
|
|
921
|
+
- `useHudFont` (function): function useHudFont(skin?: HudSkin): boolean — Loads a skin font in browsers and reports when it is available.
|
|
897
922
|
- `useHudLayout` (function): function useHudLayout(options?: { storageKey?: string; snap?: number; locked?: boolean; /** * Scene-document `ui` section — source of truth for panel placement/size. * When provided, hydrates the layout store (and wins over legacy localStorage). */ documentUi?: EditorUiDocument; /** * When true (def… — Layout state for `HudCanvas` — panel placements, edit-mode drag/resize, and per-game persistence.
|
|
898
923
|
- `useHudLayoutPersist` (function): function useHudLayoutPersist(): HudLayoutPersist | null — Injected panel-commit port, or `null` when no host has provided one.
|
|
899
924
|
- `useHudViewport` (function): function useHudViewport(): HudViewportContextValue | null — ⚠ undocumented
|
|
@@ -1044,8 +1069,8 @@
|
|
|
1044
1069
|
|
|
1045
1070
|
- `ChannelTabs` (function): function ChannelTabs({ channels, active, onSelect, className, tabClassName, activeTabClassName, renderTab, }: { channels?: readonly string[]; active: string; onSelect: (channelId: string) => void; className?: string; tabClassName?: string; activeTabClassName?: string; renderTab?: (channelId: string,… — ⚠ undocumented
|
|
1046
1071
|
- `ChatInput` (function): function ChatInput({ channelId, className, inputClassName, buttonClassName, placeholder, sendLabel, onSent, onRejected, }: { channelId: string; className?: string; inputClassName?: string; buttonClassName?: string; placeholder?: string; sendLabel?: ReactNode; onSent?: (message: ChatMessage) => void;… — ⚠ undocumented
|
|
1047
|
-
- `ChatLog` (function): function ChatLog({ channelId, limit, className, messageClassName, renderMessage, }: { channelId: string; limit?: number; className?: string; messageClassName?: string; renderMessage?: (message: ChatMessage) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
1048
|
-
- `ChatPanel` (function): function ChatPanel
|
|
1072
|
+
- `ChatLog` (function): function ChatLog({ channelId, limit, className, messageClassName, ownMessageClassName, renderMessage, }: { channelId: string; limit?: number; className?: string; messageClassName?: string; ownMessageClassName?: string; renderMessage?: (message: ChatMessage) => ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
1073
|
+
- `ChatPanel` (function): function ChatPanel<T extends ChatMessage = ChatMessage>(props: Parameters<typeof ContextChatPanel>[0] | StandaloneChatPanelProps<T>): React.JSX.Element — Chat behavior over a game context or externally supplied server messages.
|
|
1049
1074
|
- `chatTransportFromSync` (function): function chatTransportFromSync(sync: ChatSync): ChatTransport — Lifts a callback-style ChatSync (e.g. createWsBackend().chatSyncFor(serverId)) into the hook-shaped ChatTransport contract. Create once per sync — outside render or inside useMemo — so subscriptions survive re-renders.
|
|
1050
1075
|
|
|
1051
1076
|
## @jgengine/react/chatBubbles
|
|
@@ -1287,9 +1312,21 @@
|
|
|
1287
1312
|
- `HudLayoutPersistProvider` (function): function HudLayoutPersistProvider({ onPanelCommit, children, }: { onPanelCommit: HudLayoutPersist; children?: ReactNode; }): React.JSX.Element — Provides {@link HudLayoutPersist} / `onPanelCommit` to descendant `useHudLayout` calls. Mount around game UI when a host can accept document UI patches (editor). Absent provider → canvas moves/resizes are no-ops for document writes.
|
|
1288
1313
|
- `useHudLayoutPersist` (function): function useHudLayoutPersist(): HudLayoutPersist | null — Injected panel-commit port, or `null` when no host has provided one.
|
|
1289
1314
|
|
|
1315
|
+
## @jgengine/react/hudSkin
|
|
1316
|
+
|
|
1317
|
+
- `HudSkin` (interface): interface HudSkin — A game-authored visual skin layered over a {@link HudTheme}.
|
|
1318
|
+
- `HudSkinMaterial` (interface): interface HudSkinMaterial — Optional raster-backed materials for shared HUD chrome.
|
|
1319
|
+
- `hudSkinVars` (function): function hudSkinVars(skin?: HudSkin): CSSProperties — Converts a skin into the CSS variables consumed by shared HUD components.
|
|
1320
|
+
- `useHudFont` (function): function useHudFont(skin?: HudSkin): boolean — Loads a skin font in browsers and reports when it is available.
|
|
1321
|
+
|
|
1322
|
+
## @jgengine/react/hudSkinPreview
|
|
1323
|
+
|
|
1324
|
+
- `HudSkinPreview` (function): function HudSkinPreview({ className }: { className?: string }): React.JSX.Element — Procedural two-skin fixture for visual regression captures.
|
|
1325
|
+
|
|
1290
1326
|
## @jgengine/react/hudTheme
|
|
1291
1327
|
|
|
1292
1328
|
- `HUD_THEME_PRESETS` (const): const HUD_THEME_PRESETS: { "arcane-stone": HudTheme; "survival-wood": HudTheme; "military-flat": HudTheme; "sleek-hex": HudTheme; "elemental-circle": HudTheme; "sandbox-slot": HudTheme; ember: HudTheme; synthwave: HudTheme; fieldkit: HudTheme; } — Built-in theme presets for demos/scaffold only — not product identity; games author their own theme.
|
|
1329
|
+
- `HudSkin` (interface): interface HudSkin — A game-authored visual skin layered over a {@link HudTheme}.
|
|
1293
1330
|
- `HudTheme` (interface): interface HudTheme — A full HUD theme. Author one with {@link hudTheme} or {@link deriveHudTheme}.
|
|
1294
1331
|
- `HudThemeBar` (interface): interface HudThemeBar — Framed-trough tokens shared by every atomic bar.
|
|
1295
1332
|
- `HudThemeFont` (interface): interface HudThemeFont — Typography roles. Any CSS `font-family` list.
|
|
@@ -1304,6 +1341,7 @@
|
|
|
1304
1341
|
- `HudThemeSurface` (interface): interface HudThemeSurface — Chrome surfaces, edges, and text — what panels, overlays, and menus are built out of.
|
|
1305
1342
|
- `defaultHudTheme` (const): const defaultHudTheme: HudTheme — Default theme tokens for previews/scaffold — not a finished game look; author a custom theme.
|
|
1306
1343
|
- `deriveHudTheme` (function): function deriveHudTheme(seed: HudThemeSeed): HudTheme — Derives a coherent full theme from an accent/surface pair — shades, edges, dim text, frames, bar troughs, and slots all fall out of the seed, so a game gets one consistent look across the `packages/react` primitives and the `registry/jgengine` blocks without naming 50 tokens. Hex seeds only (`#rgb` or `#rrggbb`).
|
|
1344
|
+
- `hudSkinVars` (function): function hudSkinVars(skin?: HudSkin): CSSProperties — Converts a skin into the CSS variables consumed by shared HUD components.
|
|
1307
1345
|
- `hudTheme` (function): function hudTheme(overrides: HudThemeOverrides): HudTheme — Builds a full {@link HudTheme} from per-group partials, filling the rest from {@link defaultHudTheme}. Reach for this when a game wants to name exact values; use {@link deriveHudTheme} when a seed color pair is enough.
|
|
1308
1346
|
- `hudThemeVars` (function): function hudThemeVars(theme: HudTheme): CSSProperties — Emits the CSS custom properties for a theme — spread onto any HUD ancestor to re-skin the subtree.
|
|
1309
1347
|
- `resolveHudTheme` (function): function resolveHudTheme(theme?: HudThemePreset | HudTheme): HudTheme — Resolves a preset name (or a full theme) to a `HudTheme`; falls back to the default theme.
|
|
@@ -1608,6 +1646,11 @@
|
|
|
1608
1646
|
- `WorldBrowser` (function): function WorldBrowser({ listings, onJoin, className, rowClassName, joinClassName, emptyState, renderListing, }: { listings: readonly SessionListing[]; onJoin: (listing: SessionListing) => void; className?: string; rowClassName?: string; joinClassName?: string; emptyState?: ReactNode; renderListing?:… — ⚠ undocumented
|
|
1609
1647
|
- `WorldInviteToast` (function): function WorldInviteToast({ className, acceptClassName, declineClassName, onAccepted, renderInvite, }: { className?: string; acceptClassName?: string; declineClassName?: string; onAccepted: (target: WorldInviteTarget) => void; renderInvite?: (invite: WorldInvite) => ReactNode; }): React.JSX.Element … — ⚠ undocumented
|
|
1610
1648
|
|
|
1649
|
+
## @jgengine/react/standaloneChatPanel
|
|
1650
|
+
|
|
1651
|
+
- `StandaloneChatPanel` (function): function StandaloneChatPanel<T extends ChatMessage>({ messages, userId, onSend, className, logClassName, inputClassName, inputFieldClassName, messageClassName, ownMessageClassName, style, defaultExpanded = false, collapsedLimit = 3, limit = 50, maxLength = DEFAULT_CHAT_BODY_LENGTH, hotkeysEnabled = … — Headless chat interaction for external message stores. Prefer the ChatPanel entrypoint.
|
|
1652
|
+
- `StandaloneChatPanelProps` (interface): interface StandaloneChatPanelProps<T extends ChatMessage = ChatMessage> — Message-store inputs and caller-owned styling for standalone chat.
|
|
1653
|
+
|
|
1611
1654
|
## @jgengine/react/startScreen
|
|
1612
1655
|
|
|
1613
1656
|
- `ControlHint` (interface): interface ControlHint — One row of a control legend. Name the game action(s) whose bound key(s) to show (`action`) so the glyphs come straight from the keybind map — never re-typed — or give literal `keys` for controls that live outside the map (`"Mouse"`, `"LMB"`). `label` says what the control does.
|
|
@@ -1636,6 +1679,10 @@
|
|
|
1636
1679
|
- `TalentTree` (function): function TalentTree<TStat extends string = string>({ view: viewProp, nodes, tree, onLearn, icon, label, branchLabel, title = "Talents", variation = "themed", nodeSize = 54, columnGap = 30, tierGap = 46, showPoints = true, className, style, }: TalentTreeProps<TStat>): ReactNode — Drop-in talent / skill-tree widget over the existing progression model (`@jgengine/core/game/talents` + its `talentTreeView` selector). The game passes its node definitions and a live `createTalentTree` instance; the widget lays nodes out by branch column and prerequisite-depth tier, draws SVG prerequisite edges, styles each node learned/available/locked/maxed, shows an icon + rank badge, and calls `onLearn(nodeId)` when the player clicks a node that is currently allocatable. All layout, edge-drawing, and eligibility come from the model/selector — the widget never re-derives topology. Unskinned and HudTheme-token driven; node ids/branches are opaque game data the game supplies icons and labels for.
|
|
1637
1680
|
- `TalentTreeProps` (interface): interface TalentTreeProps<TStat extends string = string> — Props for {@link TalentTree}.
|
|
1638
1681
|
|
|
1682
|
+
## @jgengine/react/tileLayerPreview
|
|
1683
|
+
|
|
1684
|
+
- `TileLayerPreview` (function): function TileLayerPreview({ className }: { className?: string }): React.JSX.Element — Deterministic canvas-backed tile-layer fixture for textured tile presentation evidence.
|
|
1685
|
+
|
|
1639
1686
|
## @jgengine/react/timerReadout
|
|
1640
1687
|
|
|
1641
1688
|
- `TimerFormat` (type): type TimerFormat = "mm:ss" | "m:ss.d" | "ss.d" — Digital text format for a timer readout.
|
|
@@ -1653,6 +1700,10 @@
|
|
|
1653
1700
|
- `DebouncedCommit` (interface): interface DebouncedCommit<T> — Live-mirrored, trailing-debounced commit binding for a single control value.
|
|
1654
1701
|
- `useDebouncedCommit` (function): function useDebouncedCommit<T>(value: T, commit: (value: T) => void, delayMs = 180): DebouncedCommit<T> — See {@link DebouncedCommit}. `commit` and `delayMs` may change between renders (kept in refs); the binding identity stays stable except when `value` (the local mirror) changes.
|
|
1655
1702
|
|
|
1703
|
+
## @jgengine/react/useServerSession
|
|
1704
|
+
|
|
1705
|
+
- `useServerSession` (function): function useServerSession(transport: GameRuntimeTransport, gameId: string, preferredServerId?: string): { retry: () => void; serverId: string | null; status: "joining" | "joined" | "failed"; failureReason: string | null; } — Joins a host and exposes a retryable blocking state until membership is confirmed.
|
|
1706
|
+
|
|
1656
1707
|
## @jgengine/react/voice
|
|
1657
1708
|
|
|
1658
1709
|
- `MicToggle` (function): function MicToggle({ voice, className, mutedLabel, unmutedLabel, }: { voice: VoiceState; className?: string; mutedLabel?: ReactNode; unmutedLabel?: ReactNode; }): React.JSX.Element — ⚠ undocumented
|
|
@@ -1695,6 +1746,15 @@
|
|
|
1695
1746
|
- `UiPreviewScenario` (type): type UiPreviewScenario = (ctx: GameContext, playable: PlayableGame) => void — ⚠ undocumented
|
|
1696
1747
|
- `defaultUiScenario` (const): const defaultUiScenario: UiPreviewScenario — ⚠ undocumented
|
|
1697
1748
|
|
|
1749
|
+
## @jgengine/shell/JoinGate
|
|
1750
|
+
|
|
1751
|
+
- `JoinGate` (function): function JoinGate({ status, failureReason, retry, joiningLabel = "Joining world…", failedLabel = "Unable to join", retryLabel = "Retry", className, children, renderJoining, renderFailure }: { status: "joining" | "joined" | "failed"; failureReason?: string | null; retry: () => void; joiningLabel?: Re… — Blocking join feedback; callers may supply their own copy and classes.
|
|
1752
|
+
|
|
1753
|
+
## @jgengine/shell/TerritoryOverlay
|
|
1754
|
+
|
|
1755
|
+
- `TerritoryOverlay` (function): function TerritoryOverlay({ cells, cost, affordable, formatCost = String, renderCell, className, style }: { cells: readonly TerritoryPreviewCell[]; cost: number; affordable: boolean; formatCost?: (cost: number) => ReactNode; renderCell?: (cell: TerritoryPreviewCell) => ReactNode; className?: string;… — Placement footprint feedback with inline claim cost and affordability.
|
|
1756
|
+
- `TerritoryPreviewCell` (type): type TerritoryPreviewCell = { key: string; x: number; z: number; status: "owned" | "claimable" | "blocked" } — A placement footprint cell and its authoritative preview status.
|
|
1757
|
+
|
|
1698
1758
|
## @jgengine/shell/audio/AudioComponents
|
|
1699
1759
|
|
|
1700
1760
|
- `AudioListener` (function): function AudioListener({ engine }: { engine: AudioEngine }): null — ⚠ undocumented
|
|
@@ -1706,6 +1766,7 @@
|
|
|
1706
1766
|
- `AudioEmitterHandle` (interface): interface AudioEmitterHandle — ⚠ undocumented
|
|
1707
1767
|
- `AudioEngine` (interface): interface AudioEngine — ⚠ undocumented
|
|
1708
1768
|
- `AudioSceneConfig` (interface): interface AudioSceneConfig — ⚠ undocumented
|
|
1769
|
+
- `ListenerPose` (interface): interface ListenerPose — Position and orientation for a spatial-audio listener.
|
|
1709
1770
|
- `Vec3` (interface): interface Vec3 — ⚠ undocumented
|
|
1710
1771
|
- `createAudioEngine` (function): function createAudioEngine(config: AudioSceneConfig = {}): AudioEngine — ⚠ undocumented
|
|
1711
1772
|
|
|
@@ -1969,7 +2030,7 @@
|
|
|
1969
2030
|
|
|
1970
2031
|
## @jgengine/shell/drivers/FrameDriver
|
|
1971
2032
|
|
|
1972
|
-
- `FrameDriver` (function): function FrameDriver({ ctx, playable, tracker, yawRef, pitchRef, primaryClickRef, pointerAxisRef, analogRef, gateRef, onRuntimeError, multiplayer, serverIdRef, pointerService, pointerAim, pingCommand, poster, onPosterSettled, }: { ctx: GameContext; playable: PlayableGame;
|
|
2033
|
+
- `FrameDriver` (function): function FrameDriver({ ctx, playable, tracker, yawRef, pitchRef, primaryClickRef, pointerAxisRef, analogRef, gateRef, onRuntimeError, multiplayer, serverIdRef, pointerService, pointerAim, pingCommand, poster, onPosterSettled, authoritativeFrameRef, }: { ctx: GameContext; playable: PlayableGame; trac… — ⚠ undocumented
|
|
1973
2034
|
- `POSTER_SETTLE_SECONDS` (const): const POSTER_SETTLE_SECONDS: 1.6 — ⚠ undocumented
|
|
1974
2035
|
|
|
1975
2036
|
## @jgengine/shell/drivers/HudOnlyDriver
|
|
@@ -2059,6 +2120,18 @@
|
|
|
2059
2120
|
|
|
2060
2121
|
- `SkyLightOwnership` (type): type SkyLightOwnership = "authored" | "sky-default" — Policy for composing sky backdrops with `PlayableGame.lighting`: - authored lighting present → sky renders dome + fog only; lights stay game-owned - no authored lighting → sky may emit its default sun/hemisphere with the dome Time-of-day never rewrites configured lights; it only drives sky colors/fog (and sky-owned lights when the game did not author lighting).
|
|
2061
2122
|
|
|
2123
|
+
## @jgengine/shell/input/gamepadMerge
|
|
2124
|
+
|
|
2125
|
+
- `GamepadInputFrame` (interface): interface GamepadInputFrame — Per-frame gamepad actions and analog values ready to merge with another input source.
|
|
2126
|
+
- `mergeGamepadFrame` (function): function mergeGamepadFrame(base: GamepadInputFrame, gamepad: GamepadFrame): GamepadInputFrame — Merge one resolved gamepad frame with another input source's semantic state.
|
|
2127
|
+
- `mergeGamepadInput` (function): function mergeGamepadInput(frames: readonly GamepadFrame[], base: GamepadInputFrame = { held: [], analog: {} }): GamepadInputFrame — Pure reducer used by the shell and synthetic gamepad tests.
|
|
2128
|
+
|
|
2129
|
+
## @jgengine/shell/input/gamepadSource
|
|
2130
|
+
|
|
2131
|
+
- `GamepadSource` (function): function GamepadSource({ tracker, bindings, analogRef, input, }: { tracker: ActionStateTracker<string>; bindings: ActionCodesMap; analogRef: { current: Readonly<Record<string, number>> | null }; input: InputSnapshot; }): null — Poll browser gamepads and feed semantic actions into the shell tracker.
|
|
2132
|
+
- `mergeGamepadFrame` (function): function mergeGamepadFrame(base: GamepadInputFrame, gamepad: GamepadFrame): GamepadInputFrame — Merge one resolved gamepad frame with another input source's semantic state.
|
|
2133
|
+
- `mergeGamepadInput` (function): function mergeGamepadInput(frames: readonly GamepadFrame[], base: GamepadInputFrame = { held: [], analog: {} }): GamepadInputFrame — Pure reducer used by the shell and synthetic gamepad tests.
|
|
2134
|
+
|
|
2062
2135
|
## @jgengine/shell/input/mouseLook
|
|
2063
2136
|
|
|
2064
2137
|
- `MouseLookAim` (interface): interface MouseLookAim — ⚠ undocumented
|
|
@@ -2124,7 +2197,7 @@
|
|
|
2124
2197
|
|
|
2125
2198
|
## @jgengine/shell/postfx/PostProcessing
|
|
2126
2199
|
|
|
2127
|
-
- `PostProcessing` (function): function PostProcessing({ config, quality = "high" }: { config: PostProcessingConfig; quality?: GraphicsQuality }): null — Mounts an `EffectComposer` inside the shell Canvas and takes over rendering (priority-1 `useFrame`, which disables R3F auto-render) to run the configured post chain: RenderPass → GTAO → UnrealBloom → SMAA → OutputPass → Grade. Rendered only when `PlayableGame.postProcessing` is set, so games without it draw unchanged.
|
|
2200
|
+
- `PostProcessing` (function): function PostProcessing({ config, quality = "high", stages }: { config: PostProcessingConfig; quality?: GraphicsQuality; stages?: { ao: boolean; bloom: boolean; dof: boolean; smaa: boolean } }): null — Mounts an `EffectComposer` inside the shell Canvas and takes over rendering (priority-1 `useFrame`, which disables R3F auto-render) to run the configured post chain: RenderPass → GTAO → UnrealBloom → SMAA → OutputPass → Grade. Rendered only when `PlayableGame.postProcessing` is set, so games without it draw unchanged.
|
|
2128
2201
|
|
|
2129
2202
|
## @jgengine/shell/postfx/ScreenEffectsOverlay
|
|
2130
2203
|
|
|
@@ -2150,6 +2223,11 @@
|
|
|
2150
2223
|
- `RenderObject` (type): type RenderObject = (object: SceneObject) => ReactNode — ⚠ undocumented
|
|
2151
2224
|
- `resolveGameLoader` (function): function resolveGameLoader(registry: GameRegistry, gameId: string, fallbackGameId?: string): (() => Promise<PlayableGame>) | undefined — ⚠ undocumented
|
|
2152
2225
|
|
|
2226
|
+
## @jgengine/shell/render/CascadedShadows
|
|
2227
|
+
|
|
2228
|
+
- `CsmMaterialSetup` (interface): interface CsmMaterialSetup — Structural slice of CSM so the patcher is testable without a renderer.
|
|
2229
|
+
- `patchSceneMaterials` (function): function patchSceneMaterials(scene: THREE.Scene, csm: CsmMaterialSetup, patched: WeakSet<THREE.Material>): void — Run CSM's `setupMaterial` over every unpatched standard material in the scene, chaining rather than clobbering a material's own `onBeforeCompile`. Called every frame (WeakSet-guarded) so streamed meshes never render lit by all cascades at once.
|
|
2230
|
+
|
|
2153
2231
|
## @jgengine/shell/render/EntityPreview
|
|
2154
2232
|
|
|
2155
2233
|
- `EntityPreview` (function): function EntityPreview({ children, model, instanceId, mood = "studio", backdrop, turntable = 0, faceCamera = false, forward, environment = true, cameraPosition = [0, 1, 3], fov = 35, dpr = [1, 2], className, style, }: EntityPreviewProps): React.JSX.Element — Drop-in live 3D preview of a single entity — the character-screen portrait, unit inspector, or loadout viewer. It owns all the plumbing a game would otherwise re-derive by hand: a nested `<Canvas>`, the {@link GameContextBridge} that carries the running `GameContext` across the R3F reconciler boundary (so the subject's `useEntityRenderCues` / `useGameContext` hooks resolve and it mirrors the live game), a {@link StudioStage} 3-point lighting rig with optional turntable / face-camera, and a capture-friendly GL surface. The game keeps ownership of its `renderEntity`: pass it as `children`, or hand a native `model` (+ `instanceId`) for an engine-composed body. Bound to a live `instanceId`, the portrait walks, flinches, and topples in lockstep with the world instead of a canned spin.
|
|
@@ -2162,7 +2240,9 @@
|
|
|
2162
2240
|
## @jgengine/shell/render/SceneLighting
|
|
2163
2241
|
|
|
2164
2242
|
- `BackdropFog` (function): function BackdropFog({ fog }: { fog: BackdropConfig["fog"] }): React.JSX.Element | null — ⚠ undocumented
|
|
2165
|
-
- `ConfiguredLighting` (function): function ConfiguredLighting({ lighting }: { lighting: LightingConfig }): React.JSX.Element — ⚠ undocumented
|
|
2243
|
+
- `ConfiguredLighting` (function): function ConfiguredLighting({ lighting, profile }: { lighting: LightingConfig; profile?: GraphicsProfile }): React.JSX.Element — ⚠ undocumented
|
|
2244
|
+
- `POINT_LIGHT_BUDGET` (const): const POINT_LIGHT_BUDGET: 8 — Default cap for combined dynamic point and spot lights.
|
|
2245
|
+
- `syncShadowProjection` (function): function syncShadowProjection(light: DirectionalLight): void — Refresh a directional light's shadow projection after its frustum bounds change. R3F pierced `shadow-camera-*` props write the bounds but never call `updateProjectionMatrix()`, so depth renders with the stale default ~10×10 box and `shadowCameraSize` is silently inert.
|
|
2166
2246
|
|
|
2167
2247
|
## @jgengine/shell/render/SceneModels
|
|
2168
2248
|
|
|
@@ -2192,12 +2272,16 @@
|
|
|
2192
2272
|
|
|
2193
2273
|
## @jgengine/shell/render/modelLoad
|
|
2194
2274
|
|
|
2275
|
+
- `ModelLoaderConfig` (interface): interface ModelLoaderConfig — CDN-backed decoder configuration for compressed model and texture assets.
|
|
2276
|
+
- `configureModelLoaders` (function): function configureModelLoaders(options: ModelLoaderConfig = {}): Readonly<Required<ModelLoaderConfig>> — Configures shared Draco and KTX2 loaders. Repeated calls with the same paths are no-ops.
|
|
2277
|
+
- `detectKtx2Support` (function): function detectKtx2Support(renderer: THREE.WebGLRenderer): void — Detects GPU support for the configured KTX2 transcoder after a renderer exists.
|
|
2195
2278
|
- `modelLoadFallbacks` (function): function modelLoadFallbacks(): readonly { url: string; message: string }[] — Every model the shared loader diagnosed as broken and replaced with a magenta placeholder, in load order.
|
|
2196
2279
|
- `modelLoadIdleMs` (function): function modelLoadIdleMs(): number — How long the shared GLB loader has been idle, in ms — `0` while any model is still in flight. A capture host reads this to wait for streaming to finish instead of guessing a settle delay: models that pop in after the shot are why an establishing capture used to come back half-empty until someone hand-tuned `--settle`.
|
|
2197
2280
|
|
|
2198
2281
|
## @jgengine/shell/render/modelRender
|
|
2199
2282
|
|
|
2200
2283
|
- `MaterialCache` (interface): interface MaterialCache — ⚠ undocumented
|
|
2284
|
+
- `ModelShadowMode` (type): type ModelShadowMode = "cast" | "receive" | "both" | "none" — Shadow participation applied to every mesh of a cloned model; mirrors `ModelConfig.shadows`.
|
|
2201
2285
|
- `PAINT_TEXTURE_SIZE` (const): const PAINT_TEXTURE_SIZE: 512 — ⚠ undocumented
|
|
2202
2286
|
- `PaintCanvas` (interface): interface PaintCanvas — ⚠ undocumented
|
|
2203
2287
|
|
|
@@ -2213,6 +2297,10 @@
|
|
|
2213
2297
|
- `captureCanvas` (function): function captureCanvas(gl: CaptureRenderer): string | null — Read the current frame to a PNG data URL. Requires the R3F `<Canvas>` to have been created with `gl={{ preserveDrawingBuffer: true }}` (the shell's game canvas already is); returns null if the backing canvas can't be read.
|
|
2214
2298
|
- `downloadImage` (function): function downloadImage(dataUrl: string, filename = "screenshot.png"): void — Trigger a browser download of an image data URL (the photo-mode "save" action).
|
|
2215
2299
|
|
|
2300
|
+
## @jgengine/shell/render/testFixtures/proceduralTileLayer
|
|
2301
|
+
|
|
2302
|
+
- `drawProceduralTileLayer` (function): function drawProceduralTileLayer(canvas: CanvasFixture): TilemapWorldConfig — Draw the deterministic tile atlas used by textured tile-layer captures and tests.
|
|
2303
|
+
|
|
2216
2304
|
## @jgengine/shell/render/useDisposable
|
|
2217
2305
|
|
|
2218
2306
|
- `Disposable` (interface): interface Disposable — Anything exposing dispose() — three.js geometries, materials, textures, render targets.
|
|
@@ -2223,9 +2311,14 @@
|
|
|
2223
2311
|
|
|
2224
2312
|
- `useEntityRenderCues` (function): function useEntityRenderCues(instanceId: string | undefined, tuning?: RenderCueTuning): MutableRefObject<EntityRenderCues> — Live motion + animation cues for one entity, read from a mutable ref inside your own `useFrame` — no re-render per frame, no diffing the parent group's position, no game-side module map for attack/hit timing. Backs both custom `renderEntity` rigs and a custom first-person viewmodel (#542): call it with `entity.id` / the local player's userId and drive bob/recoil/reload poses from `cuesRef.current` inside the calling component's own `useFrame`.
|
|
2225
2313
|
|
|
2314
|
+
## @jgengine/shell/render/useFootIk
|
|
2315
|
+
|
|
2316
|
+
- `applyFootIk` (function): function applyFootIk(scene: THREE.Object3D, config: FootIkConfig, raycast: GameContext["scene"]["raycast"], weight: number, cameraTarget?: readonly [number, number, number]): boolean — Applies one frame of foot IK to a loaded rig. Exported for renderer tests and custom model hosts.
|
|
2317
|
+
- `useFootIk` (function): function useFootIk(scene: THREE.Object3D, config: FootIkConfig | undefined, ctx: GameContext | null, instanceId?: string): void — Runs foot IK after the model animation mixer, fading the correction out while the entity is airborne.
|
|
2318
|
+
|
|
2226
2319
|
## @jgengine/shell/render/useModelAnimation
|
|
2227
2320
|
|
|
2228
|
-
- `useModelAnimation` (function): function useModelAnimation(scene: THREE.Object3D, clips: THREE.AnimationClip[], animationInput: ModelAnimationConfig | "auto" | "none" | undefined, instanceId?: string): void — The engine's model animation driver as a standalone hook — the same mixer `EntityModel` runs, for games that render a cloned scene themselves (custom materials, procedural composition). Handles `"auto"` derivation from the GLB's clip names, speed-driven idle/walk/run crossfades read from the entity's live position when `instanceId` is set, one-shots fired from `entity.animation` / `combat.hitReaction` / `entity.died`, held poses, and the death clamp.
|
|
2321
|
+
- `useModelAnimation` (function): function useModelAnimation(scene: THREE.Object3D, clips: THREE.AnimationClip[], animationInput: ModelAnimationConfig | "auto" | "none" | undefined, instanceId?: string): void — The engine's model animation driver as a standalone hook — the same mixer `EntityModel` runs, for games that render a cloned scene themselves (custom materials, procedural composition). Handles `"auto"` derivation from the GLB's clip names, speed-driven idle/walk/run crossfades read from the entity's live position when `instanceId` is set, one-shots fired from `entity.animation` / `combat.hitReaction` / `entity.died`, held poses, and the death clamp. With `animation.graph` set, the headless `AnimGraph` runtime owns every clip's time and weight and the mixer only applies them; clip events surface as `animation.event`.
|
|
2229
2322
|
|
|
2230
2323
|
## @jgengine/shell/replay/useSessionRecorder
|
|
2231
2324
|
|
|
@@ -2301,7 +2394,7 @@
|
|
|
2301
2394
|
|
|
2302
2395
|
- `AudioSettingsBridge` (function): function AudioSettingsBridge({ store, engine, buses, }: { store: SettingsStore; engine: AudioEngine; buses: Record<string, AudioBusDef> | undefined; }): null — ⚠ undocumented
|
|
2303
2396
|
- `TOUCH_STYLE_AUTO` (const): const TOUCH_STYLE_AUTO: "auto" — Sentinel Controls value meaning "defer to the game's suggested touch skin".
|
|
2304
|
-
- `useGraphicsSettings` (function): function useGraphicsSettings(store: SettingsStore, shadowsDefault: boolean): { shadows: boolean; dpr: number; uiScale: number; quality: GraphicsQuality } — ⚠ undocumented
|
|
2397
|
+
- `useGraphicsSettings` (function): function useGraphicsSettings(store: SettingsStore, shadowsDefault: boolean, overrides?: Partial<Record<GraphicsQuality, Partial<GraphicsProfile>>>): { shadows: boolean; dpr: number; uiScale: number; quality: GraphicsQuality; profile: GraphicsProfile } — ⚠ undocumented
|
|
2305
2398
|
- `useSettingsRevision` (function): function useSettingsRevision(store: SettingsStore): number — ⚠ undocumented
|
|
2306
2399
|
|
|
2307
2400
|
## @jgengine/shell/settings/settingsController
|
|
@@ -2569,7 +2662,7 @@
|
|
|
2569
2662
|
|
|
2570
2663
|
## @jgengine/shell/useShellMultiplayerSync
|
|
2571
2664
|
|
|
2572
|
-
- `useShellMultiplayerSync` (function): function useShellMultiplayerSync(ctx: GameContext | null, multiplayer: ShellMultiplayer | null, playable: PlayableGame, serverIdRef: { current: string | null }, setRemotePlayers: Dispatch<SetStateAction<PresencePoseRow[]
|
|
2665
|
+
- `useShellMultiplayerSync` (function): function useShellMultiplayerSync(ctx: GameContext | null, multiplayer: ShellMultiplayer | null, playable: PlayableGame, serverIdRef: { current: string | null }, setRemotePlayers: Dispatch<SetStateAction<PresencePoseRow[]>>, authoritativeFrameRef?: { current: AuthoritativeFrameHandler | null }): { st… — Joins the multiplayer server for the live context and wires presence, feed relay, and chat sync until teardown.
|
|
2573
2666
|
|
|
2574
2667
|
## @jgengine/shell/vfx/ParticleField
|
|
2575
2668
|
|
|
@@ -2584,7 +2677,7 @@
|
|
|
2584
2677
|
|
|
2585
2678
|
## @jgengine/shell/visibility/CullingProvider
|
|
2586
2679
|
|
|
2587
|
-
- `CullingProvider` (function): function CullingProvider({ config, children }: { config: VisibilityConfig | undefined; children: ReactNode }): ReactNode — Drives automatic frustum + distance culling for every entity and placed object. It reads the live render camera each frame, updates the engine VisibilitySystem, and exposes a predicate the entity/object markers consult to toggle `group.visible` — objects fully outside the view (plus a conservative preload margin) are never submitted to the renderer, without unmounting them or touching gameplay. UI, sky, terrain, and environment live outside this subtree and are unaffected.
|
|
2680
|
+
- `CullingProvider` (function): function CullingProvider({ config, drawDistance, children }: { config: VisibilityConfig | undefined; drawDistance?: number; children: ReactNode }): ReactNode — Drives automatic frustum + distance culling for every entity and placed object. It reads the live render camera each frame, updates the engine VisibilitySystem, and exposes a predicate the entity/object markers consult to toggle `group.visible` — objects fully outside the view (plus a conservative preload margin) are never submitted to the renderer, without unmounting them or touching gameplay. UI, sky, terrain, and environment live outside this subtree and are unaffected.
|
|
2588
2681
|
- `useRenderVisibility` (function): function useRenderVisibility(): MutableRefObject<VisiblePredicate> — Read the current render-visibility predicate. Backward compatible: with no CullingProvider mounted (or culling disabled) it returns an always-visible ref, so a marker that consults it behaves exactly as before this feature existed.
|
|
2589
2682
|
|
|
2590
2683
|
## @jgengine/shell/vision/FrustumSensorHud
|
|
@@ -2788,6 +2881,11 @@
|
|
|
2788
2881
|
- `SpriteBatchInstance` (interface): interface SpriteBatchInstance — ⚠ undocumented
|
|
2789
2882
|
- `SpriteBatchProps` (interface): interface SpriteBatchProps — ⚠ undocumented
|
|
2790
2883
|
|
|
2884
|
+
## @jgengine/shell/world/TileLayerRenderer
|
|
2885
|
+
|
|
2886
|
+
- `TileLayerRenderer` (function): function TileLayerRenderer({ config, parallax = [1, 1], pixelated = true }: TileLayerRendererProps): React.JSX.Element | null — Renders a tilemap as one instanced quad mesh with atlas UV rectangles.
|
|
2887
|
+
- `TileLayerRendererProps` (interface): interface TileLayerRendererProps — Inputs for the instanced textured tile-layer renderer.
|
|
2888
|
+
|
|
2791
2889
|
## @jgengine/shell/world/WorldEntityFrames
|
|
2792
2890
|
|
|
2793
2891
|
- `WorldEntityFrames` (function): function WorldEntityFrames<E extends EntityFrameEntry>({ entries, renderFrame, tickMs = 0, className, anchorTransform, ...layout }: WorldEntityFramesProps<E>): React.JSX.Element — R3F convenience that mounts inside the scene, samples the live camera each frame (throttled by `tickMs`), and renders `@jgengine/react`'s {@link EntityFrames} through a fullscreen `<Html>` overlay. This is the one-line way an R3F game gets overhead enemy nameplates/health bars from its own entity array without a store: pass `entries` + a `renderFrame` that composes the shipped bars. The projection, viewport culling, and stacking come for free.
|
|
@@ -2814,6 +2912,10 @@
|
|
|
2814
2912
|
|
|
2815
2913
|
- `WorldItems` (function): function WorldItems({ config }: { config?: WorldItemRenderConfig }): React.JSX.Element — Rarity→beam/color/label render binding + loot-filter overlay (#32/#33) for every dropped `worldItem`.
|
|
2816
2914
|
|
|
2915
|
+
## @jgengine/shell/world/WorldParticles
|
|
2916
|
+
|
|
2917
|
+
- `resolveParticleBudget` (function): function resolveParticleBudget(quality: GraphicsQuality, requested: number | undefined, particleCap?: number): number — The per-effect particle pool a graphics tier allows: the requested `max` clamped to the tier cap, so lower tiers degrade density instead of dropping effects entirely.
|
|
2918
|
+
|
|
2817
2919
|
## @jgengine/shell/world/WorldPings
|
|
2818
2920
|
|
|
2819
2921
|
- `WorldPings` (function): function WorldPings({ markers, kindStyles, pingsOnly = true, height = 2.4, showCallout = true, renderCallout, }: WorldPingsProps): ReactNode — World-space pings — the in-scene side of a ping/marker: a bobbing downward arrowhead pointing at the spot, a ground ring, and a billboarded callout, colored by marker kind and fading in/out over the marker's lifetime. Reads a `MarkerSet` (typically the one a `createPingSystem` writes to), a marker source, or a static array; mount through `PlayableGame.WorldOverlay`.
|
|
@@ -2821,7 +2923,7 @@
|
|
|
2821
2923
|
|
|
2822
2924
|
## @jgengine/shell/world/WorldScene
|
|
2823
2925
|
|
|
2824
|
-
- `RemotePlayers` (function): function RemotePlayers({ rows }: { rows: PresencePoseRow[] }): React.JSX.Element — ⚠ undocumented
|
|
2926
|
+
- `RemotePlayers` (function): function RemotePlayers({ rows, presenceInterpolationMs = 100 }: { rows: PresencePoseRow[]; presenceInterpolationMs?: number }): React.JSX.Element — ⚠ undocumented
|
|
2825
2927
|
- `WorldView` (function): function WorldView({ entitySprites, entityModels, objectModels, objectStyles, environment, assets, renderEntity, renderObject, selectedIds, hideLocalActor, }: { entitySprites: Record<string, EntitySpriteConfig> | undefined; entityModels: Record<string, string | ModelConfig> | undefined; objectModels… — ⚠ undocumented
|
|
2826
2928
|
|
|
2827
2929
|
## @jgengine/shell/world/entityPose
|
|
@@ -2840,8 +2942,17 @@
|
|
|
2840
2942
|
- `pingBobOffset` (function): function pingBobOffset(elapsedSeconds: number, amplitude = 0.18, speedHz = 1.1): number — Vertical bob offset (world units) for a hovering ping arrow at `elapsedSeconds`.
|
|
2841
2943
|
- `pingOpacity` (function): function pingOpacity(input: PingOpacityInput): number — Alpha for a world ping in `[0, 1]`: ramps up over `fadeInMs` after it appears and ramps back down over `fadeOutMs` before it expires. Pure math so the lifecycle can be unit-tested without an R3F canvas.
|
|
2842
2944
|
|
|
2945
|
+
## @jgengine/shell/world/tileLayerInstances
|
|
2946
|
+
|
|
2947
|
+
- `TileLayerInstance` (interface): interface TileLayerInstance — One resolved map cell with its world position and atlas UV rectangle.
|
|
2948
|
+
- `resolveTileLayerInstances` (function): function resolveTileLayerInstances(config: TilemapWorldConfig): readonly TileLayerInstance[] — Resolve map glyphs to atlas frames and normalized UV rectangles for deterministic tests and renderers.
|
|
2949
|
+
|
|
2843
2950
|
## @jgengine/shell/world/worldBarSamples
|
|
2844
2951
|
|
|
2845
2952
|
- `NameplateSample` (interface): interface NameplateSample — One entity's projected nameplate: screen `x`/`y`, display `name`, health `percent` (or `null` when statless), and world `distance` from the player.
|
|
2846
2953
|
- `Projectable` (interface): interface Projectable — ⚠ undocumented
|
|
2847
2954
|
- `WorldBarSample` (interface): interface WorldBarSample — ⚠ undocumented
|
|
2955
|
+
|
|
2956
|
+
## @jgengine/shell/worldSync
|
|
2957
|
+
|
|
2958
|
+
- `AuthoritativeFrameHandler` (type): type AuthoritativeFrameHandler = (revision: number) => void — Receives the revision of an authoritative world frame after it is applied locally.
|
|
@@ -286,6 +286,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
286
286
|
|
|
287
287
|
- `InteractionPrompt` (function) · `import { InteractionPrompt } from "@jgengine/react"`
|
|
288
288
|
|
|
289
|
+
## join-gate — block gameplay until joined and show failures with retry
|
|
290
|
+
|
|
291
|
+
- `JoinGate` (function) · `import { JoinGate } from "@jgengine/shell/JoinGate"`
|
|
292
|
+
|
|
289
293
|
## key-hint — keyboard/mouse control hint that hides itself on touch
|
|
290
294
|
|
|
291
295
|
- `KeyHint` (function) · `import { KeyHint } from "@jgengine/react"`
|
|
@@ -499,6 +503,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
499
503
|
|
|
500
504
|
- `SelectionPanel` (function) · `import { SelectionPanel } from "@jgengine/react"`
|
|
501
505
|
|
|
506
|
+
## server-session — join a multiplayer host with status, retry, and teardown
|
|
507
|
+
|
|
508
|
+
- `useServerSession` (function) · `import { useServerSession } from "@jgengine/react/useServerSession"`
|
|
509
|
+
|
|
502
510
|
## 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
|
|
503
511
|
|
|
504
512
|
- `ShopGrid` (function) · `import { ShopGrid } from "@jgengine/react"`
|
|
@@ -507,6 +515,15 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
507
515
|
|
|
508
516
|
- `formatSpeed` (function) · `import { formatSpeed } from "@jgengine/core/ui"`
|
|
509
517
|
|
|
518
|
+
## sprite-2d — animate a sprite atlas clip from headless or rendered game code
|
|
519
|
+
|
|
520
|
+
- `createSpriteClipPlayer` (function) · `import { createSpriteClipPlayer } from "@jgengine/core/render/sprite2d"`
|
|
521
|
+
- `sortingOrder` (function) · `import { sortingOrder } from "@jgengine/core/render/sprite2d"`
|
|
522
|
+
|
|
523
|
+
## standalone-chat — render persisted chat with focus controls and visible send failures
|
|
524
|
+
|
|
525
|
+
- `StandaloneChatPanel` (function) · `import { StandaloneChatPanel } from "@jgengine/react/standaloneChatPanel"`
|
|
526
|
+
|
|
510
527
|
## start-screen — headless title/attract overlay the game fills and skins
|
|
511
528
|
|
|
512
529
|
- `StartScreen` (function) · `import { StartScreen } from "@jgengine/react"`
|
|
@@ -523,6 +540,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
523
540
|
|
|
524
541
|
- `TalentTree` (function) · `import { TalentTree } from "@jgengine/react"`
|
|
525
542
|
|
|
543
|
+
## territory-overlay — show footprint ownership, claim cost, and affordability
|
|
544
|
+
|
|
545
|
+
- `TerritoryOverlay` (function) · `import { TerritoryOverlay } from "@jgengine/shell/TerritoryOverlay"`
|
|
546
|
+
|
|
526
547
|
## timer-readout — live digital mm:ss/m:ss.d timer readout bound to a TimerSet
|
|
527
548
|
|
|
528
549
|
- `TimerReadout` (function) · `import { TimerReadout } from "@jgengine/react"`
|
|
@@ -551,3 +551,6 @@ UI work is complete only when:
|
|
|
551
551
|
- screenshots have been reviewed and revised
|
|
552
552
|
- the implementation remains accessible and performant
|
|
553
553
|
- future generated UI is explicitly prevented from falling back to generic website-card styling
|
|
554
|
+
## 2D sprite presentation
|
|
555
|
+
|
|
556
|
+
Core owns renderer-independent atlas data and animation state. Convert Aseprite or TexturePacker JSON with `fromAseprite` / `fromTexturePacker` from `@jgengine/core/assets/spriteAtlas`, then drive a clip with `createSpriteClipPlayer` from `@jgengine/core/render/sprite2d`. Persist `snapshot()` and restore it on load; use `retune({ speed })` for runtime playback changes. Use `sortingOrder(layers, layer, offset)` when a game maps named presentation layers to renderer order.
|
|
@@ -54,3 +54,9 @@ Render seams fall back to placeholders when content is unauthored: default green
|
|
|
54
54
|
- Generated environments still need deterministic data assertions; authored environments need scene-document assertions.
|
|
55
55
|
- Audio files and licensing belong to `jgengine-assets`; spatial playback policy belongs here.
|
|
56
56
|
|
|
57
|
+
|
|
58
|
+
### Territory and placement
|
|
59
|
+
|
|
60
|
+
Use `world/territory` for chunk-backed ownership: `planFootprintClaims` prices previews, `placeWithTerritory` commits claims and object placement atomically, and `createTerritory` binds host-owned snapshot storage to `ctx.game.territory`. Use `territoryChunkKeys` to load every footprint and gap-neighbor chunk before planning; never interpret an unloaded neighborhood as vacant. Claims persist in `RuntimeChunkRow.territory`; `RuntimePlayerRow.territoryOwnedCount` preserves the price curve and `ownedTerritoryChunkKeys` bounds owner queries. Convex hosts use `loadTerritoryState`/`persistTerritoryState` from `@jgengine/convex/territory` to commit dirty claim chunks/profiles without a shared-server write. Grant `starterBlock` before the first placement verb. Placement previews must show the claim cost and affordability on the placement surface.
|
|
61
|
+
|
|
62
|
+
Use `chunkKeysAround(position, rings)` for bounded command/presence reads; declare `commands[name].scope(input)` for every hosted command. Missing scopes load only the actor and no chunks. A whole-world command must opt in explicitly with `scope: () => ({})` and justify its read budget.
|