@jgengine/core 0.34.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/dist/agents/system.d.ts +135 -0
- package/dist/agents/system.js +195 -0
- package/dist/audio/ambience.d.ts +47 -0
- package/dist/audio/ambience.js +75 -0
- package/dist/audio/audioFalloff.d.ts +12 -0
- package/dist/audio/occlusion.d.ts +40 -0
- package/dist/audio/occlusion.js +27 -0
- package/dist/game/playableGame.d.ts +21 -1
- package/dist/meta/changelog.d.ts +1 -1
- package/dist/meta/changelog.js +43 -1
- package/dist/runtime/headlessRunner.d.ts +10 -1
- package/dist/runtime/headlessRunner.js +10 -1
- package/dist/world/pathTerrain.js +23 -28
- package/dist/world/polylineIndex.d.ts +30 -0
- package/dist/world/polylineIndex.js +80 -0
- package/dist/world/spatialBuckets.d.ts +15 -0
- package/dist/world/spatialBuckets.js +80 -0
- package/dist/world/terrain.js +58 -11
- package/package.json +1 -1
- package/skills/jgengine/api.md +3 -3
- package/skills/jgengine-gameplay/api.md +29 -0
- package/skills/jgengine-gameplay/capabilities.md +1 -0
- package/skills/jgengine-world/api.md +18 -2
- package/skills/jgengine-world/capabilities.md +8 -0
|
@@ -455,13 +455,22 @@
|
|
|
455
455
|
- `sumMagnitude` (function): function sumMagnitude<P>(memberships: readonly AreaMembership<P>[], magnitudeOf: MagnitudeOf<P>): number — Sum a numeric magnitude across memberships — additive aggregation for a total field strength (total damage per tick, total slow). A terminal reducer, not a filter, so it returns the number.
|
|
456
456
|
- `uniqueByStackKey` (function): function uniqueByStackKey<P>(magnitudeOf?: MagnitudeOf<P>): AreaStackPolicy<P> — Keep at most one membership per `stackKey`. With `magnitudeOf` the strongest per key wins (ties broken by `sourceId` for determinism); without it the first-seen per key wins. Use for unique-by-key buffs where reapplying the same aura should not stack.
|
|
457
457
|
|
|
458
|
+
## @jgengine/core/audio/ambience
|
|
459
|
+
|
|
460
|
+
- `AmbienceWeight` (interface): interface AmbienceWeight — One zone's share of the ambience mix at a listener position, 0..1.
|
|
461
|
+
- `AmbienceZoneDef` (interface): interface AmbienceZoneDef — One ambience zone: a sound bed keyed to a volume of the scene.
|
|
462
|
+
- `AmbienceZoneShape` (type): type AmbienceZoneShape = | { kind: "sphere"; center: readonly [number, number, number]; radius: number } | { kind: "box"; min: readonly [number, number, number]; max: readonly [number, number, number] } — A world-space volume whose sound bed plays while the listener is inside it.
|
|
463
|
+
- `activeAmbienceZone` (function): function activeAmbienceZone(weights: readonly AmbienceWeight[]): string | null — The loudest zone in a weight list, or null when every zone is silent.
|
|
464
|
+
- `ambienceWeights` (function): function ambienceWeights(zones: readonly AmbienceZoneDef[], x: number, y: number, z: number, out: AmbienceWeight[] = []): AmbienceWeight[] — Every zone's mix weight at a listener position. A zone is at full level `crossfade` units inside its boundary, at half level on the boundary and silent `crossfade` units outside, so a listener walking between two zones that share a boundary hears a constant-sum handover. Weights that would sum above 1 (overlapping zones) are normalized so total bed level never exceeds unity. Writes into `out` when given, so a per-frame caller allocates nothing.
|
|
465
|
+
- `zoneSignedDistance` (function): function zoneSignedDistance(shape: AmbienceZoneShape, x: number, y: number, z: number): number — Distance from a point to a zone boundary, positive inside and negative outside. Spheres measure from the surface; boxes use the nearest face.
|
|
466
|
+
|
|
458
467
|
## @jgengine/core/audio/audioFalloff
|
|
459
468
|
|
|
460
469
|
- `AudioBusDef` (interface): interface AudioBusDef { id: AudioBusId; gain?: number } — ⚠ undocumented · used by `withFeedbackCueSounds` (@jgengine/core/audio/feedbackCues): Merge the default feedback reactions into a game's sound catalog.
|
|
461
470
|
- `AudioBusId` (type): type AudioBusId = string — ⚠ undocumented
|
|
462
471
|
- `AudioFalloffConfig` (interface): interface AudioFalloffConfig { minDistance?: number; maxDistance?: number; curve?: FalloffCurve } — ⚠ undocumented
|
|
463
472
|
- `FalloffCurve` (type): type FalloffCurve = "linear" | "inverse" | "none" — ⚠ undocumented
|
|
464
|
-
- `SoundDef` (interface): interface SoundDef { id: string; url?: string; synth?: SynthPatch; bus: AudioBusId; gain?: number; loop?: boolean; maxVoices?: number; priority?: number;
|
|
473
|
+
- `SoundDef` (interface): interface SoundDef { id: string; url?: string; synth?: SynthPatch; bus: AudioBusId; gain?: number; loop?: boolean; maxVoices?: number; priority?: number; duck?: {buses?: readonly string[]; amount?: number; seconds?: number;}; positional?: boolean; falloff?: A… — ⚠ undocumented · used by `DEFAULT_FEEDBACK_CUE_SOUNDS` (@jgengine/core/audio/feedbackCues): Short procedural reactions - no samples to load, so every game has impact feedback without authoring audio.
|
|
465
474
|
- `computeFalloffGain` (function): function computeFalloffGain(distance: number, config: AudioFalloffConfig = {}): number — ⚠ undocumented
|
|
466
475
|
- `distance3` (function): function distance3(a: { x: number; y: number; z: number }, b: { x: number; y: number; z: number }): number — ⚠ undocumented
|
|
467
476
|
- `resolveEmitterGain` (function): function resolveEmitterGain(distance: number, sound: Pick<SoundDef, "gain" | "positional" | "falloff">, busGain: number): number — ⚠ undocumented
|
|
@@ -513,6 +522,13 @@
|
|
|
513
522
|
- `createMusicState` (function): function createMusicState(): MusicStateSnapshot — Fresh state with no tier entered, so the first resolve always settles and reports `changed`.
|
|
514
523
|
- `resolveMusicState` (function): function resolveMusicState(state: MusicStateSnapshot, input: MusicStateInput, config: MusicStateConfig): MusicStateResult — Pick the theme for the current intensity. Escalation is immediate; de-escalation waits for the tier's `holdMs` and needs the intensity to fall a `release` margin below the tier it is leaving.
|
|
515
524
|
|
|
525
|
+
## @jgengine/core/audio/occlusion
|
|
526
|
+
|
|
527
|
+
- `AUDIO_OCCLUSION_DEFAULTS` (const): const AUDIO_OCCLUSION_DEFAULTS: { readonly maxTestsPerTick: 8; readonly intervalMs: 150; readonly attenuation: 0.55; readonly lowpassHz: 1200; readonly maxDistance: 60; } — Defaults for {@link AudioOcclusionConfig}.
|
|
528
|
+
- `AudioOcclusionConfig` (interface): interface AudioOcclusionConfig — Geometry occlusion for retained positional loops: a cheap line test between the listener and an emitter behind blocking geometry, bounded so a busy scene can never turn audio into a raycast pass. The shell runs the test against the scene's blockable colliders; the engine applies the resulting attenuation and low-pass to the loop it already owns.
|
|
529
|
+
- `ResolvedAudioOcclusionConfig` (interface): interface ResolvedAudioOcclusionConfig — A fully specified occlusion policy, with every unset field replaced by its default.
|
|
530
|
+
- `resolveOcclusionConfig` (function): function resolveOcclusionConfig(config: AudioOcclusionConfig | false = {}): ResolvedAudioOcclusionConfig — Fill in the occlusion defaults and clamp each field to a workable range: a finite test budget, a non-negative retest interval and distance cap, and an attenuation in `0..1`.
|
|
531
|
+
|
|
516
532
|
## @jgengine/core/audio/stepCadence
|
|
517
533
|
|
|
518
534
|
- `StepCadenceConfig` (interface): interface StepCadenceConfig — Distance-driven footstep cadence. Pure state-in/state-out: feed it how far a mover travelled this frame and it tells you how many steps landed, so foley stays locked to ground distance instead of a wall-clock timer that desyncs when speed changes.
|
|
@@ -2859,7 +2875,7 @@
|
|
|
2859
2875
|
- `SnapMode` (type): type SnapMode = "grid" | "free" | "surface" — ⚠ undocumented
|
|
2860
2876
|
- `SnowEnvironmentDescriptor` (type): type SnowEnvironmentDescriptor = { kind: "snow" } & Required< Pick<SnowEnvironmentConfig, "area" | "density" | "speed" | "flakeSize" | "drift" | "wind" | "color" | "opacity"> > — ⚠ undocumented · used by `snow`: Declares a snowfall weather effect for `environment()` — area, density, drift, wind, and flake opacity.
|
|
2861
2877
|
- `SoilRules` (interface): interface SoilRules — Fully-defaulted soil params parsed from a volume's `meta`.
|
|
2862
|
-
- `SoundDef` (interface): interface SoundDef { id: string; url?: string; synth?: SynthPatch; bus: AudioBusId; gain?: number; loop?: boolean; maxVoices?: number; priority?: number;
|
|
2878
|
+
- `SoundDef` (interface): interface SoundDef { id: string; url?: string; synth?: SynthPatch; bus: AudioBusId; gain?: number; loop?: boolean; maxVoices?: number; priority?: number; duck?: {buses?: readonly string[]; amount?: number; seconds?: number;}; positional?: boolean; falloff?: A… — ⚠ undocumented · used by `DEFAULT_FEEDBACK_CUE_SOUNDS` (@jgengine/core/audio/feedbackCues): Short procedural reactions - no samples to load, so every game has impact feedback without authoring audio.
|
|
2863
2879
|
- `SpatialGrid` (class): class SpatialGrid — A uniform-grid broad-phase over the x/z plane, separate from the rigid-body sim, for cheap same-tick proximity across hundreds–thousands of simple movers (swarm enemies). Rebuild each tick from the caller's own position arrays, then `queryCircle` (enemies hitting the player / an AoE) or `forEachPair` (mutual separation). Both are precise: no false negatives, no false positives beyond the exact distance test.
|
|
2864
2880
|
- `SpawnDirectorConfig` (interface): interface SpawnDirectorConfig { waves: readonly WaveManifest[]; maxAlive?: number; escalationPerSecond?: number; alertBudgetPerSecond?: number; alertDecayPerSecond?: number; playerBudgetPerSecond?: number; maxSpawnsPerTick?: number; loop?: boolean; seed?: number; spawnP… — ⚠ undocumented
|
|
2865
2881
|
- `SpawnDirectorState` (interface): interface SpawnDirectorState { wave: number; elapsed: number; waveElapsed: number; budget: number; alert: number; spawnedThisWave: number; spawnedTotal: number; rng: RandomSeed; done: boolean } — ⚠ undocumented
|
|
@@ -28,6 +28,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
28
28
|
|
|
29
29
|
- `measureAir` (function) · `import { measureAir } from "@jgengine/core/physics/handlingProbe"`
|
|
30
30
|
|
|
31
|
+
## ambience-zones — a scene declares looping sound beds keyed to world volumes; walking between them crossfades bed levels on the existing buses instead of cutting.
|
|
32
|
+
|
|
33
|
+
- `AmbienceZoneDef` (interface) · `import { AmbienceZoneDef } from "@jgengine/core/audio/ambience"`
|
|
34
|
+
|
|
31
35
|
## anim-graph — data-first animation state machine with blend trees, crossfades, layers, and clip events
|
|
32
36
|
|
|
33
37
|
- `createAnimGraphRuntime` (function) · `import { createAnimGraphRuntime } from "@jgengine/core/anim/animGraph"`
|
|
@@ -109,6 +113,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
109
113
|
|
|
110
114
|
- `defineAttackMoveOrder` (function) · `import { defineAttackMoveOrder } from "@jgengine/core/world"`
|
|
111
115
|
|
|
116
|
+
## audio-occlusion — an emitter behind blocking world geometry is attenuated and darkened by a budgeted line test, and falls back to distance-only once the tick's budget is spent.
|
|
117
|
+
|
|
118
|
+
- `AudioOcclusionConfig` (interface) · `import { AudioOcclusionConfig } from "@jgengine/core/audio/occlusion"`
|
|
119
|
+
|
|
112
120
|
## audio-voice-budget — bound simultaneous sound playback with per-sound caps, priorities, and deterministic stealing
|
|
113
121
|
|
|
114
122
|
- `createVoiceAllocator` (function) · `import { createVoiceAllocator } from "@jgengine/core/audio/voiceAllocator"`
|