A Godot 4.7 plugin for multi-device local + online multiplayer input.
Requires Godot 4.7+. Input Forge 0.2.0 uses the Godot 4.7-native editor dock API and is held to strict, fully typed GDScript. The last Godot 4.6 -compatible release is
0.1.0.
Input Forge turns a shared keyboard (split into key-zones) and any number of gamepads into abstract, action-keyed commands, configured from the project's regular Godot InputMap - no game-specific action names are baked into the plugin. It provides per-device polling, lobby join/leave, runtime rebinding, persistence, and a packet-loss-tolerant command codec for streaming input to an authoritative server.
The plugin itself lives in addons/input_forge/. This
repository is a tiny dev project that exists only to develop and test the addon
in isolation; consumers just copy the addon folder into their game.
Godot's action API has no device parameter, so per-player couch co-op cannot use
the shared action map directly. Input Forge polls each device individually while
still letting you define your controls in the normal Godot Input Map: it derives
its per-device binding defaults from those actions.
Requires Godot 4.7.x.
- Manual: copy the
addons/input_forge/folder into your project'saddons/folder, then enable Input Forge underProject > Project Settings > Plugins. - Asset Library: install, then enable the plugin.
If your project treats GDScript warnings as errors, set the Godot 4.7
debug/gdscript/warnings/directory_rules so res://addons is held to the same
standard (see this repo's project.godot for the exact value).
- Define your controls in
Project > Project Settings > Input Mapas usual (e.g.move_left/right/up/down,jump,dash). - For multiple keyboard players, bind one key per zone to each action - the
Nth keyboard event of an action becomes keyboard zone N (e.g.
jump=Spacefor zone 0 andEnterfor zone 1). - Open the Input Forge dock, create an
InputForgeActionSet, pick the four movement actions, the ordered button actions, and the join action from the dropdowns (populated from your InputMap), then Apply + Save. The dock previews the per-device bindings Input Forge derives. - In code:
var actions := InputForgeActionSet.new()
actions.move_left = &"move_left" ; actions.move_right = &"move_right"
actions.move_up = &"move_up" ; actions.move_down = &"move_down"
actions.buttons = [&"jump", &"dash"]
actions.join_action = &"jump"
var listener := InputForgeJoinListener.new()
listener.action_set = actions
add_child(listener)
listener.join_requested.connect(func(device, profile):
var source := InputForgeDeviceSource.new(device, profile, actions)
add_child(source)
# Attach `source` to a player; call source.poll() once per physics tick:
# var cmd := source.poll()
# var move: Vector2 = cmd.move
# if cmd.is_pressed(&"jump"): ...
)See addons/input_forge/README.md for the full
API, the network codec details, and the device-prompt provider.
The addon is kept to strict, typed GDScript. With Godot 4.7.x on your PATH (or set
$GODOT):
./check.sh # parse + strict typing
godot --headless --path . --script res://test/network_codec.gd # codec unit testcheck.sh type-checks every addon script; the directory_rules setting plus
untyped_declaration=2 and unsafe_*=2 make untyped/unsafe declarations hard
errors. See CONTRIBUTING.md for the typing contract and how
unavoidable Variant narrowing is quarantined.
MIT - see LICENSE.