🔢 Binds Module

A centralized, context-based input configuration system that prevents bind conflicts by organizing bindings into logical contexts (Global, Combat, Inventory, Drop).

Why Contexts?

The problem with traditional bind systems

❌ The Problem

In traditional systems, if you bind "X" to "Drop" globally, it will trigger even when:

  • Opening the backpack
  • In a menu
  • During combat

This causes conflicts and confusing UX.

✔ The Solution

Stoway's context system ensures "X" only triggers "Drop" when:

  • Gamepad input is active
  • Inventory mode is enabled
  • A slot is selected

Same key, different actions in different contexts.

Context Structure

Four contexts for different interaction modes

Context Name
When Enabled
Contains
StowayGlobal
Always
Backpack toggle, Mode switch
StowayCombat
Combat Mode
Hotbar slot selection
StowayInventory
Inventory Mode
Swap, Drop, QuickMove, Cancel
StowayDrop
Dropping Item
Increase/Decrease amount

File Structure

Location and organization

File Location Tree
ReplicatedStorage/
- Shared/
-   Binds.luau       -- Main configuration file
Binds.luau Structure Luau
local Binds = {}

-- Helper function for applying binds
function Binds.ApplyToAction(action, bindConfig, inputType?)

-- Hotbar slot configuration (1-10)
Binds.HotbarSlots = {
    [1] = { Display = "1", PC = {...}, Console = {...} },
    [2] = { ... },
    -- ... up to 10
}

-- Global binds (always available)
Binds.Global = {
    Backpack = { PC = {...}, Console = {...} },
    SwitchMode = { PC = {...}, Console = {...} },
    InventoryActions = { Swap = {...}, Drop = {...}, ... },
    DropActions = { Increase = {...}, Decrease = {...} }
}

return Binds

Bind Format

How to define input bindings

Bind Structure Luau
-- Single bind entry
{
    Main = Enum.KeyCode."KeyName",        -- Required: primary key
    Modifiers = { Enum.KeyCode."Modifier" }  -- Optional: modifier keys
}

-- Examples
{ Main = Enum.KeyCode.One }                                    -- Just "1"
{ Main = Enum.KeyCode.ButtonX, Modifiers = { Enum.KeyCode.ButtonR1 } }  -- R1 + X
{ Main = Enum.KeyCode.Tab }                                    -- Tab key
Field Type Required Description
Main Enum.KeyCode Yes The primary key to bind
Modifiers {Enum.KeyCode} No Modifier keys that must be held

Hotbar Slots Configuration

Slot binding for 1-10 keys

Hotbar Bind Examples Luau
Binds.HotbarSlots = {
    [1] = {
        Display = "1",  -- Shown on slot
        PC = { {Main = Enum.KeyCode.One} },
        Console = { {Main = Enum.KeyCode.ButtonX, Modifiers = {Enum.KeyCode.ButtonR1}} }
    },
    [2] = {
        Display = "2",
        PC = { {Main = Enum.KeyCode.Two} },
        Console = { {Main = Enum.KeyCode.ButtonY, Modifiers = {Enum.KeyCode.ButtonR1}} }
    },
    [3] = {
        Display = "3",
        PC = { {Main = Enum.KeyCode.Three} },
        Console = { {Main = Enum.KeyCode.ButtonB, Modifiers = {Enum.KeyCode.ButtonR1}} }
    },
    [4] = {
        Display = "4",
        PC = { {Main = Enum.KeyCode.Four} },
        Console = { {Main = Enum.KeyCode.ButtonA, Modifiers = {Enum.KeyCode.ButtonR1}} }
    },
    [5] = {
        Display = "5",
        PC = { {Main = Enum.KeyCode.Five} },
        Console = { {Main = Enum.KeyCode.ButtonX, Modifiers = {Enum.KeyCode.ButtonL1}} }
    },
    [6] = {
        Display = "6",
        PC = { {Main = Enum.KeyCode.Six} },
        Console = { {Main = Enum.KeyCode.ButtonY, Modifiers = {Enum.KeyCode.ButtonL1}} }
    },
    [7] = {
        Display = "7",
        PC = { {Main = Enum.KeyCode.Seven} },
        Console = { {Main = Enum.KeyCode.ButtonB, Modifiers = {Enum.KeyCode.ButtonL1}} }
    },
    [8] = {
        Display = "8",
        PC = { {Main = Enum.KeyCode.Eight} },
        Console = { {Main = Enum.KeyCode.ButtonA, Modifiers = {Enum.KeyCode.ButtonL1}} }
    },
    [9] = {
        Display = "9",
        PC = { {Main = Enum.KeyCode.Nine} },
        Console = { {Main = Enum.KeyCode.DPadUp, Modifiers = {Enum.KeyCode.ButtonR1}} }
    },
    [10] = {
        Display = "0",
        PC = { {Main = Enum.KeyCode.Zero} },
        Console = { {Main = Enum.KeyCode.DPadDown, Modifiers = {Enum.KeyCode.ButtonR1}} }
    }
}
💡 Tip: PC binds use number keys 1-0. Console binds use R1/L1 + face buttons for quick access.

Global Binds

Bindings available in all contexts

Global Configuration Luau
Binds.Global = {
    -- Toggle backpack visibility
    Backpack = {
        PC = { 
            {Main = Enum.KeyCode.Tab},
            {Main = Enum.KeyCode.B}
        },
        Console = { {Main = Enum.KeyCode.DPadLeft} }
    },

    -- Switch between Combat/Inventory modes
    SwitchMode = {
        PC = { {Main = Enum.KeyCode.M} },  -- M key for testing
        Console = { {Main = Enum.KeyCode.ButtonL3} }  -- Long press L3
    },

    -- Inventory mode actions
    InventoryActions = {
        Swap = {
            Console = { {Main = Enum.KeyCode.ButtonY} }
        },
        Drop = {
            Console = { {Main = Enum.KeyCode.ButtonX} }
        },
        QuickMove = {
            Console = { {Main = Enum.KeyCode.ButtonL1, Modifiers = {Enum.KeyCode.ButtonR1}} }
        },
        Cancel = {
            Console = { {Main = Enum.KeyCode.ButtonB} }
        }
    },

    -- Drop amount adjustment
    DropActions = {
        Increase = { Console = { {Main = Enum.KeyCode.DPadUp} } },
        Decrease = { Console = { {Main = Enum.KeyCode.DPadDown} } },
    }
}

Helper Function

ApplyToAction for easy binding

The ApplyToAction helper function simplifies applying binds to IllusionIAS actions:

ApplyToAction Usage Luau
-- Signature
function Binds.ApplyToAction(
    action,              -- IllusionIAS action object
    bindConfig,          -- Bind entry from Binds table
    inputType: ("PC" | "Console")?  -- Optional: filter by input type
)

-- Example 1: Apply all binds (PC + Console)
local swapAction = IllusionIAS.new("ConsoleSwapAction")
Binds.ApplyToAction(swapAction, Binds.Global.InventoryActions.Swap)

-- Example 2: Apply only Console binds
local dropAction = IllusionIAS.new("ConsoleDropAction")
Binds.ApplyToAction(dropAction, Binds.Global.InventoryActions.Drop, "Console")

-- Example 3: Apply PC binds only
local backpackAction = IllusionIAS.new("BackpackAction")
Binds.ApplyToAction(backpackAction, Binds.Global.Backpack, "PC")

Customization Example

Adding a custom bind

1

Add to Binds.luau

Custom bind entry Luau
-- In Binds.Global section
InventoryActions = {
    Swap = { Console = { {Main = Enum.KeyCode.ButtonY} } },
    Drop = { Console = { {Main = Enum.KeyCode.ButtonX} } },
    QuickMove = { Console = { {Main = Enum.KeyCode.ButtonL1, Modifiers = {Enum.KeyCode.ButtonR1}} } },
    Cancel = { Console = { {Main = Enum.KeyCode.ButtonB} } },
    -- Add your custom action
    EquipBest = { 
        Console = { {Main = Enum.KeyCode.ButtonR3} }  -- R3 (right stick click)
    }
}
2

Create the Action

In SelectionManager.luau Luau
-- Create action
local equipBestAction = IllusionIAS.new("ConsoleEquipBestAction")
Binds.ApplyToAction(equipBestAction, Binds.Global.InventoryActions.EquipBest, "Console")

-- Connect handler
equipBestAction.Activated:Connect(function(active, pressed)
    if not SelectionState.enabled or not pressed then return end
    SelectionManager.HandleEquipBest()
end)

-- Add to inventory context
IllusionIAS.addContext(InputManager.ContextInventory, equipBestAction)

Available Key Codes

Commonly used Enum.KeyCode values

Category Key Codes
Number Keys One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Zero
Letter Keys A, B, C, ... Z
Gamepad - Face Buttons ButtonA, ButtonB, ButtonX, ButtonY
Gamepad - Shoulder ButtonL1, ButtonR1, ButtonL2, ButtonR2
Gamepad - Stick ButtonL3, ButtonR3 (click)
Gamepad - D-Pad DPadUp, DPadDown, DPadLeft, DPadRight
Special Tab, Escape, Space, Backspace, Enter

Related Documentation

See also