@jgengine/core 0.18.1 → 0.19.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 +158 -7
- package/dist/ai/decisionGraph.d.ts +48 -4
- package/dist/ai/decisionGraph.js +153 -23
- package/dist/ai/groupAssist.d.ts +10 -0
- package/dist/ai/groupAssist.js +11 -0
- package/dist/ai/pursuit.d.ts +1 -1
- package/dist/ai/pursuit.js +1 -1
- package/dist/ai/threat.d.ts +8 -0
- package/dist/ai/threat.js +10 -0
- package/dist/anim/animGraph.d.ts +11 -0
- package/dist/anim/animGraph.js +128 -0
- package/dist/anim/boneTexture.d.ts +55 -0
- package/dist/anim/boneTexture.js +43 -0
- package/dist/anim/footPlacement.d.ts +57 -0
- package/dist/anim/footPlacement.js +67 -0
- package/dist/anim/locomotionGraph.d.ts +9 -0
- package/dist/anim/locomotionGraph.js +29 -0
- package/dist/audio/audioFalloff.d.ts +2 -0
- package/dist/audio/doppler.d.ts +21 -0
- package/dist/audio/doppler.js +32 -0
- package/dist/audio/engineLayers.d.ts +83 -0
- package/dist/audio/engineLayers.js +115 -0
- package/dist/combat/abilityKit.d.ts +1 -0
- package/dist/combat/abilityKit.js +1 -0
- package/dist/combat/death.d.ts +7 -0
- package/dist/combat/shotOrigin.d.ts +6 -0
- package/dist/combat/shotOrigin.js +6 -0
- package/dist/combat/weaponFeedback.d.ts +36 -0
- package/dist/combat/weaponFeedback.js +42 -0
- package/dist/combat/weaponHandling.d.ts +161 -0
- package/dist/combat/weaponHandling.js +202 -0
- package/dist/combat/weaponPresentation.d.ts +115 -0
- package/dist/combat/weaponPresentation.js +96 -0
- package/dist/devtools/warnOnce.d.ts +8 -0
- package/dist/devtools/warnOnce.js +18 -0
- package/dist/editor/document.js +3 -1
- package/dist/editor/environment.js +8 -0
- package/dist/editor/types.d.ts +4 -0
- package/dist/faction/reputation.d.ts +6 -0
- package/dist/faction/reputation.js +11 -0
- package/dist/game/cameraConfig.d.ts +51 -1
- package/dist/game/events.d.ts +6 -0
- package/dist/game/lootTable.d.ts +4 -0
- package/dist/game/lootTable.js +16 -0
- package/dist/game/playableGame.d.ts +84 -17
- package/dist/game/toasts.d.ts +8 -0
- package/dist/game/toasts.js +7 -0
- package/dist/game/vfxInstance.d.ts +9 -0
- package/dist/game/vfxInstance.js +12 -1
- package/dist/game/viewports.d.ts +43 -0
- package/dist/game/viewports.js +46 -0
- package/dist/game/worldItem.d.ts +5 -1
- package/dist/game/worldItem.js +0 -1
- package/dist/input/actionBindings.d.ts +15 -1
- package/dist/input/actionBindings.js +14 -3
- package/dist/input/actionContexts.d.ts +25 -1
- package/dist/input/actionContexts.js +82 -25
- package/dist/input/axisInput.d.ts +4 -0
- package/dist/input/axisInput.js +4 -0
- package/dist/input/axisShaper.d.ts +73 -0
- package/dist/input/axisShaper.js +105 -0
- package/dist/input/gamepadModel.d.ts +36 -2
- package/dist/input/gamepadModel.js +69 -30
- package/dist/input/haptics.d.ts +50 -0
- package/dist/input/haptics.js +74 -0
- package/dist/input/inputBuffer.d.ts +40 -0
- package/dist/input/inputBuffer.js +59 -0
- package/dist/input/lookChannel.d.ts +10 -0
- package/dist/input/lookChannel.js +6 -0
- package/dist/input/pointer.d.ts +2 -0
- package/dist/input/pointer.js +4 -0
- package/dist/item/affix.d.ts +6 -0
- package/dist/item/affix.js +6 -0
- package/dist/meta/changelog.d.ts +1 -1
- package/dist/meta/changelog.js +112 -1
- package/dist/movement/glideModel.d.ts +3 -0
- package/dist/movement/glideModel.js +6 -0
- package/dist/movement/grappleSwing.d.ts +2 -0
- package/dist/movement/grappleSwing.js +5 -1
- package/dist/movement/movementModel.d.ts +39 -0
- package/dist/movement/movementModel.js +62 -19
- package/dist/movement/movementProbe.d.ts +51 -0
- package/dist/movement/movementProbe.js +119 -0
- package/dist/movement/playerMovement.d.ts +21 -2
- package/dist/movement/playerMovement.js +89 -6
- package/dist/movement/solidObstacles.d.ts +9 -1
- package/dist/movement/solidObstacles.js +44 -2
- package/dist/movement/voxelController.js +7 -7
- package/dist/nav/navFromEnvironment.d.ts +9 -3
- package/dist/nav/navFromEnvironment.js +18 -12
- package/dist/nav/navMesh.d.ts +43 -2
- package/dist/nav/navMesh.js +534 -128
- package/dist/physics/aircraftDynamics.d.ts +390 -0
- package/dist/physics/aircraftDynamics.js +704 -0
- package/dist/physics/boatDynamics.d.ts +116 -0
- package/dist/physics/boatDynamics.js +160 -0
- package/dist/physics/drivableVehicle.d.ts +22 -8
- package/dist/physics/drivableVehicle.js +4 -2
- package/dist/physics/flightDynamics.d.ts +21 -4
- package/dist/physics/flightDynamics.js +28 -5
- package/dist/physics/handlingProbe.d.ts +249 -0
- package/dist/physics/handlingProbe.js +606 -0
- package/dist/physics/kinematicVehicle.d.ts +32 -2
- package/dist/physics/kinematicVehicle.js +15 -0
- package/dist/physics/physicsBackend.d.ts +12 -0
- package/dist/physics/physicsBackendConformance.js +34 -0
- package/dist/physics/physicsWorldBackend.d.ts +1 -0
- package/dist/physics/physicsWorldBackend.js +33 -0
- package/dist/physics/vehicleBackendLink.d.ts +49 -0
- package/dist/physics/vehicleBackendLink.js +102 -0
- package/dist/physics/vehicleDynamics.d.ts +374 -0
- package/dist/physics/vehicleDynamics.js +737 -0
- package/dist/physics/worldColliders.d.ts +1 -1
- package/dist/physics/worldColliders.js +35 -3
- package/dist/puzzle/cellGrid.d.ts +15 -9
- package/dist/puzzle/cellGrid.js +13 -9
- package/dist/render/lookPreset.d.ts +9 -2
- package/dist/render/lookPreset.js +29 -2
- package/dist/render/postProcessing.d.ts +30 -0
- package/dist/render/postProcessing.js +1 -1
- package/dist/runtime/cameraDirector.d.ts +17 -3
- package/dist/runtime/cameraDirector.js +25 -0
- package/dist/runtime/commandInput.d.ts +37 -0
- package/dist/runtime/commandInput.js +58 -0
- package/dist/runtime/commandRunner.d.ts +27 -0
- package/dist/runtime/commandRunner.js +31 -3
- package/dist/runtime/context/combat.d.ts +1 -0
- package/dist/runtime/context/combat.js +2 -1
- package/dist/runtime/context/deathLoot.d.ts +2 -0
- package/dist/runtime/context/deathLoot.js +1 -0
- package/dist/runtime/gameContext.js +7 -0
- package/dist/runtime/gameContextTypes.d.ts +19 -3
- package/dist/runtime/gameRuntime.d.ts +3 -1
- package/dist/runtime/gameRuntime.js +4 -0
- package/dist/runtime/inputSnapshot.d.ts +6 -0
- package/dist/runtime/inputSnapshot.js +10 -0
- package/dist/runtime/localPlayers.d.ts +73 -0
- package/dist/runtime/localPlayers.js +119 -0
- package/dist/runtime/transport.d.ts +9 -0
- package/dist/runtime/transport.js +7 -1
- package/dist/scene/behaviorRuntime.d.ts +12 -2
- package/dist/scene/behaviorRuntime.js +30 -14
- package/dist/scene/behaviors.d.ts +5 -1
- package/dist/scene/sceneKinds.d.ts +9 -0
- package/dist/scene/vehicleSeat.d.ts +5 -1
- package/dist/scene/vehicleSeat.js +5 -1
- package/dist/sensor/concealment.d.ts +6 -0
- package/dist/sensor/concealment.js +8 -0
- package/dist/sensor/freezeMonitor.d.ts +6 -0
- package/dist/sensor/freezeMonitor.js +8 -0
- package/dist/sensor/perception.d.ts +11 -1
- package/dist/sensor/perception.js +57 -10
- package/dist/sensor/recordingBuffer.d.ts +3 -0
- package/dist/sensor/recordingBuffer.js +8 -0
- package/dist/session/roundState.d.ts +4 -0
- package/dist/session/roundState.js +11 -0
- package/dist/settings/frameRateLimit.d.ts +16 -0
- package/dist/settings/frameRateLimit.js +37 -0
- package/dist/settings/graphicsProfile.d.ts +2 -0
- package/dist/settings/graphicsProfile.js +12 -0
- package/dist/settings/graphicsSettings.d.ts +40 -0
- package/dist/settings/graphicsSettings.js +81 -0
- package/dist/settings/settingsModel.d.ts +9 -1
- package/dist/settings/settingsModel.js +10 -0
- package/dist/stats/eventMeter.d.ts +1 -1
- package/dist/stats/eventMeter.js +1 -1
- package/dist/vfx/feedbackMixer.d.ts +61 -0
- package/dist/vfx/feedbackMixer.js +106 -0
- package/dist/visibility/simulationCulling.d.ts +8 -1
- package/dist/visibility/simulationCulling.js +7 -0
- package/dist/visibility/spatialIndex.d.ts +21 -0
- package/dist/visibility/spatialIndex.js +16 -0
- package/dist/world/authoredSolids.d.ts +46 -0
- package/dist/world/authoredSolids.js +75 -0
- package/dist/world/buildingGenerator.js +2 -2
- package/dist/world/buildingKit.d.ts +3 -1
- package/dist/world/buildings.d.ts +34 -2
- package/dist/world/buildings.js +11 -1
- package/dist/world/cityKind.d.ts +7 -0
- package/dist/world/cityKind.js +52 -1
- package/dist/world/features.d.ts +29 -2
- package/dist/world/features.js +6 -0
- package/dist/world/footprintGrid.d.ts +7 -0
- package/dist/world/footprintGrid.js +16 -0
- package/dist/world/interiors.d.ts +1 -0
- package/dist/world/interiors.js +5 -3
- package/dist/world/lod.d.ts +6 -0
- package/dist/world/lod.js +8 -0
- package/dist/world/terraform.d.ts +8 -0
- package/dist/world/terraform.js +7 -0
- package/dist/world/walls.d.ts +7 -0
- package/dist/world/walls.js +7 -0
- package/dist/world/worldSolids.d.ts +84 -0
- package/dist/world/worldSolids.js +240 -0
- package/dist/world.d.ts +2 -2
- package/dist/world.js +1 -1
- package/package.json +1 -1
- package/skills/ce-handoff/SKILL.md +1 -1
- package/skills/game-design/SKILL.md +2 -2
- package/skills/jgengine/SKILL.md +7 -5
- package/skills/jgengine/api.md +118 -89
- package/skills/jgengine/capabilities.md +28 -0
- package/skills/jgengine/recipes/minimal-game.md +3 -0
- package/skills/jgengine-combat/SKILL.md +5 -0
- package/skills/jgengine-combat/api.md +138 -103
- package/skills/jgengine-combat/capabilities.md +29 -1
- package/skills/jgengine-combat/recipes/weapon-feel.md +50 -0
- package/skills/jgengine-gameplay/api.md +462 -436
- package/skills/jgengine-gameplay/capabilities.md +24 -0
- package/skills/jgengine-gameplay/reference-systems.md +4 -0
- package/skills/jgengine-world/SKILL.md +15 -3
- package/skills/jgengine-world/api.md +873 -626
- package/skills/jgengine-world/capabilities.md +130 -6
- package/skills/jgengine-world/recipes/character-animation.md +39 -0
- package/skills/jgengine-world/recipes/controls.md +44 -0
- package/skills/jgengine-world/recipes/flight-feel.md +76 -0
- package/skills/jgengine-world/recipes/npc-senses.md +43 -0
- package/skills/jgengine-world/recipes/vehicle-feel.md +85 -0
- package/skills/jgengine-world/reference.md +31 -2
- package/skills/jgengine-world/visibility.md +112 -0
|
@@ -12,6 +12,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
12
12
|
|
|
13
13
|
- `advanceLedger` (function) · `import { advanceLedger } from "@jgengine/core/gameplay"`
|
|
14
14
|
|
|
15
|
+
## affix-roller — roll randomized gear (guns, armor, loot) with rarity tiers, stat scaling and prefix/suffix affixes from a seed
|
|
16
|
+
|
|
17
|
+
- `createAffixRoller` (function) · `import { createAffixRoller } from "@jgengine/core/gameplay"`
|
|
18
|
+
|
|
15
19
|
## auction-book — timed bid auctions with escrowed bids, buyout, anti-snipe close extension, and collection-box settlement
|
|
16
20
|
|
|
17
21
|
- `createAuctionBook` (function) · `import { createAuctionBook } from "@jgengine/core/gameplay"`
|
|
@@ -40,6 +44,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
40
44
|
|
|
41
45
|
- `totalLoad` (function) · `import { totalLoad } from "@jgengine/core/inventory/encumbrance"`
|
|
42
46
|
|
|
47
|
+
## cell-grid — immutable 2D board of cells with row clears, gravity collapse, and match runs
|
|
48
|
+
|
|
49
|
+
- `createCellGrid` (function) · `import { createCellGrid } from "@jgengine/core/puzzle/cellGrid"`
|
|
50
|
+
|
|
43
51
|
## clip-roles — map a rigged asset's pack-specific clip name to its semantic animation role
|
|
44
52
|
|
|
45
53
|
- `classifyClip` (function) · `import { classifyClip } from "@jgengine/core/game/clipRoles"`
|
|
@@ -136,6 +144,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
136
144
|
|
|
137
145
|
- `createEventTicker` (function) · `import { createEventTicker } from "@jgengine/core/gameplay"`
|
|
138
146
|
|
|
147
|
+
## fire-input — bind a key or mouse button to a named action that runs the same-named command with the aim; repeatMs auto-fires while held
|
|
148
|
+
|
|
149
|
+
- `ActionCodesMap` (type) · `import { ActionCodesMap } from "@jgengine/core/gameplay"`
|
|
150
|
+
|
|
139
151
|
## game-save — save/load game state with a pluggable backend, autosave, slots, and migration
|
|
140
152
|
|
|
141
153
|
- `createSaveStore` (function) · `import { createSaveStore } from "@jgengine/core/gameplay"`
|
|
@@ -239,6 +251,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
239
251
|
|
|
240
252
|
- `localSaveBackend` (function) · `import { localSaveBackend } from "@jgengine/core/gameplay"`
|
|
241
253
|
|
|
254
|
+
## loot-beams — rarity-colored loot beams and labels on dropped items via defineGame({ worldItem: { rarityStyle, beamHeight } })
|
|
255
|
+
|
|
256
|
+
- `RarityStyle` (interface) · `import { RarityStyle } from "@jgengine/core/gameplay"`
|
|
257
|
+
|
|
242
258
|
## loot-filter — filter and highlight drops by rarity/name rules
|
|
243
259
|
|
|
244
260
|
- `evaluateLootFilter` (function) · `import { evaluateLootFilter } from "@jgengine/core/gameplay"`
|
|
@@ -312,6 +328,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
312
328
|
|
|
313
329
|
- `createPingSystem` (function) · `import { createPingSystem } from "@jgengine/core/gameplay"`
|
|
314
330
|
|
|
331
|
+
## pointer-commands — click an entity or the ground to run a command (click-to-target, click-to-move, grab loot, marquee select)
|
|
332
|
+
|
|
333
|
+
- `PointerConfig` (interface) · `import { PointerConfig } from "@jgengine/core/gameplay"`
|
|
334
|
+
|
|
315
335
|
## policy-annotate — tag a scheduled transaction's provenance without changing its value
|
|
316
336
|
|
|
317
337
|
- `annotate` (function) · `import { annotate } from "@jgengine/core/gameplay"`
|
|
@@ -435,6 +455,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
|
|
|
435
455
|
|
|
436
456
|
- `createSpawnPoints` (function) · `import { createSpawnPoints } from "@jgengine/core/gameplay"`
|
|
437
457
|
|
|
458
|
+
## split-screen — Split the screen into one viewport per local seat, each with its own follow camera.
|
|
459
|
+
|
|
460
|
+
- `splitViewports` (function) · `import { splitViewports } from "@jgengine/core/game/viewports"`
|
|
461
|
+
|
|
438
462
|
## stat-graph — derive game-defined stats from named inputs with provenance and preview
|
|
439
463
|
|
|
440
464
|
- `createStatGraph` (function) · `import { createStatGraph } from "@jgengine/core/gameplay"`
|
|
@@ -63,3 +63,7 @@ Default stages: fixed `input → movement → combat → ai → activities → c
|
|
|
63
63
|
|
|
64
64
|
- **Save / replicate** — system modules register via `ctx.game.registerSave` / `registerReplicate` at install.
|
|
65
65
|
- **Reset / dispose** — `loop.onReset` / `loop.onDispose` (composed) run system hooks.
|
|
66
|
+
|
|
67
|
+
## Snapshot and restore on stateful handles
|
|
68
|
+
|
|
69
|
+
These handles hand back a plain JSON `snapshot()` that later ticks do not mutate, and take it back with `restore(next)`, so a host, save file or replay can rewind them bit-exactly: `game/lootTable` `createLootRegistry` (registered tables; not JSON when an entry uses `generate`), `game/toasts` `createToastQueue`, `game/vfxInstance` `createVfxInstanceStore` (restore emits `stop` then `upsert` so the renderer follows), `session/roundState` `createRoundState` (`RoundSnapshot` now carries `pendingWinner`), `input/lookChannel` `createLookChannel`, and `input/pointer` `createDragCapture` (`state()` out, `restore(state | null)` in).
|
|
@@ -9,30 +9,38 @@ description: Build spatial runtime, movement, interaction, AI, and environments.
|
|
|
9
9
|
|
|
10
10
|
This skill owns runtime spatial behavior: authored-scene consumption, environments, movement, input mapping, interaction, AI, navigation, physics, visibility, time, and spatial audio. Scene creation and placement stay in `jgengine-editor`; presentation stays in `jgengine-ui`.
|
|
11
11
|
|
|
12
|
-
Search [capabilities.md](capabilities.md) by intent before designing a primitive. Use [api.md](api.md) for exact exports and [reference.md](reference.md) for environment, camera, navigation, physics, audio, and authored-scene recipes.
|
|
12
|
+
Search [capabilities.md](capabilities.md) by intent before designing a primitive. Use [api.md](api.md) for exact exports and [reference.md](reference.md) for environment, camera, navigation, physics, audio, and authored-scene recipes. Culling and streaming overrides are in [visibility.md](visibility.md).
|
|
13
13
|
|
|
14
14
|
For a *connected* walkthrough that wires several primitives into a running loop, read the goal-oriented recipes under [recipes/](recipes/) — organized by composition seam (what connects to what), never by genre. Start there before reading a game's source to learn how pieces fit; a hybrid game is just a different composition of the same primitives.
|
|
15
15
|
|
|
16
16
|
- [recipes/commanding-entities.md](recipes/commanding-entities.md) — select → order → tick → resolve: direct command over a group of entities (the command loop behind squad control, base-defense, herding, autobattle, or a mutating game's real-time phase).
|
|
17
|
+
- [recipes/npc-senses.md](recipes/npc-senses.md) — perceive → remember → decide → route: perception memory written into a decision-graph blackboard, with nav-mesh routing (guards, mobs, pedestrians, police response).
|
|
17
18
|
- [recipes/building-kit.md](recipes/building-kit.md) — bind the facade generator's part slots to real models: one massing, swappable art per style, blocks where the kit is silent.
|
|
19
|
+
- [recipes/vehicle-feel.md](recipes/vehicle-feel.md) — feel target → handling metrics → physical knobs for a ground vehicle, plus the camera, sound and rumble hooks that hang off its telemetry.
|
|
20
|
+
- [recipes/flight-feel.md](recipes/flight-feel.md) — an aircraft as physical numbers: surfaces, inertia and engine, with the symptom → knob table for how it flies.
|
|
21
|
+
- [recipes/controls.md](recipes/controls.md) — actions → layered contexts that rebind live → keyboard, touch and gamepad on the same actions → per-axis feel.
|
|
22
|
+
- [recipes/character-animation.md](recipes/character-animation.md) — clips → graph → rig → ground: data-driven state machines, triggers and clip events, root motion, foot IK that keeps feet on slopes, and instanced crowds.
|
|
18
23
|
|
|
19
24
|
## Canonical workflows
|
|
20
25
|
|
|
21
26
|
### Declare the place
|
|
22
27
|
|
|
23
|
-
A world is the place you play in: substrate + laws, via `world()` from `@jgengine/core/world/place` — `{ id, ground: { mode: flat|round|voxel|board, size, surface?, generator? }, physics? }`. Thin is complete: flat with `Infinity` axes for 3D, `board` for 2D, or omit `world` for pure UI/rules games. Never put seed, sky, or vegetation in a world definition — seeds derive from world id + save/run (`seedForPlace`); sky look and foliage scatter are editor-authored scene content, with the engine default sky when the document has none. `ground.surface` carries matter/feel laws (metal vs slime vs felt) that the same rule systems read — swap the surface, not the rules. See [reference.md](reference.md) for the full shape; `environment()` is the
|
|
28
|
+
A world is the place you play in: substrate + laws, via `world()` from `@jgengine/core/world/place` — `{ id, ground: { mode: flat|round|voxel|board, size, surface?, generator? }, physics? }`. Thin is complete: flat with `Infinity` axes for 3D, `board` for 2D, or omit `world` for pure UI/rules games. Never put seed, sky, or vegetation in a world definition — seeds derive from world id + save/run (`seedForPlace`); sky look and foliage scatter are editor-authored scene content, with the engine default sky when the document has none. `ground.surface` carries matter/feel laws (metal vs slime vs felt) that the same rule systems read — swap the surface, not the rules. See [reference.md](reference.md) for the full shape; `environment()` is the consumption path for editor/preset-written scene data: a created 3D game's `world.ts` passes it the document's sculpt, sky, and clearings through `environmentContentFromDocument`, never code-declared noise or coordinates.
|
|
24
29
|
|
|
25
30
|
### Authored world
|
|
26
31
|
|
|
27
32
|
1. Load the scene document through the shared authored-scene feature.
|
|
28
33
|
2. Render objects, paths, terrain, foliage, and markers generically.
|
|
29
34
|
3. Query the same ids/layers for spawns, routes, plots, and interaction.
|
|
30
|
-
4.
|
|
35
|
+
4. Collision for generated and studio content comes from its data through `ctx.world.solids`; never hand-place invisible blockers for it (see reference.md, World solids).
|
|
36
|
+
5. Keep derived caches rebuildable; the document remains authoritative.
|
|
31
37
|
|
|
32
38
|
### Movement and interaction
|
|
33
39
|
|
|
34
40
|
Choose input intent, controller/motor, collision/navigation, and camera as separate seams. Commands express game intent; world systems resolve motion. Interaction targets come from bounded spatial/sensor queries, not full-world scans.
|
|
35
41
|
|
|
42
|
+
Walk feel is data, not code. `movement.feel` sets `groundAcceleration`, `airAcceleration` and `groundFriction` (response rates, 1/s) plus `runMultiplier`, `crouchMultiplier`, jump forgiveness (`jumpBufferMs`, `coyoteMs`) and jump shape (`jumpCutFactor`, `apexGravityScale`, `fallGravityScale`, `landingRecoveryMs`), and `physics` sets `gravity` and `jumpVelocity`. A floaty platformer and a weighty shooter differ only in these numbers; pin them with `measureMovement` (`movement/movementProbe`) in a test.
|
|
43
|
+
|
|
36
44
|
### Stateful placed objects
|
|
37
45
|
|
|
38
46
|
Per-instance state belongs on the placement, not in a game-owned map keyed by `instanceId`. Set `SceneObject.state` (opaque) through `ctx.scene.object.setState`/`patchState`; declare `slotInventory` on the catalog entry and mutate contents through `ctx.scene.object.slots`, which enforces the declared capacity and `accepts`. Both replicate and save with the object through the always-on `objects` snapshot module, and `toRuntimeObjectRow`/`fromRuntimeObjectRow` (`@jgengine/core/multiplayer`) convert to and from the host's persisted rows.
|
|
@@ -41,6 +49,10 @@ Per-instance state belongs on the placement, not in a game-owned map keyed by `i
|
|
|
41
49
|
|
|
42
50
|
Compose perception, selection, planning/behavior, movement, and lifecycle independently. Inject randomness and scheduling. Use spatial indexes, interest tiers, or bounded candidate sets for scale.
|
|
43
51
|
|
|
52
|
+
NPC decisions are a `decisionGraph` behavior: the graph and its blackboard are data, actions are registered by name, and perception or game systems write facts into `behaviorControl(ctx).blackboard(id)` rather than actions querying the world. Set `thinkInterval` so crowds think a few times a second, not every frame, and release movement or claims in `onAbort`.
|
|
53
|
+
|
|
54
|
+
Route on a polygon nav mesh through one `createNavMeshQuery(mesh)` per mesh; price terrain and gate doors with `areaCosts` via `retune`, and keep `maxNodes` bounded so a long request returns a `partial` route instead of stalling a frame.
|
|
55
|
+
|
|
44
56
|
### Fallback-seam diagnostics
|
|
45
57
|
|
|
46
58
|
Render seams fall back to placeholders when content is unauthored: default green ground (no environment), primitive capsule/box actors (no `entityModels`/`objectModels` mapping), stylized proxy foliage (no scatter `resolveItem`). These placeholders are sometimes intended, so runtime never changes — but a dev-only, opt-in probe (`@jgengine/core/devtools/fallbackSeams`) tells "unauthored/misconfigured" apart from "intended". The shell arms it via `armFallbackSeams(devtoolsEnabled)`; each seam reports at its choice site (`reportFallbackSeam`), and counts surface through the devtools `fallbacks` probe. Disarmed (production) it is a pure, allocation-free no-op.
|