How to remap input actions in code in Godot 4: InputMap and keycode

By Eduardo Orellana · Updated

Make an InputEventKey with physical_keycode set, then InputMap.action_erase_events("jump") and InputMap.action_add_event("jump", event). Godot 3's scancode property is gone: event.scancode = KEY_W stops with Invalid assignment of property or key 'scancode' with value of type 'int' on a base object of type 'InputEventKey'.

AppImage, x86_64. Ubuntu 22.04, Debian 12, Fedora 39 or newer.

Intel or AMD Chromebook, with Linux turned on.

Download for macOSDownload for Windows

What Godot is checking

Godot 4 splits a key into keycode, the character the keyboard layout produces, and physical_keycode, the key's position on a US QWERTY board. Bind movement to physical_keycode so WASD stays in the same place on AZERTY keyboards.

InputMap changes apply at once and last until the game quits. Save the player's bindings yourself, for example as keycodes in a ConfigFile, and re-apply them at startup.

Reproduce it

A Godot 3 key event, in a Godot 4 project.

extends Node

func _ready() -> void:
	var event := InputEventKey.new()
	event.scancode = KEY_W
	print("after")

What Godot 4.7.2 prints

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Invalid assignment of property or key 'scancode' with value of type 'int' on a base object of type 'InputEventKey'.
   at: _ready (res://answers/how-to-remap-input-in-code-in-godot-4/repro.gd:5)
   GDScript backtrace (most recent call first):
       [0] _ready (res://answers/how-to-remap-input-in-code-in-godot-4/repro.gd:5)

Fix it

Create a jump action, bind it to the physical W key, then rebind it to Space.

extends Node

func bind(action: StringName, key: Key) -> void:
	var event := InputEventKey.new()
	event.physical_keycode = key
	InputMap.action_erase_events(action)
	InputMap.action_add_event(action, event)

func _ready() -> void:
	InputMap.add_action("jump")
	bind("jump", KEY_W)
	print(InputMap.action_get_events("jump")[0].as_text_physical_keycode())
	bind("jump", KEY_SPACE)
	print(InputMap.action_get_events("jump")[0].as_text_physical_keycode())

What the fixed script prints

Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

W
Space

Verified on Godot 4.7.2

Both scripts on this page were run headless on Godot 4.7.2 (4.7.2.stable.mono.official.ed1daf0bf) on 18 October 2026, and the output above is what Godot printed, unedited.

Where the check lives in Godot's source: [gdscript_vm.cpp line 1235, the message](https://github.com/godotengine/godot/blob/4.7.2-stable/modules/gdscript/gdscript_vm.cpp#L1235), [InputMap in the class reference](https://github.com/godotengine/godot/blob/4.7.2-stable/doc/classes/InputMap.xml).

Questions

How do I wait for the player to press the new key?
In _input(event), take the first InputEventKey with event.pressed and pass its physical_keycode to your bind function, then stop listening.
How do I get the name of a key?
OS.get_keycode_string(KEY_W) returns "W"; Godot 3's OS.get_scancode_string() was renamed.