Creating a quiz with Echo Buttons and Alexa.NET.Gadgets

In my last article I wrote a little about using Gadgets with the Amazon Echo – specifically (at least at the moment) the Echo Buttons. We talked about the concept of the Gadget Controller changing the state of the buttons and the Game Engine interpreting the interactions.

So now what? Well now we write a simple skill that uses these techniques and gives us a starting point for building more advanced ideas in the future.

The idea that everyone can understand and relate to is a simple quiz – first person to press the button gets to answer the question.

Because I want to focus on the gadget interaction in this post, the resulting code may not feel very natural – and I’d expect anyone using it to fill in the blanks, make Alexa sound more game show host than this will before trying to get the skill live.

Roll Call

The first step in getting your gadgets to work with your skill is to ensure that you know which gadgets you’re playing with. The Roll Call. You shouldn’t assume which gadgets are going to be used – plus in the case of the Echo Buttons they switch off after a period of inactivity so you want them up and running again before you start the skill.

The way this works is that you ask your players to press the buttons they plan to use with your skill, in the order they want to use them (player 1 first, then player 2 etc.)

Requesting Roll Call

With the request you send a match recogniser, looking to match a “down” event from each button in turn. When the event returns an event to your skill – you can pick up the gadget ids in the order they were pressed and store them as state against your skill. Then for the duration of the session you know which gadget maps to each player.

But how do you make sure the players don’t just press the same button twice for a two player game? You don’t know which buttons they plan to use so you can’t restrict the input…right?

Well actually, Amazon have thought of this and introduced the concept of proxies. So the way this works is that you specify an array of friendly names that represent individual gadgets. Amazon assigns these friendly names on a first-come, first-served basis.

What this means is that you end up with a directive looking a little like the following for your skill to roll call two gadgets; a proxy for each gadget, a recogniser wanting a down event from each in turn, and an event to let you know what that happened.

{
  "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
    }
  }
}

Now sure – you can wire this up in a skill, but it’s a lot of boilerplate code for each gadget enabled skill. Once you’ve understood what’s happening under the hood you really want it wrapped up and hidden away.

Which is exactly what I’ve done with Alexa.NET.Gadgets!

using Alexa.NET.Gadgets.GameEngine
...
var response = ResponseBuilder.Ask("Please press the buttons you want to use for this quiz",null);
...
response.AddRollCall(20000, "first", "second");

This is assuming you only want two, but it will look for as many friendly names as you give.

Response from user

So you’ve asked – and now Alexa is waiting for the buttons to be pressed, if they were switched off then pressing them down will turn them on and register the event.

Once the right number of buttons have been pressed, you’ll receive an InputHandlerEventRequest. The trick is to then look at the event – make sure the event name matches the one you sent out for a roll call, then look at the events involved in triggering the event and get the gadgetIds in order.

Again – boilerplate. Considering you had a helper on the way out, it would be rude not to have one to figure out the response. So you can ask Alexa.NET.Gadgets to do the figuring out for you and just put the results in a Dictionary<string,string> for you, matching the names in the order you give them with the order they appear in the event request.

If the event doesn’t match the one used for roll call – then the method will return false.

using Alexa.NET.Gadgets.GameEngine
...
switch(skillRequest.Request)
{
    case InputHandlerEventRequest inputHandler:
      if(!inputHandler.TryRollCallResult(out Dictionary<string,string> mapping, "first","second"))
			{
			  //Time out - respond asking for a proper roll call
			}
			
			//Success - Log mapping["first"] and mapping["second"] for future use.
}

shameless plug: If you want a nice easy way to mess around with request and session level state, you can always use Alexa.NET.StateManagement which makes that a lot easier 😉

Fingers on buzzers

Okay – so you’ve now got your gadget IDs for your quiz. Player 1 and player 2 are stored as a pair of gadgetIDs somewhere. So now you’re ready for your first question.

Requesting

You start doing this as part of your feedback from the successful rollcall.

With voice you ask the question. With Gadgets you send another match recogniser and event.

This match recogniser has a different pattern though – asking for just one button down event, and the event can come from any of the gadgets you’ve just received back from the roll call (but only those gadgets – don’t want them turning on another gadget and suddenly not knowing which player is involved)

Yup – you guessed it. Boilerplate means helper method! (and yes, it is a ridiculous question – focusing on the gadgets remember).

var question = "Question One. Which is the bigger number, 3 or 5?";
var response = ResponseBuilder.Ask($"Okay then, let's begin! {question}",null);
response.WhenFirstButtonDown(mapping, "buzzedIn", 10000);

Oh, yeah, the WhenFirstButtonDown option can handle an array of gadgetIds you’ve stored, but it can also handle mappings that came from TryRollCallResult as well, making it easier to flow from roll call straight into your quiz.

Response

So the users response is going to come back as another InputHandlerEventRequest. You once again need to ensure that the event name that’s passed back is the one you need for the button down response (always that chance they’ve walked off and you’re getting a timed out event!)

And this time – if the event name is right, you just want the first gadget mentioned, because that’s the one that was pressed. You can then match this gadgetId to one of the two you’ve got stored in state and ask that player for the answer.

I know – it’s getting repetitive, but so is writing this code to match the event and get the gadget id. So a helper means that although you have to keep doing it, it only takes a couple of lines.

using Alexa.NET.Gadgets.GameEngine
...
switch(skillRequest.Request)
{
    case InputHandlerEventRequest inputHandler:
      if(inputHandler.TryMapEventGadget("buzzedIn", out var gadgetId))
      {
        //Perform logic based on who buzzed in
      }
}

Ask for the answer – back to voice.

So now you’ve got your fastest player, you can go back to a standard skill pattern – asking them to give the answer to the question and comparing it to the known answer. Responding with an appropriate response (possibly using a sound effect based on the answer being correct or not?)

Then you can ask the players if they’re ready for the next question, or if they want to stop the quiz now. If they’re happy to continue – you loop the whole process with a different question and start again; continuing the process until you run out of questions or the users run out of desire to keep playing.

Now this has all been a very quick view on how the gadgets work, and I don’t expect you to base it all off the little code snippets I’ve embedded in this blog post. They’re just references to use against the sample I’ve written:

Alexa.NET.Samples – Simple Gadget Quiz

But hopefully it helps explain the steps that the quiz goes through with the gadgets, and why it’s structured the way it is.

Let me know if there’s anything more I can write about that would help.

One thought on “Creating a quiz with Echo Buttons and Alexa.NET.Gadgets

Leave a Reply

Your email address will not be published. Required fields are marked *