# Exit the Game by a Long Key Press

The usual way of exiting a game and returning to PinballY is to press the "Exit" button on your cabinet. PinballY lets you map the Exit function to any keyboard key or joystick button, so as long as you have a dedicated button on your cab labeled Exit, you can assign it in PinballY as the "end game" button.

But what if your cab doesn't have a separate Exit button? Some cab builders prefer a very minimal set of buttons, to better replicate the spare look of a real pinball machine.

There are a few ways to operate a cab without an Exit button. The most obvious way is to cheat, by really having an Exit button after all, but putting it someplace hidden, such as on the bottom of the cabinet, or inside the coin door. Another option is to use special features in your key encoder to simulate extra buttons; for example, some key encoders let you create "Shift" buttons that give all of your other buttons a second meaning. So you could make your Start button do double duty as both the Start and Exit button, by assigning Exit to its shifted function.

Hidden buttons and shifted buttons can be a little cumbersome to use, though. Another possibility that you might find a little more convenient is to use a "long press" with one of your regular buttons. That means that you pick one of the standard buttons (the Start button, say), and hold it down for a few seconds to activate the Exit Game function. The Start button seems like the right choice to me, since there's a nice symmetry to using the same button to start and end a game. The Start button is also a good choice for practical reasons, in that I can't think of any pinball tables where you'd need to press and hold the Start button while playing - so you won't accidentally exit the game when you meant to do something else within the game. (In contrast, you wouldn't want to use the flipper buttons for a long-press gesture, since it's perfectly normal to hold down a flipper button for a long time while playing, such as when you want to trap a ball.)

PinballY doesn't have any notion of a "long press" built in, but it's something that we can easily implement with Javascript.

## Key event listeners and timers

Our approach to implementing the long press is pretty simple, especially if you've read any of the other worked examples that involve keyboard events. We really just need three elements:

- A key event listener that fires when you press the button that we're going to use for the long press. This listener will start a timer each time you press the button; when the timer expires, it'll fire a Kill Game command to terminate the running game and return to PinballY, as though you had pressed a physical Exit button on the cabinet.
- Another key event listener that fires when you release the button. This simply cancels the timer, if it's running, so that short presses (below the desired hold interval) don't also exit the running game.
- The timer function, which simply fires the Kill Game command. The timer function will only execute when the timer runs to completion, which will only happen when the player presses and holds the button for longer than the timeout interval.

For more details on keyboard events, see KeyEvent. For details on timers, see setTimeout() and clearTimeout() in System Functions.

### The script

Here's the script that puts this all together. To make it easier to adapt to different situations, we defined the button that triggers the command and the long-press hold time with constants at the top. Just change those constants to customize either element.

// The key code to use for the long press. Set this to one of the // standard Web browser KeyboardEvent key codes: see, for example, // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values const StartButtonCode = "Digit1"; // Long key press time. This is the time in milliseconds for the long // press. Hold down the key for this long to exit the game. const LongPressTime = 3000; // When a key timer is running, we remember it here let timer = undefined; // When the start button is pressed, start a timer. When the timer // expires, send a KILL GAME command to the main window, to simulate // the effect of the EXIT button. mainWindow.on("keydown keybgdown", ev => { if (!ev.repeat && ev.code == StartButtonCode && mainWindow.getUIMode().runMode) { cancelTimer(); timer = setTimeout(function() { mainWindow.doCommand(command.KillGame); timer = undefined; }, LongPressTime); } }); // If the start button is released while our long-press timer is // running, cancel the timer. mainWindow.on("keyup keybgup", ev => { if (ev.code == StartButtonCode) cancelTimer(); }); // Cancel the timer, if it's running. function cancelTimer() { if (timer) { clearTimeout(timer); timer = undefined; } }