{"schemaVersion":1,"record":{"key":"lesson/input-and-feedback","type":"lesson","id":"input-and-feedback","lang":"en","title":"Input and feedback","summary":"Turn button presses into gameplay intent and show whether an action was accepted, rejected, or completed.","updatedAt":"2026-10-20","status":"active","url":"https://gamemechanics.pro/en/lessons/input-and-feedback/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/input-and-feedback.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/input-and-feedback.md","aliases":[],"tags":["input","feedback","accessibility"],"sourceIds":["source-663cb05191120f23"],"sources":[{"id":"source-663cb05191120f23","title":"Godot: Using InputEvent","url":"https://docs.godotengine.org/en/stable/tutorials/inputs/inputevent.html","verifiedAt":null}],"sections":[{"id":"prerequisites","title":"Prerequisites","body":"Use an early playable prototype with one action, such as interacting with a door. You need an input handler and a small amount of game state. The goal is for players to understand the result of a press while game rules remain independent of a particular key."},{"id":"principle","title":"The principle","body":"Separate the physical signal, gameplay intent, and outcome. A keyboard key or gamepad button produces `interact`. Game rules decide whether a door can open. Presentation communicates what happened. This is easier to inspect than a key handler that also animates the door, plays audio, and edits the inventory.\n\nAn action mapping lets several input devices express the same intent. Godot provides InputMap for this purpose, and its event propagation can let the interface consume input before the game world receives it. See [Using InputEvent](https://docs.godotengine.org/en/stable/tutorials/inputs/inputevent.html).\n\nMovement usually depends on a held input. Toggling a menu or using an item usually needs a press edge: the change from released to pressed. Toggling on every held frame makes one physical press repeatedly open and close the menu.\n\n<span id=\"example-a-locked-door\"></span>"},{"id":"example","title":"Practical example","body":"### A locked door\n\nDefine three outcomes: opened, needs a key, and out of range. Game logic returns one outcome; presentation selects a suitable message, sound, or animation.\n\n```text\ntryInteract(player, door):\n    if distance(player, door) > interactRange:\n        return outOfRange\n    if door.locked and not player.hasKey:\n        return needsKey\n    door.open = true\n    return opened\n\nonActionPressed(interact):\n    result = tryInteract(player, selectedDoor)\n    presentInteractionResult(result)\n```\n\nPlace two doors in your exercise scene, one nearby and one outside interaction range. Check the outcomes before adding effects, then introduce a short explanation when an action is rejected. Do not play a successful opening animation before the rules accept the interaction.\n\nWhen multiple doors exist, define target selection explicitly: nearest eligible object, object under the crosshair, or highlighted object. Show the selected target before the press. This makes target-selection errors distinguishable from incorrect key checks."},{"id":"mistakes","title":"Common mistakes","body":"The same input must not activate a menu button and fire a weapon behind it. Closing a window must not leave movement permanently held. Clear held actions when focus is lost, because a release event may not arrive where your handler expects it.\n\nDo not communicate rejection through red coloring alone or a quiet sound alone. In this example, include a reason label and a distinguishable door state. Rate-limit repeated rejection cues so that holding a button does not create a stream of identical sounds.\n\nDo not automatically buffer every action. A buffered jump may help a particular movement design, while a delayed purchase confirmation or quit command can be surprising. The lifetime of an intent belongs in that action's rules."},{"id":"checks","title":"Verify it","body":"- Keyboard and gamepad activate the same gameplay action.\n- Holding a button does not repeat a single-shot action every frame.\n- Menus receive input without triggering the world behind them.\n- Losing and restoring focus does not leave movement stuck.\n- Rejection reasons remain understandable without color discrimination or audio.\n- Players can see the selected target before confirming."},{"id":"agent-task","title":"Prompt for an AI agent","body":"> Separate input collection, interaction rules, and result presentation for a door. Preserve existing control bindings. Define held-input, interface, and focus-loss behavior. Add checks for the three outcomes and explain how players learn why an action was rejected. Do not add delay or input buffering without an explicit rule."}],"relations":[{"type":"requires","direction":"outgoing","label":"Before you start","key":"lesson/game-loop","title":"The game loop and time","url":"https://gamemechanics.pro/en/lessons/game-loop/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/game-loop.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/game-loop.md"},{"type":"requires","direction":"incoming","label":"Continue learning","key":"lesson/state-machines","title":"States and transitions","url":"https://gamemechanics.pro/en/lessons/state-machines/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/state-machines.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/state-machines.md"},{"type":"requires","direction":"incoming","label":"Continue learning","key":"lesson/game-feel","title":"Game feel: making actions readable","url":"https://gamemechanics.pro/en/lessons/game-feel/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/game-feel.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/game-feel.md"},{"type":"requires","direction":"incoming","label":"Continue learning","key":"lesson/teaching-a-mechanic","title":"Teaching one mechanic through a level","url":"https://gamemechanics.pro/en/lessons/teaching-a-mechanic/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/teaching-a-mechanic.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/teaching-a-mechanic.md"},{"type":"requires","direction":"incoming","label":"Continue learning","key":"lesson/game-accessibility","title":"Basic accessibility across a play session","url":"https://gamemechanics.pro/en/lessons/game-accessibility/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/lesson/game-accessibility.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/lesson/game-accessibility.md"},{"type":"explains","direction":"outgoing","label":"Apply the principle","key":"mechanic/voice-audio--family-01","title":"Direct voice commands","url":"https://gamemechanics.pro/en/knowledge/mechanic/voice-audio--family-01/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/mechanic/voice-audio--family-01.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/mechanic/voice-audio--family-01.md"},{"type":"explains","direction":"outgoing","label":"Apply the principle","key":"mechanic/point-and-click--family-43","title":"Input and action selection","url":"https://gamemechanics.pro/en/knowledge/mechanic/point-and-click--family-43/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/mechanic/point-and-click--family-43.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/mechanic/point-and-click--family-43.md"},{"type":"contains","direction":"incoming","label":"Learning paths","key":"path/first-prototype","title":"Your first verifiable prototype","url":"https://gamemechanics.pro/en/learn/first-prototype/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/path/first-prototype.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/path/first-prototype.md"},{"type":"requires","direction":"incoming","label":"Continue learning","key":"path/level-design","title":"Level design","url":"https://gamemechanics.pro/en/learn/level-design/","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/path/level-design.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/path/level-design.md"},{"type":"uses","direction":"outgoing","label":"Sources in the selection","key":"resource/godot-input","title":"Godot: input handling","url":"https://gamemechanics.pro/en/resources/#resource-godot-input","jsonUrl":"https://gamemechanics.pro/api/v1/knowledge/en/resource/godot-input.json","markdownUrl":"https://gamemechanics.pro/content/knowledge/en/resource/godot-input.md"}],"placements":[],"supersededBy":[],"attributes":{"category":"foundations","level":"beginner","minutes":6},"endsAt":null,"provenance":"Original gamemechanics.pro material. Check illustrative examples in your own project.","license":"CC-BY-4.0","codeLicense":"MIT","attribution":"gamemechanics.pro contributors"}}