@benev/tact 0.4.0-1 → 0.4.0-2

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 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
  ![](https://i.imgur.com/dCAlD14.png)
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
- - 🍏 **now we can setup tact and register the html elements.**
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
- - 🍏 **simply put the `<tact-deck>` in your html page.**
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
- - 🍏 **color the whole ui with css.**
69
- ```html
70
- <style>
71
- html {
72
- --tact-prime: aqua;
73
- --tact-bg: black;
74
- }
75
- </style>
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
- - 🍏 **make a collector.**
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@benev/tact",
3
- "version": "0.4.0-1",
3
+ "version": "0.4.0-2",
4
4
  "description": "🎮 from keypress to couch co-op",
5
5
  "license": "MIT",
6
6
  "author": "Chase Moskal <chasemoskal@gmail.com>",
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,33 @@
67
71
  }
68
72
 
69
73
  > header {
74
+ display: flex;
75
+ flex-wrap: wrap;
76
+ justify-content: space-between;
77
+ gap: 1em;
70
78
  padding: 0 2em;
71
- h1 small { font-size: 0.6em; font-weight: normal; }
72
- * + * { margin-top: 0.5em; }
73
- label { padding-left: 1em; }
79
+
80
+ h1 small {
81
+ font-size: 0.6em;
82
+ font-weight: normal;
83
+ }
84
+
85
+ blockquote {
86
+ opacity: 0.5;
87
+ font-style: italic;
88
+ padding-left: 1em;
89
+ }
90
+
91
+ label {
92
+ display: flex;
93
+ flex-direction: column;
94
+ align-items: end;
95
+ gap: 0.1em;
96
+ }
97
+
98
+ .links span {
99
+ opacity: 0.5;
100
+ }
74
101
  }
75
102
 
76
103
  > section {
@@ -79,6 +106,13 @@
79
106
  padding-left: 1em;
80
107
  }
81
108
  }
109
+
110
+ > footer {
111
+ padding: 1em 2em;
112
+ p {
113
+ opacity: 0.5;
114
+ }
115
+ }
82
116
  }
83
117
  }
84
118
 
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
- <blockquote>"from keypress to couch co-op"</blockquote>
40
- <p class=links>
41
- <a href="./gamepad/">gamepad visualizer</a>
42
- —
43
- <a href="https://github.com/benev-gg/tact">github</a>
44
- —
45
- <a href="https://benev.gg/">benev.gg</a>
46
- </p>
47
- <p>
48
- <label>
49
- <span>➣ choose your color:</span>
50
- <input type="color"/>
51
- </label>
52
- </p>
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
- <tact-visualizer></tact-visualizer>
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
- kv,
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)
@@ -82,7 +82,7 @@ ${cssReset}
82
82
  --base: var(--tint, var(--prime));
83
83
  font: inherit;
84
84
  color: inherit;
85
- background: transparent;
85
+ background: var(--bg);
86
86
  border: 1px solid var(--base);
87
87
  border-radius: var(--round);
88
88
  padding: var(--nib) var(--pad);
@@ -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
- overflow-wrap: anywhere;
16
- text-overflow: ellipsis;
12
+
13
+ font-size: 1em;
17
14
  height: 8em;
18
- padding: 0 4em;
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
  }`
@@ -10,6 +10,7 @@ export const [VisualizerView, makeVisualizerElement] = shadowDuplex((visualizer:
10
10
  useCss(themeCss, styleCss)
11
11
 
12
12
  return html`
13
+ <slot></slot>
13
14
  <output class=viz>${visualizer.$hex()}</output>
14
15
  `
15
16
  })