6 min read

Source: Roblox Creator Hub · CC BY 4.0 · View source · Code samples: MIT Imported 2026-10-03. Formatting adapted for this site.

Micro gamepad input

Roblox experiences can receive input from micro gamepads, navigation-focused controllers that typically provide a directional pad and can include additional buttons. TV remotes are one type of micro gamepad; they commonly provide a directional pad, center button, and back button. Micro gamepads use the Gamepad1–Gamepad8 input slots and are represented as MicroGamepad when they are the player's preferred input.

TV remotes expose TV remote-specific keycodes, but their button events currently map to legacy gamepad keycodes before reaching experience code. Use the Input Action System or ContextActionService to bind actions to those legacy events.

Input type detection

MicroGamepad is a future API for identifying TV remotes and other navigation-focused controllers. It is not currently set for these devices, so until runtime support is complete, check the supported keycodes for Gamepad1:

local UserInputService = game:GetService("UserInputService")

local function isMicroGamepadPreferred()
	local gamepad = Enum.UserInputType.Gamepad1
	if not UserInputService:GetGamepadConnected(gamepad) then
		return false
	end

	local supportsThumbstick1 = UserInputService:GamepadSupports(
		gamepad,
		Enum.KeyCode.Thumbstick1
	)
	local supportsThumbstick2 = UserInputService:GamepadSupports(
		gamepad,
		Enum.KeyCode.Thumbstick2
	)

	return not supportsThumbstick1 and not supportsThumbstick2
end

Gamepad1 is always the most preferred connected gamepad. If a player has only a TV remote, it occupies Gamepad1. If another gamepad is connected, that gamepad occupies Gamepad1 instead. Therefore, checking that Gamepad1 supports neither Thumbstick1 nor Thumbstick2 indicates that the currently preferred gamepad is a micro gamepad.

If you need to identify a TV remote specifically, check whether the preferred gamepad supports ButtonCenter in addition to checking its micro gamepad capabilities:

local UserInputService = game:GetService("UserInputService")

local function isTVRemotePreferred()
	return isMicroGamepadPreferred()
		and UserInputService:GamepadSupports(
			Enum.UserInputType.Gamepad1,
			Enum.KeyCode.ButtonCenter
		)
end

Reuse isMicroGamepadPreferred() in your action handlers instead of implementing device detection separately for each action system. Use isTVRemotePreferred() only when behavior must be specific to a TV remote rather than to micro gamepads generally.

Micro gamepad keycodes

Micro gamepads can expose these navigation-oriented keycodes. TV remotes commonly support this set:

Keycode Meaning
[`ButtonUp`](/docs/enum-keycode) Move focus or selection up.
[`ButtonDown`](/docs/enum-keycode) Move focus or selection down.
[`ButtonLeft`](/docs/enum-keycode) Move focus or selection left.
[`ButtonRight`](/docs/enum-keycode) Move focus or selection right.
[`ButtonCenter`](/docs/enum-keycode) Confirm, select, or activate the focused item.
[`ButtonBack`](/docs/enum-keycode) Cancel, close, or return to the previous screen.

These are example TV remote capabilities; experiences might encounter additional supported keycodes. See Legacy gamepad control schema for how these keycodes currently map to gamepad events.

Legacy gamepad control schema

Until raw TV remote events are available, bind actions to the legacy keycodes generated by TV remote input. The mapping depends on the input context:

TV remote keycode Context Current gamepad event Common use
[`ButtonCenter`](/docs/enum-keycode) All contexts [`ButtonA`](/docs/enum-keycode) Select or jump.
[`ButtonBack`](/docs/enum-keycode) All contexts [`ButtonB`](/docs/enum-keycode) Go back, dismiss a dialog, or open the selector menu.
[`ButtonUp`](/docs/enum-keycode), [`ButtonDown`](/docs/enum-keycode), [`ButtonLeft`](/docs/enum-keycode), [`ButtonRight`](/docs/enum-keycode) Menu, selection mode, or virtual cursor [`DPadUp`](/docs/enum-keycode), [`DPadDown`](/docs/enum-keycode), [`DPadLeft`](/docs/enum-keycode), [`DPadRight`](/docs/enum-keycode) Navigate focus or selection.
[`ButtonUp`](/docs/enum-keycode), [`ButtonDown`](/docs/enum-keycode) Studio or experience with Classic Camera [`Thumbstick1`](/docs/enum-keycode) Move the character.
[`ButtonLeft`](/docs/enum-keycode), [`ButtonRight`](/docs/enum-keycode) Studio or experience with Classic Camera [`Thumbstick2`](/docs/enum-keycode) Rotate the camera.
[`ButtonUp`](/docs/enum-keycode), [`ButtonDown`](/docs/enum-keycode), [`ButtonLeft`](/docs/enum-keycode), [`ButtonRight`](/docs/enum-keycode) Studio or experience with Follow Camera [`Thumbstick1`](/docs/enum-keycode) Move the character with an auto-rotated camera.

Note

Do not use legacy keycodes alone to identify a TV remote. The same keycodes can also come from a full gamepad.

Binding actions

Choose the approach that matches your experience:

Both examples below reuse the isMicroGamepadPreferred() helper from the input type detection section.

Option 1: Input Action System

For example, create ConfirmOrJump and BackOrCancel actions with legacy ButtonA and ButtonB bindings:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Create these InputAction instances and bindings in Studio:
-- ReplicatedStorage.Inputs.NavigationContext.ConfirmOrJump -> ButtonA
-- ReplicatedStorage.Inputs.NavigationContext.BackOrCancel -> ButtonB
local navigationContext = ReplicatedStorage:WaitForChild("Inputs"):WaitForChild("NavigationContext")
local confirmOrJump = navigationContext:WaitForChild("ConfirmOrJump")
local backOrCancel = navigationContext:WaitForChild("BackOrCancel")

confirmOrJump.Pressed:Connect(function()
	if isMicroGamepadPreferred() then
		ActivateFocusedItem()
	else
		Jump()
	end
end)

backOrCancel.Pressed:Connect(function()
	if isMicroGamepadPreferred() then
		NavigateBack()
	else
		CancelGameplayAction()
	end
end)

For example, directional navigation actions can use DPadUp, DPadDown, DPadLeft, and DPadRight bindings and call focus-navigation functions only when isMicroGamepadPreferred() returns true. Use separate input contexts for navigation and gameplay so the same legacy button does not trigger both actions simultaneously.

Option 2: ContextActionService

If your experience already uses CAS, keep the existing bindings and reuse the same capability check:

local ContextActionService = game:GetService("ContextActionService")

local function confirmOrJump(actionName, inputState)
	if inputState ~= Enum.UserInputState.Begin then
		return Enum.ContextActionResult.Pass
	end

	if isMicroGamepadPreferred() then
		ActivateFocusedItem()
	else
		Jump()
	end

	return Enum.ContextActionResult.Sink
end

ContextActionService:BindAction(
	"ConfirmOrJump",
	confirmOrJump,
	false,
	Enum.KeyCode.ButtonA
)

Use the same pattern for ButtonB and the D-pad bindings. Return Pass for input states you don't handle so other bound actions can still process them, and return Sink once you handle the input.

In the future, raw TV remote events will allow IAS or CAS actions to bind directly to ButtonUp, ButtonDown, ButtonLeft, ButtonRight, ButtonCenter, and ButtonBack, without legacy-keycode branching.

Designing UI for TV remote input

Controller emulation

Test on the target TV platform with a physical remote whenever possible. You can also emulate Android TV in Studio with the Device Emulator and Controller Emulator.

Selecting Android TV makes Studio render a TV-sized 1920×1080 viewport and enables a virtual TV Remote on Gamepad1. The remote is driven from the keyboard or mouse and follows the same input path as a connected TV remote.

To test TV remote input:

  1. Open Studio's Test menu, enable Device Emulator, and select the Android TV device in the Device Emulator.
  2. Open the Controller Emulator and select TV Remote from the controller picker. The TV Remote controller is available only when Android TV is selected in the Device Emulator.
  3. Use the displayed keyboard controls to send D-pad, center, and back input.
  4. Verify the resulting InputBegan, InputChanged, and action events in your experience.
View of the TV Remote controller in the Controller Emulator.

You can control the virtual remote with the keyboard or mouse using the displayed mappings. To view or change those mappings, use Edit mappings in the Controller Emulator; see Controller emulation for more details.