{"id":"illusionac/illusion-inputactionsystem","name":"illusion-inputactionsystem","scope":"illusionac","platform":"roblox","description":"Illusion's InputActionSystem - A modular input & keybind management library for Roblox","version":"1.2.5","latest":"1.2.5","versions":["1.0.0","1.1.0","1.2.0","1.2.5"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"e54caf2494765f0493e0cf72dd67a0c0af230750356248a4290e2bc04b35e6e0","likes":0,"downloads":0,"install":"forest install illusionac/illusion-inputactionsystem","url":"https://forest.dev/p/roblox/illusionac/illusion-inputactionsystem","files":"https://api.forest.dev/ai/package/roblox/illusionac/illusion-inputactionsystem/files","readme":"# <div align=\"center\"> Illusion's InputActionSystem (IIAS) </div>\n\n<div align=\"center\">\n\n![IIASLogo|256x256, 75%](./IIASLogo.png)\n</div>\n\n[![Wally Version](https://img.shields.io/badge/wally-v1.2.5-blue.svg)](https://wally.run/package/illusionac/illusion-inputactionsystem)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n**Illusion's InputActionSystem (IIAS)** is a powerful, production-ready input and keybind management library built for Roblox's modern **InputActionSystem (IAS)** engine architecture. It provides an intuitive, high-level API over native `InputContext`, `InputAction`, and `InputBinding` instances while adding game-ready mechanics like dynamic cooldowns, input buffering, double-tap activation, context groups, mobile GUI integration, and lifecycle signals.\n\n---\n\n## 📑 Table of Contents\n\n- [Key Features](#-key-features)\n- [Installation](#-installation)\n- [Quick Start](#-quick-start)\n- [Core Concepts](#-core-concepts)\n  - [Hold vs Toggle Modes](#1-hold-vs-toggle-modes)\n  - [Cooldown System & Lifecycle Signals](#2-cooldown-system--lifecycle-signals)\n  - [Context Groups](#3-context-groups)\n  - [Input Buffering](#4-input-buffering)\n  - [Multi-Tap Activation](#5-multi-tap-activation)\n  - [GUI Button Integration (Mobile Support)](#6-gui-button-integration-mobile-support)\n  - [Directional & Composite Vector Actions](#7-directional--composite-vector-actions)\n- [API Reference](#-api-reference)\n  - [IIAS Static Functions](#iias-static-functions)\n  - [BindingObject Methods](#bindingobject-methods)\n  - [BindingObject Properties](#bindingobject-properties)\n  - [Signals & Event Payloads](#signals--event-payloads)\n- [Practical Examples](#-practical-examples)\n- [State Machine & Activation Lifecycle](#-state-machine--activation-lifecycle)\n- [License & Support](#-license--support)\n\n---\n\n## ✨ Key Features\n\n- **Roblox IAS Engine Integration**: Automatically manages underlying `InputContext`, `InputAction`, and `InputBinding` instances.\n- **Flexible InputActionTypes**: Full support for `Bool`, `Direction1D`, `Direction2D`, `Direction3D`, and `ViewportPosition`.\n- **Flexible Key Representations**: Pass either `Enum.KeyCode` items or string names (`\"E\"`, `\"MouseButton1\"`, `\"MouseButton2\"`, `\"Touch\"`).\n- **Hold & Toggle Modes**: Seamlessly switch between hold-to-activate and state-toggling inputs.\n- **Multi-Binding & Modifiers**: Bind primary keys, alternate keys, and key combinations with primary & secondary modifiers (e.g., `Shift + F`, `Ctrl + Alt + E`).\n- **Dynamic & Timed Cooldowns**: Configure fixed numeric cooldowns or control cooldowns manually via booleans with `.Began` and `.Completed` lifecycle signals.\n- **Input Buffering**: Capture inputs during active cooldowns or busy frames and consume them automatically when available.\n- **Tap Sequences**: Trigger actions only after sequences like double-tapping within a configurable time window.\n- **Context Groups**: Group related keybinds into contexts (e.g., `\"Combat\"`, `\"Vehicle\"`, `\"Menu\"`) to enable/disable them simultaneously.\n- **GUI Mobile Integration**: Connect Roblox `GuiButton` instances directly as alternate inputs or modifiers for touch/mobile platforms.\n- **ControlHints Support**: Integrated helper for displaying ZurichBT's ControlHints UI.\n\n---\n\n## 📦 Installation\n\n> [!NOTE]\n> IIAS is designed to run on the client (`LocalScript` or client Actors) where player inputs and Roblox `InputContext` instances are processed.\n\n### Option 1: Wally (Recommended)\n\nAdd IIAS to your `wally.toml`:\n\n```toml\n[dependencies]\nIllusionIAS = \"illusionac/illusion-inputactionsystem@^1.2.5\"\n```\n\nThen install with `wally install`.\n\n### Option 2: Roblox Creator Store\n\nDownload the pre-packaged Roblox model from the [Creator Store](https://create.roblox.com/store/asset/92059655869452/Illusions-InputActionSystem-Module).\n\n### Option 3: GitHub & Rojo\n\nClone the repository directly into your project:\n\n```bash\ngit clone https://github.com/IllusionAC/Illusion-InputActionSystem.git\n```\n\nRequire the module in a `LocalScript`:\n\n```lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\nlocal IIAS = require(ReplicatedStorage.IllusionIAS)\n-- Or if using Wally:\n-- local IIAS = require(ReplicatedStorage.Packages.IllusionIAS)\n```\n\n---\n\n## 🚀 Quick Start\n\nHere is a simple example creating an interaction bind in under 10 lines of code:\n\n```lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\nlocal IIAS = require(ReplicatedStorage.IllusionIAS)\n\n-- 1. Create a new Bool action bind\nlocal interact = IIAS.new(\"Interact\", Enum.InputActionType.Bool)\n\n-- 2. Add keyboard and gamepad binds\ninteract:AddBind(Enum.KeyCode.E)\ninteract:AddBind(Enum.KeyCode.ButtonX)\n\n-- 3. Configure mode (Hold to interact)\ninteract:SetHold(true)\n\n-- 4. Listen for activation\ninteract.Activated:Connect(function(active: boolean, pressed: boolean)\n    print(\"Interact state:\", active, \"| Pressed:\", pressed)\nend)\n```\n\n---\n\n## 🧠 Core Concepts\n\n### 1. Hold vs Toggle Modes\n\nActions behave in one of two modes:\n- **Hold Mode (`:SetHold(true)`)**: The action is active as long as the input is held down. When pressed, `Activated` fires with `(activeValue, true)` and `Started` fires. When released, `Activated` fires with `(inactiveValue, false)` and `Ended` fires.\n- **Toggle Mode (`:SetHold(false)`)**: Each press toggles the internal state between active and inactive.\n\n```lua\nlocal flashlight = IIAS.new(\"Flashlight\")\nflashlight:AddBind(Enum.KeyCode.F)\nflashlight:SetHold(false) -- Toggle mode\n\nflashlight.Activated:Connect(function(active: boolean)\n    print(\"Flashlight is now:\", active and \"ON\" or \"OFF\")\nend)\n```\n\n---\n\n### 2. Cooldown System & Lifecycle Signals\n\nIIAS supports both **timed (automatic)** and **manual (dynamic)** cooldowns. Cooldown state is fully observable via lifecycle signals:\n\n#### Timed Cooldowns\nSet a numeric duration in seconds. When the action is triggered, it automatically enters cooldown and expires after the duration:\n\n```lua\nlocal dash = IIAS.new(\"Dash\")\ndash:AddBind(Enum.KeyCode.Q)\ndash:SetCooldown(3) -- 3-second cooldown on activation\n\n-- Observe cooldown lifecycle\ndash.Cooldown.Began:Connect(function()\n    print(\"Dash on cooldown! Updating UI...\")\nend)\n\ndash.Cooldown.Completed:Connect(function()\n    print(\"Dash ready! Re-enabling UI...\")\nend)\n```\n\n#### Manual / Dynamic Cooldowns\nControl cooldowns manually via boolean flags (e.g., during animations, casting sequences, or server responses):\n\n```lua\nlocal castSpell = IIAS.new(\"CastSpell\")\ncastSpell:AddBind(Enum.KeyCode.R)\n\n-- Lock input immediately:\ncastSpell:SetCooldown(true)\n\n-- Later, unlock input when the animation or cast completes:\ncastSpell:SetCooldown(false) -- Fires Cooldown.Completed\n```\n\n#### Cooldown Query & Utility Methods\n- `bind:IsInCooldown()`: Returns `true` if currently on cooldown (timed or manual).\n- `bind:GetCooldownRemaining()`: Returns remaining seconds, or `math.huge` during manual cooldown (`0` if not on cooldown).\n- `bind:StartCooldown(duration?)`: Programmatically trigger a timed cooldown immediately.\n- `bind:ResetCooldown()`: Clears active cooldowns and fires `Cooldown.Completed`.\n\n---\n\n### 3. Context Groups\n\nOrganize keybinds into logical groups (e.g., `\"Combat\"`, `\"Inventory\"`, `\"Driving\"`). Binds can belong to multiple contexts: if **any** context containing a bind is disabled, the bind is automatically disabled.\n\n```lua\nlocal attack = IIAS.new(\"Attack\")\nlocal block = IIAS.new(\"Block\")\n\n-- Add binds to a \"Combat\" context group\nIIAS.addContext(\"Combat\", attack, block)\n\n-- Disable all combat actions when opening a menu:\nIIAS.enableContext(\"Combat\", false)\n\n-- Check context status:\nprint(\"Combat enabled:\", IIAS.isContextEnabled(\"Combat\"))\n\n-- Re-enable when closing the menu:\nIIAS.enableContext(\"Combat\", true)\n```\n\n---\n\n### 4. Input Buffering\n\nInput buffering prevents lost inputs when a player presses a button shortly before a cooldown expires:\n\n```lua\nlocal comboAttack = IIAS.new(\"ComboAttack\")\ncomboAttack:AddBind(Enum.KeyCode.F)\ncomboAttack:SetCooldown(1.5)\n\n-- Enable buffering with a 0.25-second window\ncomboAttack:SetInputBufferEnabled(true)\ncomboAttack:SetInputBufferTime(0.25)\n```\n\nIf the player presses `F` within the last `0.25s` of the cooldown, the input is buffered and automatically executes the instant the cooldown ends!\n\n---\n\n### 5. Multi-Tap Activation\n\nRequire multiple taps within a time window (e.g., double-tap to sprint or dodge):\n\n```lua\nlocal dodge = IIAS.new(\"Dodge\")\ndodge:AddBind(Enum.KeyCode.W)\n\n-- Require 2 taps of 'W' within 0.35 seconds\ndodge:SetTapActivation(2, 0.35)\n\ndodge.Activated:Connect(function(active, pressed)\n    print(\"Dodge triggered by double-tap!\")\nend)\n```\n\n---\n\n### 6. GUI Button Integration (Mobile Support)\n\nConnect on-screen `GuiButton` instances to keybinds. The button will automatically behave like a physical keybind, including hold/toggle behavior and modifier combinations:\n\n```lua\nlocal mobileButton = playerGui.HUD.SkillButton\n\nlocal skill = IIAS.new(\"Skill\")\nskill:AddBind(Enum.KeyCode.E)\nskill:SetUIButton(mobileButton) -- Seamless cross-platform support!\n```\n\n---\n\n### 7. Directional & Composite Vector Actions\n\nIIAS natively supports Roblox IAS directional action types:\n- `Enum.InputActionType.Direction1D` (Number: `-1` to `1`)\n- `Enum.InputActionType.Direction2D` (Vector2: e.g. Thumbsticks, WASD)\n- `Enum.InputActionType.Direction3D` (Vector3)\n- `Enum.InputActionType.ViewportPosition` (Vector2 screen coordinates)\n\nFor directional actions, you can configure composite bindings (e.g. WASD composite for a Vector2 action):\n\n```lua\nlocal move = IIAS.new(\"Movement\", Enum.InputActionType.Direction2D)\n\n-- Assign directional composite keys\nmove:SetCompositeDirections(\n    Enum.KeyCode.W, -- Up\n    Enum.KeyCode.S, -- Down\n    Enum.KeyCode.A, -- Left\n    Enum.KeyCode.D  -- Right\n)\n\nmove.Activated:Connect(function(direction: Vector2)\n    print(\"Movement vector:\", direction)\nend)\n```\n\n---\n\n## 📚 API Reference\n\n### IIAS Static Functions\n\n| Function | Signature | Description |\n|---|---|---|\n| `IIAS.new` | `(name: string, inputType?: Enum.InputActionType) -> BindingObject` | Creates a new keybind action (defaults to `Bool`). |\n| `IIAS.get` | `(name: string) -> BindingObject?` | Retrieves a registered binding by name. |\n| `IIAS.getAll` | `() -> { [string]: BindingObject }` | Returns a dictionary of all active registered bindings. |\n| `IIAS.newContext` | `(name: string) -> ()` | Creates a new context group. |\n| `IIAS.getContext` | `(name: string) -> Context?` | Returns a copy of the context group data `{ Enabled: boolean, Members: { [string]: boolean } }`. |\n| `IIAS.addContext` | `(name: string, ...: BindingObject) -> ()` | Adds one or more bindings to a context group. |\n| `IIAS.enableContext` | `(name: string, enabled: boolean) -> ()` | Enables or disables all actions belonging to the context group. |\n| `IIAS.isContextEnabled` | `(name: string) -> boolean` | Returns whether the context group is currently enabled. |\n| `IIAS.removeContext` | `(name: string) -> ()` | Removes a context group. |\n| `IIAS.removeFromContext` | `(name: string, bind: BindingObject) -> ()` | Removes a specific binding from a context group. |\n| `IIAS.removeAllFromContext` | `(name: string) -> ()` | Empties all bindings from a context group without deleting the group. |\n| `IIAS.clearContexts` | `() -> ()` | Clears all context groups and recalculates action states. |\n| `IIAS.enableControlHints` | `(module: Instance \\| string, parent?: Instance \\| PlayerGui) -> ScreenGui` | Integrates with ZurichBT's ControlHints module. |\n\n---\n\n### BindingObject Methods\n\n> [!TIP]\n> In the signatures below, `Key` represents `Enum.KeyCode | string` (e.g. `Enum.KeyCode.E` or `\"E\"`, `\"MouseButton1\"`, `\"Touch\"`), and `Content` represents a Roblox content string or asset URL (`\"rbxassetid://...\"`).\n\n#### Keybind Configuration\n```lua\n:AddBind(mainKey: Key, primaryMod?: Key, secondaryMod?: Key, uiButton?: GuiButton, uiModifier?: GuiButton, displayName?: string, displayImage?: Content, bindingType?: Enum.InputBindingType)\n-- Adds a new key binding. Keys accept Enum.KeyCode or string names (\"E\", \"MouseButton1\", \"Touch\").\n\n:SetBind(mainKey: Key, primaryMod?: Key, secondaryMod?: Key, uiButton?: GuiButton, uiModifier?: GuiButton, displayName?: string, displayImage?: Content, bindingType?: Enum.InputBindingType)\n-- Clears existing keybinds and sets a single binding.\n\n:SetAllBinds(binds: Binds)\n-- Replaces all binds with a cloned binds table.\n\n:RemoveBind(mainKey: Key, primaryMod?: Key, secondaryMod?: Key)\n-- Removes a specific keybind matching key and modifiers.\n\n:EditBind(oldMain: Key, oldMods: { PrimaryModifier: Key?, SecondaryModifier: Key? }, newMain: Key, newMods: { PrimaryModifier: Key?, SecondaryModifier: Key? })\n-- Modifies an existing binding in-place.\n\n:GetBinds() -> Binds\n-- Returns a deep clone of the binds table.\n\n:ClearBinds()\n-- Clears all configured keybinds on the action.\n\n:Destroy() -> boolean\n-- Disconnects all signals, cancels timers, and destroys underlying Roblox instances.\n```\n\n#### Mode & Activation Settings\n```lua\n:SetHold(hold: boolean)\n-- true = hold to activate; false = toggle mode.\n\n:SetTapActivation(requiredTaps: number, tapWindow: number)\n-- Requires N taps within tapWindow seconds to activate (e.g. 2 taps in 0.3s).\n\n:Fire(active: variant, pressed: boolean)\n-- Manually fires the binding object with the specified active payload and pressed state.\n\n:GetState() -> variant\n-- Returns the current active variant value (boolean, number, Vector2, or Vector3).\n\n:GetToggleState() -> boolean\n-- Returns the current toggle state for toggle-mode binds.\n\n:GetActiveMainKey() -> Enum.KeyCode\n-- Returns the primary KeyCode currently driving the action, if active.\n\n:GetActiveBindCount() -> number\n-- Returns 1 if currently active, 0 otherwise.\n```\n\n#### Cooldown Management\n```lua\n:SetCooldown(cooldown: number | boolean, startImmediately?: boolean)\n-- Passing a number sets timed duration (seconds). Passing true/false sets manual cooldown. Optional boolean starts timed cooldown immediately.\n\n:StartCooldown(duration?: number)\n-- Programmatically starts a timed cooldown immediately (uses duration or configured Cooldown.Value).\n\n:ResetCooldown()\n-- Clears active timed & manual cooldowns, cancels running timer, and fires Cooldown.Completed.\n\n:IsInCooldown() -> boolean\n-- Returns true if the action is currently on cooldown (timed or manual).\n\n:GetCooldownRemaining() -> number\n-- Returns remaining seconds on timed cooldown, math.huge if manual, or 0 if inactive.\n```\n\n#### Input Buffering\n```lua\n:SetInputBufferEnabled(enabled: boolean)\n-- Enables or disables input buffering.\n\n:SetInputBufferTime(time: number)\n-- Sets buffer window duration in seconds (default: 0.15).\n\n:IsBuffered() -> boolean\n-- Returns whether an input is currently waiting in the buffer.\n\n:ResetBuffer()\n-- Clears any currently buffered input.\n\n:GetBufferedVariant() -> variant?\n-- Returns the buffered value payload, if present.\n\n:GetBufferedKey() -> Enum.KeyCode\n-- Returns the buffered KeyCode, if present.\n```\n\n#### State & Priority Control\n```lua\n:SetEnabled(enabled: boolean)\n-- Enables or disables the action.\n\n:IsEnabled() -> boolean\n-- Returns whether the action is enabled.\n\n:SetPriority(priority: number)\n-- Sets input processing priority on the underlying InputContext.\n\n:GetPriority() -> number\n-- Returns current priority.\n\n:SetSink(sink: boolean)\n-- Sets whether the action sinks inputs, preventing lower-priority actions from receiving them.\n\n:GetSink() -> boolean\n-- Returns current sink state.\n```\n\n#### GUI Integration\n```lua\n:SetUIButton(button: GuiButton?)\n-- Links a GuiButton as an alternate input. Automatically handles cleanup when button is destroyed.\n\n:SetUIModifier(button: GuiButton?)\n-- Links a GuiButton as an input modifier.\n\n:GetUIModifier() -> GuiButton?\n-- Returns the linked modifier GuiButton.\n\n:CreateActionLabel(parent?: Instance) -> GuiObject?\n-- Creates a native Roblox InputActionLabel bo","readmeTruncated":true,"readmeFull":"https://api.forest.dev/v1/package/illusionac/roblox/illusion-inputactionsystem/1.2.5/readme"}