Async Input

TurboWarp extension · User guide

Input now. React anywhere.

Async Input connects a physical key, a sprite tap, or an accumulated pose to a Temporary Variables runtime variable. Your project can read the latest value from any script—and optionally receive a broadcast at the same moment.

Kamishibai DSL 4.0 bundle

Open this guide from the bundled palette

Under the Async Input member heading, use the documentation button. The bundled blocks retain the keyboard, sprite-tap, pose, runtime-variable, broadcast, ownership, and cleanup behavior described here; only their namespace and icon identify their origin inside the combined runtime.

Quick start

Ready in four steps

Register listeners when the project starts. Registration remembers what should happen; it does not wait for the input and it does not initialize the runtime variable for you.

  1. Load dependencies

    Add Temporary Variables first. Then load Async Input as a custom extension with Run extension without sandbox enabled.

  2. Initialize a value

    Use Temporary Variables to create a runtime variable, such as input or score. Use 0 before arithmetic updates.

  3. Register a listener

    Put an Async Input “listen” block under when green flag clicked. The sprite, clone, or stage running the block owns that binding.

  4. Press, tap, or pose

    Matching input updates the runtime variable immediately. “And broadcast” blocks then start the named Scratch broadcast.

What happens after registration

The runtime variable is always written before the optional broadcast starts.

Extension URL

Use the reviewed, version-pinned build: @kubohiroya/turbowarp-async-input@0.4.0.

Examples

Choose the input source

Key and touch blocks are included in the distributed build. Accumulated pose blocks are optional and only appear in a build with the poseInput feature flag enabled.

⌨ Keyboard

Add one point with Space

when green flag clicked
set runtime variable score to 0
listen for key Space set runtime var score to +1

Key IDs use KeyboardEvent.code: KeyA, Digit1, ArrowLeft, Space, or Enter.

☝ Touch / click

Tap a sprite and broadcast

when green flag clicked
set runtime variable input to
listen for touch on this sprite set runtime var input to tapped and broadcast actor-tapped

Only the topmost rendered sprite under the pointer matches. Transparent pixels and clones follow TurboWarp renderer behavior.

◇ Accumulated pose · optional

React when “jump” becomes active

when green flag clicked
set runtime variable pose to waiting
listen for accumulated pose jump set runtime var pose to detected

Requires TMPose with accumulated pose scoring and change events enabled. The binding runs when the active accumulated pose changes to the registered name.

Application integration

Wait for one candidate without registering blocks

Version 0.3.0 adds a side-effect-free Composition API for controllers that need to await a pose, physical key, or topmost actor touch candidate.

Injected event sources

Import @kubohiroya/turbowarp-async-input/composition and inject only the pose, key, or actor-touch sources the controller uses. Importing it does not access Scratch, the DOM, or the TurboWarp VM.

Latest wait wins

Pose, key, and actor-touch waits share one owner. Starting a valid wait aborts the previous wait, and abort, completion, rejection, or releaseAll() unsubscribes immediately.

Target ownership

Each target keeps its own binding

Re-registering the same input from the same target replaces only that target’s binding. Other sprites and clones can listen for the same key or pose independently.

One physical key, three independent bindings

One KeyA press updates every matching target-owned binding.

Touch is target-specific

  • A normal touch listener belongs to the sprite or clone that registers it.
  • The Stage cannot register the “this sprite” touch block.
  • The actor compatibility block can bind a named actor while retaining its caller as owner.

Bindings clean up automatically

  • Deleting a target removes every binding owned by that target.
  • Green flag, Stop All, and runtime disposal remove all bindings.
  • Use the stop blocks when you need to remove bindings earlier.

Values

Set text or calculate a new number

A value beginning with +, -, *, or / is a compound arithmetic update. Any other value is assigned as exact text.

Example: a Space press adds two
VALUEEffectStarting value required
+2Add 2Finite number
-1Subtract 1Finite number
*3Multiply by 3Finite number
/2Divide by 2Finite number; non-zero divisor
pressedSet exact textNone

Invalid or non-finite arithmetic leaves the current value unchanged and skips that binding’s broadcast.

Block reference

Listeners and cleanup

“Listen” blocks register or replace behavior and return immediately. “Stop” blocks only affect bindings owned by the target that runs them.

Keyboard · default

  • listen for key … writes a runtime value.
  • listen for key … and broadcast … writes, then broadcasts.
  • stop listening for key … removes one key binding.
  • stop all key listeners … removes this target’s key bindings.

Touch · default

  • listen for touch on this sprite … writes a runtime value.
  • listen for touch … and broadcast … writes, then broadcasts.
  • stop listening for touch … removes this target’s touch binding.
  • listen for touch on actor … is provided for kamishibai integration.

Accumulated pose · optional

  • listen for accumulated pose … writes on a pose-name change.
  • stop listening for accumulated pose … removes one pose binding.
  • stop all pose listeners … removes this target’s pose bindings.
  • stop all input listeners … removes every input binding this target owns.

Troubleshooting

If nothing happens

Open each item for the most common cause and the shortest fix.

The listen block reports that Temporary Variables is required

Load TurboWarp’s Temporary Variables extension before Async Input, then start the project again. Async Input writes through that extension’s runtime-variable API.

A key does not match

Use the physical key code, not the typed character: KeyA, not a; Digit1, not 1. Auto-repeat, IME composition, and key presses inside editable controls are intentionally ignored.

Touch works on one sprite but not another

Run a registration block from each sprite or clone that needs a listener. Only the renderer’s topmost picked sprite receives a pointer match, and the Stage is not valid for a “this sprite” touch listener.

The pose blocks are missing

Pose input is behind the independently reversible poseInput feature flag, which is OFF in the distributed build. A pose-enabled build also needs TMPose with accumulated scoring and change events enabled.

An arithmetic update does not change the value

Initialize the runtime variable to a finite number. Missing values, non-numeric text, division by zero, overflow, and non-finite operands are rejected without changing the current value.

A listener worked before pressing the green flag, but not after

Starting or stopping the project clears all bindings by design. Register listeners under when green flag clicked so the intended bindings are recreated for each run.