ball2d 0.0.1 → 0.1.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 (56) hide show
  1. package/README.md +154 -5
  2. package/dist/browser.js +4051 -0
  3. package/dist/core.wasm +0 -0
  4. package/dist/licenses/fflate.txt +21 -0
  5. package/dist/licenses/json5.txt +23 -0
  6. package/dist/licenses/native.json +236 -0
  7. package/dist/licenses/werift.txt +21 -0
  8. package/dist/node.js +43399 -0
  9. package/dist/stadiums/big.hbs +85 -0
  10. package/dist/stadiums/big_easy.hbs +85 -0
  11. package/dist/stadiums/big_hockey.hbs +87 -0
  12. package/dist/stadiums/big_rounded.hbs +100 -0
  13. package/dist/stadiums/classic.hbs +85 -0
  14. package/dist/stadiums/easy.hbs +85 -0
  15. package/dist/stadiums/hockey.hbs +87 -0
  16. package/dist/stadiums/huge.hbs +85 -0
  17. package/dist/stadiums/provenance.json +46 -0
  18. package/dist/stadiums/rounded.hbs +100 -0
  19. package/dist/stadiums/small.hbs +85 -0
  20. package/dist/types/client/announcement.d.ts +10 -0
  21. package/dist/types/client/connection-stats.d.ts +11 -0
  22. package/dist/types/client/headless.d.ts +130 -0
  23. package/dist/types/client/host-config.d.ts +11 -0
  24. package/dist/types/client/host-runtime.d.ts +10 -0
  25. package/dist/types/client/network-runtime.d.ts +8 -0
  26. package/dist/types/client/network.d.ts +91 -0
  27. package/dist/types/client/stadium-library.d.ts +4 -0
  28. package/dist/types/client/startup-scope.d.ts +6 -0
  29. package/dist/types/client/traffic.d.ts +9 -0
  30. package/dist/types/core/avatar.d.ts +2 -0
  31. package/dist/types/core/build-id.d.ts +2 -0
  32. package/dist/types/core/control.d.ts +5 -0
  33. package/dist/types/core/disc-properties.d.ts +7 -0
  34. package/dist/types/core/engine.d.ts +68 -0
  35. package/dist/types/core/host-types.d.ts +21 -0
  36. package/dist/types/core/match-state.d.ts +17 -0
  37. package/dist/types/core/protocol.d.ts +24 -0
  38. package/dist/types/core/replay-codec.d.ts +6 -0
  39. package/dist/types/core/replay-types.d.ts +41 -0
  40. package/dist/types/core/replay-wire.d.ts +5 -0
  41. package/dist/types/core/replay.d.ts +48 -0
  42. package/dist/types/core/stadium.d.ts +91 -0
  43. package/dist/types/core/team-colors.d.ts +8 -0
  44. package/dist/types/sdk/browser.d.ts +11 -0
  45. package/dist/types/sdk/command-queue.d.ts +11 -0
  46. package/dist/types/sdk/config.d.ts +6 -0
  47. package/dist/types/sdk/create-options.d.ts +4 -0
  48. package/dist/types/sdk/node-transport.d.ts +4 -0
  49. package/dist/types/sdk/node.d.ts +18 -0
  50. package/dist/types/sdk/replay.d.ts +4 -0
  51. package/dist/types/sdk/room.d.ts +7 -0
  52. package/dist/types/sdk/stadium.d.ts +9 -0
  53. package/dist/types/sdk/types.d.ts +78 -0
  54. package/dist/types/shared/room-link.d.ts +6 -0
  55. package/package.json +21 -19
  56. package/index.js +0 -3
@@ -0,0 +1,85 @@
1
+ {
2
+ "name" : "Huge",
3
+
4
+ "width" : 800,
5
+ "height" : 350,
6
+
7
+ "spawnDistance" : 350,
8
+
9
+ "bg" : { "type" : "grass", "width" : 700, "height" : 320, "kickOffRadius" : 80, "cornerRadius" : 0 },
10
+
11
+ "vertexes" : [
12
+ { "x" : -700, "y" : 320, "trait" : "ballArea" },
13
+ { "x" : -700, "y" : 100, "trait" : "ballArea" },
14
+ { "x" : -700, "y" : -100, "trait" : "ballArea" },
15
+ { "x" : -700, "y" : -320, "trait" : "ballArea" },
16
+
17
+ { "x" : 700, "y" : 320, "trait" : "ballArea" },
18
+ { "x" : 700, "y" : 100, "trait" : "ballArea" },
19
+ { "x" : 700, "y" : -100, "trait" : "ballArea" },
20
+ { "x" : 700, "y" : -320, "trait" : "ballArea" },
21
+
22
+ { "x" : 0, "y" : 350, "trait" : "kickOffBarrier" },
23
+ { "x" : 0, "y" : 80, "trait" : "kickOffBarrier" },
24
+ { "x" : 0, "y" : -80, "trait" : "kickOffBarrier" },
25
+ { "x" : 0, "y" : -350, "trait" : "kickOffBarrier" },
26
+
27
+ { "x" : -710, "y" : -100, "trait" : "goalNet" },
28
+ { "x" : -730, "y" : -80, "trait" : "goalNet" },
29
+ { "x" : -730, "y" : 80, "trait" : "goalNet" },
30
+ { "x" : -710, "y" : 100, "trait" : "goalNet" },
31
+
32
+ { "x" : 710, "y" : -100, "trait" : "goalNet" },
33
+ { "x" : 730, "y" : -80, "trait" : "goalNet" },
34
+ { "x" : 730, "y" : 80, "trait" : "goalNet" },
35
+ { "x" : 710, "y" : 100, "trait" : "goalNet" }
36
+ ],
37
+
38
+ "segments" : [
39
+ { "v0" : 0, "v1" : 1, "trait" : "ballArea" },
40
+ { "v0" : 2, "v1" : 3, "trait" : "ballArea" },
41
+ { "v0" : 4, "v1" : 5, "trait" : "ballArea" },
42
+ { "v0" : 6, "v1" : 7, "trait" : "ballArea" },
43
+
44
+ { "v0" : 12, "v1" : 13, "trait" : "goalNet", "curve" : -90 },
45
+ { "v0" : 13, "v1" : 14, "trait" : "goalNet" },
46
+ { "v0" : 14, "v1" : 15, "trait" : "goalNet", "curve" : -90 },
47
+
48
+ { "v0" : 16, "v1" : 17, "trait" : "goalNet", "curve" : 90 },
49
+ { "v0" : 17, "v1" : 18, "trait" : "goalNet" },
50
+ { "v0" : 18, "v1" : 19, "trait" : "goalNet", "curve" : 90 },
51
+
52
+ { "v0" : 8, "v1" : 9, "trait" : "kickOffBarrier" },
53
+ { "v0" : 9, "v1" : 10, "trait" : "kickOffBarrier", "curve" : 180, "cGroup" : ["blueKO"] },
54
+ { "v0" : 9, "v1" : 10, "trait" : "kickOffBarrier", "curve" : -180, "cGroup" : ["redKO"] },
55
+ { "v0" : 10, "v1" : 11, "trait" : "kickOffBarrier" }
56
+ ],
57
+
58
+ "goals" : [
59
+ { "p0" : [-700, 100], "p1" : [-700,-100], "team" : "red" },
60
+ { "p0" : [700, 100], "p1" : [700,-100], "team" : "blue" }
61
+ ],
62
+
63
+ "discs" : [
64
+ { "pos" : [-700, 100], "trait" : "goalPost", "color" : "FFCCCC" },
65
+ { "pos" : [-700, -100], "trait" : "goalPost", "color" : "FFCCCC" },
66
+ { "pos" : [ 700, 100], "trait" : "goalPost", "color" : "CCCCFF" },
67
+ { "pos" : [ 700, -100], "trait" : "goalPost", "color" : "CCCCFF" }
68
+ ],
69
+
70
+ "planes" : [
71
+ { "normal" : [0, 1], "dist" : -320, "trait" : "ballArea" },
72
+ { "normal" : [0,-1], "dist" : -320, "trait" : "ballArea" },
73
+ { "normal" : [ 0, 1], "dist" : -350, "bCoef" : 0.1 },
74
+ { "normal" : [ 0,-1], "dist" : -350, "bCoef" : 0.1 },
75
+ { "normal" : [ 1, 0], "dist" : -800, "bCoef" : 0.1 },
76
+ { "normal" : [-1, 0], "dist" : -800, "bCoef" : 0.1 }
77
+ ],
78
+
79
+ "traits" : {
80
+ "ballArea" : { "vis" : false, "bCoef" : 1, "cMask" : ["ball"] },
81
+ "goalPost" : { "radius" : 8, "invMass" : 0, "bCoef" : 0.5 },
82
+ "goalNet" : { "vis" : true, "bCoef" : 0.1, "cMask" : ["ball"] },
83
+ "kickOffBarrier" : { "vis" : false, "bCoef" : 0.1, "cGroup" : ["redKO", "blueKO"], "cMask" : ["red", "blue"] }
84
+ }
85
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "source": "https://github.com/haxball/haxball-issues/tree/master/stadiums",
3
+ "commit": "d3154004b7ef1c41788dde754d8b6bbf38a0a091",
4
+ "files": [
5
+ {
6
+ "file": "big.hbs",
7
+ "sha256": "0b325750b6c21677c8a7d3a5d7b17466a4f7c6cceeb43748a79fbaf224cf751c"
8
+ },
9
+ {
10
+ "file": "big_easy.hbs",
11
+ "sha256": "8cc9b06cf10d114c1285790ad7fc77dda37fbcec21f6cca3d0ca2d4040443d03"
12
+ },
13
+ {
14
+ "file": "big_hockey.hbs",
15
+ "sha256": "bc008f5bac3b3f39084d12b53b07c54a28df8032c765da23b5c08c0acc53319c"
16
+ },
17
+ {
18
+ "file": "big_rounded.hbs",
19
+ "sha256": "55d967ceb06d6774bc0be30b22af283b0fe0d690bcc8b9052c5555a19d27ec70"
20
+ },
21
+ {
22
+ "file": "classic.hbs",
23
+ "sha256": "e37799568e4fbdc04f64bcebc8b62825d426bf418ca1e0274f26d6aac204c3c8"
24
+ },
25
+ {
26
+ "file": "easy.hbs",
27
+ "sha256": "60fcc0863d68b847dd0fcb8037aa9f0d78451683591a72dfae6a6190dce13cd8"
28
+ },
29
+ {
30
+ "file": "hockey.hbs",
31
+ "sha256": "4e040662c3da6e1afa42cab93ffe8985497dabc1512ed81643b3ac157564713e"
32
+ },
33
+ {
34
+ "file": "huge.hbs",
35
+ "sha256": "704eb73b2e198e792a04badbf1f97212d361e184481d676d092b5181733c62c9"
36
+ },
37
+ {
38
+ "file": "rounded.hbs",
39
+ "sha256": "287cef71daac552256b06a29c103aedb9ce26177bf85b9bab00da13e0b3cfcd2"
40
+ },
41
+ {
42
+ "file": "small.hbs",
43
+ "sha256": "757a35605d65a2f610992bd8c87e2b6396845e4f8996786bccd29661b025fb13"
44
+ }
45
+ ]
46
+ }
@@ -0,0 +1,100 @@
1
+ {
2
+ "name" : "Rounded",
3
+
4
+ "width" : 420,
5
+ "height" : 200,
6
+
7
+ "spawnDistance" : 170,
8
+
9
+ "bg" : { "type" : "grass", "width" : 370, "height" : 170, "kickOffRadius" : 75, "cornerRadius" : 75 },
10
+
11
+ "vertexes" : [
12
+ { "x" : -370, "y" : 170, "trait" : "ballArea" },
13
+ { "x" : -370, "y" : 64, "trait" : "ballArea" },
14
+ { "x" : -370, "y" : -64, "trait" : "ballArea" },
15
+ { "x" : -370, "y" : -170, "trait" : "ballArea" },
16
+
17
+ { "x" : 370, "y" : 170, "trait" : "ballArea" },
18
+ { "x" : 370, "y" : 64, "trait" : "ballArea" },
19
+ { "x" : 370, "y" : -64, "trait" : "ballArea" },
20
+ { "x" : 370, "y" : -170, "trait" : "ballArea" },
21
+
22
+ { "x" : 0, "y" : 200, "trait" : "kickOffBarrier" },
23
+ { "x" : 0, "y" : 75, "trait" : "kickOffBarrier" },
24
+ { "x" : 0, "y" : -75, "trait" : "kickOffBarrier" },
25
+ { "x" : 0, "y" : -200, "trait" : "kickOffBarrier" },
26
+
27
+ { "x" : -380, "y" : -64, "trait" : "goalNet" },
28
+ { "x" : -400, "y" : -44, "trait" : "goalNet" },
29
+ { "x" : -400, "y" : 44, "trait" : "goalNet" },
30
+ { "x" : -380, "y" : 64, "trait" : "goalNet" },
31
+
32
+ { "x" : 380, "y" : -64, "trait" : "goalNet" },
33
+ { "x" : 400, "y" : -44, "trait" : "goalNet" },
34
+ { "x" : 400, "y" : 44, "trait" : "goalNet" },
35
+ { "x" : 380, "y" : 64, "trait" : "goalNet" },
36
+
37
+ { "x" : -295, "y" : -170, "trait" : "ballArea" },
38
+ { "x" : -370, "y" : -95, "trait" : "ballArea" },
39
+ { "x" : -370, "y" : 95, "trait" : "ballArea" },
40
+ { "x" : -295, "y" : 170, "trait" : "ballArea" },
41
+
42
+ { "x" : 295, "y" : -170, "trait" : "ballArea" },
43
+ { "x" : 370, "y" : -95, "trait" : "ballArea" },
44
+ { "x" : 370, "y" : 95, "trait" : "ballArea" },
45
+ { "x" : 295, "y" : 170, "trait" : "ballArea" }
46
+ ],
47
+
48
+ "segments" : [
49
+ { "v0" : 0, "v1" : 1, "trait" : "ballArea" },
50
+ { "v0" : 2, "v1" : 3, "trait" : "ballArea" },
51
+ { "v0" : 4, "v1" : 5, "trait" : "ballArea" },
52
+ { "v0" : 6, "v1" : 7, "trait" : "ballArea" },
53
+
54
+ { "v0" : 12, "v1" : 13, "trait" : "goalNet", "curve" : -90 },
55
+ { "v0" : 13, "v1" : 14, "trait" : "goalNet" },
56
+ { "v0" : 14, "v1" : 15, "trait" : "goalNet", "curve" : -90 },
57
+
58
+ { "v0" : 16, "v1" : 17, "trait" : "goalNet", "curve" : 90 },
59
+ { "v0" : 17, "v1" : 18, "trait" : "goalNet" },
60
+ { "v0" : 18, "v1" : 19, "trait" : "goalNet", "curve" : 90 },
61
+
62
+ { "v0" : 8, "v1" : 9, "trait" : "kickOffBarrier" },
63
+ { "v0" : 9, "v1" : 10, "trait" : "kickOffBarrier", "curve" : 180, "cGroup" : ["blueKO"] },
64
+ { "v0" : 9, "v1" : 10, "trait" : "kickOffBarrier", "curve" : -180, "cGroup" : ["redKO"] },
65
+ { "v0" : 10, "v1" : 11, "trait" : "kickOffBarrier" },
66
+
67
+ { "v0" : 20, "v1" : 21, "trait" : "ballArea", "curve" : -90 },
68
+ { "v0" : 22, "v1" : 23, "trait" : "ballArea", "curve" : -90 },
69
+ { "v0" : 24, "v1" : 25, "trait" : "ballArea", "curve" : 90 },
70
+ { "v0" : 26, "v1" : 27, "trait" : "ballArea", "curve" : 90 }
71
+ ],
72
+
73
+ "goals" : [
74
+ { "p0" : [-370, 64], "p1" : [-370,-64], "team" : "red" },
75
+ { "p0" : [370, 64], "p1" : [370,-64], "team" : "blue" }
76
+ ],
77
+
78
+ "discs" : [
79
+ { "pos" : [-370, 64], "trait" : "goalPost", "color" : "FFCCCC" },
80
+ { "pos" : [-370, -64], "trait" : "goalPost", "color" : "FFCCCC" },
81
+ { "pos" : [ 370, 64], "trait" : "goalPost", "color" : "CCCCFF" },
82
+ { "pos" : [ 370, -64], "trait" : "goalPost", "color" : "CCCCFF" }
83
+ ],
84
+
85
+ "planes" : [
86
+ { "normal" : [0, 1], "dist" : -170, "trait" : "ballArea" },
87
+ { "normal" : [0,-1], "dist" : -170, "trait" : "ballArea" },
88
+ { "normal" : [ 0, 1], "dist" : -200, "bCoef" : 0.1 },
89
+ { "normal" : [ 0,-1], "dist" : -200, "bCoef" : 0.1 },
90
+ { "normal" : [ 1, 0], "dist" : -420, "bCoef" : 0.1 },
91
+ { "normal" : [-1, 0], "dist" : -420, "bCoef" : 0.1 }
92
+ ],
93
+
94
+ "traits" : {
95
+ "ballArea" : { "vis" : false, "bCoef" : 1, "cMask" : ["ball"] },
96
+ "goalPost" : { "radius" : 8, "invMass" : 0, "bCoef" : 0.5 },
97
+ "goalNet" : { "vis" : true, "bCoef" : 0.1, "cMask" : ["ball"] },
98
+ "kickOffBarrier" : { "vis" : false, "bCoef" : 0.1, "cGroup" : ["redKO", "blueKO"], "cMask" : ["red", "blue"] }
99
+ }
100
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "name" : "Small",
3
+
4
+ "width" : 420,
5
+ "height" : 200,
6
+
7
+ "spawnDistance" : 130,
8
+
9
+ "bg" : { "type" : "grass", "width" : 320, "height" : 130, "kickOffRadius" : 70, "cornerRadius" : 0 },
10
+
11
+ "vertexes" : [
12
+ { "x" : -320, "y" : 130, "trait" : "ballArea" },
13
+ { "x" : -320, "y" : 55, "trait" : "ballArea" },
14
+ { "x" : -320, "y" : -55, "trait" : "ballArea" },
15
+ { "x" : -320, "y" : -130, "trait" : "ballArea" },
16
+
17
+ { "x" : 320, "y" : 130, "trait" : "ballArea" },
18
+ { "x" : 320, "y" : 55, "trait" : "ballArea" },
19
+ { "x" : 320, "y" : -55, "trait" : "ballArea" },
20
+ { "x" : 320, "y" : -130, "trait" : "ballArea" },
21
+
22
+ { "x" : 0, "y" : 200, "trait" : "kickOffBarrier" },
23
+ { "x" : 0, "y" : 70, "trait" : "kickOffBarrier" },
24
+ { "x" : 0, "y" : -70, "trait" : "kickOffBarrier" },
25
+ { "x" : 0, "y" : -200, "trait" : "kickOffBarrier" },
26
+
27
+ { "x" : -330, "y" : -55, "trait" : "goalNet" },
28
+ { "x" : -350, "y" : -35, "trait" : "goalNet" },
29
+ { "x" : -350, "y" : 35, "trait" : "goalNet" },
30
+ { "x" : -330, "y" : 55, "trait" : "goalNet" },
31
+
32
+ { "x" : 330, "y" : -55, "trait" : "goalNet" },
33
+ { "x" : 350, "y" : -35, "trait" : "goalNet" },
34
+ { "x" : 350, "y" : 35, "trait" : "goalNet" },
35
+ { "x" : 330, "y" : 55, "trait" : "goalNet" }
36
+ ],
37
+
38
+ "segments" : [
39
+ { "v0" : 0, "v1" : 1, "trait" : "ballArea" },
40
+ { "v0" : 2, "v1" : 3, "trait" : "ballArea" },
41
+ { "v0" : 4, "v1" : 5, "trait" : "ballArea" },
42
+ { "v0" : 6, "v1" : 7, "trait" : "ballArea" },
43
+
44
+ { "v0" : 12, "v1" : 13, "trait" : "goalNet", "curve" : -90 },
45
+ { "v0" : 13, "v1" : 14, "trait" : "goalNet" },
46
+ { "v0" : 14, "v1" : 15, "trait" : "goalNet", "curve" : -90 },
47
+
48
+ { "v0" : 16, "v1" : 17, "trait" : "goalNet", "curve" : 90 },
49
+ { "v0" : 17, "v1" : 18, "trait" : "goalNet" },
50
+ { "v0" : 18, "v1" : 19, "trait" : "goalNet", "curve" : 90 },
51
+
52
+ { "v0" : 8, "v1" : 9, "trait" : "kickOffBarrier" },
53
+ { "v0" : 9, "v1" : 10, "trait" : "kickOffBarrier", "curve" : 180, "cGroup" : ["blueKO"] },
54
+ { "v0" : 9, "v1" : 10, "trait" : "kickOffBarrier", "curve" : -180, "cGroup" : ["redKO"] },
55
+ { "v0" : 10, "v1" : 11, "trait" : "kickOffBarrier" }
56
+ ],
57
+
58
+ "goals" : [
59
+ { "p0" : [-320, 55], "p1" : [-320,-55], "team" : "red" },
60
+ { "p0" : [320, 55], "p1" : [320,-55], "team" : "blue" }
61
+ ],
62
+
63
+ "discs" : [
64
+ { "pos" : [-320, 55], "trait" : "goalPost", "color" : "FFCCCC" },
65
+ { "pos" : [-320, -55], "trait" : "goalPost", "color" : "FFCCCC" },
66
+ { "pos" : [ 320, 55], "trait" : "goalPost", "color" : "CCCCFF" },
67
+ { "pos" : [ 320, -55], "trait" : "goalPost", "color" : "CCCCFF" }
68
+ ],
69
+
70
+ "planes" : [
71
+ { "normal" : [0, 1], "dist" : -130, "trait" : "ballArea" },
72
+ { "normal" : [0,-1], "dist" : -130, "trait" : "ballArea" },
73
+ { "normal" : [ 0, 1], "dist" : -200, "bCoef" : 0.1 },
74
+ { "normal" : [ 0,-1], "dist" : -200, "bCoef" : 0.1 },
75
+ { "normal" : [ 1, 0], "dist" : -420, "bCoef" : 0.1 },
76
+ { "normal" : [-1, 0], "dist" : -420, "bCoef" : 0.1 }
77
+ ],
78
+
79
+ "traits" : {
80
+ "ballArea" : { "vis" : false, "bCoef" : 1, "cMask" : ["ball"] },
81
+ "goalPost" : { "radius" : 8, "invMass" : 0, "bCoef" : 0.5 },
82
+ "goalNet" : { "vis" : true, "bCoef" : 0.1, "cMask" : ["ball"] },
83
+ "kickOffBarrier" : { "vis" : false, "bCoef" : 0.1, "cGroup" : ["redKO", "blueKO"], "cMask" : ["red", "blue"] }
84
+ }
85
+ }
@@ -0,0 +1,10 @@
1
+ export declare const announcementStyles: readonly ['normal', 'bold', 'italic', 'small', 'small-bold', 'small-italic'];
2
+ export type AnnouncementStyle = (typeof announcementStyles)[number];
3
+ export interface Announcement {
4
+ type: 'announcement';
5
+ text: string;
6
+ color: number | null;
7
+ style: AnnouncementStyle;
8
+ sound: 0 | 1 | 2;
9
+ }
10
+ export declare function announcement(text: string, color?: number | null, style?: AnnouncementStyle | null, sound?: number | null): Announcement;
@@ -0,0 +1,11 @@
1
+ interface StatsRow {
2
+ id: string;
3
+ type: string;
4
+ selectedCandidatePairId?: string;
5
+ state?: string;
6
+ nominated?: boolean;
7
+ currentRoundTripTime?: number;
8
+ }
9
+ /** Selected ICE path RTT from STUN checks; not input-to-display latency. */
10
+ export declare function selectedRtt(rows: Iterable<StatsRow>): number | null;
11
+ export {};
@@ -0,0 +1,130 @@
1
+ import { type HostConfig } from './host-config.js';
2
+ import { type AnnouncementStyle } from './announcement.js';
3
+ import { type DiscPropertyPatch } from '../core/disc-properties.js';
4
+ import { type HostRuntime } from './host-runtime.js';
5
+ import { Engine, type MatchState } from '../core/engine.js';
6
+ import { Network } from './network.js';
7
+ import type { HostPlayer, HostScores, HostDiscProperties } from '../core/host-types.js';
8
+ export type { HostPlayer, HostScores, HostDiscProperties } from '../core/host-types.js';
9
+ export type { HostConfig } from './host-config.js';
10
+ /** Shared headless room implementation; browser runtime is the current default. */
11
+ export declare class HeadlessRoom {
12
+ private readonly runtime;
13
+ readonly engine: Engine;
14
+ network: Network;
15
+ roomId: string;
16
+ roomLink: string;
17
+ roomName: string;
18
+ private epoch;
19
+ private stadiumSelection;
20
+ private players;
21
+ private nextPlayerId;
22
+ private bans;
23
+ private loop?;
24
+ private linkNotification?;
25
+ private last;
26
+ private accumulator;
27
+ private recorder?;
28
+ private closed;
29
+ private readonly closeController;
30
+ readonly signal: AbortSignal;
31
+ private finishingRecording;
32
+ lastRecording: Blob | null;
33
+ onRecordingComplete?: (blob: Blob, reason: string) => void;
34
+ private locked;
35
+ private teamStyles;
36
+ private inputs;
37
+ private traffic;
38
+ onRoomLink?: (url: string) => void;
39
+ onPlayerJoin?: (p: HostPlayer) => void;
40
+ onPlayerTeamChange?: (p: HostPlayer, byPlayer: HostPlayer | null) => void;
41
+ onPlayerAdminChange?: (p: HostPlayer, byPlayer: HostPlayer | null) => void;
42
+ onGameStart?: (byPlayer: HostPlayer | null) => void;
43
+ onGameStop?: (byPlayer: HostPlayer | null) => void;
44
+ onTeamVictory?: (scores: HostScores) => void;
45
+ /** Legacy Ball2D callback; prefer onTeamVictory. */
46
+ onGameVictory?: (scores: HostScores) => void;
47
+ onGamePauseChange?: (paused: boolean) => void;
48
+ onGamePause?: (byPlayer: HostPlayer | null) => void;
49
+ onGameUnpause?: (byPlayer: HostPlayer | null) => void;
50
+ onPlayerLeave?: (p: HostPlayer) => void;
51
+ onPlayerKicked?: (p: HostPlayer, reason: string, ban: boolean, byPlayer: HostPlayer | null) => void;
52
+ onPlayerActivity?: (p: HostPlayer) => void;
53
+ onPlayerChat?: (p: HostPlayer, text: string) => boolean | void;
54
+ onPlayerBallKick?: (p: HostPlayer) => void;
55
+ onTeamGoal?: (team: 1 | 2) => void;
56
+ onPositionsReset?: () => void;
57
+ onStadiumChange?: (name: string, byPlayer: HostPlayer | null) => void;
58
+ onTeamsLockChange?: (locked: boolean, byPlayer: HostPlayer | null) => void;
59
+ onKickRateLimitSet?: (min: number, rate: number, burst: number, byPlayer: HostPlayer | null) => void;
60
+ onGameTick?: () => void;
61
+ onError?: (message: string) => void;
62
+ private report;
63
+ private invoke;
64
+ private constructor();
65
+ static create(config: HostConfig, runtime?: HostRuntime, signal?: AbortSignal): Promise<HeadlessRoom>;
66
+ private advance;
67
+ private allowed;
68
+ private control;
69
+ private fast;
70
+ private command;
71
+ private roster;
72
+ private sync;
73
+ private state;
74
+ private leave;
75
+ private playerCopy;
76
+ getPlayerList(): HostPlayer[];
77
+ getPlayer(id: number): HostPlayer | null;
78
+ setTeamColors(team: number, angle: number, textColor: number, colors: number[]): void;
79
+ private changeTeamColors;
80
+ reorderPlayers(playerIdList: number[], moveToTop: boolean): void;
81
+ setPlayerAvatar(id: number, avatar: string | null): void;
82
+ setPlayerTeam(id: number, team: 0 | 1 | 2): void;
83
+ private changeTeam;
84
+ setPlayerAdmin(id: number, admin: boolean): void;
85
+ setTeamsLock(locked: boolean): void;
86
+ private changeTeamsLock;
87
+ kickPlayer(id: number, reason?: string, ban?: boolean): void | Promise<void>;
88
+ private banPlayer;
89
+ clearBan(id: number): Promise<void>;
90
+ clearBans(): Promise<void>;
91
+ private removePlayer;
92
+ sendChat(text: string, targetId?: number | null): void;
93
+ sendAnnouncement(text: string, targetId?: number | null, color?: number | null, style?: AnnouncementStyle | null, sound?: number | null): void;
94
+ startGame(): void;
95
+ private beginGame;
96
+ stopGame(): void;
97
+ private endGame;
98
+ pauseGame(paused: boolean): void;
99
+ private changePause;
100
+ setKickRateLimit(min?: number, rate?: number, burst?: number): void;
101
+ private changeKickRateLimit;
102
+ setPassword(password: string | null): Promise<void>;
103
+ get requireVerification(): boolean | null;
104
+ setRequireVerification(required: boolean): Promise<void>;
105
+ /** Migration alias: Ball2D uses Turnstile, not Google's reCAPTCHA. */
106
+ setRequireRecaptcha(required: boolean): Promise<void>;
107
+ setScoreLimit(limit: number): void;
108
+ setTimeLimit(minutes: number): void;
109
+ setDefaultStadium(name: string): Promise<void>;
110
+ setCustomStadium(source: string): void;
111
+ private changeStadium;
112
+ getScores(): HostScores | null;
113
+ getBallPosition(): {
114
+ x: number;
115
+ y: number;
116
+ } | null;
117
+ private readDisc;
118
+ get CollisionFlags(): Readonly<Record<string, number>>;
119
+ getDiscCount(): number;
120
+ getDiscProperties(discIndex: number): HostDiscProperties | null;
121
+ setDiscProperties(discIndex: number, properties: DiscPropertyPatch): void;
122
+ setPlayerDiscProperties(playerId: number, properties: DiscPropertyPatch): void;
123
+ private changeDisc;
124
+ getPlayerDiscProperties(playerId: number): HostDiscProperties | null;
125
+ getState(): MatchState;
126
+ startRecording(): void;
127
+ private finishRecording;
128
+ stopRecording(): Blob | null;
129
+ close(): void;
130
+ }
@@ -0,0 +1,11 @@
1
+ export interface HostConfig {
2
+ noPlayer?: boolean;
3
+ playerName?: string;
4
+ roomName: string;
5
+ maxPlayers?: number;
6
+ password?: string;
7
+ public?: boolean;
8
+ stadium?: string;
9
+ }
10
+ /** Validate before allocating an engine or making an admission request. */
11
+ export declare function hostConfig(input: unknown): HostConfig;
@@ -0,0 +1,10 @@
1
+ import { Engine } from '../core/engine.js';
2
+ import { type NetworkRuntime } from './network-runtime.js';
3
+ /** Internal boundary shared by the browser host and future native SDK adapter. */
4
+ export interface HostRuntime {
5
+ readonly network: NetworkRuntime;
6
+ readonly request: (url: URL, init?: RequestInit) => Promise<Response>;
7
+ readonly loadEngine: (signal: AbortSignal) => Promise<Engine>;
8
+ readonly loadStadium: (name: string) => Promise<string>;
9
+ }
10
+ export declare function browserHostRuntime(): HostRuntime;
@@ -0,0 +1,8 @@
1
+ /** Internal transport boundary. Adapters must preserve browser channel/recovery semantics. */
2
+ export interface NetworkRuntime {
3
+ readonly serviceOrigin: string;
4
+ readonly createWebSocket: (url: URL) => WebSocket;
5
+ readonly createPeerConnection: (config: RTCConfiguration) => RTCPeerConnection;
6
+ }
7
+ export declare function serviceOrigin(value: string): string;
8
+ export declare function browserNetworkRuntime(): NetworkRuntime;
@@ -0,0 +1,91 @@
1
+ import { type NetworkRuntime } from './network-runtime.js';
2
+ /** The service may have committed the operation before confirmation was lost. */
3
+ export declare class UnconfirmedBanError extends Error {
4
+ }
5
+ export interface Peer {
6
+ id: string;
7
+ pc: RTCPeerConnection;
8
+ control?: RTCDataChannel;
9
+ fast?: RTCDataChannel;
10
+ connected: boolean;
11
+ rtt?: number | null;
12
+ admissionTimer?: ReturnType<typeof setTimeout>;
13
+ created: number;
14
+ candidates: RTCIceCandidateInit[];
15
+ lostAt?: number;
16
+ lastRestart: number;
17
+ restarts: number;
18
+ restarting: boolean;
19
+ }
20
+ export interface Hooks {
21
+ verify?: (challenge: {
22
+ siteKey: string;
23
+ roomId: string;
24
+ }, signal: AbortSignal) => Promise<string>;
25
+ allowStadiumUpload?: (peer: Peer) => boolean;
26
+ ready: (id: string, host: boolean) => void;
27
+ open: (peer: Peer) => void;
28
+ control: (peer: Peer, msg: unknown) => void;
29
+ fast: (peer: Peer, data: ArrayBuffer) => void;
30
+ leave: (id: string) => void;
31
+ status: (text: string) => void;
32
+ ended?: (reason: string) => void;
33
+ }
34
+ export declare class Network {
35
+ private room;
36
+ private credentials;
37
+ private hooks;
38
+ private readonly runtime;
39
+ ws: WebSocket;
40
+ peers: Map<string, Peer>;
41
+ id: string;
42
+ host: boolean;
43
+ hostId: string;
44
+ closed: boolean;
45
+ timer: ReturnType<typeof setInterval>;
46
+ bytesSent: number;
47
+ bytesReceived: number;
48
+ private pollingStats;
49
+ private verificationState;
50
+ get requireVerification(): boolean | null;
51
+ private verificationSequence;
52
+ private verificationRequest?;
53
+ private challenge?;
54
+ private rejectVerification;
55
+ setRequireVerification(required: boolean): Promise<boolean>;
56
+ private passwordRequestId;
57
+ private passwordRequest?;
58
+ private rejectPasswordUpdate;
59
+ setPassword(password: string | null): Promise<boolean>;
60
+ private banSequence;
61
+ private banRequest?;
62
+ private rejectBan;
63
+ updateBan(type: 'ban' | 'clearBan' | 'clearBans', target?: string): Promise<void>;
64
+ get rtt(): number | null;
65
+ private signalQueue;
66
+ private lastHeartbeat;
67
+ private controlId;
68
+ private controlAssemblers;
69
+ constructor(room: string, credentials: {
70
+ hostToken?: string;
71
+ password?: string;
72
+ }, hooks: Hooks, runtime?: NetworkRuntime);
73
+ signal(m: unknown): void;
74
+ private message;
75
+ private current;
76
+ private queueCandidate;
77
+ private noteHealthy;
78
+ private flushCandidates;
79
+ /** Host-only ICE repair; preserves channels, player identity and simulation state. */
80
+ restartPeer(id: string): Promise<boolean>;
81
+ private make;
82
+ private bind;
83
+ /** Called by the host only after validating and allocating a player slot. */
84
+ admit(p: Peer): void;
85
+ control(p: Peer, m: unknown): void;
86
+ fast(p: Peer, data: ArrayBuffer): void;
87
+ broadcast(m: unknown): void;
88
+ stats(): Promise<void>;
89
+ remove(id: string): void;
90
+ close(): void;
91
+ }
@@ -0,0 +1,4 @@
1
+ export declare const defaultStadiums: readonly [readonly ['classic', 'Classic'], readonly ['easy', 'Easy'], readonly ['small', 'Small'], readonly ['big', 'Big'], readonly ['rounded', 'Rounded'], readonly ['hockey', 'Hockey'], readonly ['big_easy', 'Big Easy'], readonly ['big_rounded', 'Big Rounded'], readonly ['big_hockey', 'Big Hockey'], readonly ['huge', 'Huge']];
2
+ /** Each loader owns its cache; origins and runtime lifetimes cannot share entries. */
3
+ export declare function createStadiumLoader(load: (path: string) => Promise<Response>): (name: string) => Promise<string>;
4
+ export declare const loadDefaultStadium: (name: string) => Promise<string>;
@@ -0,0 +1,6 @@
1
+ /** One cancellable deadline for assets, HTTP admission and signaling readiness. */
2
+ export declare function startupScope(external?: AbortSignal): {
3
+ signal: AbortSignal;
4
+ run<T>(work: Promise<T>): Promise<T>;
5
+ dispose(): void;
6
+ };
@@ -0,0 +1,9 @@
1
+ type Budget = 'message' | 'action' | 'chat';
2
+ /** Separate action budgets bound broadcast amplification during normal gameplay traffic. */
3
+ export declare class PeerTraffic {
4
+ private peers;
5
+ allow(id: string, kind: Budget, now?: number): boolean;
6
+ delete(id: string): void;
7
+ clear(): void;
8
+ }
9
+ export {};
@@ -0,0 +1,2 @@
1
+ /** Bound avatar labels before they enter rosters or canvas text rendering. */
2
+ export declare function validAvatar(value: unknown): value is string | null;
@@ -0,0 +1,2 @@
1
+ export declare const ENGINE_BUILD = "3de72bdcf92ccb0d235a";
2
+ export declare const ENGINE_WASM_HASH = "18e0600cd78f6896249e672d14fefbc34e88826b1febf0b794dc5367f176e338";
@@ -0,0 +1,5 @@
1
+ export declare function controlPackets(message: unknown, id: number): (string | ArrayBuffer)[];
2
+ export declare class ControlAssembler {
3
+ private partial?;
4
+ push(data: string | ArrayBuffer, now?: number): unknown | undefined;
5
+ }
@@ -0,0 +1,7 @@
1
+ /** Runtime disc fields in reference action order; -1 denotes the color array. */
2
+ export declare const DISC_PROPERTY_FIELDS: readonly [readonly ['x', 0, -8192, 8192], readonly ['y', 1, -8192, 8192], readonly ['xspeed', 2, -8192, 8192], readonly ['yspeed', 3, -8192, 8192], readonly ['xgravity', 8, -8192, 8192], readonly ['ygravity', 9, -8192, 8192], readonly ['radius', 4, 0.5, 100], readonly ['bCoeff', 7, -1, 8192], readonly ['invMass', 5, 0, 8192], readonly ['damping', 6, 0, 8192], readonly ['color', -1, -1, 16777215], readonly ['cMask', 11, -2147483648, 2147483647], readonly ['cGroup', 10, -2147483648, 2147483647]];
3
+ export type DiscProperty = (typeof DISC_PROPERTY_FIELDS)[number][0];
4
+ export type DiscProperties = Record<DiscProperty, number>;
5
+ export type DiscPropertyPatch = Partial<Record<DiscProperty, number | null>>;
6
+ /** Validate the entire update before any engine field can be changed. */
7
+ export declare function normalizeDiscProperties(properties: unknown): Partial<DiscProperties>;