결정론적 락스텝과 스냅샷 동기화, 멀티플레이의 기준

profile_image
작성자 멀티플레이개발자 이든
댓글 0건 조회 7회

같은 공격 버튼을 눌렀는데 한 플레이어의 화면에서는 적이 쓰러지고, 다른 화면에서는 살아남는다면 문제는 단순한 네트워크 지연이 아닙니다. 서버와 클라이언트가 게임 상태를 어떤 방식으로 공유할지 결정하지 못한 채 기능부터 늘린 결과일 가능성이 큽니다. 멀티플레이 게임 프로그래밍에서 자주 거론되는 결정론적 락스텝과 스냅샷 동기화는 패킷 형식만 다른 기술이 아니라, 게임의 규칙과 개발 조직까지 바꾸는 설계 선택입니다.

이번 글은 실시간 전략 게임과 액션 게임의 네트워크 코드를 모두 다뤄 온 서버 프로그래머 강현우 씨와의 가상 심층 인터뷰 형식으로 구성했습니다. 지연 시간, 대역폭, 치트 대응, 수학 연산, 디버깅 비용을 기준으로 두 구조가 어디에서 갈리는지 구체적으로 묻습니다.

Q. 락스텝과 스냅샷은 무엇을 주고받나요?

A. 명령을 보내느냐, 계산된 상태를 보내느냐의 차이입니다

결정론적 락스텝은 플레이어의 이동 명령, 유닛 선택, 기술 사용처럼 시뮬레이션에 들어갈 입력을 교환합니다. 모든 참여자가 동일한 초기 상태와 동일한 입력으로 같은 틱을 계산하면 결과도 같아진다는 전제가 붙습니다. 유닛이 수백 개여도 각 유닛의 위치를 계속 전송할 필요가 없으므로, 복잡한 시뮬레이션에 비해 네트워크 사용량이 작을 수 있습니다.

스냅샷 동기화는 권한을 가진 서버가 계산한 위치, 회전, 체력, 애니메이션 상태 등을 일정 주기로 전송합니다. 클라이언트는 도착한 두 상태 사이를 보간하거나, 이미 예측한 상태를 서버 값에 맞게 보정합니다. 서버 결과가 기준이므로 모든 기기가 완전히 똑같은 부동소수점 계산을 수행할 필요는 없지만, 전송할 객체가 늘수록 관심 영역 관리와 압축이 중요해집니다.

“둘 중 어느 쪽이 더 최신 기술인가요?”라는 질문은 적절하지 않습니다. 장르와 조작 감각에 따라 해결해야 할 문제가 다르기 때문입니다. 여러 플랫폼에서 대규모 전투 규칙을 정확히 재현해야 한다면 락스텝이 매력적이고, 순간적인 조준과 이동 반응이 핵심이라면 서버 권한 스냅샷에 예측을 결합하는 방식이 자연스럽습니다.

  • 락스텝의 전송 단위: 명령, 입력 틱, 난수 시드, 확인 응답
  • 스냅샷의 전송 단위: 엔티티 ID, 변환 값, 속도, 게임플레이 상태
  • 공통 요구사항: 틱 관리, 패킷 순서 판별, 재접속 처리, 상태 검증
  • 첫 질문: 우리 게임에서 반드시 동일해야 하는 것은 입력인가요, 최종 상태인가요?
“네트워크 모델은 구현 막바지에 붙이는 전송 계층이 아닙니다. 무엇을 게임의 진실로 인정할지 정하는 규칙서에 가깝습니다.”

Q. 결정론적 락스텝은 왜 수학 코드까지 바꾸나요?

A. 같은 입력이 같은 비트 결과를 만들어야 하기 때문입니다

락스텝에서는 한 클라이언트의 계산 결과가 단 한 번만 달라도 이후 상태가 계속 벌어질 수 있습니다. 예를 들어 유닛의 거리를 비교하는 과정에서 한 플랫폼은 경계값을 안쪽으로, 다른 플랫폼은 바깥쪽으로 반올림하면 공격 대상 선정부터 달라집니다. 그 다음에는 피해량, 사망 여부, 길 찾기 장애물까지 연쇄적으로 어긋납니다. 눈에 보이는 오차가 아주 작더라도 게임 규칙에서는 전혀 다른 분기가 될 수 있습니다.

전문가는 단순히 “부동소수점을 쓰지 말라”는 처방으로는 부족하다고 설명합니다. 고정소수점 수학을 선택하더라도 오버플로 범위, 나눗셈 반올림 방향, 벡터 정규화 오차, 삼각함수 근사 테이블을 명시해야 합니다. 컨테이너 순회 순서와 병렬 작업 완료 순서도 결과를 흔들 수 있습니다. 따라서 결정론은 숫자 형식 하나가 아니라 전체 시뮬레이션의 계약입니다.

난수 역시 같은 계약 안에 들어갑니다. 전투 치명타와 시각 효과 파티클이 하나의 난수 스트림을 공유하면, 그래픽 옵션에 따라 전투 결과가 달라지는 황당한 문제가 생길 수 있습니다. 전투, 인공지능, 맵 생성처럼 시스템별 난수 스트림을 나누고 시드와 호출 횟수를 추적해야 재현 가능한 리플레이를 만들 수 있습니다.

  1. 연산 규칙 고정: 좌표 단위와 값의 허용 범위, 반올림 방향을 문서화합니다.
  2. 순회 순서 고정: 해시 컨테이너 대신 안정된 키 정렬이나 명시적 엔티티 순서를 사용합니다.
  3. 난수 분리: 게임 판정과 표현 효과의 난수 생성기를 분리합니다.
  4. 상태 해시 기록: 일정 틱마다 핵심 시뮬레이션 상태의 해시를 남깁니다.
  5. 교차 플랫폼 검증: 같은 입력 로그를 서로 다른 빌드와 기기에서 반복 실행합니다.

Q. 물리 엔진을 그대로 사용하면 안 되나요?

범용 물리 엔진은 성능과 현실적인 움직임에 최적화된 경우가 많고, 모든 플랫폼에서 비트 단위로 같은 결과를 보장하는 것이 주목적은 아닐 수 있습니다. 락스텝 게임이라면 게임 판정용 단순 충돌 모델과 화면 표현용 물리를 분리하는 방법을 검토할 수 있습니다. 반면 작은 오차를 서버 상태로 지속 보정하는 스냅샷 구조에서는 범용 물리를 활용할 여지가 더 큽니다.

  • 판정에는 원, 캡슐, 격자처럼 재현하기 쉬운 도형을 우선합니다.
  • 프레임 시간이 아니라 고정된 시뮬레이션 틱을 기준으로 적분합니다.
  • 게임 상태에 포함되지 않는 래그돌과 파편 효과는 별도 계층으로 둡니다.
  • 오버플로와 0으로 나누기를 테스트 케이스에 명시적으로 포함합니다.

Q. 액션 게임에서는 스냅샷만 보내면 충분한가요?

A. 보간, 예측, 보정이 함께 있어야 조작감이 살아납니다

서버가 초당 일정 횟수로 스냅샷을 보내더라도 네트워크 지연과 지터 때문에 패킷은 고르게 도착하지 않습니다. 받은 위치를 즉시 화면에 적용하면 캐릭터가 계단처럼 끊겨 보입니다. 그래서 원격 캐릭터는 약간 과거의 두 스냅샷 사이를 보간해 부드럽게 표시합니다. 이 방식은 안정적이지만 의도적으로 작은 표시 지연을 추가한다는 대가가 있습니다.

자신이 조작하는 캐릭터는 서버 응답을 기다린 뒤 움직이면 입력 지연이 그대로 느껴집니다. 클라이언트는 입력 직후 결과를 예측하고, 입력 번호와 당시 상태를 보관합니다. 서버의 확정 상태가 도착하면 그 시점으로 되돌아간 뒤 아직 확인받지 못한 입력을 다시 적용합니다. 이를 흔히 클라이언트 예측과 재조정이라고 부릅니다.

보정량을 무조건 한 프레임에 적용하면 순간 이동이 보이고, 너무 오래 나누어 적용하면 조준 판정과 화면 위치가 계속 어긋납니다. 작은 오차는 몇 프레임 동안 감쇠하고, 벽 통과나 큰 위치 차이처럼 게임 규칙을 위반하는 상태는 즉시 교정하는 식의 문턱값이 필요합니다. 여러분의 게임에서 10cm 오차와 1m 오차가 같은 의미인지 먼저 물어야 합니다.

대상주요 처리감수하는 비용
로컬 플레이어입력 예측과 서버 재조정재시뮬레이션 복잡도
원격 플레이어스냅샷 보간짧은 표시 지연
투사체상황에 따라 예측 또는 서버 생성오판정 보정
장식 오브젝트클라이언트 로컬 표현기기별 시각 차이

Q. 패킷이 유실되면 전체 상태를 다시 보내야 하나요?

항상 전체 상태를 보내면 구현은 단순하지만 객체 수가 늘었을 때 대역폭이 빠르게 증가합니다. 실무에서는 기준 스냅샷과 현재 상태의 차이만 보내는 델타 압축, 값의 범위를 제한하는 양자화, 플레이어 주변 엔티티만 보내는 관심 영역을 조합합니다. 단, 기준 패킷이 유실되면 이후 델타를 해석하지 못할 수 있으므로 어느 기준에 대한 차이인지 식별하고 복구 경로를 마련해야 합니다.

  • 위치는 월드 전체 좌표보다 구역 기준 상대 좌표로 압축할 수 있습니다.
  • 항상 변하는 값과 사건이 있을 때만 변하는 값을 다른 채널로 분리합니다.
  • 중요도가 낮은 엔티티는 전송 빈도를 줄이되 화면 보간 시간을 조정합니다.
  • 평균 대역폭뿐 아니라 전투가 집중되는 순간의 상위 백분위 대역폭도 측정합니다.
“스냅샷 주기를 높이면 부드러워질 것이라는 기대부터 의심해야 합니다. 병목이 지터나 렌더링 보간에 있다면 패킷을 더 보내도 화면은 좋아지지 않습니다.”

Q. 장르와 팀 규모에 따라 선택 기준이 달라지나요?

A. 플레이 감각과 운영 능력을 함께 계산해야 합니다

실시간 전략 게임, 동기식 전술 게임, 대규모 자동 전투처럼 많은 객체가 같은 규칙으로 움직이는 게임은 락스텝의 장점을 얻기 쉽습니다. 입력 데이터는 작고 리플레이도 명령 로그로 구성할 수 있기 때문입니다. 다만 느린 참가자의 입력을 기다리는 지연 문제, 중도 참가자를 위한 전체 상태 전달, 결정론 검증이라는 높은 초기 비용을 감당해야 합니다.

슈팅, 레이싱, 실시간 근접 액션처럼 즉각적인 조작과 서버 판정이 중요한 게임은 권한 서버 기반 스냅샷 모델이 일반적으로 설명하기 쉽습니다. 그렇다고 구현 비용이 낮다는 뜻은 아닙니다. 지연 보상, 과거 위치 판정, 관심 영역, 예측 실패 시 화면 처리까지 세밀하게 다뤄야 합니다. 특히 공격자 화면에서는 맞았지만 방어자 화면에서는 이미 벽 뒤에 숨은 상황에 어떤 판정을 내릴지 제품 정책이 필요합니다.

여기서 기획과 엔지니어링을 분리하면 의사결정이 늦어집니다. 게임 기획자의 역할과 맥락을 살펴보면 규칙과 사용자 경험을 구체화하는 일이 기술 선택과 맞닿아 있음을 알 수 있습니다. 또 업계 사례를 찾을 때는 GDC의 성격을 이해한 뒤 발표 자료의 장르, 동시 접속 규모, 출시 플랫폼이 우리 프로젝트와 같은지 확인해야 합니다.

판단 항목락스텝 쪽 신호스냅샷 쪽 신호
동기화 대상다수 객체의 규칙적 시뮬레이션플레이어 중심의 연속 상태
조작 요구명령 지연을 일부 허용즉각적인 로컬 반응이 핵심
플랫폼동일 연산 보장 전략이 있음이기종 연산 차이를 서버가 흡수
팀 역량수학·재현 테스트 경험이 있음서버 운영·대역폭 최적화 경험이 있음
치트 대응명령 유효성 검증이 핵심서버 권한 판정이 핵심

Q. 하이브리드 구조도 현실적인 선택인가요?

가능하지만 “좋은 점만 섞는다”는 접근은 위험합니다. 예를 들어 전투 규칙은 결정론적 틱으로 처리하고, 플레이어의 시각적 이동은 스냅샷으로 보간할 수 있습니다. 서버가 락스텝 시뮬레이션을 권위 있게 실행하면서 클라이언트에는 제한된 상태만 전달하는 구조도 가능합니다. 중요한 것은 각 데이터의 권한 소유자와 불일치 복구 방식을 한 문장으로 설명할 수 있어야 한다는 점입니다.

  • 규칙 상태: 체력, 자원, 승패처럼 반드시 합의되어야 하는 값
  • 운동 상태: 위치, 속도, 회전처럼 빈번하게 변하는 값
  • 표현 상태: 파티클, 카메라 흔들림처럼 동기화하지 않아도 되는 값
  • 복구 상태: 재접속과 역직렬화를 위해 별도로 저장할 값

Q. 이번 주에 어떤 실험부터 시작하면 될까요?

A. 작은 전투 장면을 두 방식으로 재생해 수치로 비교하세요

처음부터 완성형 네트워크 계층을 만들 필요는 없습니다. 이동 가능한 플레이어 2명과 상호작용 객체 20개가 있는 작은 장면을 준비하고, 동일한 입력 기록을 두 기기에서 10분간 재생해 보세요. 락스텝 후보라면 매 30틱마다 상태 해시를 비교하고 최초 불일치 틱을 저장합니다. 스냅샷 후보라면 왕복 지연, 지터, 패킷 유실률을 인위적으로 바꾸며 화면 오차와 보정 횟수를 기록합니다.

테스트 조건은 평균 지연 하나로 끝내지 않는 것이 좋습니다. 예컨대 왕복 지연 40ms와 120ms, 지터 0ms와 30ms, 유실률 0%와 3%를 조합하면 구조의 약점이 훨씬 빨리 드러납니다. 수치는 절대적인 합격 기준이 아니라 비교 기준입니다. 조작 장르에서는 보정 발생 횟수와 최대 위치 오차가 중요하고, 전략 장르에서는 상태 불일치 여부와 느린 입력 참가자가 전체 진행에 미치는 영향이 중요합니다.

프로토타입 비용도 기술 예산에 포함해야 합니다. 계획과 예산을 연결하는 개념처럼 네트워크 실험을 기능 개발과 분리된 취미 작업으로 두지 말고, 실패 조건과 투입 시간을 명시한 개발 항목으로 잡으세요. 이틀짜리 검증으로 잘못된 구조를 버릴 수 있다면 몇 달 뒤의 재작성보다 훨씬 저렴합니다.

  1. 고정 틱으로 움직이는 최소 장면과 10분 분량 입력 로그를 만듭니다.
  2. 네트워크 시뮬레이터에 지연, 지터, 유실률 세 조건을 설정합니다.
  3. 락스텝에서는 상태 해시와 틱 처리 시간을 기록합니다.
  4. 스냅샷에서는 초당 전송량, 최대 화면 오차, 강제 보정 횟수를 기록합니다.
  5. 플레이 영상을 수치 로그와 함께 보며 허용 가능한 불일치 기준을 기획자와 합의합니다.

Q. 실험 결과는 어떤 문장으로 남겨야 하나요?

“락스텝이 더 효율적이었다”처럼 넓은 평가는 다음 의사결정에 도움이 되지 않습니다. “객체 20개, 30틱, 왕복 지연 120ms 조건에서 입력 대기 시간을 100ms 이하로 유지했지만 ARM과 x86 빌드의 상태 해시가 4분 12초에 달라졌다”처럼 조건과 실패 시점을 함께 적어야 합니다. 스냅샷도 “초당 20회 전송에서 평균은 부드러웠으나 3% 유실 조건에서 50cm 이상 보정이 분당 8회 발생했다”처럼 남기면 다음 실험이 선명해집니다.

  • 측정한 빌드와 플랫폼을 기록합니다.
  • 서버 틱과 스냅샷 전송 빈도를 구분해 적습니다.
  • 평균값과 최대값, 상위 백분위 값을 함께 봅니다.
  • 눈으로 느낀 불편을 영상 타임코드와 수치 로그에 연결합니다.
  • 통과 기준을 바꿨다면 이유와 결정자를 남깁니다.

지금 당장 할 행동은 하나입니다. 기존 플레이 장면에서 플레이어 입력 60초를 파일로 저장하고, 같은 입력을 두 번 재생한 뒤 매 틱의 위치와 체력 해시가 일치하는지 확인하세요. 이 짧은 실험이 성공하면 결정론을 확장할 근거가 생기고, 실패하면 어느 시스템부터 격리해야 하는지 보여 주는 첫 좌표가 됩니다.

결정론적 락스텝과 스냅샷 동기화, 멀티플레이의 기준

댓글목록

등록된 댓글이 없습니다.