@rydr/game-sdk 8.13.0 → 8.15.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.
Files changed (70) hide show
  1. package/dist/protocol/identity.d.ts +39 -0
  2. package/dist/protocol/identity.d.ts.map +1 -1
  3. package/dist/protocol/version.d.ts +1 -1
  4. package/dist/protocol/version.js +1 -1
  5. package/dist/three/README.md +132 -4
  6. package/dist/three/character/riders.d.ts.map +1 -1
  7. package/dist/three/character/riders.js.map +1 -1
  8. package/dist/three/controller/index.d.ts +2 -0
  9. package/dist/three/controller/index.d.ts.map +1 -1
  10. package/dist/three/controller/index.js +2 -0
  11. package/dist/three/controller/index.js.map +1 -1
  12. package/dist/three/controller/joycon-designs.d.ts +15 -1
  13. package/dist/three/controller/joycon-designs.d.ts.map +1 -1
  14. package/dist/three/controller/joycon-designs.js +302 -60
  15. package/dist/three/controller/joycon-designs.js.map +1 -1
  16. package/dist/three/controller/joycon-object.d.ts +216 -0
  17. package/dist/three/controller/joycon-object.d.ts.map +1 -0
  18. package/dist/three/controller/joycon-object.js +578 -0
  19. package/dist/three/controller/joycon-object.js.map +1 -0
  20. package/dist/three/controller/joycon-spec.d.ts +116 -4
  21. package/dist/three/controller/joycon-spec.d.ts.map +1 -1
  22. package/dist/three/controller/joycon-spec.js +128 -22
  23. package/dist/three/controller/joycon-spec.js.map +1 -1
  24. package/dist/three/controller/press-pulse.d.ts +89 -0
  25. package/dist/three/controller/press-pulse.d.ts.map +1 -0
  26. package/dist/three/controller/press-pulse.js +309 -0
  27. package/dist/three/controller/press-pulse.js.map +1 -0
  28. package/dist/three/controller/three-pad-renderer.d.ts +11 -22
  29. package/dist/three/controller/three-pad-renderer.d.ts.map +1 -1
  30. package/dist/three/controller/three-pad-renderer.js +44 -258
  31. package/dist/three/controller/three-pad-renderer.js.map +1 -1
  32. package/dist/three/rider/three-rider-rig.d.ts +12 -0
  33. package/dist/three/rider/three-rider-rig.d.ts.map +1 -1
  34. package/dist/three/rider/three-rider-rig.js +102 -9
  35. package/dist/three/rider/three-rider-rig.js.map +1 -1
  36. package/dist/ui/README.md +133 -7
  37. package/dist/ui/choice-card.d.ts +8 -0
  38. package/dist/ui/choice-card.d.ts.map +1 -1
  39. package/dist/ui/choice-card.js +1 -1
  40. package/dist/ui/choice-card.js.map +1 -1
  41. package/dist/ui/controller/controller-pad.d.ts +105 -2
  42. package/dist/ui/controller/controller-pad.d.ts.map +1 -1
  43. package/dist/ui/controller/controller-pad.js +347 -16
  44. package/dist/ui/controller/controller-pad.js.map +1 -1
  45. package/dist/ui/controller/renderer.d.ts +13 -0
  46. package/dist/ui/controller/renderer.d.ts.map +1 -1
  47. package/dist/ui/controller/renderer.js.map +1 -1
  48. package/dist/ui/controller/styles.js +50 -1
  49. package/dist/ui/controller/styles.js.map +1 -1
  50. package/dist/ui/dialogue-card.d.ts +8 -0
  51. package/dist/ui/dialogue-card.d.ts.map +1 -1
  52. package/dist/ui/dialogue-card.js +1 -1
  53. package/dist/ui/dialogue-card.js.map +1 -1
  54. package/dist/ui/hud-placement.d.ts +81 -0
  55. package/dist/ui/hud-placement.d.ts.map +1 -0
  56. package/dist/ui/hud-placement.js +74 -0
  57. package/dist/ui/hud-placement.js.map +1 -0
  58. package/dist/ui/index.d.ts +1 -0
  59. package/dist/ui/index.d.ts.map +1 -1
  60. package/dist/ui/index.js +1 -0
  61. package/dist/ui/index.js.map +1 -1
  62. package/dist/ui/rider-rig.d.ts +108 -10
  63. package/dist/ui/rider-rig.d.ts.map +1 -1
  64. package/dist/ui/rider-rig.js +299 -48
  65. package/dist/ui/rider-rig.js.map +1 -1
  66. package/dist/ui/solo-labeled-diamond.d.ts +13 -0
  67. package/dist/ui/solo-labeled-diamond.d.ts.map +1 -1
  68. package/dist/ui/solo-labeled-diamond.js +1 -1
  69. package/dist/ui/solo-labeled-diamond.js.map +1 -1
  70. package/package.json +4 -2
@@ -63,10 +63,75 @@ export declare const TUNING: {
63
63
  outerBottomR: number;
64
64
  innerTopR: number;
65
65
  innerBottomR: number;
66
+ /**
67
+ * ONE KNOB THAT GROWS EVERY KEY — the face diamond, the d-pad cross and `−`/`+`/Home together.
68
+ *
69
+ * The individual sizes below are what set each family's PROPORTIONS against the others; this scales
70
+ * all of them at once, so the keys can be made bigger or smaller without re-balancing four numbers
71
+ * by hand and losing the relationship between them. 1 = the sizes as written.
72
+ *
73
+ * It deliberately leaves the STICKS alone — they are sized by their well, not by the key family —
74
+ * and it leaves the RELIEF alone, so growing a key does not also make it taller. Those have their
75
+ * own knobs.
76
+ *
77
+ * The d-pad would otherwise bind almost at once — its four points nearly meet at the hub, so a key
78
+ * grown in place collides with its neighbours within a few percent. It does not, because the four
79
+ * d-pad PLACEMENTS scale with it: the cross grows as one object, about its own centre, and the hub
80
+ * gap stays proportional. See the placement loop in `joycon-designs.ts`.
81
+ */
82
+ buttonScale: number;
66
83
  /** Radii, ÷ width. */
67
84
  faceR: number;
68
- dpadR: number;
69
85
  systemR: number;
86
+ /**
87
+ * @deprecated Drives nothing since PLAT-1579 — the d-pad is no longer round.
88
+ *
89
+ * It sized the four direction pips; they are arrow keys now, cut by `dpadKeyLength` /
90
+ * `dpadKeyWidth` / `dpadKeyRound` below. Kept only because `TUNING` is exported from
91
+ * `@rydr/game-sdk/three`, so deleting a key off it would break any consumer reading this one.
92
+ * Remove it in the next deliberate breaking change.
93
+ */
94
+ dpadR: number;
95
+ /**
96
+ * The d-pad's four ARROW keys — length from base to tip, and width at the base, both ÷ shell width.
97
+ *
98
+ * These replaced a radius: the directions used to be round pips like the face diamond's, and at this
99
+ * scale the two halves read as the same control twice. An arrow says which way it points without any
100
+ * lettering, which round pips can never do.
101
+ *
102
+ * Length is what sets the gap down the middle of the cross. A key is centred on its own face
103
+ * position, so half of it reaches back towards the centre: push the length past twice the
104
+ * centre-to-centre distance and opposite keys start to overlap.
105
+ */
106
+ dpadKeyLength: number;
107
+ dpadKeyWidth: number;
108
+ /**
109
+ * Corner rounding of a d-pad key, ÷ its own width, applied to the END UNDER THE THUMB. The shoulders
110
+ * and the point take a fraction of it, so the key stays pointed where it meets the other three.
111
+ */
112
+ dpadKeyRound: number;
113
+ /**
114
+ * How much of a d-pad key's length is the POINT, 0 → 1.
115
+ *
116
+ * The key is pointed towards the centre of the cross and widens outwards into a rounded rectangle —
117
+ * the DualSense shape. This says where the point stops and the parallel sides begin: 0.45 means the
118
+ * inner 45% tapers and the outer 55% is a straight-sided end.
119
+ *
120
+ * Low values give a stubby key with a blunt nose; high values a long dart. It also sets how close
121
+ * the four can sit: the narrower a key is where they meet, the tighter the hub can be.
122
+ */
123
+ dpadKeyTaper: number;
124
+ /**
125
+ * The little arrow ENGRAVED on each d-pad key: its size, ÷ the key's width, and where it sits along
126
+ * the key, as a fraction of the key's length from the middle towards the rounded end.
127
+ *
128
+ * On the hardware this is the only mark on the cross, and it is the one that actually names the
129
+ * direction — the key's own shape says "d-pad", the engraving says "up". It rides on the broad end
130
+ * under the thumb, not in the middle, which is what `dpadGlyphNudge` is for. Set the size to 0 to
131
+ * draw no arrows at all.
132
+ */
133
+ dpadGlyphSize: number;
134
+ dpadGlyphNudge: number;
70
135
  /** How far a domed button stands proud of the face, ÷ width. */
71
136
  buttonRise: number;
72
137
  /** `−` and `+` are nearly flush. */
@@ -133,7 +198,10 @@ export declare let SILHOUETTE: {
133
198
  /** Control sizes, as fractions of the shell width — so they scale with the model. */
134
199
  export declare let SIZES: {
135
200
  faceR: number;
201
+ /** @deprecated Drives nothing — see {@link TUNING.dpadR}. */
136
202
  dpadR: number;
203
+ dpadKeyLength: number;
204
+ dpadKeyWidth: number;
137
205
  systemR: number;
138
206
  stickWellR: number;
139
207
  stickCapR: number;
@@ -165,9 +233,17 @@ export declare function faceToLocal(p: FacePos): {
165
233
  /**
166
234
  * The LEFT half's controls, normalised from `JOYCON_LAYOUT` (shell x 24→104, y 16→142).
167
235
  *
168
- * The left half is the one with the stick UP TOP and four discrete direction buttons below it — not a
169
- * cross. That is real: a Joy-Con's left half has four separate round buttons, which is why the flat
170
- * layout models them individually too.
236
+ * The left half has the stick UP TOP and the four directions below it. On the real hardware those are
237
+ * four separate ROUND buttons, not a cross — and this file used to say so and draw them that way. We
238
+ * now draw them as a PS5-style cross of arrow keys instead (PLAT-1579): a deliberate trade of hardware
239
+ * fidelity for readability, because at this size four round pips are indistinguishable from the face
240
+ * diamond opposite, and nothing about them says "direction". They are still four INDEPENDENT keys —
241
+ * only their shape changed, so every view that lights one direction on its own still works.
242
+ *
243
+ * The four positions are spaced EQUALLY IN WORLD UNITS, not in u/v. `u` is a fraction of the width and
244
+ * `v` a fraction of the height, and the shell is far taller than it is wide — so the u/v values read
245
+ * off the flat layout (which are a diamond, wider than tall) have to be un-skewed here or the cross
246
+ * comes out squashed. Hence the horizontal offsets look smaller than the vertical ones.
171
247
  */
172
248
  export declare const LEFT_FACE: Record<string, FacePos>;
173
249
  /** The RIGHT half's controls: the face diamond up top, stick below it. */
@@ -230,4 +306,40 @@ export declare const VIEW: {
230
306
  /** Yaw: a slight turn so the pair isn't perfectly symmetric and the side walls catch light. */
231
307
  yaw: number;
232
308
  };
309
+ /**
310
+ * NAMED ORIENTATIONS — the two questions a game actually asks, answered in words (PLAT-1582).
311
+ *
312
+ * Posing the pad used to mean naming a pitch in radians and knowing which way it leans. That is a
313
+ * detail of the model, not of the intent: what a game wants to say is *show the face* or *show the
314
+ * triggers*, and be given whatever angle does that.
315
+ *
316
+ * - `"front"` — head-on, no yaw. The face keys, the d-pad and both sticks read at their true relative
317
+ * sizes, which is what a diagram wants. The triggers are edge-on and effectively invisible, so this
318
+ * is the wrong view for teaching one.
319
+ * - `"angled"` — the three-quarter reading view, and the DEFAULT everywhere. A little pitch so the
320
+ * crown is legible, a little yaw so the shell has thickness. What every existing caller already got.
321
+ * - `"triggers"` — rolled well forward, looking down onto the crown. `ZL`/`ZR`/`L`/`R` are the subject;
322
+ * the face is foreshortened but still readable. Pair it with `triggerTilt: 0` — the automatic roll
323
+ * that a lit trigger provokes is there to reach this view from `"angled"`, and applying it again from
324
+ * here tips the pad past flat.
325
+ *
326
+ * Anything more specific is still a `tilt`/`yaw` away: an explicit angle always wins over a preset, so
327
+ * a view is a starting point rather than a cage.
328
+ */
329
+ export declare const PAD_VIEWS: {
330
+ readonly front: {
331
+ readonly tilt: 0;
332
+ readonly yaw: 0;
333
+ };
334
+ readonly angled: {
335
+ tilt: number;
336
+ yaw: number;
337
+ };
338
+ readonly triggers: {
339
+ readonly tilt: 0.95;
340
+ readonly yaw: 0;
341
+ };
342
+ };
343
+ /** The name of one of the {@link PAD_VIEWS}. */
344
+ export type PadViewName = keyof typeof PAD_VIEWS;
233
345
  //# sourceMappingURL=joycon-spec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"joycon-spec.d.ts","sourceRoot":"","sources":["../../../src/three/controller/joycon-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM;IAEjB;;;;;;;;OAQG;;;IAGH,mCAAmC;;IAEnC,8EAA8E;;IAE9E,8EAA8E;;;IAG9E,6CAA6C;;IAE7C,uDAAuD;;IAIvD,iGAAiG;;;;;IAOjG,sBAAsB;;;;IAItB,gEAAgE;;IAEhE,oCAAoC;;;;;IAKpC,sGAAsG;;IAEtG,iEAAiE;;IAIjE;;;;;;;;OAQG;;IAEH,qCAAqC;;IAErC,2DAA2D;;IAI3D,wFAAwF;;IAExF,4BAA4B;;CAE7B,CAAC;AAEF,mCAAmC;AACnC,eAAO,IAAI,CAAC,QAAqB,CAAC;AAGlC,mBAAmB;AACnB,eAAO,IAAI,CAAC,QAAoB,CAAC;AACjC,2DAA2D;AAC3D,eAAO,IAAI,SAAS,QAAsB,CAAC;AAC3C;;;;;;GAMG;AACH,eAAO,IAAI,YAAY,QAAyB,CAAC;AACjD,gFAAgF;AAChF,eAAO,IAAI,CAAC,QAAY,CAAC;AACzB,8BAA8B;AAC9B,eAAO,IAAI,GAAG,QAAiB,CAAC;AAChC,oCAAoC;AACpC,eAAO,IAAI,YAAY,QAAyB,CAAC;AAEjD;;;;;;GAMG;AACH,eAAO,IAAI,UAAU;;;;;CAKpB,CAAC;AAEF,qFAAqF;AACrF,eAAO,IAAI,KAAK;;;;;;;;;CASf,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAwBlC;AAED,6DAA6D;AAC7D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI1C;AAED,kFAAkF;AAClF,MAAM,WAAW,OAAO;IACtB,gEAAgE;IAChE,CAAC,EAAE,MAAM,CAAC;IACV,4CAA4C;IAC5C,CAAC,EAAE,MAAM,CAAC;CACX;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAEhE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAU7C,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAa9C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ;IACnB;;;;;;;;;;;;;OAaG;;;;;IAKH;;;;;;OAMG;;;IAGH;;;;;;OAMG;;CAEK,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,IAAI;IACf;uFACmF;oBACtE,MAAM;IAGnB,+FAA+F;;CAEhG,CAAC"}
1
+ {"version":3,"file":"joycon-spec.d.ts","sourceRoot":"","sources":["../../../src/three/controller/joycon-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM;IAEjB;;;;;;;;OAQG;;;IAGH,mCAAmC;;IAEnC,8EAA8E;;IAE9E,8EAA8E;;;IAG9E,6CAA6C;;IAE7C,uDAAuD;;IAIvD,iGAAiG;;;;;IAOjG;;;;;;;;;;;;;;;OAeG;;IAEH,sBAAsB;;;IAGtB;;;;;;;OAOG;;IAEH;;;;;;;;;;OAUG;;;IAGH;;;OAGG;;IAEH;;;;;;;;;OASG;;IAEH;;;;;;;;OAQG;;;IAGH,gEAAgE;;IAEhE,oCAAoC;;;;;IAKpC,sGAAsG;;IAEtG,iEAAiE;;IAIjE;;;;;;;;OAQG;;IAEH,qCAAqC;;IAErC,2DAA2D;;IAI3D,wFAAwF;;IAExF,4BAA4B;;CAE7B,CAAC;AAEF,mCAAmC;AACnC,eAAO,IAAI,CAAC,QAAqB,CAAC;AAGlC,mBAAmB;AACnB,eAAO,IAAI,CAAC,QAAoB,CAAC;AACjC,2DAA2D;AAC3D,eAAO,IAAI,SAAS,QAAsB,CAAC;AAC3C;;;;;;GAMG;AACH,eAAO,IAAI,YAAY,QAAyB,CAAC;AACjD,gFAAgF;AAChF,eAAO,IAAI,CAAC,QAAY,CAAC;AACzB,8BAA8B;AAC9B,eAAO,IAAI,GAAG,QAAiB,CAAC;AAChC,oCAAoC;AACpC,eAAO,IAAI,YAAY,QAAyB,CAAC;AAEjD;;;;;;GAMG;AACH,eAAO,IAAI,UAAU;;;;;CAKpB,CAAC;AAEF,qFAAqF;AACrF,eAAO,IAAI,KAAK;;IAEd,6DAA6D;;;;;;;;;;CAU9D,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,IAAI,CA2BlC;AAED,6DAA6D;AAC7D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI1C;AAED,kFAAkF;AAClF,MAAM,WAAW,OAAO;IACtB,gEAAgE;IAChE,CAAC,EAAE,MAAM,CAAC;IACV,4CAA4C;IAC5C,CAAC,EAAE,MAAM,CAAC;CACX;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAEhE;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAU7C,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAa9C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ;IACnB;;;;;;;;;;;;;OAaG;;;;;IAKH;;;;;;OAMG;;;IAGH;;;;;;OAMG;;CAEK,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,IAAI;IACf;uFACmF;oBACtE,MAAM;IAGnB,+FAA+F;;CAEhG,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,SAAS;;;;;qBAEN;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;;;;;CAIqB,CAAC;AAEnE,gDAAgD;AAChD,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,SAAS,CAAC"}
@@ -66,12 +66,77 @@ export const TUNING = {
66
66
  innerTopR: 0.09,
67
67
  innerBottomR: 0.09,
68
68
  // ── controls ──
69
+ /**
70
+ * ONE KNOB THAT GROWS EVERY KEY — the face diamond, the d-pad cross and `−`/`+`/Home together.
71
+ *
72
+ * The individual sizes below are what set each family's PROPORTIONS against the others; this scales
73
+ * all of them at once, so the keys can be made bigger or smaller without re-balancing four numbers
74
+ * by hand and losing the relationship between them. 1 = the sizes as written.
75
+ *
76
+ * It deliberately leaves the STICKS alone — they are sized by their well, not by the key family —
77
+ * and it leaves the RELIEF alone, so growing a key does not also make it taller. Those have their
78
+ * own knobs.
79
+ *
80
+ * The d-pad would otherwise bind almost at once — its four points nearly meet at the hub, so a key
81
+ * grown in place collides with its neighbours within a few percent. It does not, because the four
82
+ * d-pad PLACEMENTS scale with it: the cross grows as one object, about its own centre, and the hub
83
+ * gap stays proportional. See the placement loop in `joycon-designs.ts`.
84
+ */
85
+ buttonScale: 1,
69
86
  /** Radii, ÷ width. */
70
- faceR: 0.07,
87
+ faceR: 0.08,
88
+ systemR: 0.05,
89
+ /**
90
+ * @deprecated Drives nothing since PLAT-1579 — the d-pad is no longer round.
91
+ *
92
+ * It sized the four direction pips; they are arrow keys now, cut by `dpadKeyLength` /
93
+ * `dpadKeyWidth` / `dpadKeyRound` below. Kept only because `TUNING` is exported from
94
+ * `@rydr/game-sdk/three`, so deleting a key off it would break any consumer reading this one.
95
+ * Remove it in the next deliberate breaking change.
96
+ */
71
97
  dpadR: 0.07,
72
- systemR: 0.06,
98
+ /**
99
+ * The d-pad's four ARROW keys — length from base to tip, and width at the base, both ÷ shell width.
100
+ *
101
+ * These replaced a radius: the directions used to be round pips like the face diamond's, and at this
102
+ * scale the two halves read as the same control twice. An arrow says which way it points without any
103
+ * lettering, which round pips can never do.
104
+ *
105
+ * Length is what sets the gap down the middle of the cross. A key is centred on its own face
106
+ * position, so half of it reaches back towards the centre: push the length past twice the
107
+ * centre-to-centre distance and opposite keys start to overlap.
108
+ */
109
+ dpadKeyLength: 0.145,
110
+ dpadKeyWidth: 0.135,
111
+ /**
112
+ * Corner rounding of a d-pad key, ÷ its own width, applied to the END UNDER THE THUMB. The shoulders
113
+ * and the point take a fraction of it, so the key stays pointed where it meets the other three.
114
+ */
115
+ dpadKeyRound: 0.335,
116
+ /**
117
+ * How much of a d-pad key's length is the POINT, 0 → 1.
118
+ *
119
+ * The key is pointed towards the centre of the cross and widens outwards into a rounded rectangle —
120
+ * the DualSense shape. This says where the point stops and the parallel sides begin: 0.45 means the
121
+ * inner 45% tapers and the outer 55% is a straight-sided end.
122
+ *
123
+ * Low values give a stubby key with a blunt nose; high values a long dart. It also sets how close
124
+ * the four can sit: the narrower a key is where they meet, the tighter the hub can be.
125
+ */
126
+ dpadKeyTaper: 0.55,
127
+ /**
128
+ * The little arrow ENGRAVED on each d-pad key: its size, ÷ the key's width, and where it sits along
129
+ * the key, as a fraction of the key's length from the middle towards the rounded end.
130
+ *
131
+ * On the hardware this is the only mark on the cross, and it is the one that actually names the
132
+ * direction — the key's own shape says "d-pad", the engraving says "up". It rides on the broad end
133
+ * under the thumb, not in the middle, which is what `dpadGlyphNudge` is for. Set the size to 0 to
134
+ * draw no arrows at all.
135
+ */
136
+ dpadGlyphSize: 0.52,
137
+ dpadGlyphNudge: 0.17,
73
138
  /** How far a domed button stands proud of the face, ÷ width. */
74
- buttonRise: 0.042,
139
+ buttonRise: 0.032,
75
140
  /** `−` and `+` are nearly flush. */
76
141
  systemRise: 0.008,
77
142
  stickWellR: 0.215,
@@ -80,7 +145,7 @@ export const TUNING = {
80
145
  /** Height of the cap itself, ÷ its own radius. A real thumb cap is roughly 0.7 — it is not a disc. */
81
146
  stickCapDepth: 0.7,
82
147
  /** How deep the thumb dish sinks below the rim, ÷ cap radius. */
83
- stickCapDish: 0.26,
148
+ stickCapDish: 0.36,
84
149
  // ── shoulders ──
85
150
  /**
86
151
  * The shoulder keys are the reference model's own triangles, so their SHAPE is fixed. What is
@@ -138,9 +203,12 @@ export let SILHOUETTE = {
138
203
  };
139
204
  /** Control sizes, as fractions of the shell width — so they scale with the model. */
140
205
  export let SIZES = {
141
- faceR: W * TUNING.faceR,
206
+ faceR: W * TUNING.faceR * TUNING.buttonScale,
207
+ /** @deprecated Drives nothing — see {@link TUNING.dpadR}. */
142
208
  dpadR: W * TUNING.dpadR,
143
- systemR: W * TUNING.systemR,
209
+ dpadKeyLength: W * TUNING.dpadKeyLength * TUNING.buttonScale,
210
+ dpadKeyWidth: W * TUNING.dpadKeyWidth * TUNING.buttonScale,
211
+ systemR: W * TUNING.systemR * TUNING.buttonScale,
144
212
  stickWellR: W * TUNING.stickWellR,
145
213
  stickCapR: W * TUNING.stickCapR,
146
214
  stickHeight: W * TUNING.stickHeight,
@@ -169,9 +237,12 @@ export function applyTuning() {
169
237
  innerBottomR: W * TUNING.innerBottomR,
170
238
  };
171
239
  SIZES = {
172
- faceR: W * TUNING.faceR,
240
+ faceR: W * TUNING.faceR * TUNING.buttonScale,
241
+ /** @deprecated Drives nothing — see {@link TUNING.dpadR}. */
173
242
  dpadR: W * TUNING.dpadR,
174
- systemR: W * TUNING.systemR,
243
+ dpadKeyLength: W * TUNING.dpadKeyLength * TUNING.buttonScale,
244
+ dpadKeyWidth: W * TUNING.dpadKeyWidth * TUNING.buttonScale,
245
+ systemR: W * TUNING.systemR * TUNING.buttonScale,
175
246
  stickWellR: W * TUNING.stickWellR,
176
247
  stickCapR: W * TUNING.stickCapR,
177
248
  stickHeight: W * TUNING.stickHeight,
@@ -192,16 +263,24 @@ export function faceToLocal(p) {
192
263
  /**
193
264
  * The LEFT half's controls, normalised from `JOYCON_LAYOUT` (shell x 24→104, y 16→142).
194
265
  *
195
- * The left half is the one with the stick UP TOP and four discrete direction buttons below it — not a
196
- * cross. That is real: a Joy-Con's left half has four separate round buttons, which is why the flat
197
- * layout models them individually too.
266
+ * The left half has the stick UP TOP and the four directions below it. On the real hardware those are
267
+ * four separate ROUND buttons, not a cross — and this file used to say so and draw them that way. We
268
+ * now draw them as a PS5-style cross of arrow keys instead (PLAT-1579): a deliberate trade of hardware
269
+ * fidelity for readability, because at this size four round pips are indistinguishable from the face
270
+ * diamond opposite, and nothing about them says "direction". They are still four INDEPENDENT keys —
271
+ * only their shape changed, so every view that lights one direction on its own still works.
272
+ *
273
+ * The four positions are spaced EQUALLY IN WORLD UNITS, not in u/v. `u` is a fraction of the width and
274
+ * `v` a fraction of the height, and the shell is far taller than it is wide — so the u/v values read
275
+ * off the flat layout (which are a diamond, wider than tall) have to be un-skewed here or the cross
276
+ * comes out squashed. Hence the horizontal offsets look smaller than the vertical ones.
198
277
  */
199
278
  export const LEFT_FACE = {
200
- stick: { u: 0.568, v: 0.284 },
201
- dpadUp: { u: 0.600, v: 0.465 },
202
- dpadDown: { u: 0.600, v: 0.600 },
203
- dpadLeft: { u: 0.395, v: 0.531 },
204
- dpadRight: { u: 0.792, v: 0.531 },
279
+ stick: { u: 0.554, v: 0.32 },
280
+ dpadUp: { u: 0.558, v: 0.5558 },
281
+ dpadDown: { u: 0.558, v: 0.6968 },
282
+ dpadLeft: { u: 0.428, v: 0.6258 },
283
+ dpadRight: { u: 0.688, v: 0.6258 },
205
284
  /** `−`, top INNER corner — towards the right half. */
206
285
  select: { u: 0.79, v: 0.124 },
207
286
  /** The square capture button, bottom. */
@@ -210,17 +289,17 @@ export const LEFT_FACE = {
210
289
  /** The RIGHT half's controls: the face diamond up top, stick below it. */
211
290
  export const RIGHT_FACE = {
212
291
  /** X — top of the diamond. Glyphs are in TRUE PHYSICAL places, as on the hardware. */
213
- faceTop: { u: 0.442, v: 0.231 },
292
+ faceTop: { u: 0.4419, v: 0.2269 },
214
293
  /** A — right. */
215
- faceRight: { u: 0.633, v: 0.297 },
294
+ faceRight: { u: 0.612, v: 0.32 },
216
295
  /** B — bottom. */
217
- faceBottom: { u: 0.442, v: 0.365 },
296
+ faceBottom: { u: 0.4419, v: 0.42 },
218
297
  /** Y — left. */
219
- faceLeft: { u: 0.237, v: 0.297 },
220
- stick: { u: 0.429, v: 0.569 },
298
+ faceLeft: { u: 0.2718, v: 0.32 },
299
+ stick: { u: 0.462, v: 0.634 },
221
300
  /** `+`, top INNER corner — towards the left half. */
222
301
  start: { u: 0.21, v: 0.124 },
223
- home: { u: 0.299, v: 0.738 },
302
+ home: { u: 0.268, v: 0.846 },
224
303
  };
225
304
  /**
226
305
  * The shoulder row, on the TOP face of each half.
@@ -282,4 +361,31 @@ export const VIEW = {
282
361
  /** Yaw: a slight turn so the pair isn't perfectly symmetric and the side walls catch light. */
283
362
  yaw: -0.34,
284
363
  };
364
+ /**
365
+ * NAMED ORIENTATIONS — the two questions a game actually asks, answered in words (PLAT-1582).
366
+ *
367
+ * Posing the pad used to mean naming a pitch in radians and knowing which way it leans. That is a
368
+ * detail of the model, not of the intent: what a game wants to say is *show the face* or *show the
369
+ * triggers*, and be given whatever angle does that.
370
+ *
371
+ * - `"front"` — head-on, no yaw. The face keys, the d-pad and both sticks read at their true relative
372
+ * sizes, which is what a diagram wants. The triggers are edge-on and effectively invisible, so this
373
+ * is the wrong view for teaching one.
374
+ * - `"angled"` — the three-quarter reading view, and the DEFAULT everywhere. A little pitch so the
375
+ * crown is legible, a little yaw so the shell has thickness. What every existing caller already got.
376
+ * - `"triggers"` — rolled well forward, looking down onto the crown. `ZL`/`ZR`/`L`/`R` are the subject;
377
+ * the face is foreshortened but still readable. Pair it with `triggerTilt: 0` — the automatic roll
378
+ * that a lit trigger provokes is there to reach this view from `"angled"`, and applying it again from
379
+ * here tips the pad past flat.
380
+ *
381
+ * Anything more specific is still a `tilt`/`yaw` away: an explicit angle always wins over a preset, so
382
+ * a view is a starting point rather than a cage.
383
+ */
384
+ export const PAD_VIEWS = {
385
+ front: { tilt: 0, yaw: 0 },
386
+ get angled() {
387
+ return { tilt: VIEW.pitch, yaw: 0 };
388
+ },
389
+ triggers: { tilt: 0.95, yaw: 0 },
390
+ };
285
391
  //# sourceMappingURL=joycon-spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"joycon-spec.js","sourceRoot":"","sources":["../../../src/three/controller/joycon-spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"joycon-spec.js","sourceRoot":"","sources":["../../../src/three/controller/joycon-spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * THE PRESS PULSE — the white circle that marks the INSTANT a key goes down (PLAT-1580).
3
+ *
4
+ * The 3D pad already says a key is down twice over: it sinks along the viewing axis and it lights up.
5
+ * Neither reads. The sink is projected to almost nothing at the reading angle (the pad is tilted ~21°,
6
+ * so travel along z barely moves on screen), which leaves the colour — and a colour change is a STATE,
7
+ * not an EVENT. A tap of a few frames on a small key (the d-pad, `−`/`+`, Home) can come and go without
8
+ * the eye catching it at all.
9
+ *
10
+ * So: a circle, born on the key's own surface, that grows and fades out. The same thing a phone draws
11
+ * under a finger, and read the same way.
12
+ *
13
+ * ## Why it is drawn in the scene and not over the canvas
14
+ *
15
+ * The renderer can hand out a control's screen rectangle (`partRect`), so a DOM circle laid over the
16
+ * canvas would be a dozen lines. It would also be wrong: it would stay a perfect screen-space circle
17
+ * while the surface it claims to be on is tilted, yawed, and — for a trigger — rolling forward as it
18
+ * lights. It would read as a badge in front of the pad rather than as something ON the key. In the
19
+ * scene, the ring is a child of the pad's own group, so perspective, tilt and the trigger roll all
20
+ * apply to it for free, and the shell can occlude it.
21
+ *
22
+ * ## Not the same white as the "do this" pulse
23
+ *
24
+ * The flat pad already spends white on `hint` — *press this* — as a slow endless throb (see
25
+ * `ui/controller/styles.ts`). This one has to be unmistakably a different word: it fires ONCE, it is
26
+ * brief, and it GROWS. Nothing in the hint vocabulary grows.
27
+ */
28
+ import * as THREE from "three";
29
+ /**
30
+ * Which animation marks a press.
31
+ *
32
+ * - `"wave"` — a ring leaves the key's edge, swells to about twice its size and fades. The phone-tap
33
+ * reading; legible even on the smallest key. The default.
34
+ * - `"flash"` — a filled disc, wider than the key, closing back onto it as it fades. Quieter, and it
35
+ * never spills onto a neighbour — which matters in the four-button diamond, where they nearly touch.
36
+ * - `"sonar"` — two rings, the second ~90 ms behind, repeating slowly while the key is HELD. The most
37
+ * visible at a distance and the only one that says "still down"; also the noisiest when several keys
38
+ * fire at once, as they do in a combo.
39
+ * - `"none"` — no pulse at all.
40
+ */
41
+ export type PressPulseStyle = "wave" | "flash" | "sonar" | "none";
42
+ /**
43
+ * What a HELD key does, once its press has been marked.
44
+ *
45
+ * An axis of its own rather than a fourth style, because "how do I say a key went down" and "how do I
46
+ * say it is still down" are two questions: any of the styles above can want either answer.
47
+ *
48
+ * - `"echo"` — the same pulse again, quieter and slower (default). No new vocabulary: a held key just
49
+ * keeps saying the same word, under its breath.
50
+ * - `"collar"` — a ring that appears at the key's edge and STAYS, breathing gently until release. A
51
+ * continuous state marked by a continuous sign, with no repeated motion: the calmest option when
52
+ * several keys are held at once.
53
+ * - `"none"` — nothing. A held key is simply a key that stayed lit, and the pad goes fully idle again.
54
+ */
55
+ export type PressHoldStyle = "none" | "echo" | "collar";
56
+ /** Which way a control's working surface looks, in the pad model's own axes. */
57
+ export type PulseFacing = "front" | "up";
58
+ export interface PressPulseOptions {
59
+ /** The pad's group. Pulses are parented here so they inherit tilt, yaw and the trigger roll. */
60
+ parent: THREE.Object3D;
61
+ style: PressPulseStyle;
62
+ /** What a key does while it is HELD. */
63
+ hold: PressHoldStyle;
64
+ /** Lifetime of one pulse, ms. */
65
+ ms: number;
66
+ /** Multiplier on the pulse's radius, for dialling it in against a given design. */
67
+ scale: number;
68
+ /** World units used as the "one shell width" reference, for the lift off the surface. */
69
+ unit: number;
70
+ }
71
+ export interface PressPulses {
72
+ /** A key just went down: start a pulse on it. No-op for `"none"`. */
73
+ fire(key: string, node: THREE.Object3D, facing: PulseFacing): void;
74
+ /** A key came back up: stop whatever the hold was doing on it. */
75
+ release(key: string): void;
76
+ /** Drop everything in flight, e.g. on `clearAll()`. */
77
+ cancelAll(): void;
78
+ /** Advance to `now`. Returns true while anything is still animating — the loop's wake-up signal. */
79
+ step(now: number): boolean;
80
+ dispose(): void;
81
+ }
82
+ /**
83
+ * Build the pulse pool for one pad.
84
+ *
85
+ * Everything is allocated lazily and then RECYCLED: a combo demo loops forever, and a pad that minted a
86
+ * mesh per press would leak one every second or so.
87
+ */
88
+ export declare function createPressPulses(opts: PressPulseOptions): PressPulses;
89
+ //# sourceMappingURL=press-pulse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"press-pulse.d.ts","sourceRoot":"","sources":["../../../src/three/controller/press-pulse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAExD,gFAAgF;AAChF,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,IAAI,CAAC;AAEzC,MAAM,WAAW,iBAAiB;IAChC,gGAAgG;IAChG,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC;IACvB,KAAK,EAAE,eAAe,CAAC;IACvB,wCAAwC;IACxC,IAAI,EAAE,cAAc,CAAC;IACrB,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,yFAAyF;IACzF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACnE,kEAAkE;IAClE,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,uDAAuD;IACvD,SAAS,IAAI,IAAI,CAAC;IAClB,oGAAoG;IACpG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,OAAO,IAAI,IAAI,CAAC;CACjB;AAoED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,GAAG,WAAW,CAuPtE"}