Builtin Library
README.md
inputAuthor
Write control schemes whose every control already carries keyboard, gamepad and touch.
Why a toolbox for this
A binding must cover all three devices — that rule is what stops a world shipping playable on a desktop and dead on a phone. A rule like that only survives if obeying it is cheap; otherwise authors reach for a canonical name that half-fits, or bind the keyboard and mean to come back.
So the catalog fills in the common controls. Ask for jump and get Space,
the south face button, and a lower-right touch button, already complete.
Ask for six controls and get a whole scheme in one call.
tools.use("inputAuthor", "map", "shooter",
{ "move", "look", "attack", "aim", "reload", "jump" })
Where each control lands is a judgement about the device rather than a
translation of the keyboard binding: sprint is a stick click on a pad
because that is where a thumb already rests, and a lower-right button on
touch for the same reason. aim is a trigger, not a face button.
Overriding
A control is either a catalog name or a table naming it with overrides:
tools.use("inputAuthor", "map", "racer", {
"move",
"brake",
-- a sprint, under the name this game calls it
{ name = "boost", from = "sprint", label = "Nitro" },
{ name = "horn", -- unknown: supply all three
kind = "button",
kbm = '{ B.key("KeyH") }',
gamepad = '{ B.padButton("north") }',
touch = '{ B.touchButton({ zone = "right-lower" }) }' },
})
from is for the common case where a game's control IS a canonical one
under its own name — a racer's boost is a sprint, a shooter's fire is an
attack. It keeps the control named what the game calls it without retyping
three bindings.
A name the catalog does not know, and that does not say what it is based on, needs all three classes from you. It cannot guess where a control nobody has named before belongs on a pad or a phone screen, and guessing would produce exactly the half-right layout this whole model exists to prevent.
Labels in the player's language
Every catalog control is labelled from the built-in controls catalog, and
the record it writes carries label = i18n.text("controls.control.jump"), so
the touch button and a rebind list read in the player's language. For a
control of your own, labelKey names a message of the world's catalogs
(/zero/source/locales/<tag>/<namespace>.json) and the record carries it the
same way; label writes the text as given.
-- /zero/source/locales/en/hud.json: { "horn": "Horn" }, and pt-BR beside it
{ name = "horn", labelKey = "hud.horn", kind = "button", ... }
A control's name is its identity: code subscribes to it, inputSim taps
its button by it, and a player's rebinding is stored under it, so the label
can read differently in every language and nothing that names the control
changes.
Nothing is written until every control resolves, so a scheme with one unknown control names it rather than leaving half a map on disk.
Tools
| Tool | What it does |
|---|---|
map | Write a scheme: the map folder and every control it declares |
control | Add one control to a scheme that already exists |
catalog | List the controls that come pre-filled, and what each is bound to |
check | Report every problem across a scheme's controls, without activating it |
check reports all faults at once and activates nothing, so a scheme can
be inspected before a world runs it. To drive the result on each device,
use the inputSim toolbox.