Input

TEMPLATE NAME: Input
CORE VERSION: 1.0.291
TEMPLATE VERSION: 1.0.0

TEMPLATE DESCRIPTION:

"The complexity of your game is limited by your ability to manage state."

Flexible micro-framework for managing input across overlapping UI layers. Includes support for tap, longpress (hold), pulse (auto-repeat), and double-tap input gestures.

Based upon the concepts in Descendent's Framework Architecture, for easy integration and customization with other code.

TEMPLATE ROADMAP:

  • No-code Bindings for common use-cases

TEMPLATE VERSION NOTES:

Version 1.0.0

  • First stable release.

ADDITIONAL INFO:

  • Community Content — "Input"
  • Community Project (example) — "Input"

Getting Started

Import

  1. In Community Content, search for "descendent".
  2. Browse to the listing for "Input", and click "Import"; then click "Yes".
  3. In Core Content, under the "Community Content" category, select the "Imported Content > Input" group.
  4. Add the "Input" template to the Hierarchy (in Default Context).

Set Up

  1. In Project Content, select the "Imported Content > Input > Dependent Scripts" group.
  2. Add the "Input_InputConfigurationStatic" script to the Hierarchy, in Static Context.
  3. Add the "Input_InputStartClient" script to the Hierarchy, in Client Context.
  4. In the Hierarchy, select the "Input_InputStartClient" script instance; then drag the "Input_InputConfigurationStatic" script instance (from the Hierarchy) into the "Input_InputStartClient" script instance's "Configuration" custom property (in the Properties panel).
  5. Add a Layer Catalog data table and script. (See "Create a Catalog".)
  6. Add Binding scripts. (See "Create a Binding".)

How-To Guides

Use this Service in a Script

  1. In Project Content, browse to the script that will be using the Service, and select it.
  2. In the Properties panel, add a custom property of type "Asset Reference", and name it "InputService"; then set its default value to reference the "Input_InputService" script.
  3. Edit the script that will be using the Service; at or near the top of the code, add…
    local InputService = require(script:GetCustomProperty("InputService"))
    
    local _inputService = InputService.Use()
    
  4. Use this Service's singleton instance via the _inputService variable. (See "InputService" API reference.)

Create a Catalog

Use a Catalog to register templates, game objects, or ID's with this Service, and associate each entry with static game data.

  1. In Project Content, select the "My Tables" group.
  2. At the top of the right frame (where the "Search" field is), click the :open_file_folder: ("Create Folder") button; enter "Example", and press Enter.
  3. In Project Content, select the "Imported Content > Input > Dependent Data Tables" group, then browse to the "Example" folder.
  4. Right-click an example Catalog data table, and select "Duplicate Asset"; then rename the new copy to an appropriate name, and move it to an appropriate folder.
    • The new copy will initially be placed in the "My Tables" group, in the "Example" folder, and have " - Copy" appended to its name; if the "Example" folder or the new copy doesn't appear in Project Content, save, close, and re-open the project.
  5. In Project Content, select the "Imported Content > Input > Dependent Scripts" group.
  6. Add the matching Catalog script to the Hierarchy, as a child of the "Input_InputStartClient" script instance.
  7. If the new Catalog script instance has a "GroupId" custom property, configure that custom property.
  8. In Project Content, select the "My Tables" group, then browse to the new Catalog data table.
  9. In the Hierarchy, select the new Catalog script instance; then drag the new Catalog data table (from Project Content) into the new Catalog script instance's "Table" custom property (in the Properties panel).
  10. Edit the new Catalog data table, to add relevant game data. (See "Catalogs" data table reference.)

Create a Binding

Use a Binding to customize this Service with game-specific game logic.

  1. In Project Content, select the "My Scripts" group.
  2. At the top of the right frame (where the "Search" field is), click the :open_file_folder: ("Create Folder") button; enter "Example", and press Enter.
  3. In Project Content, select the "Imported Content > Input > Dependent Scripts" group, then browse to the "Example" folder.
  4. Right-click an example Binding script, and select "Duplicate Asset"; then rename the new copy to an appropriate name, and move it to an appropriate folder.
    • The new copy will initially be placed in the "My Scripts" group, in the "Example" folder, and have " - Copy" appended to its name; if the "Example" folder or the new copy doesn't appear in Project Content, save, close, and re-open the project.
  5. Add custom properties to the new Binding script (if applicable), and configure their default values.
  6. Add the new Binding script to the Hierarchy, as a child of the "Input_InputStartClient" script instance.
  7. Configure the new Binding script instance's "GroupId" custom property.
  8. Edit the new Binding script, to add relevant game logic. (See "Bindings" API reference.)

Use an Existing Binding

Use a Binding to customize this Service with game-specific game logic.

  1. In Project Content, browse to the existing Binding script.
  2. Add the existing Binding script to the Hierarchy, as a child of the "Input_InputStartClient" script instance.
  3. Configure the new Binding script instance's "InputService" custom property to reference the "Input_InputService" script.
  4. Configure the new Binding script instance's "GroupId" custom property.

Share an Adapter, Handler, or Binding with Other Projects or Creators

  1. In Project Content, browse to the Adapter, Handler, or Binding script that will be shared with other projects or creators, and select it.
  2. In the Properties panel, for each custom property of type "Asset Reference", "Core Object Reference", or "Net Reference": right-click the large icon in the custom property's value (or the custom property's value itself), and select "Clear Value".
    • Custom properties referencing assets or objects that shouldn't be duplicated in other projects must be cleared, to prevent the assets or objects from being packaged together with the Adapter, Handler, or Binding script when shared. These custom properties will need to be re-configured on each script instance (in the Hierarchy) in each project.
  3. Right-click the Adapter, Handler, or Binding script, and select ":rocket: Publish to Community Content"; then complete the process to publish as a public or private Community Content package.

Update

  1. In Project Content, right-click the "Imported Content > Input" group, and select "Download Latest"; then click "Yes"; then click "Continue with save: I accept the risk".

Delete

  1. In Project Content, right-click the "Imported Content > Input" group, and select "Delete Assets"; then, if asked, click "Delete All and Save" each time; then click "Delete All" each time.
  2. In Core Content, under the "Community Content" category, right-click the "Imported Content > Input" group, and select "Delete Assets"; then click "Delete All" each time.

Custom Properties Reference

Input_InputStartClient

Custom Properties

AssetReference InputService

"Input_InputService" script.

string Await

Field in each tracked script's context that's expected to be assigned a truthy value, once the tracked script has finished loading.
Default: "ready"

float AwaitTimer

Amount of time (in seconds) to wait for each of this script instance's tracked scripts to finish loading, before logging a warning. This script instance will wait forever if the field specified by its "Await" custom property couldn't be found in a tracked script's context.
Default: 60

CoreObjectReference Configuration

"Input_InputConfigurationStatic" script instance.

Input_InputConfigurationStatic

Custom Properties

float LongpressTimer

Amount of time (in seconds) an action must remain pressed, before it will be interpreted as a longpress gesture.
Default: 0.5

float PulseBeginTimer

Amount of time (in seconds) an action must remain pressed, before it will be interpreted as a pulse gesture.
Default: 0.4

float PulseTimer

Amount of time (in seconds) between pulse triggers, during a pulse gesture.
Default: 0.1

float DoubletapTimer

Maximum amount of time (in seconds) after releasing an action, during which tapping that same action again will be interpreted as a double-tap gesture instead.
Default: 0.35

Catalogs

Input_InputLayerCatalogClient

Custom Properties

AssetReference InputService

"Input_InputService" script.

AssetReference Table

Data Table that provides the entities and game data for this Catalog to register.

string GetId

Data Table column for unique ID's for Layers.
Default: "Id"

string GetIndex

Data Table column for Layers' priority levels.
Default: "Index"

Bindings

Input_ExampleInputBindingClient

Custom Properties

AssetReference InputService

"Input_InputService" script.

string GroupId

ID of Group this Binding provides game logic for. A Group can have at most one Binding of each type.

Data Table Reference

Catalogs

Input_ExampleInputLayerCatalog

Columns

string Id

Unique ID for the Layer.

integer Index

The Layer's priority level. For each action, among presented Bindings that contain input behaviors for that action, the Binding that's presented in the Layer with the greatest index value is considered the "topmost" Binding for that action. Input behaviors in the topmost Binding for an action will override input behaviors for that action in other Bindings. Multiple Layer ID's can share the same index; however, at most one Binding can be presented at each index.

API Reference

Configuration

Properties

float longpressTimer

Amount of time (in seconds) an action must remain pressed, before it will be interpreted as a longpress gesture.

float pulseBeginTimer

Amount of time (in seconds) an action must remain pressed, before it will be interpreted as a pulse gesture.

float pulseTimer

Amount of time (in seconds) between pulse triggers, during a pulse gesture.

float doubletapTimer

Maximum amount of time (in seconds) after releasing an action, during which tapping that same action again will be interpreted as a double-tap gesture instead.

InputService

Static Methods

InputService Use()

Returns the singleton instance of this Service.

Methods (Accessors)

Configuration GetConfiguration()

Returns this Service's Configuration instance.

float GetTimer(id)

Returns the amount of time (in seconds) that action id has remained pressed.

Methods

nil AwaitConfiguration()

Blocks execution until this Service's Configuration instance is initialized.

nil AwaitSetup()

Blocks execution until all scripts tracked by this Service's "Input_InputSetupClient" script instance have finished loading.

nil AwaitStart()

Blocks execution until all scripts tracked by this Service's "Input_InputStartClient" script instance have finished loading.

nil AfterConfiguration(function thunk)

Schedules function thunk to be called after this Service's Configuration instance is initialized.

nil AfterSetup(function thunk)

Schedules function thunk to be called after all scripts tracked by this Service's "Input_InputSetupClient" script instance have finished loading.

nil AfterStart(function thunk)

Schedules function thunk to be called after all scripts tracked by this Service's "Input_InputStartClient" script instance have finished loading.

LayerCatalog AddLayerCatalog()

Creates, registers, and returns a new LayerCatalog instance for this Service. This Service can have at most one LayerCatalog instance.

Binding AddBinding(string groupId)

Creates, registers, and returns a new Binding instance for Group groupId, for this Service. A Group can have at most one Binding instance.

nil Present(string groupId, string layerId)

Presents the Binding for Group groupId, in Layer layerId. If this operation will change the topmost Binding for an action that's being pressed, that action will be treated as canceled.

nil Dismiss(string groupId)

Dismisses the Binding for Group groupId. If this operation will change the topmost Binding for an action that's being pressed, that action will be treated as canceled.

nil DismissLayer(string layerId)

Dismisses the Binding that's presented in Layer layerId. If this operation will change the topmost Binding for an action that's being pressed, that action will be treated as canceled.

Catalogs

LayerCatalog

Methods

nil Add(string key, integer value)

Adds Layer with ID key, and index value to this LayerCatalog instance. key must be unique within this LayerCatalog instance.

Bindings

Binding

Methods

nil AddPointerPresent(InputType inputStyle)

Declares that the mouse pointer should be visible when the device's input type (from Core's Input.GetCurrentInputType static method) is inputStyle.

nil AddPointerDismiss(InputType inputStyle)

Declares that the mouse pointer should be hidden when the device's input type (from Core's Input.GetCurrentInputType static method) is inputStyle.

nil AddControlPresent(InputType inputStyle)

Declares that virtual controls should be visible when the device's input type (from Core's Input.GetCurrentInputType static method) is inputStyle.

nil AddControlDismiss(InputType inputStyle)

Declares that virtual controls should be hidden when the device's input type (from Core's Input.GetCurrentInputType static method) is inputStyle.

nil AddExclusionDefault()

Declares that input behaviors in Bindings that are presented in Layers with lesser index values should be treated as overridden.

nil AddExclusion(string id)

Declares that input behaviors for action id in Bindings that are presented in Layers with lesser index values should be treated as overridden.

nil AddExclusionEsc()

Declares that input behaviors for the "Esc" key in Bindings that are presented in Layers with lesser index values should be treated as overridden.

nil AddExtrinsic(string id)

Declares action id as a valid input, without specifying any input behavior. Input behavior is expected to be provided by a Core behavior, or by other frameworks or code, instead.

nil AddExtrinsicEsc()

Declares the "Esc" key as a valid input, without specifying any input behavior. Input behavior is expected to be provided by a Core behavior, or by other frameworks or code, instead.

nil AddInputBegin(string id, function thunk)

Declares input behavior thunk for when action id is pressed. thunk must be a function that accepts a float parameter for the action value.

nil AddInput(string id, function thunk)

Declares input behavior thunk for every tick, while action id remains pressed. thunk must be a function that accepts a float parameter for the action value.

nil AddInputEnd(string id, function thunk)

Declares input behavior thunk for when action id is released. thunk must be a function that accepts a float parameter for the action value, and a boolean parameter for whether the action was canceled (instead of voluntarily released by the player).

nil AddTap(string id, function thunk)

Declares input behavior thunk for when action id produces a tap gesture.

nil AddLongpress(string id, function thunk)

Declares input behavior thunk for when action id produces a longpress (hold) gesture.

nil AddPulse(string id, function thunk)

Declares input behavior thunk for when action id produces a pulse (auto-repeat) gesture.

nil AddDoubletap(string id, function thunk)

Declares input behavior thunk for when action id produces a double-tap gesture.

nil AddEsc(function thunk)

Declares input behavior thunk for when the "Esc" key is pressed.

Examples

See "Input" by Descendent in Community Projects.