Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit61a33237e0

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

ToolWhat it does
mapWrite a scheme: the map folder and every control it declares
controlAdd one control to a scheme that already exists
catalogList the controls that come pre-filled, and what each is bound to
checkReport 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.