건즈 안티리드 보고서English3D 랩 →
스팀 건즈 · 넷코드 분석 · 2026년 10월 27일

맞혔는데 왜 안 들어갈까: 스팀 건즈 안티리드의 작동 방식

스팀 건즈에서 내가 상대를 맞혔는지는 내 PC가 정하지 않습니다. 맞는 쪽, 즉 피격자의 PC가 정합니다. 그것도 자기 캐릭터를 핑 한 번만큼 과거로 되돌린 뒤에요. 내 화면에서는 분명히 맞았는데 데미지가 안 들어가는 상황은 대부분 이 구조 하나로 설명됩니다.

개인이 진행한 커뮤니티 분석이며 게임 개발사·퍼블리셔와는 관계가 없습니다. 아래 수치는 모두 실제 녹화된 경기에서 측정했거나 통제된 재현 실험(랩)에서 나온 것이며, 어느 쪽인지 본문에 밝혀 두었습니다.

요약

1. 지금 샷 하나가 처리되는 과정

대부분의 슈팅 게임은 한 플레이어의 PC에 히트 판정을 통째로 맡기지 않습니다. 스팀 건즈는 전투를 P2P로 처리하고, 판정은 피격자 쪽에 맡깁니다. 순서대로 보면 이렇습니다.

현재: 피격자 판정공격자 A가 탄의 방향을 피격자 B에게 보냅니다. B는 자신을 약 한 번의 왕복 시간만큼 되돌려 판정하고 데미지 기록을 돌려보냅니다. 두 메시지 모두 유실될 수 있습니다. A · 공격자 B · 피격자 발사 탄 방향만 · 한 번만 · 재전송 없음 · ½ RTT 유실되면 = 조용히 빗나감 B가 자신을 약 1 RTT 되돌리고 그 과거 위치에 탄을 대 본 뒤 자기 HP / AP를 직접 깎음 데미지 기록 · ½ RTT · 재전송 없음 유실되면 = 맞혔는데 기록이 안 남음 인정 발사부터 인정까지 왕복 한 번. 유실될 기회 두 번, 그 사이에 추정 한 번.
그림 1. 현재 구조. 게임 자체 리플레이 파일로 측정한 결과, 데미지 기록은 항상 피격자가 보냅니다(10월 27일 업데이트 이후 3,909건 중 보낸 사람이 자기를 공격자로 적은 기록은 0건). HP 감소의 99.5%가 피격자 본인의 기록과 같은 시점에 발생합니다.
  1. A가 쏩니다. 게임은 발사 시각, 총구 위치, 조준 방향만 담은 작은 메시지를 보냅니다. 대상이나 데미지는 없습니다. 각 플레이어에게 한 번씩 보내고, 수신 확인이나 재전송은 없습니다.
  2. B는 대략 왕복 시간의 절반 뒤에 받습니다. 그사이 B는 계속 움직였습니다. 지금 위치로 판정하면 움직이는 상대를 노린 샷은 거의 다 빗나갑니다.
  3. 그래서 B는 자신을 되감습니다. B의 게임은 자기 위치 기록을 잠시 보관하다가, 추정한 'A가 쏜 순간'의 위치를 꺼내 씁니다. 실제로는 왕복 시간 한 번만큼 되돌립니다.
    판정 시각 = 발사 시각 − 시계 오프셋(A→B) − 마지막 핑(RTT)
    녹화된 경기에서 측정한 되감기 폭은 1.13 × RTT + 14 ms에 잘 맞았고(r = 0.87), 안정된 조건에서 랩 재현은 정확히 1.00 × RTT를 보였습니다.
  4. B가 산탄 펠릿마다 판정하고, 데미지를 자기에게 적용한 뒤 결과를 모두에게 알립니다. 맞은 펠릿마다 데미지 기록 하나, 그리고 새 HP/AP입니다. 그 기록이 A에게 도착해야 비로소 A의 데미지로 인정됩니다.

여기서 말하는 '안티리드'의 실체를 짚고 넘어가겠습니다. 안티리드 전용 메시지도, 서버 검증도 없습니다. 방 설정의 안티리드 값은 피격자가 받은 탄을 어떻게 다룰지를 바꿀 뿐이고, 판정은 언제나 피격자 PC에서 일어납니다.

2. 맞힌 샷이 사라지는 여섯 가지 이유

10~20%녹화된 경기에서 정확히 조준했는데 데미지 기록이 없던 샷의 비율
0.61%12분 1:1 경기에서 돌아오는 길에 유실된 데미지. 한쪽 방향만 발생
196만 건 중 0건랩에서 제자리에 서 있는 상대의 판정 불일치. 시간 오차를 빗나감으로 바꾸는 건 움직임입니다

1되감기는 추정치이고, 핑이 출렁이면 틀어집니다

되감기는 서로 다른 시점에 잰 두 값을 조합합니다. 하나는 시계 오프셋(A와 B의 시계 차이, 위치 업데이트로 천천히 학습)이고, 다른 하나는 마지막 핑(가장 최근에 끝난 핑 교환 한 번)입니다. 연결이 안정적이면 두 값이 맞아떨어져 오차가 1 ms도 안 됩니다. 하지만 핑이 변하면(지터, 순간 렉, 경로 변경, 한쪽 방향만 느려짐) 두 값이 서로 다른 순간을 가리키게 됩니다. 대략 이렇습니다.

오차 ≈ −오프셋(A→B) − 오프셋(B→A) − 측정 RTT

이 오차는 시간입니다. 상대의 이동 속도를 곱하면 B가 엉뚱한 자세로 판정하는 거리가 됩니다. 건즈의 좌우 무빙 속도(700 유닛/초)에서 40 ms 오차면 히트박스가 약 28유닛 어긋나는데, 몸통 캡슐의 너비가 60유닛입니다. 대시나 벽타기는 더 빠르고 방향도 바뀌니 더 나빠집니다.

랩에서 직접 측정했습니다. 방향마다 15 ms 정도의 무작위 지터만 있어도 무빙 중인 상대를 노린 샷의 약 19%에서 피격자 쪽 펠릿 수가 공격자 화면과 달랐습니다. 기본 핑 50 ms부터 320 ms까지 모두 같았습니다. 방향 전환이 섞이면 57%까지 올라갑니다. 반대로 800 ms라도 완전히 안정된 연결이면 거의 어긋나지 않습니다. 높은 핑보다 변하는 핑이 더 큰 문제입니다.

2내 히트가 상대의 다운로드에 달려 있습니다

내 샷은 플레이어마다 수신 확인 없는 데이터그램 하나입니다. 피격자에게 가는 길에 하나라도 빠지면 피격자는 판정조차 하지 않습니다. 내 화면에서는 그냥 빗나간 것과 똑같아 보입니다. 오류도, 재시도도, 기록도 없습니다.

3데미지 인정은 별개의 두 번째 도박입니다

피격자가 히트를 인정해 HP가 깎여도, 데미지 기록이 다시 돌아와야 합니다. 이것도 재전송이 없습니다. 핑 12 ms 환경에서 양쪽 PC로 동시에 녹화한 1:1 경기에서, 한쪽 방향으로 데미지 기록 1,960건 중 12건(데미지 134)이 공격자에게 도착하지 못했고, 반대 방향은 0건이었습니다. 피격자는 HP를 잃었는데 공격자의 스코어보드에는 끝내 반영되지 않았습니다.

4릴레이를 타는 유저는 두 번 노출됩니다

두 PC가 직접 연결되지 못하면(엄격한 NAT, 일부 통신사) 메시지가 릴레이 서버를 거칩니다. 그러면 샷도 데미지 기록도 한 번이 아니라 두 번씩 건너가야 합니다. 유실될 기회가 두 배가 되고, 지연이 늘어 되감기 폭이 커지고 부정확해지며, 릴레이 자체의 지터까지 1번 문제에 더해집니다.

5상대의 프레임이 곧 내 히트 판정입니다

피격자의 위치 기록은 피격자 게임의 프레임마다 한 번씩 남고, 샷도 피격자의 다음 프레임에서야 처리됩니다. 녹화된 방에서 이 기록 간격은 4인 듀얼에서 약 12 ms, 23인 방에서 약 23 ms였습니다. 프레임이 낮거나 들쭉날쭉한 상대일수록 되감을 기록이 성기니, 내 에임은 보간된 추측을 상대로 판정받습니다. 내 쪽에서는 어떻게 할 방법이 없습니다.

6신뢰받는 쪽이 하필 피격자입니다

피격자가 자기 데미지를 스스로 판정하고 보고하므로, 변조된 클라이언트는 히트를 적용하지도 보고하지도 않으면 그만입니다. 다른 사람 눈에는 2번·3번의 네트워크 유실과 똑같아 보여서 증명하기도 매우 어렵습니다. 지금 구조도 이미 플레이어 PC를 신뢰하고 있습니다. 다만 거짓말할 이유가 가장 큰 쪽을 믿고 있을 뿐입니다.

3. 재현 랩이 보여 주는 것

시간 오차의 영향만 따로 떼어 보기 위해(네트워크 유실, 프레임, 벽 제외), 타이밍·시계 추정·위치 기록·히트 판정 로직을 독립된 모델로 재구성하고 통제된 네트워크와 움직임을 넣어 돌렸습니다. 게임을 실행하지 않았고 실제 플레이어도 없습니다. 산탄 퍼짐은 양쪽이 같게 두었으므로, 아래의 모든 차이는 피격자가 자기 위치를 어디로 기억하느냐에서만 나옵니다.

기본 핑지터(방향별 표준편차)좌우 무빙: 펠릿 수 불일치방향 전환: 펠릿 수 불일치시간 오차(P95)
전 구간(0~320 ms)0 ms0~1%1~6%0.1 ms 미만
50 ms15 ms18.8%59.8%39 ms
150 ms15 ms18.7%56.7%41 ms
280 ms15 ms18.3%56.5%40 ms
320 ms15 ms18.9%56.2%42 ms
320 ms30 ms28.0%69.8%77 ms
320 ms45 ms34.9%75.4%122 ms

몸통 조준, 시계 정렬 기준의 공격자 화면, 이동 속도 700 유닛/초, 위치 업데이트 20 ms, 핑 간격 250 ms, 칸마다 시드 5~20개. '펠릿 수 불일치'는 12발 중 피격자가 인정한 펠릿 수가 공격자 화면과 다른 샷의 비율입니다(많든 적든). 통제된 모델에서의 충돌 판정 결과이며, 실제 경기에서의 발생 빈도가 아닙니다.

핑과 지터에 따른 시간 오차와 펠릿 수 불일치 히트맵
그림 2. 전체 격자로 보면 피해를 키우는 것은 핑(가로축)이 아니라 지터(세로축)입니다. 그래프 글자는 영어입니다.

3D로 직접 확인하세요. 실제 건즈 모델로 랩의 샷을 하나씩 쏴 보고, 탄이 날아가는 동안 피격자가 어떻게 되감기는지, 12발의 펠릿이 공격자 화면과 피격자 판정에서 각각 어떻게 다른지 비교할 수 있습니다.

3D 랩 열기

4. 10월 27일 업데이트가 드러낸 것

10월 27일 스팀 업데이트로 플로팅 컴뱃 텍스트, 즉 상대 머리 위에 뜨는 데미지 숫자가 추가됐습니다. 이 숫자는 공격자 PC가 자기 화면을 기준으로 계산합니다. 실제로 들어가는 데미지는 여전히 피격자가 정합니다. 업데이트 이후에도 데미지 기록은 피격자만 보내고, HP 감소의 99.5%가 피격자 본인의 기록과 같은 시점에 일어납니다.

그래서 이제 게임이 같은 질문에 두 개의 답을 보여 줍니다. 업데이트 이후 테스트 경기에서 조준이 맞은 샷 5발 중 1발꼴로, 쏜 사람 화면에는 숫자가 떴지만 피격자는 끝내 인정하지 않았습니다. "분명 맞았는데"가 더는 기분 탓이 아닙니다. 게임이 직접 보여 주고 있으니까요.

이번 업데이트에서 반가운 점도 하나 보입니다. 클라이언트가 이미 공격자 기준의 히트 계산을 하고 있다는 사실입니다. 남은 일은 그 계산을 실제 판정으로 인정하고 검증하는 것뿐입니다.

5. 해결책: 공격자 판정

제안은 히트 판정을 100% 공격자에게 넘기는 것입니다. 흔히 '쏜 사람 우선(favor the shooter)'이라 부르는 방식이고, 피격자와 서버의 역할은 판정자에서 검증자로 바뀝니다.

제안: 공격자 판정A가 자기 화면 기준으로 판정하고, 확실히 전달되는 히트 클레임을 보냅니다. B는 상한이 있는 시간 범위 안에서 자기 기록과 대조해 검증한 뒤 적용합니다. A · 공격자 B · 피격자 (+ 서버) A가 자기 화면에 보이는 그대로 12발의 펠릿을 판정 히트 클레임 · 수신 확인 + 도착할 때까지 재전송 B가 확인: 실제 발사된 샷인지, 출발점이 그럴듯한지, 주장한 위치가 내 기록과 허용 범위 안인지, 상한 이내인지 → 적용 상한이 있는 범위 안에서는 쏜 사람 화면이 기준. 피격자는 다시 판정하지 않고 검증만 합니다.
그림 3. 제안하는 구조. 정확한 위치 정보는 실제로 그 장면을 본 공격자가 제공하고, 피격자와 서버는 그 주장이 말이 되는지만 확인합니다.

작동 방식

  1. 공격자 PC에서 판정합니다. A가 쏘는 순간, A의 게임이 그때 화면에 그리고 있던 상대 자세를 기준으로 12발의 펠릿을 판정합니다. 플로팅 컴뱃 텍스트가 이미 하고 있는 바로 그 계산입니다. A는 자기가 무엇을 그렸는지 정확히 알기 때문에 추정이 필요 없습니다.
  2. 탄 방향 대신 '클레임'을 보냅니다. 샷 번호, 시각, 탄의 궤적, 대상, 펠릿별 피격 부위, 그리고 A가 그리고 있던 상대 위치 정보의 시각을 담습니다.
  3. 확실히 전달합니다. 클레임은 수신 확인을 받고, 도착할 때까지 재전송합니다(또는 매치 서버를 거칩니다). 샷 번호로 중복 집계를 막습니다. 데이터그램 하나가 빠져도 히트가 사라지지 않고, 데미지 기록이 돌아와야만 인정받는 구조도 없어집니다.
  4. 다시 판정하지 않고 검증합니다. 피격자(가능하면 서버도)는 실제로 발사가 알려진 샷인지, A가 있을 법한 위치에서 출발했는지, 주장한 상대 위치가 그 시각 피격자 본인의 기록과 허용 범위 안에서 맞는지, 클레임이 상한 시간 이내인지(아래 참고) 확인합니다. 이 한도 안이면 주장대로 인정합니다.

무엇이 해결되나

6. 솔직한 비용과 그 한도

공격자 판정에도 대가가 있습니다. 아래는 실제로 치러야 할 비용과 각각을 묶어 두는 방법입니다.

비용 1 · 공격자 PC를 믿어야 한다

변조된 클라이언트가 실제로 맞히지 않은 히트를 주장할 수 있습니다. 벽 너머 샷이나 불가능한 조준 같은 것들입니다. 가장 큰 위험이며, 신뢰가 필요 없는 검사들로 묶어 둡니다.

에임봇과 월핵은 이 방식 때문에 더 강해지지 않습니다. 어느 방식에서든 이미 진짜 탄을 조준하기 때문입니다. 새로 생기는 위험은 조작된 히트이고, 위의 검사들이 바로 그것을 걸러내기 위한 장치입니다.

비용 2 · "나는 이미 엄폐했는데"

쏜 사람 우선 방식에서는 피격자가 자기 화면에서 엄폐물 뒤로 들어간 직후에 맞을 수 있습니다. 쏜 사람 화면에서는 아직 노출돼 있었기 때문입니다. 쏜 사람 우선을 택한 게임이라면 모두 의도적으로 감수하는 트레이드오프입니다. 되감기 상한(예: 200~250 ms)으로 묶습니다. 상한보다 오래된 클레임은 지금처럼 피격자 판정으로 돌아가므로, 핑이 아주 높은 공격자가 무한정 과거로 손을 뻗을 수는 없습니다. 해외 원거리 유저는 이득이 조금 줄고, 나머지 모두는 일관된 히트 판정을 얻습니다.

비용 3 · 동시 킬이 늘어난다

같은 왕복 시간 안에 서로 쏜 두 사람은 둘 다 히트가 인정될 수 있습니다. 두 사람이 각자 본 화면과 일치하는 결과이고, 메시지 유실 때문에 한쪽 히트가 증발하는 것보다 공정합니다.

비용 4 · 개발과 배포

프로토콜이 바뀌므로 모든 클라이언트가 함께 업데이트돼야 하지만, 스팀 빌드라면 어차피 그렇게 관리됩니다. 위험을 줄이려면 먼저 공격자 판정 결과를 지금 방식과 나란히 섀도 모드로 계산해 불일치를 기록하고, 실제 데이터로 허용 범위와 상한을 조정한 뒤, 수치가 확인되면 방의 안티리드 설정을 전환하면 됩니다.

그래도 더 나은 선택인 이유

지금 구조도 이미 플레이어 PC를 믿고 있습니다. 그것도 가장 검증하기 어려운 방식으로요. 사라진 히트는 아무 흔적도 남기지 않습니다. 공격자 판정은 실제로 그 샷을 본 사람을 믿고, 모든 히트를 검증 가능한 명시적 클레임으로 만들며, 그 신뢰가 닿는 범위에 확실한 한도를 둡니다. 모두의 판정 일관성이 좋아지고, 핵은 더 숨기 어려워집니다.

7. 이 분석으로 증명하지 못하는 것

용어. RTT·핑: 메시지가 상대에게 갔다가 돌아오는 시간. 지터: 그 시간이 순간순간 얼마나 출렁이는지. 되감기: 어떤 플레이어가 과거 특정 시점에 어디 있었는지 찾아보는 것. 펠릿: 샷건 한 발에 들어 있는 12개의 산탄.