Hey everyone! I’m really locking in right now, it’s been 3 days in a row where I’ve been putting in at least around 4h a day on UAI, and yesterday I did a solid 5h30. It’s honestly a bit exhausting with studies on the side, but it also feels good because I’m finally pushing on the “real” hard problems instead of just polishing UI.
I started by building an actual POC for global key blocking, and it went better than I expected. The POC uses WH_KEYBOARD_LL, so it’s a true system-wide Windows hook: it sees every physical keyboard event before any app gets it. When a key that’s bound in UAI is pressed, the hook just returns 1 and the event is consumed, the result is kind of insane in the best way: the game literally never sees the keyboard input, so the double-input problem just disappears. I also did some research to make sure this wasn’t a “works until you launch a real game” type of trick, and it turns out none of the mainstream engines rely on RIDEV_NOLEGACY (which is basically the only clean way to bypass this hook). Unreal, Unity, Source, Godot, SDL2… they all end up using the usual paths (WM_KEYDOWN and/or Raw Input without that flag), so they all get blocked properly by the hook. I was initially worried about the 1% of weird cases (mostly rhythm games / very specific input stacks), and I thought I might need something extreme like an injected DLL to cover everything, but that would instantly raise anti-cheat flags, and ironically those are the games where the low-level hook already works perfectly anyway. So the conclusion is pretty clear: this POC is basically the optimal solution for UAI, and I don’t need to over-engineer it.
After that, I kept going on performance work. I’m still in the “careful” phase because anything in the mapping hot path is easy to break in subtle ways, but I started pushing real optimizations instead of just thinking about them. The core polling side is already efficient (bulk reads, minimal overhead), so my focus has been on smoothing the loop and cutting pointless work: reusing buffers more aggressively, reducing per-tick overhead, and moving toward a strategy where we don’t hammer the virtual controller update when nothing actually changed. It’s not fully done yet, and there were definitely a few moments where I felt stuck debugging timing/edge cases instead of making visible progress, but overall it feels like the project is getting more “serious”: less jitter, less waste, and a clearer path to both better responsiveness and stability.
That’s it for today, it was a lot, but I’m genuinely excited because the key blocking POC feels like one of those rare breakthroughs where a problem just… collapses into a clean solution. See you in the next devlog!