@jgengine/assets 0.12.0 → 0.13.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 CHANGED
@@ -12,6 +12,32 @@ Agents building on the published SDK can also read this programmatically:
12
12
  same data as typed values, so an updater can diff its installed version against
13
13
  the latest and surface the migration steps.
14
14
 
15
+ ## 0.13.0
16
+
17
+ ### Migrate
18
+
19
+ - **Nothing required** — this release is additive fixes, defaults, and new drop-in primitives. Bump `@jgengine/*` pins to `^0.13.0` (CLI `jgengine` is 0.10.0; `@jgengine/github` unchanged at 0.1.0) and rebuild.
20
+ - Two defaults changed in the player's favor, both overridable: **offline games now persist to localStorage automatically** (#1207) and **rigged catalog assets animate by default** via clip metadata + semantic clip roles (#1209). If a game relied on rigged models staying frozen or on saves being memory-only, opt out explicitly; otherwise you get better behavior for free.
21
+
22
+ ### Added
23
+
24
+ - **Drop-in inventory grid, window manager, and character sheet** (#1220) — `@jgengine/react` ships `InventoryGrid` (real drag/stack/split), a toggleable-window system (`panels`: bag, character sheet, spellbook-style windows with `@jgengine/core/ui/panelModel` state), and a `CharacterSheet` paperdoll, all HudTheme-skinnable — wire in a line or two instead of re-deriving from raw divs.
25
+ - **Serializable runtime snapshots** (#1179) — capture/restore of live runtime state, including magazine state (`@jgengine/core/combat/magazine`) and stat modifiers, for saves and replication.
26
+ - **Portable weapon plumbing** (#1211) — `@jgengine/core/combat/weaponFire` composes trigger → magazine → spread → projectile/hitscan as data, no game-local glue.
27
+ - **Portable leveling** (#1206) and **portable damage-pool access** (#1208) — progression and damage pools exposed as genre-agnostic seams on the game context.
28
+ - **Named combat VFX presets** (#1204) — `@jgengine/core/combat/vfxPresets`: a visible attack is one line.
29
+ - **Runtime-measured render-bounds hitboxes** (#1227) — colliders wrap what the shell actually mounts, not the raw asset bounds.
30
+ - **Character motion feel** — procedural part motion for rig-less part-composed characters (#1222) plus squash & stretch and death splat (#1229).
31
+ - **City fabric** (#1191) — `streetGenerator` + `cityGenerator`, editor bake verb, street-aware lots, road junctions, grounding, and a web playground.
32
+ - **`jgengine recipe` CLI** (#1214, #1231) — vetted wired compositions, compile-pinned against the SDK, listed and copied from the CLI.
33
+ - **Editor/debug modes mirror to the URL** with a proper editor exit (#1203); game template ships a dependency-free WebGL screenshot script (#1202).
34
+
35
+ ### Changed
36
+
37
+ - Offline games persist to localStorage by default (#1207); rigged assets animate by default (#1209).
38
+ - RTS camera pan inversion fixed (#1228); sprite raycast warning silenced and duplicate nameplate health bars removed (#1194); scaffolded F2+E editor Tailwind `@source` renders its theme (#1195).
39
+ - Outside-game DX: stat-pool no-op stability, camera-transparent decor, cleaner install/version output, headless UI-intent seam (#1223); new-game briefs direct engine bugs/gaps upstream (#1200).
40
+
15
41
  ## 0.12.0
16
42
 
17
43
  ### Migrate
package/README.md CHANGED
@@ -55,7 +55,7 @@ assets pull <source-id> [--dir public] [--mirror <baseUrl>] [--offline]
55
55
  # download + extract a pack into <dir>/models|materials|sprites/<source>/
56
56
  assets register <path|url> --category <c> --license <l> [--author <a>]
57
57
  # register a one-off single into the shipped index
58
- assets reindex [public/models] # regenerate generated/*.json from pulled model packs
58
+ assets reindex [public/models] # regenerate generated/*.json (dims + animation clip names) from pulled model packs
59
59
  assets reindex-sprites [public/sprites] # regenerate generated-sprites/*.json from pulled sprite packs
60
60
  assets verify # license + alias-integrity gate
61
61
  assets provenance <id> [<id>...] # resolve each id's owner (committed/provisioned/dangling); non-zero on any dangling
@@ -34,6 +34,7 @@ export function buildCatalog(options = {}) {
34
34
  url,
35
35
  ...(entry.dims === undefined ? {} : { dims: entry.dims }),
36
36
  ...(entry.collisionMesh === undefined ? {} : { collisionMesh: entry.collisionMesh }),
37
+ ...(entry.clips === undefined ? {} : { clips: entry.clips }),
37
38
  });
38
39
  }
39
40
  if (includeSingles) {
@@ -53,6 +54,7 @@ export function buildCatalog(options = {}) {
53
54
  url: ref.url,
54
55
  ...(ref.dims === undefined ? {} : { dims: ref.dims }),
55
56
  ...(ref.collisionMesh === undefined ? {} : { collisionMesh: ref.collisionMesh }),
57
+ ...(ref.clips === undefined ? {} : { clips: ref.clips }),
56
58
  });
57
59
  }
58
60
  }
package/dist/dims.d.ts CHANGED
@@ -2,6 +2,13 @@ import type { ModelDims } from "@jgengine/core/scene/assetCatalog";
2
2
  import { type CollisionMeshData } from "@jgengine/core/scene/collisionMesh";
3
3
  export type { ModelDims };
4
4
  export declare function readGlbDims(bytes: Uint8Array): ModelDims | null;
5
+ /**
6
+ * Animation clip names read from a GLB's JSON chunk, de-duplicated and order-preserving;
7
+ * `null` for an unreadable GLB or one with no (named) animations.
8
+ *
9
+ * @capability clip-metadata read a GLB's animation clip names for the asset index at reindex
10
+ */
11
+ export declare function readGlbClips(bytes: Uint8Array): string[] | null;
5
12
  /**
6
13
  * Extract a model-space collision triangle soup from a GLB and compress it with {@link encodeCollisionMesh}.
7
14
  * Walks the default scene, transforming each TRIANGLES primitive's float32 VEC3 positions by the node's world
package/dist/dims.js CHANGED
@@ -144,6 +144,27 @@ export function readGlbDims(bytes) {
144
144
  maxY: bounds.max[1],
145
145
  };
146
146
  }
147
+ /**
148
+ * Animation clip names read from a GLB's JSON chunk, de-duplicated and order-preserving;
149
+ * `null` for an unreadable GLB or one with no (named) animations.
150
+ *
151
+ * @capability clip-metadata read a GLB's animation clip names for the asset index at reindex
152
+ */
153
+ export function readGlbClips(bytes) {
154
+ const gltf = readJsonChunk(bytes);
155
+ if (gltf === null)
156
+ return null;
157
+ const clips = [];
158
+ const seen = new Set();
159
+ for (const animation of gltf.animations ?? []) {
160
+ const name = animation.name;
161
+ if (name === undefined || name.length === 0 || seen.has(name))
162
+ continue;
163
+ seen.add(name);
164
+ clips.push(name);
165
+ }
166
+ return clips.length === 0 ? null : clips;
167
+ }
147
168
  const COMPONENT_FLOAT = 5126;
148
169
  const COMPONENT_U8 = 5121;
149
170
  const COMPONENT_U16 = 5123;
@@ -107,7 +107,85 @@
107
107
  },
108
108
  "minY": -0.000026527046429691836,
109
109
  "maxY": 2.397774257224249
110
- }
110
+ },
111
+ "clips": [
112
+ "1H_Melee_Attack_Chop",
113
+ "1H_Melee_Attack_Slice_Diagonal",
114
+ "1H_Melee_Attack_Slice_Horizontal",
115
+ "1H_Melee_Attack_Stab",
116
+ "1H_Ranged_Aiming",
117
+ "1H_Ranged_Reload",
118
+ "1H_Ranged_Shoot",
119
+ "1H_Ranged_Shooting",
120
+ "2H_Melee_Attack_Chop",
121
+ "2H_Melee_Attack_Slice",
122
+ "2H_Melee_Attack_Spin",
123
+ "2H_Melee_Attack_Spinning",
124
+ "2H_Melee_Attack_Stab",
125
+ "2H_Melee_Idle",
126
+ "2H_Ranged_Aiming",
127
+ "2H_Ranged_Reload",
128
+ "2H_Ranged_Shoot",
129
+ "2H_Ranged_Shooting",
130
+ "Block",
131
+ "Block_Attack",
132
+ "Block_Hit",
133
+ "Blocking",
134
+ "Cheer",
135
+ "Death_A",
136
+ "Death_A_Pose",
137
+ "Death_B",
138
+ "Death_B_Pose",
139
+ "Dodge_Backward",
140
+ "Dodge_Forward",
141
+ "Dodge_Left",
142
+ "Dodge_Right",
143
+ "Dualwield_Melee_Attack_Chop",
144
+ "Dualwield_Melee_Attack_Slice",
145
+ "Dualwield_Melee_Attack_Stab",
146
+ "Hit_A",
147
+ "Hit_B",
148
+ "Idle",
149
+ "Interact",
150
+ "Jump_Full_Long",
151
+ "Jump_Full_Short",
152
+ "Jump_Idle",
153
+ "Jump_Land",
154
+ "Jump_Start",
155
+ "Lie_Down",
156
+ "Lie_Idle",
157
+ "Lie_Pose",
158
+ "Lie_StandUp",
159
+ "PickUp",
160
+ "Running_A",
161
+ "Running_B",
162
+ "Running_Strafe_Left",
163
+ "Running_Strafe_Right",
164
+ "Sit_Chair_Down",
165
+ "Sit_Chair_Idle",
166
+ "Sit_Chair_Pose",
167
+ "Sit_Chair_StandUp",
168
+ "Sit_Floor_Down",
169
+ "Sit_Floor_Idle",
170
+ "Sit_Floor_Pose",
171
+ "Sit_Floor_StandUp",
172
+ "Spellcast_Long",
173
+ "Spellcast_Raise",
174
+ "Spellcast_Shoot",
175
+ "Spellcasting",
176
+ "T-Pose",
177
+ "Throw",
178
+ "Unarmed_Idle",
179
+ "Unarmed_Melee_Attack_Kick",
180
+ "Unarmed_Melee_Attack_Punch_A",
181
+ "Unarmed_Melee_Attack_Punch_B",
182
+ "Unarmed_Pose",
183
+ "Use_Item",
184
+ "Walking_A",
185
+ "Walking_B",
186
+ "Walking_Backwards",
187
+ "Walking_C"
188
+ ]
111
189
  },
112
190
  {
113
191
  "id": "kaykit-adventurers/crossbow_1handed",
@@ -195,7 +273,85 @@
195
273
  },
196
274
  "minY": -0.000026527046429691836,
197
275
  "maxY": 2.4665521719403785
198
- }
276
+ },
277
+ "clips": [
278
+ "1H_Melee_Attack_Chop",
279
+ "1H_Melee_Attack_Slice_Diagonal",
280
+ "1H_Melee_Attack_Slice_Horizontal",
281
+ "1H_Melee_Attack_Stab",
282
+ "1H_Ranged_Aiming",
283
+ "1H_Ranged_Reload",
284
+ "1H_Ranged_Shoot",
285
+ "1H_Ranged_Shooting",
286
+ "2H_Melee_Attack_Chop",
287
+ "2H_Melee_Attack_Slice",
288
+ "2H_Melee_Attack_Spin",
289
+ "2H_Melee_Attack_Spinning",
290
+ "2H_Melee_Attack_Stab",
291
+ "2H_Melee_Idle",
292
+ "2H_Ranged_Aiming",
293
+ "2H_Ranged_Reload",
294
+ "2H_Ranged_Shoot",
295
+ "2H_Ranged_Shooting",
296
+ "Block",
297
+ "Block_Attack",
298
+ "Block_Hit",
299
+ "Blocking",
300
+ "Cheer",
301
+ "Death_A",
302
+ "Death_A_Pose",
303
+ "Death_B",
304
+ "Death_B_Pose",
305
+ "Dodge_Backward",
306
+ "Dodge_Forward",
307
+ "Dodge_Left",
308
+ "Dodge_Right",
309
+ "Dualwield_Melee_Attack_Chop",
310
+ "Dualwield_Melee_Attack_Slice",
311
+ "Dualwield_Melee_Attack_Stab",
312
+ "Hit_A",
313
+ "Hit_B",
314
+ "Idle",
315
+ "Interact",
316
+ "Jump_Full_Long",
317
+ "Jump_Full_Short",
318
+ "Jump_Idle",
319
+ "Jump_Land",
320
+ "Jump_Start",
321
+ "Lie_Down",
322
+ "Lie_Idle",
323
+ "Lie_Pose",
324
+ "Lie_StandUp",
325
+ "PickUp",
326
+ "Running_A",
327
+ "Running_B",
328
+ "Running_Strafe_Left",
329
+ "Running_Strafe_Right",
330
+ "Sit_Chair_Down",
331
+ "Sit_Chair_Idle",
332
+ "Sit_Chair_Pose",
333
+ "Sit_Chair_StandUp",
334
+ "Sit_Floor_Down",
335
+ "Sit_Floor_Idle",
336
+ "Sit_Floor_Pose",
337
+ "Sit_Floor_StandUp",
338
+ "Spellcast_Long",
339
+ "Spellcast_Raise",
340
+ "Spellcast_Shoot",
341
+ "Spellcasting",
342
+ "T-Pose",
343
+ "Throw",
344
+ "Unarmed_Idle",
345
+ "Unarmed_Melee_Attack_Kick",
346
+ "Unarmed_Melee_Attack_Punch_A",
347
+ "Unarmed_Melee_Attack_Punch_B",
348
+ "Unarmed_Pose",
349
+ "Use_Item",
350
+ "Walking_A",
351
+ "Walking_B",
352
+ "Walking_Backwards",
353
+ "Walking_C"
354
+ ]
199
355
  },
200
356
  {
201
357
  "id": "kaykit-adventurers/Mage",
@@ -217,7 +373,85 @@
217
373
  },
218
374
  "minY": -0.000026527046429691836,
219
375
  "maxY": 3.0028017151609516
220
- }
376
+ },
377
+ "clips": [
378
+ "1H_Melee_Attack_Chop",
379
+ "1H_Melee_Attack_Slice_Diagonal",
380
+ "1H_Melee_Attack_Slice_Horizontal",
381
+ "1H_Melee_Attack_Stab",
382
+ "1H_Ranged_Aiming",
383
+ "1H_Ranged_Reload",
384
+ "1H_Ranged_Shoot",
385
+ "1H_Ranged_Shooting",
386
+ "2H_Melee_Attack_Chop",
387
+ "2H_Melee_Attack_Slice",
388
+ "2H_Melee_Attack_Spin",
389
+ "2H_Melee_Attack_Spinning",
390
+ "2H_Melee_Attack_Stab",
391
+ "2H_Melee_Idle",
392
+ "2H_Ranged_Aiming",
393
+ "2H_Ranged_Reload",
394
+ "2H_Ranged_Shoot",
395
+ "2H_Ranged_Shooting",
396
+ "Block",
397
+ "Block_Attack",
398
+ "Block_Hit",
399
+ "Blocking",
400
+ "Cheer",
401
+ "Death_A",
402
+ "Death_A_Pose",
403
+ "Death_B",
404
+ "Death_B_Pose",
405
+ "Dodge_Backward",
406
+ "Dodge_Forward",
407
+ "Dodge_Left",
408
+ "Dodge_Right",
409
+ "Dualwield_Melee_Attack_Chop",
410
+ "Dualwield_Melee_Attack_Slice",
411
+ "Dualwield_Melee_Attack_Stab",
412
+ "Hit_A",
413
+ "Hit_B",
414
+ "Idle",
415
+ "Interact",
416
+ "Jump_Full_Long",
417
+ "Jump_Full_Short",
418
+ "Jump_Idle",
419
+ "Jump_Land",
420
+ "Jump_Start",
421
+ "Lie_Down",
422
+ "Lie_Idle",
423
+ "Lie_Pose",
424
+ "Lie_StandUp",
425
+ "PickUp",
426
+ "Running_A",
427
+ "Running_B",
428
+ "Running_Strafe_Left",
429
+ "Running_Strafe_Right",
430
+ "Sit_Chair_Down",
431
+ "Sit_Chair_Idle",
432
+ "Sit_Chair_Pose",
433
+ "Sit_Chair_StandUp",
434
+ "Sit_Floor_Down",
435
+ "Sit_Floor_Idle",
436
+ "Sit_Floor_Pose",
437
+ "Sit_Floor_StandUp",
438
+ "Spellcast_Long",
439
+ "Spellcast_Raise",
440
+ "Spellcast_Shoot",
441
+ "Spellcasting",
442
+ "T-Pose",
443
+ "Throw",
444
+ "Unarmed_Idle",
445
+ "Unarmed_Melee_Attack_Kick",
446
+ "Unarmed_Melee_Attack_Punch_A",
447
+ "Unarmed_Melee_Attack_Punch_B",
448
+ "Unarmed_Pose",
449
+ "Use_Item",
450
+ "Walking_A",
451
+ "Walking_B",
452
+ "Walking_Backwards",
453
+ "Walking_C"
454
+ ]
221
455
  },
222
456
  {
223
457
  "id": "kaykit-adventurers/mug_empty",
@@ -305,7 +539,85 @@
305
539
  },
306
540
  "minY": -0.000026527046429691836,
307
541
  "maxY": 2.2512404918670654
308
- }
542
+ },
543
+ "clips": [
544
+ "1H_Melee_Attack_Chop",
545
+ "1H_Melee_Attack_Slice_Diagonal",
546
+ "1H_Melee_Attack_Slice_Horizontal",
547
+ "1H_Melee_Attack_Stab",
548
+ "1H_Ranged_Aiming",
549
+ "1H_Ranged_Reload",
550
+ "1H_Ranged_Shoot",
551
+ "1H_Ranged_Shooting",
552
+ "2H_Melee_Attack_Chop",
553
+ "2H_Melee_Attack_Slice",
554
+ "2H_Melee_Attack_Spin",
555
+ "2H_Melee_Attack_Spinning",
556
+ "2H_Melee_Attack_Stab",
557
+ "2H_Melee_Idle",
558
+ "2H_Ranged_Aiming",
559
+ "2H_Ranged_Reload",
560
+ "2H_Ranged_Shoot",
561
+ "2H_Ranged_Shooting",
562
+ "Block",
563
+ "Block_Attack",
564
+ "Block_Hit",
565
+ "Blocking",
566
+ "Cheer",
567
+ "Death_A",
568
+ "Death_A_Pose",
569
+ "Death_B",
570
+ "Death_B_Pose",
571
+ "Dodge_Backward",
572
+ "Dodge_Forward",
573
+ "Dodge_Left",
574
+ "Dodge_Right",
575
+ "Dualwield_Melee_Attack_Chop",
576
+ "Dualwield_Melee_Attack_Slice",
577
+ "Dualwield_Melee_Attack_Stab",
578
+ "Hit_A",
579
+ "Hit_B",
580
+ "Idle",
581
+ "Interact",
582
+ "Jump_Full_Long",
583
+ "Jump_Full_Short",
584
+ "Jump_Idle",
585
+ "Jump_Land",
586
+ "Jump_Start",
587
+ "Lie_Down",
588
+ "Lie_Idle",
589
+ "Lie_Pose",
590
+ "Lie_StandUp",
591
+ "PickUp",
592
+ "Running_A",
593
+ "Running_B",
594
+ "Running_Strafe_Left",
595
+ "Running_Strafe_Right",
596
+ "Sit_Chair_Down",
597
+ "Sit_Chair_Idle",
598
+ "Sit_Chair_Pose",
599
+ "Sit_Chair_StandUp",
600
+ "Sit_Floor_Down",
601
+ "Sit_Floor_Idle",
602
+ "Sit_Floor_Pose",
603
+ "Sit_Floor_StandUp",
604
+ "Spellcast_Long",
605
+ "Spellcast_Raise",
606
+ "Spellcast_Shoot",
607
+ "Spellcasting",
608
+ "T-Pose",
609
+ "Throw",
610
+ "Unarmed_Idle",
611
+ "Unarmed_Melee_Attack_Kick",
612
+ "Unarmed_Melee_Attack_Punch_A",
613
+ "Unarmed_Melee_Attack_Punch_B",
614
+ "Unarmed_Pose",
615
+ "Use_Item",
616
+ "Walking_A",
617
+ "Walking_B",
618
+ "Walking_Backwards",
619
+ "Walking_C"
620
+ ]
309
621
  },
310
622
  {
311
623
  "id": "kaykit-adventurers/Rogue",
@@ -327,7 +639,85 @@
327
639
  },
328
640
  "minY": -0.000026527046429691836,
329
641
  "maxY": 2.186978340148926
330
- }
642
+ },
643
+ "clips": [
644
+ "1H_Melee_Attack_Chop",
645
+ "1H_Melee_Attack_Slice_Diagonal",
646
+ "1H_Melee_Attack_Slice_Horizontal",
647
+ "1H_Melee_Attack_Stab",
648
+ "1H_Ranged_Aiming",
649
+ "1H_Ranged_Reload",
650
+ "1H_Ranged_Shoot",
651
+ "1H_Ranged_Shooting",
652
+ "2H_Melee_Attack_Chop",
653
+ "2H_Melee_Attack_Slice",
654
+ "2H_Melee_Attack_Spin",
655
+ "2H_Melee_Attack_Spinning",
656
+ "2H_Melee_Attack_Stab",
657
+ "2H_Melee_Idle",
658
+ "2H_Ranged_Aiming",
659
+ "2H_Ranged_Reload",
660
+ "2H_Ranged_Shoot",
661
+ "2H_Ranged_Shooting",
662
+ "Block",
663
+ "Block_Attack",
664
+ "Block_Hit",
665
+ "Blocking",
666
+ "Cheer",
667
+ "Death_A",
668
+ "Death_A_Pose",
669
+ "Death_B",
670
+ "Death_B_Pose",
671
+ "Dodge_Backward",
672
+ "Dodge_Forward",
673
+ "Dodge_Left",
674
+ "Dodge_Right",
675
+ "Dualwield_Melee_Attack_Chop",
676
+ "Dualwield_Melee_Attack_Slice",
677
+ "Dualwield_Melee_Attack_Stab",
678
+ "Hit_A",
679
+ "Hit_B",
680
+ "Idle",
681
+ "Interact",
682
+ "Jump_Full_Long",
683
+ "Jump_Full_Short",
684
+ "Jump_Idle",
685
+ "Jump_Land",
686
+ "Jump_Start",
687
+ "Lie_Down",
688
+ "Lie_Idle",
689
+ "Lie_Pose",
690
+ "Lie_StandUp",
691
+ "PickUp",
692
+ "Running_A",
693
+ "Running_B",
694
+ "Running_Strafe_Left",
695
+ "Running_Strafe_Right",
696
+ "Sit_Chair_Down",
697
+ "Sit_Chair_Idle",
698
+ "Sit_Chair_Pose",
699
+ "Sit_Chair_StandUp",
700
+ "Sit_Floor_Down",
701
+ "Sit_Floor_Idle",
702
+ "Sit_Floor_Pose",
703
+ "Sit_Floor_StandUp",
704
+ "Spellcast_Long",
705
+ "Spellcast_Raise",
706
+ "Spellcast_Shoot",
707
+ "Spellcasting",
708
+ "T-Pose",
709
+ "Throw",
710
+ "Unarmed_Idle",
711
+ "Unarmed_Melee_Attack_Kick",
712
+ "Unarmed_Melee_Attack_Punch_A",
713
+ "Unarmed_Melee_Attack_Punch_B",
714
+ "Unarmed_Pose",
715
+ "Use_Item",
716
+ "Walking_A",
717
+ "Walking_B",
718
+ "Walking_Backwards",
719
+ "Walking_C"
720
+ ]
331
721
  },
332
722
  {
333
723
  "id": "kaykit-adventurers/shield_badge_color",