[Studio Beta] New Input Action System

Hi Creators!

We’re thrilled to bring you our new abstract Input Action System (IAS)! This new approach to input provides you with several new instances you can use to connect to input actions and arrange bindings across platforms at edit time. Those, combined with contexts, allows you to easily configure and edit an input system in your game and make sure that it’ll work on any device.

We’re releasing three new instances – InputContext, InputAction, and InputBinding – and one enum – InputActionType. Using the combination of these, you can:

  • :ring_buoy:Create a first-person shooter system with actions dynamically swapping in and out depending on if you’re in battle mode or in spectator mode
  • :oncoming_automobile:Build a comprehensive driving system equipped with acceleration/deceleration, car boosters, and gas stations
  • :framed_picture:Add hotkeys for your abilities system in a fighting game, so you can swap out moves seamlessly without missing a punch
  • :globe_with_meridians:Adapt your game for different platforms by adding new input bindings, no hardware-specific logic required

This is a huge step toward our broader goal of seamless cross-platform development. IAS removes the need to hardcode bindings and monitor specific input types for each piece of hardware to ensure they triggered the intended actions. Additionally, we now enable intuitive remapping of inputs during runtime depending on which input devices are detected.

With IAS, you can connect abstracted actions to multi-platform input which unlocks data-driven actions, contextual enabling and disabling of actions, and input-dependent UI. The Input Action System also makes input modular and reusable, allowing you to easily edit or reuse contexts, actions, and bindings.

During this Studio beta period, you can’t publish any Input Action System instances into your live experiences. Once we release the Input Action System to client, these will be available to use in-experience for smooth cross-platform development.

Keep reading to learn more!


How to Enable this Beta

Click here to read more

To enable this beta in Roblox Studio, follow these simple steps:

  1. Open Roblox Studio and navigate to the “File” menu.
  2. Click on “Beta Features”.
  3. Enable the “Input Action System” option by checking the corresponding checkbox (see screenshot below) and press Save.

  1. Restart Roblox Studio when prompted.

New Instances

First, let’s provide a brief overview of our new instance classes. More information can be found in our linked documentation.

InputAction: An Action is a gameplay mechanic (such as Jump or Move or Shoot) that can be triggered by several hardware inputs. Each Action has a type of input required to trigger it – whether it’s a button input type or directional movement.

InputBinding: A Binding is a hardware input that triggers an Action upon interaction. The inputs configured on a binding need to match the type of the action the binding is connected to. For example, only Thumbstick2 bindings or WASD bindings will trigger Direction2D actions. Bindings cover cross-platform hardware devices, including Keyboard/Mouse, Gamepad controllers, and even touch buttons connected on touch interfaces.

InputContext: A Context is a grouped collection of Actions. You can enable or disable Contexts (and their corresponding actions) based on game state, change the priority of Contexts to determine which Actions take precedence over others, and determine when input triggers should sink to lower priority Contexts.

Here’s a simple graphic to put it all together. You can see that InputBindings are children of InputActions, and InputActions are descendants of an InputContext.

Create your first Action

Let’s see what a simple Context-Action-Binding tree looks like in practice!

  1. Create an InputContext instance under StarterGui.
  2. Create an InputAction instance as a child of the InputContext.
  3. Let’s add a binding for Keyboard input. Create an InputBinding as a child of the InputAction.
    • Change the KeyCode to E.
  4. Let’s now add another binding for Gamepad input. Create another InputBinding as a child of the InputAction.
    • Change the KeyCode to ButtonX.
  5. Let’s now create a touch button for touch input.
    • Under StarterGui insert a ScreenGui instance.
    • Create a TextButton as a child of the ScreenGui.
    • Create a final InputBinding as a child of the InputAction.
    • Link the TextButton to the UIButton property of that final InputBinding.
  6. Create a local script as a child of the InputAction.
Here’s a sample script that implements Sprint:
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local character = player.Character
if not character or character.Parent == nil then
      character = player.CharacterAdded:Wait()
end

local humanoid = character:WaitForChild("Humanoid")

local action = script.Parent
local defaultWalkSpeed = humanoid.WalkSpeed
local fastWalkSpeed = defaultWalkSpeed * 2

action.Pressed:Connect(function()
   humanoid.WalkSpeed = fastWalkSpeed
end)

action.StateChanged:Connect(function(state)
   print("The action was changed to state " .. tostring(state))
end)

action.Released:Connect(function()
   humanoid.WalkSpeed = defaultWalkSpeed
end)

After all of this, here’s what you should see in Studio:

When you enter Play mode, you’ll be able to trigger the action with any of the input bindings you created. Keyboard E, Gamepad ButtonX, and clicking on the button will all activate the Action!

Creating an Ecosystem of Contexts and Actions

As you build out your gameplay mechanics, you may find yourself needing to group actions together into distinct contexts that swap in and out. With multiple Contexts with different priorities and sinking, you can enable/disable Actions in a group, and also reuse Bindings based on what state the player is in.

For example, you may have a “Gameplay” Context and have “Interact” with ButtonB as one of its bindings. You may also have a “UI” Context that uses ButtonB to trigger a “Dismiss” Action. Since UIContext has a higher priority and context sinking enabled, when ButtonB is pressed while UIContext is Enabled, the Interact action under GameplayContext will not be triggered.

Contexts can support entire ecosystems of Actions. For example:

  • A first-person shooter game might have a BattleContext, AimAssistContext, LobbyContext, and UIContext.
  • A racing game might have a VehicleDriverContext, VehiclePassengerContext, SpectateContext, and UIContext.

If you want to take a closer look at our Input Action System, we have two examples for you to check out here!

So how does this fit in with UserInputService (UIS) and ContextActionService (CAS)?

We strongly recommend that all Creators currently using UIS or CAS for input mapping transition to the new Input Action System. IAS addresses many of the issues and inconsistencies reported with CAS and offers a more streamlined, reliable way to handle input mapping.

What’s happening to UIS and CAS?

  • We’ll continue to support UIS functionality (e.g., GetStringForKeyCode, GamepadEnabled, and similar APIs).
  • We’ll maintain CAS as-is for existing implementations, but all future feature requests and improvements will be handled through IAS instead.

Ideally, you should rely primarily on Input Action System in your experiences for all input mapping needs as it’ll be the input API that we’ll be primarily supporting in the future.

Release Notes

Click here to read more
  • If you want to set the UIButton property on one of your Bindings to a button in StarterGui, make sure the associated Context-Action is parented to StarterGui as well.

:blue_heart: Made with love

IAS was made possible thanks to hard work from @NoUniqueAddress, @AykeriZero, @uiuxartist, and @MetaVars.

We can’t wait to hear your thoughts on IAS and see all the amazing things you create! Look out for more action types and binding settings in the future. Let us know about your experience and if you encounter any issues or features you’d like us to add! :smile:

496 Likes

This topic was automatically opened after 10 minutes.


Unless I’m missing something, I’m seeing a crucial lack of one of the biggest missing parts of the three previous input systems: a built-in way for people to rebind game actions without extra effort on part of developers. This would save a bunch of time for devs (especially smaller teams) and would be a massive win for accessibility.

Please consider implementing this. There’s no better time than now to get this right.

161 Likes

Finally a change in the input system, although it feels a little bit weird to use. Still thanks again, Roblox.

16 Likes

These input bindings feels like they were designed to be interfaced by non-programmers, but programmers are the people that would have to configure them at the end of the day. This feels a bit regressive in comparison to ContextActionService/UserInputService and libraries that build upon those. So it is quite awkward that the recommendation is to migrate to this new input mapping.

123 Likes

Will this solve? Developer Framework TextInput Component does QWERTZ wrong for UNDO and REDO shortcuts, even in Next Gen Explorer

Or will there be InputAction2 instances in the future. :thinking:

10 Likes

Will UIS InputBegan, InputChanged and InputEnded events still be supported, alongside the few mentioned?

8 Likes

We are considering this, thank you!

29 Likes

Very cool! I’ll definitely be using this refined input system. Thank you for making this.

4 Likes

+1. im not a fan of instance-oriented APIs, it requires a lot of setup and code for something that couldve just been a table :frowning_with_open_mouth:

92 Likes

How about the Mouse from Player:GetMouse()? That is an input type that is widely used but I do not see mentioned at all in this post. Does this mean that the Mouse Instance is finally getting deprecated??

4 Likes

this is a joke right? instances again?

82 Likes

This. It somewhat reminds me of the new audio api where setting up and using it in scripts is a pretty awful experience. Unnecessary Instance.new calls followed by however many property changes just can’t be done cleanly without writing a wrapper module to hide the mess and I’m not sure why this is the direction they went in for a system that can only be used via scripts anyway.

35 Likes

Don’t forget the new BodyMovers, because everyone realistically wants to create and position a bajillion attachments!

I got over my fear of using deprecated instances because of them.

27 Likes

Also a follow up question to my previous reply, does this mean that we’ll be getting the options to rebind our keybinds??? I always wanted to remove the i, o buttons and move w a s d to r d f g… This would provide great accessibility support to some.

8 Likes

Is this not just a dumbed down version of what I was already doing with UserInputService perfectly fine for years?

13 Likes

They’ve already expressed that they want to create ContextActionService rebinding in the past, don’t know how they’ll go through with this but it’s a possibility.

Hopefully they add the ability to use mouse side buttons for inputs soon, I’ve wanted that for ages and considering they’re updating inputs it might happen sometime soon.

10 Likes

I find it a little odd that we didn’t get a “toggle” action type. I know you can do it with code, but I thought it would’ve been an option if inputs are being simplified like this.

5 Likes

I’m guessing the prior art was Unity’s input system since that’s actually an asset in the project, however I think it translates poorly here because the whole point of that system was that all of your bindings are in a single asset which is configured in the editor, then you can write code using that singular instance.

Whilst a lot of the issues can be resolved with a wrapper library, I feel like the necessity of a wrapper to make it easily used suggests that this should’ve been workshopped a bit more or a feedback session should’ve been considered.

I think overall this is a step in the right direction, and it makes doing cross-platform bindings a lot easier (and is definitely easier for game designers to change things around), but I don’t think the use of multiple instances that hold tiny amounts of configuration data was the best idea. I think a singular instance containing the whole input mapping for a context would have been a better choice.

30 Likes

This is how I expect all replacement guides to look like

With every single possibility and within that layout for super easy overview and visibility.

15 Likes