Marathon Input Issues Fix: Overlay 충돌을 견디는 PC 게임 아키텍처 설계
모든 경쟁형 멀티플레이어 개발자는 Discord overlay 때문에 완벽하게 설계된 netcode가 무너지는 허탈함을 잘 알고 있습니다. 서버 인프라를 30ms 미만의 지연 시간으로 최적화하기 위해 수개월을 보냈지만, 백그라운드 스트리밍 앱이 게임의 input thread를 점유하는 바람에 플레이어의 사격이 빗나가는 상황이 발생합니다.
이 시나리오는 현재 번지의 신작 익스트랙션 슈터 Marathon의 Server Slam에서 실제로 벌어지고 있습니다. PC 플레이어들은 심각한 mouse lag과 입력 누락을 보고하고 있으며, 번지는 서드파티 유틸리티와 스트리머 overlay를 주요 원인으로 공식 인정했습니다.
커뮤니티에서는 수천 명의 플레이어가 marathon input issues fix를 절실히 찾고 있습니다. 임시 해결책은 전체 화면 캡처를 사용하고 overlay를 비활성화하는 것입니다.
하지만 개발자에게 이는 중요한 아키텍처 질문을 던집니다. 왜 스트리밍 앱이 입력을 가로채며, 이를 방지하기 위해 PC 클라이언트를 어떻게 설계해야 할까요?
이 기술 분석에서는 Windows 입력 처리 메커니즘을 분석하고, OBS Game Capture가 frame pacing 문제를 일으키는 이유와 input thread를 분리하는 방법을 살펴봅니다.
원인: Overlay가 Render Pipeline을 가로채는 방식
OBS나 Discord는 게임 프로세스에 DLL을 주입하고 DirectX의 Present 함수나 Vulkan의 vkQueuePresentKHR을 후킹합니다.
Swap Chain 병목 현상
후킹된 swap chain으로 인해 엔진은 프레임 버퍼 복사가 끝날 때까지 대기해야 합니다. 16.6ms가 걸려야 할 프레임이 갑자기 24ms가 걸리게 되며, 메인 스레드에서 수행되는 WM_MOUSEMOVE 폴링도 함께 지연됩니다.
해결책: Raw Input API 아키텍처
표준 Windows 메시지 펌프에 의존하는 것은 슈팅 게임에서 치명적입니다. Raw Input API (WM_INPUT)를 구현하고, 렌더 루프와 완전히 분리된 고우선순위 스레드에서 입력을 처리해야 합니다.
C++ (Win32) Raw Input 구현
void InitializeRawInput(HWND hwnd) {
RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = 0x01;
Rid[0].usUsage = 0x02;
Rid[0].dwFlags = 0;
Rid[0].hwndTarget = hwnd;
RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]));
}
Unreal Engine: Smoothing 비활성화
Unreal Engine 개발자는 PlayerController에서 mouse smoothing을 비활성화하여 프레임 변동 시의 입력 지연을 최소화해야 합니다.
연쇄 효과: 클라이언트 랙 vs 서버 롤백
입력 지연은 서버의 reconciliation 로직을 자극하여 rubberbanding을 유발합니다. 이는 How To Fix Player Location Desync In Uefn And Unreal Engine Multiplayer에서 다루는 현상과 유사합니다.
horizOn을 사용하면 이러한 동기화 문제를 방지하는 최적화된 게임 서버를 쉽게 배포할 수 있습니다.
PC 입력을 위한 5가지 베스트 프랙티스
- 입력과 렌더링 분리: 1000Hz 독립 스레드 사용.
- DXGI Flip Model 강제: DWM 합성을 우회하여 지연 감소.
- Hardware Cursor 사용: UI 텍스처 대신 OS 커서 사용.
- 후킹 주입 경고: overlay DLL 감지 시 알림 제공.
- Fixed Timestep Simulation: 물리와 입력을 고정 시간 단계로 처리.
결론
개발자는 Raw Input 구현과 스레드 분리를 통해 응답성을 보장해야 합니다. 백엔드 동기화는 horizOn에 맡기고 클라이언트 경험 개선에 집중하세요.