Define Echo Button Events

To enable your skill to avoid processing every Echo Button press, you define events that determine the conditions under which your skill is notified. Each event has its own logic to determine when to notify your skill. This topic describes how you specify that logic. For a description of the contents of the events themselves, see Receive Echo Button Events.

Terminology

As you define your events, you will encounter the following concepts.

  • Input Handler events – The conditions under which your skill is notified of Echo Button input. By defining these conditions, your skill can focus on processing the Echo Button input that it needs instead of processing every press and release. For example, you might define an event for "notify me only of the first player to buzz in."
  • Raw Echo Button events – The Echo Button actions, which are either down (press) or up (release), that contribute to the conditions of an Input Handler event being met. Each Input Handler event contains a record of the Raw Echo Button events that were relevant to it.
  • Recognizers – Conditions that, at any time, are either true or false. You use these to define your Input Handler events. For more information, see Recognizers.
  • Proxies – Gadget IDs that you use in your event definitions to refer to buttons that your skill cannot identify yet. For more information, see Proxies.

Defining Events

You define events when you configure the Input Handler using the GameEngine.StartInputHander directive in a response to any request from Alexa. You can define up to 32 different named Input Handler events for one Input Handler.

You configure events using the following form.

{
  "myEventName": {
    "meets": [ "a recognizer", "a different recognizer" ],
    "fails": [ "some other recognizer" ],
    "reports": "history",
    "shouldEndInputHandler": true,
    "maximumInvocations": 1,
    "triggerTimeMilliseconds": 1000
  }
}

The following is a description of each field. For detailed API reference information, see the GameEngine Interface Reference.

  • meets – Lists all of the recognizers that must be in the true state to fire this event.
  • fails – Lists all of the recognizers that must be in the false state to fire this event. You can read this as "fire the event myEventName when all of the recognizers in meets are true, and none of the recognizers in fails are true."
  • reports – Specifies which raw button events should be included in the inputEvents object in the Input Handler event that gets sent to your skill. It has three possible values:
    • history – Send all of the recorded history since the Input Handler started.
    • matches – Send only the sum of all events that made the meets conditions true.
    • nothing – Leave the inputEvents list empty.

    If you do not want to receive any raw button events, leave the inputEvents array empty.

  • shouldEndInputHandler – Determines whether the Input Handler should be considered closed after this event is fired. That is, no further events should be sent to your skill. Set this to false if you are defining an intermediate event and still expect to hear other events from the same Input Handler.
  • maximumInvocations – Enables you to limit the number of times that the skill is notified about the same event during the course of the Input Handler. This property is mutually exclusive with triggerTimeMilliseconds. Minimum: 1. Maximum (default): 2,048.

  • triggerTimeMilliseconds – Adds a time constraint to the event. Instead of being considered whenever a raw button event occurs, an event that has this parameter will only be considered once at triggerTimeMilliseconds after the Input Handler has started. Because a time-triggered event can only fire once, the maximumInvocations value is ignored. Omit this property entirely if you do not want to time-constrain the event. Minimum: 0. Maximum: 300,000.

If you want the event to be sent to your skill at the trigger time, provide both the meets and fails parameters as empty arrays.

Recognizers

Recognizers are conditions that, at any moment, are either true or false, based on all the raw button events that the Input Handler has received in the time elapsed since the Input Handler session started.

You use recognizers to define the Input Handler events for which your skill will be notified. Every time an Echo Button is pressed, the Input Handler reevaluates all the recognizers and therefore can determine if any of the Input Handler events that your skill defined have occurred.

You often use recognizers in conjunction with each other. There are the following recognizers: timed out, match, deviation, and progress.

The timed out recognizer

This recognizer is true when the Input Handler has reached the end of the timeout period that you specified using GameEngine.StartInputHandler. This is the default recognizer. It is defined automatically and cannot be overridden.

You do not need to use this recognizer when you define your Input Handler events. In any case, the timeout will happen and the Input Handler will terminate. However, you can use it to send your skill an event to tell the user something useful. The following is a simple event named "finished" that simply reports all the raw button events that happened before the Input Handler timed out.

{
  "events": {
    "finished": {
      "meets": "timed out",
      "reports": "history"
    }
  }
}

The match recognizer

The match recognizer takes a pattern of raw button events and returns true if all events are present, in the right order, somewhere in the Input Handler event history.

This recognizer has the following form.

{
  "recognizers": {
    "myRecognizerName": {
      "type": "match",
      "anchor": "end",
      "fuzzy": true,
      "gadgetIds": [ "gadgetId1", "gadgetId2", "gadgetId3" ],
      "actions": [ "down", "up" ],
      "pattern": [
        {
          "action": "down",
          "gadgetIds": [ "gadgetId1", "gadgetId2" ],
          "colors": [ "0000FF" ]
        }
      ]
    }
  }
}

The fields are as follows:

  • type – The name of the recognizer.
  • anchor – Determines where the pattern must appear in the history of this Input Handler. Possible values:
    • start – The first event in the pattern must be the first event in history. This is the default.
    • end – The last event in the pattern must be the last event in the history stream to date.
    • anywhere – The pattern may appear anywhere in the history stream.
  • fuzzy – When this field is set to true, this recognizer will consider the pattern matched even if there are extra events between the ones specified in the pattern. Otherwise, the match will fail at the first sign of deviation. The default value is false. For example, consider a pattern that requires three down events while the button is colored red. If the player presses the button four times with the pattern "red, red, green, red," then fuzzy matching would accept the overall match, while non-fuzzy matching would reject the match.
  • gadgetIds – This is a way to specify that this pattern should completely ignore raw button events that don't come from gadgets in this list. You may omit this property if you do not require gadget ID filtering. A common use for the gadgetIds property is to produce strict matching of patterns for multiple sets of Echo Buttons simultaneously. Consider a multiplayer game where each player uses two buttons to match patterns. You will want to be non-fuzzy about the order of events within each pair, but you will also want them to ignore each other's events.
  • actions – This acts as a filter to instruct the pattern to ignore any events with actions other than those in the given whitelist. You may omit this property to disable action filtering.
  • pattern – A chronological list of events that you want the recognizer to match. Each event in the list optionally allows for a range of matching criteria. All properties in a pattern are optional. Any unspecified parameter is considered a wildcard. That is, if you do not specify colors, then any color is an acceptable match. The empty object {} is the full wildcard, matching any raw button event.
    • action – Which of the Button Events to match: down or up.
    • gadgetIds – An array of acceptable sources.
    • colors – Array of acceptable colors to match, in RGB hexadecimal notation.

The deviation recognizer

This recognizer returns true when another specified recognizer reports that the player has deviated from an expected pattern.

The following is an example.

{
  "recognizers": {
    "playerHasFailed": {
      "type": "deviation",
      "recognizer": "recognizerName"
    }
  }
}

The fields are as follows:

  • type – The type of recognizer.
  • recognizer – The recognizer that, if deviated from, will trigger the event.

For example, you might have a recognizer called winningSequence that specifies a set of Echo Button presses. If the player successfully completes the sequence, then winningSequence is true. The rest of the time it is false.

The deviation recognizer enables your skill to immediately be notified if the player makes a mistake and therefore cannot complete the winning sequence. Using this example, you would define a recognizer as follows:

{
  "recognizers": {
    "playerHasFailed": {
      "type": "deviation",
      "recognizer": "winningSequence"
    }
  }
}

Then you would define an event like the following:

{
  "events": {
    "hasLost": {
      "meets": [ "playerHasFailed" ],
      "reports": "history",
      "shouldEndInputHandler": true
    }
  }
}

This way, your skill is notified immediately when the player can no longer win.

The progress recognizer

This recognizer checks another recognizer for the degree of completion and reports true if the completion is above the specified threshold.

The progress recognizer defined in the following example returns true when the patternMatcher recognizer is 50% complete.

{
  "recognizers": {
    "halfwayThere": {
      "type": "progress",
      "recognizer": "patternMatcher",
      "completion": 50
    }
  }
}

The fields are as follows:

  • type – The type of recognizer.
  • recognizer – The recognizer to check for degree of completion.
  • completion – The decimal percentage of completion at which the event should be sent. You can use this recognizer to fire off intermediate events that you want your skill to respond to before you terminate the Input Handler. Continuing the halfwayThere example, this is the definition of the event that uses the progress recognizer.
{
  "events": {
    "encourage": {
      "meets": "halfWayThere",
      "reports": "nothing",
      "maximumInvocations": 1,
      "shouldEndInputHandler": false
    }
  }
}

Proxies

Sometimes, your skill has no information on (or no preference on) which Echo Buttons you need to match to a recognizer, but you do know that they need to be different. This is the case, for example, in an anonymous roll call.

In these cases, you can use proxy gadget IDs to refer to the buttons instead. You define these in the proxies parameter of the GameEngine.StartInputHandler directive, and then use them wherever you would have used a gadget ID elsewhere. Proxies are assigned to each new raw Echo Button event that shows up on a first come, first served basis.

The following is an example of a roll call directive, where you know you want two different buttons to be pressed, but you don't care which two buttons these are.

{
  "type": "GameEngine.StartInputHandler",
  "timeout": 10000,
  "proxies": [ "one", "two" ],
  "recognizers": {
    "bothPressed": {
      "type": "match",
      "fuzzy": true,
      "anchor": "start",
      "pattern": [
        {
          "gadgetIds": [ "one" ],
          "action": "down"
        },
        {
          "gadgetIds": [ "two" ],
          "action": "down"
        }
      ]
    }
  },
  "events": {
    "allIn": {
      "meets": [ "bothPressed" ],
      "reports": "matches",
      "shouldEndInputHandler": true
    },
    "timeout": {
      "meets": [ "timed out" ],
      "reports": "history",
      "shouldEndInputHandler": true
    }
  }
}

Examples

The following are a few common scenarios and how to set them up. Keep in mind that you can combine them to achieve more complex behaviors by defining multiple recognizers and events in a single Input Handler.

Roll Call

Because Echo Buttons enter sleep mode to preserve battery life, when your skill is launched it is not likely that the Echo Buttons will actually be turned on and connected. There could also be fewer than or more than the number of buttons that your skill requires. For example, your skill might need three buttons, but the player has only paired two to this device, or has paired four. For these reasons, your skill should begin with some form of a roll call.

Imagine that you want to refer to a group of three buttons as "left", "middle" and "right" during your game. You could begin by using a GadgetController directive to set the LED animations for all three buttons to blue, and then have Alexa ask, "Great! Now, press these three blue buttons in order, from left to right."

To set this up, your GameEngine.StartInputHandler directive must include three recognizers, one for each button. The purpose is to detect if each button is pressed at least once. Set up the recognizers to recognize any down event, anywhere in the history. When all three recognizers are active, the complete event will fire and the Input Handler will stop. Otherwise, the Input Handler will time out and fire a failed event instead. In that case, the Input Handler will send all the raw button events that have occurred since the Input Handler started, so that you can determine if the player has pressed anything at all.

{
  "type": "GameEngine.StartInputHandler",
  "timeout": 10000,
  "proxies": [ "left", "middle", "right" ],
  "recognizers": {
    "all pressed": {
      "type": "match",
      "fuzzy": true,
      "anchor": "start",
      "pattern": [
        {
          "gadgetIds": [ "left" ],
          "action": "down"
        },
        {
          "gadgetIds": [ "middle" ],
          "action": "down"
        },
        {
          "gadgetIds": [ "right" ],
          "action": "down"
        }
      ]
    }
  },
  "events": {
    "complete": {
      "meets": [ "all pressed" ],
      "reports": "matches",
      "shouldEndInputHandler": true
    },
    "failed": {
      "meets": [ "timed out" ],
      "reports": "history",
      "shouldEndInputHandler": true
    }
  }
}

Three Strikes

This example plays a color sequence on the buttons and gives the player points for reproducing the sequence. We've warned the player not to hit the red buttons, though. After three strikes, they lose the game. In this case, we need a recognizer to catch the fail condition for the struck out event. Otherwise, the Input Handler will time out and report that as a survived event.

In both cases we will report all of history so that the skill code can count how many presses happened and produce a score.

{
  "type": "GameEngine.StartInputHandler",
  "timeout": 10000,
  "recognizers": {
    "three reds": {
      "type": "match",
      "anchor": "start",
      "fuzzy": true,
      "pattern": [
        {
          "action": "down",
          "colors": ["FF0000"],
          "repeat": 3
        }
      ]
    }
  },
  "events": {
    "struck out": {
      "meets": [ "three reds" ],
      "reports": "history",
      "shouldEndInputHandler": true
    },
    "survived": {
      "meets": [ "timed out" ],
      "reports": "history",
      "shouldEndInputHandler": true
    }
  }
}

Count the Goods

In this example, we have asked the player to press the buttons when they are lit up yellow. Winning means catching 20 yellow presses in the time allotted, in which case we report a win event. If the player runs out of time, we report a lose event. In this game, we don't care about other button presses, so we ignore them with fuzzy matching.

The win event will report all the yellow button presses so that the skill can determine how quickly the player won based on the event timestamps. The lose event will report the history also, so that the skill can count the number of yellow down events in the stream and tell the player how close they got.

{
  "type": "GameEngine.StartInputHandler",
  "timeout": 10000,
  "comment": "Win if we get 20 yellow down events in 10 seconds; otherwise, lose.",
  "recognizers": {
    "yellowDown": {
      "type": "match",
      "fuzzy": true,
      "anchor": "start",
      "pattern": [
        {
          "action": "down",
          "colors": [ "FFFF00" ],
          "repeat": 20
        }
      ]
    }
  },
  "events": {
    "win": {
      "meets": [ "yellowDown" ],
      "reports": "matches",
      "shouldEndInputHandler": true
    },
    "lose": {
      "meets": [ "timed out" ],
      "reports": "history",
      "shouldEndInputHandler": true
    }
  }
}