05-06-26
SOCD Cleaner Lua Script
This Lua script for Rebind hardware input devices implements SOCD (Simultaneous Opposing Cardinal Directions) cleaning. It resolves conflicting key presses, offering "Last Input" and "Neutral" modes f
Question
SOCD cleaner for any keyboard
Rebind AI
-- rebind: min_sdk=0.1.0 tick_rate=8000
-- rebind: name=SOCD Cleaner
local cfg = UI.Schema({
enabled = UI.Toggle(true, { label = "Enable SOCD" }),
mode = UI.Select("Last Input", { "Last Input", "Neutral" }, { label = "Conflict Mode" }),
delay = UI.Slider(20, { min = 0, max = 100, label = "Overlap Delay", suffix = "ms", group = "Advanced" }),
})
-- Define opposing key pairs
local PAIRS = {
{ "A", "D" },
{ "W", "S" },
{ "Left", "Right" },
{ "Up", "Down" },
}
local held = {}
local virt = {}
local lastInput = {}
local function setVirt(key, state)
if virt[key] == state then return end
if state then
HID.Down(key)
else
HID.Up(key)
end
virt[key] = state
end
local function resolveConflict(key1, key2)
local h1 = held[key1] or false
local h2 = held[key2] or false
if cfg.mode == "Neutral" then
-- Both pressed = release both
if h1 and h2 then
setVirt(key1, false)
setVirt(key2, false)
return
end
else
-- Last Input mode: the most recently pressed key wins
if h1 and h2 then
local last = lastInput[key1] or lastInput[key2] or key1
setVirt(key1, last == key1)
setVirt(key2, last == key2)
-- If delay is set, implement humanised overlap
if cfg.delay > 0 and last == key1 then
Timer.After(cfg.delay, function()
if held[key1] and held[key2] then
setVirt(key2, false)
end
end)
elseif cfg.delay > 0 and last == key2 then
Timer.After(cfg.delay, function()
if held[key1] and held[key2] then
setVirt(key1, false)
end
end)
end
return
end
end
-- One or neither pressed: pass through
setVirt(key1, h1)
setVirt(key2, h2)
end
function OnDown(key)
if not cfg.enabled then return true end
-- Check if this key is part of any pair
for _, pair in ipairs(PAIRS) do
if key == pair[1] or key == pair[2] then
held[key] = true
lastInput[pair[1]] = System.Time()
lastInput[pair[2]] = System.Time()
resolveConflict(pair[1], pair[2])
return false -- block physical input, we control output
end
end
return true
end
function OnUp(key)
if not cfg.enabled then return true end
for _, pair in ipairs(PAIRS) do
if key == pair[1] or key == pair[2] then
held[key] = false
resolveConflict(pair[1], pair[2])
return false
end
end
return true
end
function OnBlur()
-- Release all virtual keys on blur
for key, _ in pairs(virt) do
setVirt(key, false)
end
held = {}
virt = {}
lastInput = {}
end
function OnStop()
OnBlur()
endHow it works:
This script detects when two opposing keys are pressed simultaneously and handles the conflict based on your configured mode:
-
Last Input mode (default): The most recently pressed key "wins" and the other is silenced. Includes an optional Overlap Delay that humanizes transitions — if you press A+D with a 20ms delay, D will release 20ms after the switch, simulating real keyboard behavior. This is SOCD like fightstick controllers use.
-
Neutral mode: When both keys of a pair are held, both are released (neutral stick position). Useful for some game engines that don't handle conflicting inputs well.
Supported pairs:
- A/D (strafe)
- W/S (forward/back)
- Left/Right (arrows)
- Up/Down (arrows)
You can easily add more pairs to the PAIRS table if you want to handle other key combinations. The script blocks the original input and outputs the resolved state, so the game only sees valid, non-conflicting input.
Setup: Just load this script globally (no process targeting). It runs at 8000 Hz for sub-millisecond precision on conflict detection.