@benev/tact 0.4.0-1 → 0.4.0-3
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/README.md +22 -17
- package/package.json +1 -1
- package/s/demo/main.css +38 -3
- package/s/index.html.ts +25 -19
- package/s/lib/ui/deck/controls/internal/data.ts +7 -5
- package/s/lib/ui/deck/setup/tact.ts +1 -1
- package/s/lib/ui/views/theme.css.ts +1 -1
- package/s/lib/ui/views/visualizer/style.css.ts +8 -6
- package/s/lib/ui/views/visualizer/view.ts +1 -0
- package/x/demo/main.bundle.min.js +50 -47
- package/x/demo/main.bundle.min.js.map +4 -4
- package/x/demo/main.css +38 -3
- package/x/gamepad/index.html +1 -1
- package/x/index.html +27 -21
- package/x/index.html.js +25 -19
- package/x/index.html.js.map +1 -1
- package/x/lib/ui/deck/controls/internal/data.d.ts +1 -1
- package/x/lib/ui/deck/controls/internal/data.js +4 -1
- package/x/lib/ui/deck/controls/internal/data.js.map +1 -1
- package/x/lib/ui/deck/setup/tact.js +1 -1
- package/x/lib/ui/deck/setup/tact.js.map +1 -1
- package/x/lib/ui/views/theme.css.js +1 -1
- package/x/lib/ui/views/visualizer/style.css.js +8 -6
- package/x/lib/ui/views/visualizer/style.css.js.map +1 -1
- package/x/lib/ui/views/visualizer/view.js +1 -0
- package/x/lib/ui/views/visualizer/view.js.map +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
# 🎮 @benev/tact
|
|
3
3
|
> *from keypress to couch co-op.*
|
|
4
4
|
|
|
5
|
-
**tact is a user-input toolkit for web games.**
|
|
5
|
+
**tact is a user-input toolkit for web games.**
|
|
6
|
+
i made tact because i want to make indie web game development easier. user input seems like it should be easy, but doing it well is actually really complex. especially when you start thinking of multiplayer and multithreading. my goal with tact is to tame the complexity and give people something elegant and flexible that "just works".
|
|
6
7
|
|
|
7
8
|
🌐 👉 ***https://tact.benev.gg/*** 👈 *try now*
|
|
8
9
|
|
|
@@ -12,6 +13,9 @@
|
|
|
12
13
|
🫂 multiplayer and splitscreen capable.
|
|
13
14
|
🧬 binary for efficient workers and networking.
|
|
14
15
|
🎸 ready-to-rock drop-in user-interface.
|
|
16
|
+
✍️ handcrafted by a human being.
|
|
17
|
+
|
|
18
|
+
|
|
15
19
|
|
|
16
20
|

|
|
17
21
|
|
|
@@ -23,7 +27,7 @@
|
|
|
23
27
|
|
|
24
28
|
## 🎮 let's play.
|
|
25
29
|
|
|
26
|
-
- 🍏 **install tact.**
|
|
30
|
+
- 🍏 **install tact into your typescript project.**
|
|
27
31
|
```sh
|
|
28
32
|
npm install @benev/tact@next
|
|
29
33
|
```
|
|
@@ -51,7 +55,7 @@
|
|
|
51
55
|
}},
|
|
52
56
|
})
|
|
53
57
|
```
|
|
54
|
-
- 🍏 **
|
|
58
|
+
- 🍏 **setup tact.**
|
|
55
59
|
```ts
|
|
56
60
|
import {setupTact} from "@benev/tact"
|
|
57
61
|
|
|
@@ -60,20 +64,22 @@
|
|
|
60
64
|
tact.gamepads("gamepad")
|
|
61
65
|
tact.registerElements()
|
|
62
66
|
```
|
|
63
|
-
-
|
|
67
|
+
- 💡 *set `maxPlayers` to 1 for single player.*
|
|
68
|
+
- 🍏 **put the `<tact-deck>` in your html page.**
|
|
64
69
|
```html
|
|
65
70
|
<tact-deck></tact-deck>
|
|
66
71
|
```
|
|
67
72
|
- 💡 *you also have each panel, `<tact-controllers>` and `<tact-customize>`.*
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
- 💡 *you can customize the colors with css:*
|
|
74
|
+
```html
|
|
75
|
+
<style>
|
|
76
|
+
html {
|
|
77
|
+
--tact-prime: aqua;
|
|
78
|
+
--tact-bg: black;
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
81
|
+
```
|
|
82
|
+
- 🎉 **now users can configure controllers and customize bindings!**
|
|
77
83
|
|
|
78
84
|
|
|
79
85
|
|
|
@@ -81,14 +87,12 @@
|
|
|
81
87
|
|
|
82
88
|
## 🎮 encoding, decoding, and your game logic.
|
|
83
89
|
|
|
84
|
-
- 🍏 **
|
|
90
|
+
- 🍏 **now it's time for the real action!**
|
|
85
91
|
```ts
|
|
86
92
|
import {Collector} from "@benev/tact"
|
|
87
93
|
|
|
88
94
|
const collector = new Collector(bindings)
|
|
89
|
-
|
|
90
|
-
- 🍏 **now it's time for the real action!**
|
|
91
|
-
```ts
|
|
95
|
+
|
|
92
96
|
setInterval(() => {
|
|
93
97
|
const buffer = tact.deck.hub.encodeAll()
|
|
94
98
|
for (const {playerId, inputs} of collector.decodeAll(buffer)) {
|
|
@@ -104,6 +108,7 @@
|
|
|
104
108
|
}, 16.67)
|
|
105
109
|
```
|
|
106
110
|
💡 *you could stream the buffers across the network to a remote collector.*
|
|
111
|
+
💡 *maybe imagine having the tact deck on the clientside, and the collector on the serverside (or a web worker!).*
|
|
107
112
|
|
|
108
113
|
|
|
109
114
|
|
package/package.json
CHANGED
package/s/demo/main.css
CHANGED
|
@@ -53,6 +53,10 @@
|
|
|
53
53
|
background: var(--bg);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
html {
|
|
57
|
+
scrollbar-gutter: stable;
|
|
58
|
+
}
|
|
59
|
+
|
|
56
60
|
body {
|
|
57
61
|
display: flex;
|
|
58
62
|
flex-direction: column;
|
|
@@ -67,10 +71,34 @@
|
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
> header {
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-wrap: wrap;
|
|
76
|
+
justify-content: space-between;
|
|
77
|
+
align-items: end;
|
|
78
|
+
gap: 1em;
|
|
70
79
|
padding: 0 2em;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
|
|
81
|
+
h1 small {
|
|
82
|
+
font-size: 0.6em;
|
|
83
|
+
font-weight: normal;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
blockquote {
|
|
87
|
+
opacity: 0.5;
|
|
88
|
+
font-style: italic;
|
|
89
|
+
padding-left: 1em;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
label {
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
align-items: end;
|
|
96
|
+
gap: 0.1em;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.links span {
|
|
100
|
+
opacity: 0.5;
|
|
101
|
+
}
|
|
74
102
|
}
|
|
75
103
|
|
|
76
104
|
> section {
|
|
@@ -79,6 +107,13 @@
|
|
|
79
107
|
padding-left: 1em;
|
|
80
108
|
}
|
|
81
109
|
}
|
|
110
|
+
|
|
111
|
+
> footer {
|
|
112
|
+
padding: 1em 2em;
|
|
113
|
+
p {
|
|
114
|
+
opacity: 0.5;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
82
117
|
}
|
|
83
118
|
}
|
|
84
119
|
|
package/s/index.html.ts
CHANGED
|
@@ -31,30 +31,36 @@ export default template(import.meta.url, async orb => html`
|
|
|
31
31
|
</head>
|
|
32
32
|
<body>
|
|
33
33
|
<header>
|
|
34
|
-
<h1>
|
|
35
|
-
<strong>@benev/tact</strong>
|
|
36
|
-
<small>v${orb.packageVersion()}</small>
|
|
37
|
-
</h1>
|
|
38
34
|
<div>
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<span
|
|
50
|
-
<
|
|
51
|
-
</
|
|
52
|
-
</
|
|
35
|
+
<h1>
|
|
36
|
+
<strong>@benev/tact</strong>
|
|
37
|
+
<small>v${orb.packageVersion()}</small>
|
|
38
|
+
</h1>
|
|
39
|
+
<div>
|
|
40
|
+
<blockquote>"from keypress to couch co-op"</blockquote>
|
|
41
|
+
<p class=links>
|
|
42
|
+
<a href="./gamepad/">gamepad visualizer</a>
|
|
43
|
+
<span>—</span>
|
|
44
|
+
<a href="https://github.com/benev-gg/tact">github</a>
|
|
45
|
+
<span>—</span>
|
|
46
|
+
<a href="https://benev.gg/">benev.gg</a>
|
|
47
|
+
</p>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
<div>
|
|
51
|
+
<label>
|
|
52
|
+
<input type="color"/>
|
|
53
|
+
<span>choose your color ☝️</span>
|
|
54
|
+
</label>
|
|
53
55
|
</div>
|
|
54
56
|
</header>
|
|
55
57
|
|
|
56
58
|
<tact-deck></tact-deck>
|
|
57
|
-
|
|
59
|
+
|
|
60
|
+
<footer>
|
|
61
|
+
<p>binary data visualizer</p>
|
|
62
|
+
<tact-visualizer></tact-visualizer>
|
|
63
|
+
</footer>
|
|
58
64
|
</body>
|
|
59
65
|
</html>
|
|
60
66
|
`)
|
|
@@ -5,21 +5,23 @@ import {got, IdCounter, setEntries, subby} from "@e280/stz"
|
|
|
5
5
|
import {Profile, ProfileKey} from "../../types.js"
|
|
6
6
|
import {Bindings} from "../../../../input/types.js"
|
|
7
7
|
import {Controller} from "../../../../input/controller.js"
|
|
8
|
+
import {hashBindings} from "../../../../input/investigate/hash-bindings.js"
|
|
8
9
|
import {ControllerHandle, ControllerMeta, ControlsOptions} from "../types.js"
|
|
9
10
|
|
|
10
11
|
export type ControlsData<B extends Bindings> = (
|
|
11
12
|
ReturnType<typeof makeControlsData<B>>
|
|
12
13
|
)
|
|
13
14
|
|
|
14
|
-
export function makeControlsData<B extends Bindings>({
|
|
15
|
-
|
|
16
|
-
presets,
|
|
17
|
-
}: ControlsOptions<B>) {
|
|
18
|
-
|
|
15
|
+
export function makeControlsData<B extends Bindings>(options: ControlsOptions<B>) {
|
|
16
|
+
const {presets} = options
|
|
19
17
|
const fallbackKey = got(Object.keys(presets)[0], "missing presets")
|
|
20
18
|
const fallbackProfile = got(presets[fallbackKey])
|
|
21
19
|
const bindings = fallbackProfile.bindings
|
|
22
20
|
|
|
21
|
+
const kv = options.kv.scope(
|
|
22
|
+
hashBindings(bindings).toString()
|
|
23
|
+
)
|
|
24
|
+
|
|
23
25
|
const profiles = {
|
|
24
26
|
presets: new RMap<ProfileKey, Profile<B>>(),
|
|
25
27
|
customs: new RMap<ProfileKey, Profile<B>>(),
|
|
@@ -5,6 +5,7 @@ import {setupDeck} from "./deck.js"
|
|
|
5
5
|
import {SetupParams} from "./types.js"
|
|
6
6
|
import {Bindings} from "../../../input/types.js"
|
|
7
7
|
import {autoGamepads} from "../auto-gamepads.js"
|
|
8
|
+
import {ellipsis} from "../../../utils/ellipsis.js"
|
|
8
9
|
import {firstPreset} from "../utils/first-preset.js"
|
|
9
10
|
import {Controller} from "../../../input/controller.js"
|
|
10
11
|
import {Sources} from "../../../input/sources/sources.js"
|
|
@@ -19,7 +20,6 @@ import {makeControllersElement} from "../../views/controllers/view.js"
|
|
|
19
20
|
|
|
20
21
|
import devicesSvg from "../../icons/akar/devices.svg.js"
|
|
21
22
|
import gameControllerSvg from "../../icons/akar/game-controller.svg.js"
|
|
22
|
-
import { ellipsis } from "../../../utils/ellipsis.js"
|
|
23
23
|
|
|
24
24
|
export async function setupTact<B extends Bindings>(params: SetupParams<B>) {
|
|
25
25
|
const deck = await setupDeck(params)
|
|
@@ -8,15 +8,17 @@ export default css`@layer view {
|
|
|
8
8
|
|
|
9
9
|
output {
|
|
10
10
|
opacity: 0.5;
|
|
11
|
-
color: var(--prime);
|
|
12
|
-
font-size: 1em;
|
|
13
|
-
font-family: monospace;
|
|
14
11
|
display: block;
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
|
|
13
|
+
font-size: 1em;
|
|
17
14
|
height: 8em;
|
|
18
|
-
|
|
15
|
+
|
|
19
16
|
overflow: hidden;
|
|
17
|
+
overflow-wrap: anywhere;
|
|
18
|
+
|
|
19
|
+
font-family: monospace;
|
|
20
|
+
color: var(--prime);
|
|
21
|
+
text-overflow: ellipsis;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
}`
|