{"id":15922075,"url":"https://github.com/not-elm/bevy-input-sequence","last_synced_at":"2026-03-27T04:12:11.630Z","repository":{"id":189346046,"uuid":"680096637","full_name":"not-elm/bevy-input-sequence","owner":"not-elm","description":"This crate provides reading user input sequences, and sending event","archived":false,"fork":false,"pushed_at":"2026-03-06T06:10:13.000Z","size":369,"stargazers_count":17,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-03-16T06:04:00.177Z","etag":null,"topics":["bevy","bevy-plugin","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/not-elm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE2","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-08-18T10:31:43.000Z","updated_at":"2026-03-06T06:10:11.000Z","dependencies_parsed_at":"2024-03-19T16:29:39.580Z","dependency_job_id":"c9f5a5b3-9c97-4488-ab2a-d542164ec05a","html_url":"https://github.com/not-elm/bevy-input-sequence","commit_stats":null,"previous_names":["elm-register/bevy-input-sequence","elmtw/bevy-input-sequence"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/not-elm/bevy-input-sequence","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/not-elm%2Fbevy-input-sequence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/not-elm%2Fbevy-input-sequence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/not-elm%2Fbevy-input-sequence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/not-elm%2Fbevy-input-sequence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/not-elm","download_url":"https://codeload.github.com/not-elm/bevy-input-sequence/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/not-elm%2Fbevy-input-sequence/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31018556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-27T03:51:26.850Z","status":"ssl_error","status_checked_at":"2026-03-27T03:51:09.693Z","response_time":164,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bevy","bevy-plugin","rust"],"created_at":"2024-10-06T20:04:45.382Z","updated_at":"2026-03-27T04:12:11.623Z","avatar_url":"https://github.com/not-elm.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bevy-input-sequence\n\nRecognizes and acts on input sequences from the keyboard or a gamepad.\n\n# Use Cases\n\n* Hotkeys\n* Cheat codes\n* Developer UI\n\n# Installation\n\n``` sh\ncargo install bevy-input-sequence\n```\n\n# Code Examples\n\nHere are some code snippets. These also run as doctests so they do a few things\ndifferently than a regular runnable example:\n\n- Instead of `DefaultPlugins` they use `MinimalPlugins`.\n- Instead of `app.run()` they call `app.update()`.\n\nThe next section describes the runnable examples that come with the crate.\n\n## Run a System on a Key Sequence\n\nRun a system whenever the user presses the key sequence `H I` or \"hi\" within a\ntime limit.\n\n```rust\nuse bevy::prelude::*;\nuse bevy_input_sequence::prelude::*;\n\nfn main() {\n    App::new()\n        .add_plugins(MinimalPlugins)\n        .add_plugins(InputSequencePlugin::default())\n        .add_systems(Startup, setup)\n        .update(); // Normally you'd run it here.\n}\n\nfn setup(mut commands: Commands) {\n    // Add key sequence.\n    commands.queue(\n        KeySequence::new(say_hello, \n                         keyseq! { H I })\n        .time_limit(Duration::from_secs(2))\n    );\n}\n\nfn say_hello() {\n    info!(\"hello\");\n}\n```\n\n## Send an Event on Key Sequence\n\nOriginally `bevy-input-sequence` always sent an event. You can still do that\nwith `action::write_message()`.\n\n```rust\nuse bevy::prelude::*;\nuse bevy_input_sequence::prelude::*;\n\n/// Define an event.\n#[derive(Message, Clone, Debug, Default)]\nstruct MyEvent;\n\n/// Add event as an key sequence.\nfn main() {\n    App::new()\n        .add_plugins(MinimalPlugins)\n        .add_plugins(InputSequencePlugin::default())\n        .add_message::\u003cMyEvent\u003e()\n        .add_systems(Startup, setup)\n        .update(); // Normally you'd run it here.\n}\n\nfn setup(mut commands: Commands) {\n    commands.queue(\n        KeySequence::new(action::write_message(MyEvent), \n                         keyseq! { Ctrl-E Alt-L Shift-M })\n    );\n}\n\nfn check_events(mut events: MessageReader\u003cMyEvent\u003e) {\n    for event in events.read() {\n        info!(\"got event {event:?}\");\n    }\n}\n```\n\n## Send an Event on Gamepad Button Sequence\n\nGamepads have something that keyboards don't: identity problems. Which player\nhit the button sequence may be important to know. So the systems it accepts \ntake an input of `Entity`.\n\n```rust\nuse bevy::prelude::*;\nuse bevy_input_sequence::prelude::*;\n\n/// Define an event.\n#[derive(Message, Clone, Debug)]\nstruct MyEvent(Entity);\n\n/// Add event as an key sequence.\nfn main() {\n    App::new()\n        .add_plugins(MinimalPlugins)\n        .add_plugins(InputSequencePlugin::default())\n        .add_message::\u003cMyEvent\u003e()\n        .add_systems(Startup, setup)\n        .update(); // Normally you'd run it here.\n}\n\nfn setup(mut commands: Commands) {\n    commands.queue(\n        ButtonSequence::new(action::write_message_with_input(|gamepad| MyEvent(gamepad)), \n            [GamepadButton::North,\n             GamepadButton::East,\n             GamepadButton::South,\n             GamepadButton::West])\n    );\n}\n\nfn check_events(mut events: MessageReader\u003cMyEvent\u003e) {\n    for event in events.read() {\n        info!(\"got event {event:?}\");\n    }\n}\n```\n\n## Trigger an Event on Key Sequence\n\nYou can also trigger an event with `action::trigger()` or `action::trigger_targets()`.\n\n```rust\nuse bevy::prelude::*;\nuse bevy_input_sequence::prelude::*;\n\n/// Define an event.\n#[derive(Event, Clone, Debug, Default)]\nstruct MyEvent;\n\n/// Add event as an key sequence.\nfn main() {\n    App::new()\n        .add_plugins(MinimalPlugins)\n        .add_plugins(InputSequencePlugin::default())\n        .add_systems(Startup, setup)\n        .add_observer(check_trigger)\n        .update(); // Normally you'd run it here.\n}\n\nfn setup(mut commands: Commands) {\n    commands.queue(\n        KeySequence::new(action::trigger(MyEvent), \n                         keyseq! { Ctrl-E Alt-L Super-M })\n    );\n}\n\nfn check_trigger(mut trigger: On\u003cMyEvent\u003e) {\n    info!(\"got event {:?}\", trigger.event());\n}\n```\n\n## KeySequence Creation Patterns\n\n`KeySequence::new` now returns `KeySequenceBuilder`, which implements `Command`.\nTherefore, you need to call `Commands::queue` instead of `Commands::spawn`.\n\n```rust\nuse bevy::prelude::*;\nuse bevy_input_sequence::prelude::*;\n\n#[derive(Message, Clone, Debug, Default)]\nstruct MyEvent;\n\nfn create_key_sequence(mut commands: Commands) {\n    commands.queue(KeySequence::new(\n        action::write_message(bevy::app::AppExit::default()), \n        keyseq! { Ctrl-E L M }\n    ));\n}\n\nfn create_key_sequence_and_add_it_to_an_entity(mut commands: Commands) {\n    let id = commands.spawn_empty().id();\n    commands.entity(id).queue(KeySequence::new(\n        action::write_message(MyEvent), \n        keyseq! { Ctrl-E L M }\n    ));\n    // OR\n    commands.spawn_empty().queue(KeySequence::new(\n        action::write_message(MyEvent), \n        keyseq! { Ctrl-E L M }\n    ));\n}\n```\n\n### Advanced Creation\n\nThe `KeySequenceBuilder` requires a `\u0026mut World` to build it. You can build it\nyourself like so:\n\n```rust\nuse bevy::prelude::*;\nuse bevy_input_sequence::prelude::*;\n\nfn create_key_sequence_within_command(mut commands: Commands) {\n    commands.queue(|world: \u0026mut World| {\n        let builder = KeySequence::new(\n            move || { info!(\"got it\"); },\n            keyseq! { Ctrl-E L M }\n        );\n        let key_sequence: KeySequence = builder.build(world);\n        // And then put it somewhere? It ought to go as a component.\n    });\n}\n```\n\n# Runnable Examples\n\n## keycode\n\nThe `keycode` example recognizes the key sequences `W D S A` and `W A S D` and\nfires a distinct event.\n\n``` sh\ncargo run --example keycode\n```\n\n## keymod\n\nThe `keymod` example recognizes `Ctrl-W Ctrl-D Ctrl-S Ctrl-A` and fires an event.\n\n``` sh\ncargo run --example keymod\n```\n\n## gamepad_button\n\nThe `gamepad_button` example recognizes gamepad buttons `North East South West`\nor `Y B A X` on an Xbox controller and fires an event.\n\n``` sh\ncargo run --example gamepad_button\n```\n\n## multiple_input\n\nThe `multiple_input` example recognizes gamepad buttons `North East South West`,\nor `Y B A X` on an Xbox controller, or `W D S A` on a keyboard and fires an\nevent.\n\n``` sh\ncargo run --example multiple_input\n```\n\nNote: Either `W D S A` will be recognized from the keyboard, or `Y B A X` will\nbe recognized from the controller. But a mixed sequence like `W D A X` will not\ncurrently be recognized. If this should be done and how exactly one should do it\nare under consideration. Please open an issue or PR if you have thoughts on this.\n\n## only_if\n\nThe `only_if` example recognizes `Space` and fires an event if it's in game\nmode. The `Escape` key toggles the app between menu and game mode. It does this\nby only sending the `Space` event if it's in game mode.\n\n``` sh\ncargo run --example only_if\n```\n\n## run_if\n\nThe `run_if` has the same behavior as `only_if` but achieves it differently. It\nplaces the `InputSequencePlugin` systems in a system set that is configured to\nonly run in game mode. Because of this the `Escape` key which toggles between\ngame and menu mode cannot be a `KeySequence`.\n\n``` sh\ncargo run --example run_if\n```\n\n# Compatibility\n\n| bevy-input-sequence | bevy |\n|---------------------|------|\n| 0.10                | 0.18 |\n| 0.9                 | 0.17 |\n| 0.8                 | 0.16 |\n| 0.7                 | 0.15 |\n| 0.5 ~ 0.6           | 0.14 |\n| 0.3 ~ 0.4           | 0.13 |\n| 0.2                 | 0.12 |\n| 0.1                 | 0.11 |\n\n# License\n\nThis crate is licensed under the MIT License or the Apache License 2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnot-elm%2Fbevy-input-sequence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnot-elm%2Fbevy-input-sequence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnot-elm%2Fbevy-input-sequence/lists"}