ball2d 0.2.2 → 0.3.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 (30) hide show
  1. package/README.md +17 -23
  2. package/dist/browser.js +3046 -2306
  3. package/dist/core.wasm +0 -0
  4. package/dist/licenses/native.json +6 -0
  5. package/dist/licenses/valibot.txt +9 -0
  6. package/dist/node.js +33 -33
  7. package/dist/stadiums/asphalt.ball2dstadium +515 -0
  8. package/dist/stadiums/{big_hockey.hbs → asphalt_arena.ball2dstadium} +118 -119
  9. package/dist/stadiums/{big.hbs → big.ball2dstadium} +16 -16
  10. package/dist/stadiums/{big_easy.hbs → big_easy.ball2dstadium} +16 -16
  11. package/dist/stadiums/{big_rounded.hbs → big_rounded.ball2dstadium} +20 -20
  12. package/dist/stadiums/{classic.hbs → classic.ball2dstadium} +16 -16
  13. package/dist/stadiums/courtyard.ball2dstadium +611 -0
  14. package/dist/stadiums/{easy.hbs → easy.ball2dstadium} +16 -16
  15. package/dist/stadiums/{huge.hbs → huge.ball2dstadium} +16 -16
  16. package/dist/stadiums/meadow.ball2dstadium +611 -0
  17. package/dist/stadiums/provenance.json +36 -20
  18. package/dist/stadiums/{rounded.hbs → rounded.ball2dstadium} +20 -20
  19. package/dist/stadiums/{small.hbs → small.ball2dstadium} +16 -16
  20. package/dist/stadiums/{hockey.hbs → street_five.ball2dstadium} +82 -83
  21. package/dist/stadiums/training_green.ball2dstadium +611 -0
  22. package/dist/types/browser.d.ts +6 -0
  23. package/dist/types/config.d.ts +3 -0
  24. package/dist/types/match-state.d.ts +8 -2
  25. package/dist/types/node.d.ts +2 -2
  26. package/dist/types/player.d.ts +2 -0
  27. package/dist/types/replay.d.ts +1 -1
  28. package/dist/types/room-geo.d.ts +6 -0
  29. package/dist/types/room.d.ts +6 -4
  30. package/package.json +2 -1
@@ -0,0 +1,611 @@
1
+ {
2
+ "version": 1,
3
+ "physicsMode": "substeps",
4
+ "name": "Training Green",
5
+ "width": 435,
6
+ "height": 265,
7
+ "spawnDistance": 144,
8
+ "bg": {
9
+ "type": "grass",
10
+ "width": 360,
11
+ "height": 200,
12
+ "kickOffRadius": 65,
13
+ "color": "718C5A",
14
+ "cornerRadius": 24
15
+ },
16
+ "vertexes": [
17
+ {
18
+ "x": -336,
19
+ "y": -200,
20
+ "cMask": [
21
+ "ball"
22
+ ]
23
+ },
24
+ {
25
+ "x": 336,
26
+ "y": -200,
27
+ "cMask": [
28
+ "ball"
29
+ ]
30
+ },
31
+ {
32
+ "x": 360,
33
+ "y": -176,
34
+ "cMask": [
35
+ "ball"
36
+ ]
37
+ },
38
+ {
39
+ "x": 360,
40
+ "y": -90,
41
+ "cMask": [
42
+ "ball"
43
+ ]
44
+ },
45
+ {
46
+ "x": 360,
47
+ "y": 90,
48
+ "cMask": [
49
+ "ball"
50
+ ]
51
+ },
52
+ {
53
+ "x": 360,
54
+ "y": 176,
55
+ "cMask": [
56
+ "ball"
57
+ ]
58
+ },
59
+ {
60
+ "x": 336,
61
+ "y": 200,
62
+ "cMask": [
63
+ "ball"
64
+ ]
65
+ },
66
+ {
67
+ "x": -336,
68
+ "y": 200,
69
+ "cMask": [
70
+ "ball"
71
+ ]
72
+ },
73
+ {
74
+ "x": -360,
75
+ "y": 176,
76
+ "cMask": [
77
+ "ball"
78
+ ]
79
+ },
80
+ {
81
+ "x": -360,
82
+ "y": 90,
83
+ "cMask": [
84
+ "ball"
85
+ ]
86
+ },
87
+ {
88
+ "x": -360,
89
+ "y": -90,
90
+ "cMask": [
91
+ "ball"
92
+ ]
93
+ },
94
+ {
95
+ "x": -360,
96
+ "y": -176,
97
+ "cMask": [
98
+ "ball"
99
+ ]
100
+ },
101
+ {
102
+ "x": 336,
103
+ "y": -200,
104
+ "cMask": [
105
+ "ball"
106
+ ]
107
+ },
108
+ {
109
+ "x": 360,
110
+ "y": -176,
111
+ "cMask": [
112
+ "ball"
113
+ ]
114
+ },
115
+ {
116
+ "x": 360,
117
+ "y": 176,
118
+ "cMask": [
119
+ "ball"
120
+ ]
121
+ },
122
+ {
123
+ "x": 336,
124
+ "y": 200,
125
+ "cMask": [
126
+ "ball"
127
+ ]
128
+ },
129
+ {
130
+ "x": -336,
131
+ "y": 200,
132
+ "cMask": [
133
+ "ball"
134
+ ]
135
+ },
136
+ {
137
+ "x": -360,
138
+ "y": 176,
139
+ "cMask": [
140
+ "ball"
141
+ ]
142
+ },
143
+ {
144
+ "x": -360,
145
+ "y": -176,
146
+ "cMask": [
147
+ "ball"
148
+ ]
149
+ },
150
+ {
151
+ "x": -336,
152
+ "y": -200,
153
+ "cMask": [
154
+ "ball"
155
+ ]
156
+ },
157
+ {
158
+ "x": -360,
159
+ "y": -90,
160
+ "cMask": [
161
+ "ball"
162
+ ]
163
+ },
164
+ {
165
+ "x": -390,
166
+ "y": -90,
167
+ "cMask": [
168
+ "ball"
169
+ ]
170
+ },
171
+ {
172
+ "x": -390,
173
+ "y": -90,
174
+ "cMask": [
175
+ "ball"
176
+ ]
177
+ },
178
+ {
179
+ "x": -390,
180
+ "y": 90,
181
+ "cMask": [
182
+ "ball"
183
+ ]
184
+ },
185
+ {
186
+ "x": -390,
187
+ "y": 90,
188
+ "cMask": [
189
+ "ball"
190
+ ]
191
+ },
192
+ {
193
+ "x": -360,
194
+ "y": 90,
195
+ "cMask": [
196
+ "ball"
197
+ ]
198
+ },
199
+ {
200
+ "x": 360,
201
+ "y": -90,
202
+ "cMask": [
203
+ "ball"
204
+ ]
205
+ },
206
+ {
207
+ "x": 390,
208
+ "y": -90,
209
+ "cMask": [
210
+ "ball"
211
+ ]
212
+ },
213
+ {
214
+ "x": 390,
215
+ "y": -90,
216
+ "cMask": [
217
+ "ball"
218
+ ]
219
+ },
220
+ {
221
+ "x": 390,
222
+ "y": 90,
223
+ "cMask": [
224
+ "ball"
225
+ ]
226
+ },
227
+ {
228
+ "x": 390,
229
+ "y": 90,
230
+ "cMask": [
231
+ "ball"
232
+ ]
233
+ },
234
+ {
235
+ "x": 360,
236
+ "y": 90,
237
+ "cMask": [
238
+ "ball"
239
+ ]
240
+ },
241
+ {
242
+ "x": 0,
243
+ "y": -240,
244
+ "cGroup": [
245
+ "redKO",
246
+ "blueKO"
247
+ ],
248
+ "cMask": [
249
+ "red",
250
+ "blue"
251
+ ]
252
+ },
253
+ {
254
+ "x": 0,
255
+ "y": -65,
256
+ "cGroup": [
257
+ "redKO",
258
+ "blueKO"
259
+ ],
260
+ "cMask": [
261
+ "red",
262
+ "blue"
263
+ ]
264
+ },
265
+ {
266
+ "x": 0,
267
+ "y": 65,
268
+ "cGroup": [
269
+ "redKO",
270
+ "blueKO"
271
+ ],
272
+ "cMask": [
273
+ "red",
274
+ "blue"
275
+ ]
276
+ },
277
+ {
278
+ "x": 0,
279
+ "y": 240,
280
+ "cGroup": [
281
+ "redKO",
282
+ "blueKO"
283
+ ],
284
+ "cMask": [
285
+ "red",
286
+ "blue"
287
+ ]
288
+ }
289
+ ],
290
+ "segments": [
291
+ {
292
+ "v0": 0,
293
+ "v1": 1,
294
+ "curve": 0,
295
+ "cMask": [
296
+ "ball"
297
+ ],
298
+ "color": "FFFFFF",
299
+ "bCoef": 0.8
300
+ },
301
+ {
302
+ "v0": 2,
303
+ "v1": 3,
304
+ "curve": 0,
305
+ "cMask": [
306
+ "ball"
307
+ ],
308
+ "color": "FFFFFF",
309
+ "bCoef": 0.8
310
+ },
311
+ {
312
+ "v0": 4,
313
+ "v1": 5,
314
+ "curve": 0,
315
+ "cMask": [
316
+ "ball"
317
+ ],
318
+ "color": "FFFFFF",
319
+ "bCoef": 0.8
320
+ },
321
+ {
322
+ "v0": 6,
323
+ "v1": 7,
324
+ "curve": 0,
325
+ "cMask": [
326
+ "ball"
327
+ ],
328
+ "color": "FFFFFF",
329
+ "bCoef": 0.8
330
+ },
331
+ {
332
+ "v0": 8,
333
+ "v1": 9,
334
+ "curve": 0,
335
+ "cMask": [
336
+ "ball"
337
+ ],
338
+ "color": "FFFFFF",
339
+ "bCoef": 0.8
340
+ },
341
+ {
342
+ "v0": 10,
343
+ "v1": 11,
344
+ "curve": 0,
345
+ "cMask": [
346
+ "ball"
347
+ ],
348
+ "color": "FFFFFF",
349
+ "bCoef": 0.8
350
+ },
351
+ {
352
+ "v0": 12,
353
+ "v1": 13,
354
+ "curve": 90,
355
+ "cMask": [
356
+ "ball"
357
+ ],
358
+ "color": "FFFFFF",
359
+ "bCoef": 0.8
360
+ },
361
+ {
362
+ "v0": 14,
363
+ "v1": 15,
364
+ "curve": 90,
365
+ "cMask": [
366
+ "ball"
367
+ ],
368
+ "color": "FFFFFF",
369
+ "bCoef": 0.8
370
+ },
371
+ {
372
+ "v0": 16,
373
+ "v1": 17,
374
+ "curve": 90,
375
+ "cMask": [
376
+ "ball"
377
+ ],
378
+ "color": "FFFFFF",
379
+ "bCoef": 0.8
380
+ },
381
+ {
382
+ "v0": 18,
383
+ "v1": 19,
384
+ "curve": 90,
385
+ "cMask": [
386
+ "ball"
387
+ ],
388
+ "color": "FFFFFF",
389
+ "bCoef": 0.8
390
+ },
391
+ {
392
+ "v0": 20,
393
+ "v1": 21,
394
+ "curve": 0,
395
+ "cMask": [
396
+ "ball"
397
+ ],
398
+ "color": "DDE2E5",
399
+ "bCoef": 0.15
400
+ },
401
+ {
402
+ "v0": 22,
403
+ "v1": 23,
404
+ "curve": 0,
405
+ "cMask": [
406
+ "ball"
407
+ ],
408
+ "color": "DDE2E5",
409
+ "bCoef": 0.15
410
+ },
411
+ {
412
+ "v0": 24,
413
+ "v1": 25,
414
+ "curve": 0,
415
+ "cMask": [
416
+ "ball"
417
+ ],
418
+ "color": "DDE2E5",
419
+ "bCoef": 0.15
420
+ },
421
+ {
422
+ "v0": 26,
423
+ "v1": 27,
424
+ "curve": 0,
425
+ "cMask": [
426
+ "ball"
427
+ ],
428
+ "color": "DDE2E5",
429
+ "bCoef": 0.15
430
+ },
431
+ {
432
+ "v0": 28,
433
+ "v1": 29,
434
+ "curve": 0,
435
+ "cMask": [
436
+ "ball"
437
+ ],
438
+ "color": "DDE2E5",
439
+ "bCoef": 0.15
440
+ },
441
+ {
442
+ "v0": 30,
443
+ "v1": 31,
444
+ "curve": 0,
445
+ "cMask": [
446
+ "ball"
447
+ ],
448
+ "color": "DDE2E5",
449
+ "bCoef": 0.15
450
+ },
451
+ {
452
+ "v0": 32,
453
+ "v1": 33,
454
+ "vis": false,
455
+ "cGroup": [
456
+ "redKO",
457
+ "blueKO"
458
+ ],
459
+ "cMask": [
460
+ "red",
461
+ "blue"
462
+ ]
463
+ },
464
+ {
465
+ "v0": 34,
466
+ "v1": 35,
467
+ "vis": false,
468
+ "cGroup": [
469
+ "redKO",
470
+ "blueKO"
471
+ ],
472
+ "cMask": [
473
+ "red",
474
+ "blue"
475
+ ]
476
+ },
477
+ {
478
+ "v0": 34,
479
+ "v1": 33,
480
+ "curve": -180,
481
+ "vis": false,
482
+ "cGroup": [
483
+ "redKO"
484
+ ],
485
+ "cMask": [
486
+ "red",
487
+ "blue"
488
+ ]
489
+ },
490
+ {
491
+ "v0": 34,
492
+ "v1": 33,
493
+ "curve": 180,
494
+ "vis": false,
495
+ "cGroup": [
496
+ "blueKO"
497
+ ],
498
+ "cMask": [
499
+ "red",
500
+ "blue"
501
+ ]
502
+ }
503
+ ],
504
+ "planes": [
505
+ {
506
+ "normal": [
507
+ 0,
508
+ 1
509
+ ],
510
+ "dist": -240
511
+ },
512
+ {
513
+ "normal": [
514
+ 0,
515
+ -1
516
+ ],
517
+ "dist": -240
518
+ },
519
+ {
520
+ "normal": [
521
+ 1,
522
+ 0
523
+ ],
524
+ "dist": -410
525
+ },
526
+ {
527
+ "normal": [
528
+ -1,
529
+ 0
530
+ ],
531
+ "dist": -410
532
+ }
533
+ ],
534
+ "goals": [
535
+ {
536
+ "p0": [
537
+ -360,
538
+ -90
539
+ ],
540
+ "p1": [
541
+ -360,
542
+ 90
543
+ ],
544
+ "team": "red"
545
+ },
546
+ {
547
+ "p0": [
548
+ 360,
549
+ -90
550
+ ],
551
+ "p1": [
552
+ 360,
553
+ 90
554
+ ],
555
+ "team": "blue"
556
+ }
557
+ ],
558
+ "discs": [
559
+ {
560
+ "pos": [
561
+ -360,
562
+ -90
563
+ ],
564
+ "radius": 6,
565
+ "invMass": 0,
566
+ "color": "FFFFFF",
567
+ "bCoef": 0.5
568
+ },
569
+ {
570
+ "pos": [
571
+ -360,
572
+ 90
573
+ ],
574
+ "radius": 6,
575
+ "invMass": 0,
576
+ "color": "FFFFFF",
577
+ "bCoef": 0.5
578
+ },
579
+ {
580
+ "pos": [
581
+ 360,
582
+ -90
583
+ ],
584
+ "radius": 6,
585
+ "invMass": 0,
586
+ "color": "FFFFFF",
587
+ "bCoef": 0.5
588
+ },
589
+ {
590
+ "pos": [
591
+ 360,
592
+ 90
593
+ ],
594
+ "radius": 6,
595
+ "invMass": 0,
596
+ "color": "FFFFFF",
597
+ "bCoef": 0.5
598
+ }
599
+ ],
600
+ "ballPhysics": {
601
+ "radius": 9,
602
+ "damping": 0.991,
603
+ "bCoef": 0.6
604
+ },
605
+ "playerPhysics": {
606
+ "radius": 15,
607
+ "acceleration": 0.11,
608
+ "damping": 0.96,
609
+ "kickStrength": 5.5
610
+ }
611
+ }
@@ -5,6 +5,12 @@ import type { Replay } from './replay.js';
5
5
  import type { StadiumValidation } from './stadium.js';
6
6
  export type { RoomConfig, CreateRoomOptions, Room, Replay, StadiumValidation };
7
7
  export type { HostPlayer, HostScores, HostDiscProperties } from './player.js';
8
+ /** Room creation was rejected by the signaling service. */
9
+ export declare class RoomAdmissionError extends Error {
10
+ readonly status: number;
11
+ readonly retryAfterSeconds: number | null;
12
+ constructor(message: string, status: number, retryAfterSeconds?: number | null);
13
+ }
8
14
  export declare function createRoom(config?: RoomConfig, options?: CreateRoomOptions): Promise<Room>;
9
15
  export declare function readReplay(blob: Blob): Promise<Replay>;
10
16
  export declare function validateStadium(source: string): StadiumValidation;
@@ -1,3 +1,4 @@
1
+ import type { RoomGeo } from './room-geo.js';
1
2
  export interface RoomConfig {
2
3
  noPlayer?: boolean;
3
4
  playerName?: string;
@@ -6,4 +7,6 @@ export interface RoomConfig {
6
7
  password?: string;
7
8
  public?: boolean;
8
9
  stadium?: string;
10
+ /** Override the room's advertised location; does not select a game server. */
11
+ geo?: RoomGeo;
9
12
  }
@@ -1,6 +1,12 @@
1
+ export interface BallTouch {
2
+ slot: number;
3
+ team: 1 | 2;
4
+ }
1
5
  export interface MatchState {
2
- /** Complete terrain checkpoint. Omitted for historical or disabled surfaces. */
3
- surface?: number[];
6
+ /** Host-simulated touch; null when no player has touched this kickoff. */
7
+ lastTouch?: BallTouch | null;
8
+ /** Frozen at the goal line, including the player's team for own goals. */
9
+ goalTouch?: BallTouch | null;
4
10
  tick: number;
5
11
  elapsed: number;
6
12
  red: number;
@@ -1,10 +1,10 @@
1
1
  import type { RoomConfig } from './config.js';
2
2
  import type { Room } from './room.js';
3
3
  import type { CreateRoomOptions } from './creation.js';
4
- export { readReplay, validateStadium } from './browser.js';
4
+ export { readReplay, validateStadium, RoomAdmissionError } from './browser.js';
5
5
  export type { Replay, StadiumValidation, CreateRoomOptions, HostPlayer, HostScores, HostDiscProperties, } from './browser.js';
6
6
  export interface NodeRoomConfig extends RoomConfig {
7
- /** Ball2D signaling service. Defaults to https://ball2d.com. */
7
+ /** Ball2D signaling service. Defaults to HTTPS; HTTP permits loopback only. */
8
8
  serviceOrigin?: string;
9
9
  /** Required account-owned API key. Keep it on your server, never in browser code. */
10
10
  apiKey: string;
@@ -12,6 +12,8 @@ export interface HostPlayer {
12
12
  x: number;
13
13
  y: number;
14
14
  } | null;
15
+ /** Current authoritative key bitmask: up 1, down 2, left 4, right 8, kick 16. */
16
+ input: number;
15
17
  }
16
18
  export interface HostScores {
17
19
  red: number;
@@ -3,7 +3,7 @@ import type { TeamStyles } from './team.js';
3
3
  import type { MatchState } from './match-state.js';
4
4
  export type ReplayCommand = {
5
5
  tick: number;
6
- kind: 'input' | 'team' | 'start' | 'stop' | 'pause' | 'scoreLimit' | 'timeLimit' | 'kickRate' | 'join' | 'disc' | 'surface';
6
+ kind: 'input' | 'team' | 'start' | 'stop' | 'pause' | 'scoreLimit' | 'timeLimit' | 'kickRate' | 'join' | 'disc' | 'finishDraw';
7
7
  properties?: DiscPropertyPatch;
8
8
  slot: number;
9
9
  value: number;
@@ -0,0 +1,6 @@
1
+ /** Public discovery location; never a routing or authorization claim. */
2
+ export interface RoomGeo {
3
+ code: string;
4
+ lat: number;
5
+ lon: number;
6
+ }