from keypress to couch co-op
npm install @benev/tacttact is a toolkit for handling user input on the web.
customizable keybindings, multiple-gamepad couch co-op, ready-made configurator ui, efficient networking, mobile virtual thumbsticks.
import {
Devices, KeyboardDevice, PointerDevice,
makeIntentsResolver, makeActionsResolver,
} from "@benev/tact"- setup your game's keybindings
const bindings = { running: {forward: "KeyW", jump: ["and", "ShiftLeft", "Space"]}, gunning: {shoot: ["or", "pointer.button.left", "gamepad.trigger.right"]}, }
- create your devices (which provide raw input samples)
const devices = new Devices( new KeyboardDevice(), new PointerDevice(), )
- make your resolvers
const resolveIntents = makeIntentsResolver(bindings) const resolveActions = makeActionsResolver(bindings)
- run your resolvers, read your actions
import {cycle} from "@e280/stz" cycle(function myGameTick() { // ๐งโโ๏ธ samples get resolved into compact intent tuples, good for networking. const intents = resolveIntents(Date.now(), devices.samples()) // ๐งโโ๏ธ actions are your ergonomic accessors for values. const actions = resolveActions(intents) // ๐งโโ๏ธ okay, now check your actions. actions.running.forward.value // 1.0 actions.running.forward.pressed // true })
- for networking, you should encode intents as Uint8Array for better efficiency down the wire.
import {encodeIntents, decodeIntents} from "@benev/tact" const intents = [[1, 0.7853981633974483]] console.log(JSON.stringify(intents).length) // 22 โ yikes const bytes = encodeIntents(intents) console.log(bytes.length) // 6 โ noice const intents = decodeIntents(bytes)
- you can normalize bindings
this clones your app bindings and cherry-picks any compatible user bindings. useful when loading from localStorage, so changes to your schema donโt break things.
import {normalizeBindings} from "@benev/tact" const bindings = normalizeBindings(appBindings, susBindings)
๐ผ https://benev.gg/