Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Multiplayer Game Sync Techniques through CAP theorem

6.304 visualizaciones

Publicado el

멀티플레이어 게임 동기화 이야기 (최종일관성, 서버 되감기, 결정성)

Publicado en: Ingeniería
  • Dating for everyone is here: www.bit.ly/2AJerkH
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Sex in your area for one night is there tinyurl.com/hotsexinarea Copy and paste link in your browser to visit a site)
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Girls for sex are waiting for you https://bit.ly/2TQ8UAY
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Meetings for sex in your area are there: https://bit.ly/2TQ8UAY
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Best site for flirting and sex in your area you can find there: https://bit.ly/2SlcOnO
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí

Multiplayer Game Sync Techniques through CAP theorem

  1. 1. Nexon OC Studio Technical Director 구승모 최종 일관성, 서버 되감기 기법, 그리고 결정성에 관해 CAP 정리를 통한 게임 동기화 이야기
  2. 2. • 캘리포니아 오랜지 카운티에 위치 • 주로 Amazon, Blizzard, NC, Riot, Sony 출신의 개발진으로 구성 (이 게임 회사들 물리적으로 10분 이내에 위치…) • PC/Console • 주로 북미/유럽 대상
  3. 3. 발표자 소개 • Nexon OC 테크니컬 디렉터 • WOW 때문에 인생 크게 바뀐 케이스 • 이 게임 때문에 게임 업계로 이직 • NCSOFT 서버 프로그래머 • Bluehole 선임 엔지니어 / 서버 아키텍트 • NHN NEXT 게임 전공 교수 • Amazon Games 수석 엔지니어 • NDC 2014 • “사설 서버를 막는 방법들“ (우수세션) 전투/작전 사령관 캐릭 하나씩, 오리지널 낙스라마스 공대 2005년에만 순수 게임 플레이 시간: 160+일
  4. 4. 목차 1. CAP 정리 그리고 최종 일관성 2. 멀티플레이어 게임 동기화 101 3. 서버 되감기를 통한 동기화 4. 게임 로직과 결정성
  5. 5. 이 세션에서 다루지 않는 것들 • 여러가지 Dead Reckoning 테크닉* • 분산 시스템에서의 합의 알고리즘 또는 상태 복제 프로토콜들* • PACELC 같은 CAP의 확장 정리* • 각종 일관성 모델* * 자세한 내용은 참고 자료 슬라이드에…
  6. 6. CAP 정리 그리고 최종 일관성
  7. 7. CAP Theorem • 2000년, Eric Brewer* • 튼튼한(robust) 분산 시스템 설계시 기술적인 선택에 도움을 주는 정리 • 일관성 (Consistency) • 가용성 (Availability) • 분할용인 (Partition Tolerance) • C+A+P를 동시에 모두 만족하는 시스템은 없음 • 2개 선택하세요 • NoSQL과는 사실상 관련 없음 IMG From: https://docs.deistercloud.com/Technology.50/NoSQL/index.xml
  8. 8. NoSQL • 대량의 데이터를 빠르게 처리하기 위함 • 데이터간 관계가 단순 • Schemaless • Key-Value, Key-Document 형태가 일반적 • 단순하지만 고성능 및 고가용성을 제공 • 내부적으로 스토리지 구조가 샤딩 및 복제본을 두는 형태 • 실전에서 많이 사용되는 것들* • MongoDB, Cassandra, DynamoDB, … Node1 Node2 Node3 Client1 Client2 비동기 업데이트 Writes Read
  9. 9. AWS DynamoDB 예 • DynamoDB의 데이터 읽기/쓰기 • Write는 3군데의 스토리지에 분산 복제 저장 (2군데 쓰면 바로 응답리턴) • Read는 2가지 방법 중 선택 • Default Read: 3개의 노드중 가장 먼저 응답하는 하나에서 읽기. 이 경우 과거의 데이터를 읽어올 가능성이 있음 (가용성을 선택) • Consistent Read: 모든 노드의 데이터가 동기화된 후에 읽어옴 (일관성 선택) Client1  DynamoDB Storage (3벌 복제 및 분산 저장) Client2 Client3 Read ReadWrite  Client2와 Client3은 서로 다른 상태를 볼 수 있음
  10. 10. 최종 일관성 (Eventual Consistency) • A+P 시스템 기반위에 뒤늦게 일관성을 맞추는 방식* • 순간적으로 과거의 데이터를 볼 수 있지만, 결국 일관성이 맞춰짐 • (참고) AP 시스템이라고 해서 최종 일관성을 무조건 만족하는 것은 아님 (e.g.) AWS SQS IMG From: http://www.cloudcomputingpatterns.org/eventual_consistency/
  11. 11. 멀티스레드 환경에서의 일관성 • 싱글스레드 • C + A: 일관성(C) + I/O 등으로 인한 블로킹이 없다면 (A) • Lock으로 동기화하는 멀티스레드 환경 • C + P: 잠금을 통한 일관성 유지 (C) + 멀티스레드 (P) • 여러 스레드가 항상 동일한 공유자원 상태를 볼 수 있음 (Consistency) • 이 방법은 Availability가 보장되는가? • 하나의 스레드가 잠금 중일때는 다른 모든 스레드는 대기해야 함 (순간적으로 Available하지 않음을 의미) • Lock안에서 I/O등을 통한 대기가 걸린다면? Lock Convoying…
  12. 12. 최종 일관성을 통한 멀티스레드 성능 향상 • 일관성을 약간(?) 양보할 수 있는 경우 • 특정 스레드가 과거의 상태를 잠깐 보는 한이 있어도 스레드가 공유자원 접근시 대기하지 않도록 함 • C + P 대신 C + A를 선택 • 대신, 결국에는 모든 스레드가 같은 상태로 맞춰질 수 있도록 구현 • How-to • Thread Local Storage별 자료구조를 두고 업데이트 큐(lock-free or wait- free queue)를 활용하여 스레드별 업데이트 • 읽기는 스레드 로컬 접근, 업데이트는 큐를 활용하여 비동기적으로 • (예) https://github.com/zeliard/Dispatcher/blob/LB_version/JobDispatcher/LoadBalancer.h
  13. 13. TERA Case Study • 처음에는, 하나의 맵을 두고 여러 로직 스레드가 경합 • ReadLock을 통한 검색, WriteLock을 통한 업데이트 • 모든 스레드가 동일한 맵 상태를 볼 수 있지만 (일관성 유지)  CPU 100% !! Actor 11 12 13 21 22 23 31 32 33 Map C C’ Worker Thread #1 Waiting… Worker Thread #2 Lock – Update - Unlock Worker Thread #n Waiting…
  14. 14. Update Queue U (1) Push Map Update Task 0 N 1 2 3 … Queue Index Replicated Map Info Thread Local Map 1 Thread Local Map 2 Thread Local Map N Sequence of Task Execution (2) Pop & Execute Update Task U D D Current TLS index: 2Current TLS index: 1 Current TLS index: 1 Current TLS index: 1 Current TLS index: 2 Current TLS index: 2 D TLS를 이용한 최종 일관성으로 변경 순간적으로 특정 스레드는 과거의 상태를 볼 수 있지만 Lock 경합이 없음  스레드 입장에서는 맵 자료구조가 언제나 가용(available)한 상태  성능 향상
  15. 15. 멀티플레이어 게임 동기화 101
  16. 16. 싱글 플레이어 게임의 처리 과정 Inputs Simulate Render Wait States events timer State State State Time Frame Per Second (FPS)  이 루프가 1초에 몇 번 도는가? C + A 시스템
  17. 17. 멀티 플레이어 게임 동기화 타입 동기형 (타입1)비동기형 동기형 (타입2)
  18. 18. 비동기형 (Asynchronous) 게임 • 주로 웹서비스 형태의 백엔드 • 2-tier: web servers + data store • 3-tier: web front + app servers + data store • HTTPS를 이용한 보안성 확보가 쉬움 • 연결 유지가 필요 없어 접속이 불안정한 환경에서 유리 • 모바일 게임 및 소셜 게임 장르에 적합 • (요즘 대세) 서버리스 형태로도 백엔드 구축 가능 • API Gateway, Cloud function, Lambda, … Client LB Web Server Browser Web Server Client Browser Web ServerHTTP
  19. 19. 비동기형 게임의 일반적인 동기화 방식 Request/Response 구조 • 웹의 특징을 그대로 물려 받음 • Atomic, Stateless • 플레이어간 순서 보장이 필요할 경우 • 사과를 친구가 먼저 수확한 경우 어떻게 처리? • 주로 캐시서버나 DB에서 동기화 • 수동적: Server-initiated Action 어려움 • 몬스터의 선공과 같은 능동적 NPC 행동 불가 Client Web Server State State State Response Request
  20. 20. 동기형(Synchronous) 게임 • 실시간 동기화 • 멀티플레이어 게임도 하나의 분산 시스템이라고 볼 수 있음 • 사실 CAP는 분산 시스템 어디서나 적용할 수 있는 이야기 • 원격지의 상태 복제를 통해 동기화 • 게임 스타일에 따라 일관성과 가용성 중 선택해야 함 • 네트워크 게임 == 분산 환경 (즉, P는 필수 요소) • 선택지: 가용성(A) vs 일관성(C)
  21. 21. • 서버가 게임 로직 처리(Simulate) 및 동기화 • 클라이언트는 서버를 통한 간접 연결 • NPC를 서버가 능동적으로 활용(drive)할 수 있음 • 주로 사용되는 장르: FPS, MMORPG, MOBA, Sports 동기형 (타입1: 서버 동기화) Simulate States Inputs Render Wait eventsServer state info
  22. 22. • Client-Server 아키텍처 • 클라이언트에서 발생하는 이벤트는 서버에서 모두 모아 계산한 후 클라이언트로 방송 • 자본주의(?) 동기화 / 낙관적(?) / A+P System • 서버가 먼저 진행  클라는 따라올테면 따라와봐  네트워크 속도가 빠른 클라일수록 서버와의 격차가 가장 적음 (유리) • 서버/클라간 시간차는 클라가 알아서 Dead Reckoning* Server Client A Client B NPC NPC NPC A B A A B B Event A Event BNPC Event 서버 동기화 (Server-Authoritative) 클라가 늦게 받을수록 튀는 현상 발생
  23. 23. IMG From: http://m.post.naver.com/viewer/postView.nhn?volumeNo=11513471&memberNo=16036253 Rubber Banding?
  24. 24. 서버 동기화 TickRate 고려사항 • 서버 시뮬레이션 TickRate 및 방송 주기는 얼마로 할 것인가? • 높은 TickRate는 더 정확한 판정 (이후 설명할 서버 되감기에도 더 유리) • 그러나 더 많은 CPU와 네트워크 대역을 요구 (인프라 비용 상승) • (예) 고오급시계의 기본 서버 방송 주기는 20Hz, 커스텀 모드는 60Hz 까지
  25. 25. 방송 범위와 보안 • 시야 범위 (Area Of Interest) • AOI 관리를 통해서 클라가 알아야 하는 범위의 정보만 전송 • (참고) UE4 Dedicated Server의 Network Relevance • AOI 범위가 좁을수록 플레이어 경험이 불쾌해짐 (시야가 좁아짐) • AOI 범위가 넓을수록 패킷 처리량이 많아지고 보안에 불리해짐 • (예) PUBG • 원거리 저격 때문에 멀리 있는 적 정보까지 동기화 대상 • 벽뒤에서 갑툭튀(?) 때문에 AOI Occlusion Culling을 적용하기도 어려움
  26. 26. • 상대 플레이어로부터 주기적으로 이벤트를 모아 각자 시뮬레이션 • RTS 및 과거의 AOS 장르에서 주로 사용 동기형 (타입2: Lock-Step 동기화) Inputs Simulate Render Wait States peer events Inputs Simulate Render Wait States Compare Compare Same hashval?
  27. 27. Dropped from the game? IMG From: http://starcraft.burningblade.org/stories/index.html
  28. 28. Lock-Step 형태의 동기화 방식 • 각각의 클라이언트는 모두 아래와 같은 형태의 Queue를 유지 • 공산주의(?) 동기화 / 비관적(?) / C+P System • 다 함께 같이 간다  클라가 하나라도 멈추면 다 같이 기다린다 • 서버 동기화 방식과 다르게 특정 클라만 튀는 현상 없음 • 월드의 전체 내용을 서로 공유하기 때문에 해킹에 취약 (맵핵/헬퍼) • 라운드간 Lag 숨기기 기법을 최대한 활용*: (예) 스타크 마린의 Pre-Anim & Sound play events eventsevents나 상대1 상대2 Round 0 ms 50 100 150 Round Round Round events events events 모든 Peer들의 입력이 모이면 해당 Round를 처리(Simulate) 하고 렌더링 특정 Peer의 정 보가 제시간에 도달하지 않으 면 Block ?? events
  29. 29. Waiting for players?
  30. 30. Lock-Step 동기화 TickRate 고려사항 • Lock-Step 동기화 주기(Round 길이)에 영향 • 스타크래프트 Low/High latency 옵션 예 • Low: Waiting for players 화면을 볼 가능성이 더 높지만 반응성이 더 좋음 • TickRate 높고, Round 길이 짧음 • High: 게임은 더 부드럽게 진행되지만 반응성이 더 느림 • TickRate 낮고, Round 길이 김 • (예) CR게임 동기화 • 글로벌 원 서버 (A社 미국 클라우드) • 1초 Round 동기화: 지구 반바퀴 지연 0.5s 이내
  31. 31. Re:CAP • 서버 동기화 • A+P System: 플레이어들에게 랙없는 경험을 최대한 주기 위해 항상 응답 가능한 상태(Available)를 유지 • Lock-Step 동기화 • C+P System: 플레이어들에게 공평한 경험을 주기 위해 항상 일관성(Consistent)이 있는 상태를 유지
  32. 32. 서버 되감기를 통한 동기화
  33. 33. 왜 Lag을 보정해야 하는가? • 인터넷은 빨라졌지만… • 멀티플레이어 게임에 국경이 없어지고 있음 • 글로벌 원빌드, 더 먼거리의 플레이어간 대전 • 역설적으로 플레이어들은 랙에 노출이 더 심해짐 • 결국 랙을 핸들링 해야 함 • 가까운 거리상의 플레이어들끼리 매칭하도록 강제하거나, • 랙을 무시하고 클라이언트가 최대한 알아서 보정 하거나, • 게임 시스템이 알아서 보정해주는 트릭을 사용해서 플레이어를 속이거나(?)
  34. 34. 동기화 트렌드 • 어차피 Lag을 피할 수 없다면… • 일관성을 맞추기 위해 누군가를 기다려야 한다는 것은 불쾌한 경험을 줌 • CP 시스템은 아주 제한적으로 사용 가능 (예: Round주기가 500ms 이상) • 최악의 경우에도 Round 주기 이내에 응답이 오는 경우를 가정 • 누군가를 기다리지 않는 서버 동기화의 방식을 채택 (AP 시스템) • 여기에 최종 일관성을 통한 최대한의 공정함을 보장하는 방법 사용 • 공정한 플레이 및 쾌적한 느낌을 주기 위해 Lag을 보정 • 서버 되감기를 통한 동기화*
  35. 35. 서버 되감기를 통한 동기화 • 서버는 클라이언트가 보던 과거의 시점으로 돌려서 판정 • 퀘이크, 듀크뉴캠, 콜오브듀티 등이 이 방법 사용 • 게임 시뮬레이션은 서버와 클라이언트에서 모두 각자 함 • 클라이언트의 입력 및 자체 시뮬레이션 결과를 서버에 전송 • 서버에서 클라이언트의 입력 시점으로 되돌려서 시뮬레이션 • 클라에서 보내준 자체 시뮬레이션 결과와 같다면 OK • 클라에서 보내준 자체 시뮬레이션 결과와 다르다면 클라이언트에게 알려줌 • 서버에서의 최종 결과가 도착하면 클라이언트에서 보정 • 클라에서 예측을 통한 시뮬레이션을 먼저 하고 진행하는 것이 일반적 • 예: LOL의 틱당 골드 증가
  36. 36. 서버 되감기 시각화 IMG From: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
  37. 37. 아주 쉬운 예 • 울트라 캡숑 쉬운 예제: Pong Laser 게임 P2 P1 Shoot a Laser Game World
  38. 38. 기본 원리 TIME CLIENT SERVER Latency Shoot Target Hit Target Move Target Move Shoot Target Hit Target Hit? Target Hit Approved Server Rewind
  39. 39. 상태 변화 요약 • 서버가 클라에게 보낸 월드 상태 • 클라가 서버에게 보낸 입력 변화 WorldFrame TARGET PosY 1 2.0 2 3.0 3 5.0 4 8.0 WorldFrame Client Input FR Shoot 1 1 No 2 2 No 2 3 No 3 4 Yes 클라이언트가 알고 있는 WorldFrame 기준으로 서버가 상태를 되돌려 판정
  40. 40. Real Code Sample • Pong Laser • https://github.com/zeliard/PongRewind • 일부러 서버/클라이언트 양측에 랜덤 Delay를 넣어서 Desync상황 연출 최대한 쉽고 깔끔하게 만드려고 노력했으나 급하게 만든 날코딩 양해 구함
  41. 41. Pseudo Code Level • 클라이언트가 보내는 정보 Client Input (Request) • 서버가 방송하는 정보 Game Status (Broadcast)
  42. 42. 서버 되감기를 위한 히스토리 유지하기 • 서버측에서 WorldFrame별 상태 보관 • 과거의 상태가 필요한 오브젝트에 대해 WorldFrame(서버프레임)별 스냅샷 • 참고: 이번 예제는 너무 간단하므로 월드 상태를 통째로 유지함 • 실전에서는 되감기가 필요한 객체에 대해서만 제한적으로 유지하는 것을 추천
  43. 43. • Client Update Loop 1. 현재 플레이어의 입력을 얻는다 2. 플레이어 입력을 기반으로 시뮬레이션(상태 업데이트)을 한다 3. 업데이트된 상태에 대한 해시를 구한다 4. 서버에 플레이어의 입력 및 해시 값을 보낸다 5. 클라이언트 입력에 대한 History를 기록한다 • Desync시 클라이언트 Replay를 위해 Client Input Frame 단위로 보관 Client Logic https://github.com/zeliard/PongRewind/blob/master/PongClient/PongClient/GUIController.cpp#L145-L164
  44. 44. Client Logic • Client Receive Handler 1. 서버로부터 도착한 최신 상태를 덮어쓴다 • 최신의 서버 상태로 강제 업데이트를 의미하나 바로 렌더링에 반영할지, 클라이언트에서 더 부드럽게 보정(데드레커닝)을 할지는 선택의 문제 https://github.com/zeliard/PongRewind/blob/master/PongClient/PongClient/GUIController.cpp#L233 • Client Resync Handler • 클라이언트가 보낸 해시와 서버가 계산한 해시가 다를 때 호출됨 1. 서버가 상태가 어긋난 Client Input Frame을 알려줌 2. Client Input History에서 해당 프레임부터 차례대로 적용 (Replay) https://github.com/zeliard/PongRewind/blob/master/PongClient/PongClient/GUIController.cpp#L275
  45. 45. Server Logic • Server Update Loop 1. 바로 이전 WorldFrame의 상태를 꺼내온다 2. ++WorldFrame 3. 월드 상태 업데이트 4. 업데이트된 월드 상태를 현재의 WorldFrame History에 저장 5. 클라이언트에 업데이트된 상태 방송 https://github.com/zeliard/PongRewind/blob/master/PongShared/GameLogic.cpp
  46. 46. Server Logic • Server Receive Handler • 클라이언트로부터 받은 정보에 포함된 WorldFrame 시점에서 판정 • 해당 시점으로 서버 되감기 한 후 시뮬레이션 • 시뮬레이션 결과 해시와 클라에서 보내온 해시와 다르면 Desync 상황 • 이 경우 클라이언트에게 알려서 Resync 요청 • 클라이언트의 입력을 반영 https://github.com/zeliard/PongRewind/blob/master/PongServer/PongServer/GameManager.cpp#L57
  47. 47. 서버 되감기 부작용 • 최대 지연 시간만큼의 후판정으로 인한 불쾌감 • (예) 피격자가 엄폐물 뒤로 숨었는데 피격되는 일 • 지연은 제거할 수 없고, 다른 곳으로 숨길 수밖에 없기 때문 • 누구에게 더 좋은 느낌을 주도록 할까? 공격자 or 피격자? • 일반적으로 FPS는 공격의 횟수가 피격의 횟수보다 절대적으로 많기 때문에… • 현대의 FPS게임은 총 쏘는 사람 입장을 더 쾌적하게 하는 것을 주로 선택
  48. 48. 서버 되감기 모범사례 • 월드 상태를 모두 되감기 할 것인가? • 관련 있는 녀석(주로 Actor)만 되감기 하는 것이 일반적 • History를 얼마만큼 보관할 것인가? • 보통은 서버/클라간 최대 Latency 안에서 • 빠른 (서버 클라간 RTT/2 이내에 판정이 나는) 무기에 적용 • 발사체(Projectile)은 전혀 다른 방식으로 접근해야 함* • 되돌릴 수 없는 속성(Unrewindable Property) 지정 • 이미 서버에서 확정(commit)한 것들 (예: Alive, Score, …) • Desync 상황 핸들링 • 따로 패킷으로 보내서 클라에게 Resync요청하기보다 주기적으로 방송하는 업데이트 패킷에 포함 하는 것이 좋음
  49. 49. 월드 상태 방송시 고려사항 • 월드 상태 전송시 변화(delta)분만 보낼 것인가? • 전체 데이터를 보내되 압축을 사용할 것인가? • CPU 사용률은 높아지지만 네트워크 대역을 줄일 수 있음 (개인적인 경험으로는 600 bytes 이하면 패킷 압축은 크게 의미 없는 경우가 많았음) • 프로토콜별 주의사항 • TCP: Nagle 알고리즘을 꺼야 하는 경우가 대부분 • UDP: 패킷 크기가 클수록 손실 확률이 높아짐 • 크기가 충분히 작다면(100 byte 이내) 이전 프레임의 데이터를 중복 포함해서 재전송 피하기 • Bit packing 최대한 활용 • 패킷이 MTU 경계에 걸릴 확률이 높으면 압축을 고려
  50. 50. Re:Wind • 서버 되감기를 통한 동기화 • FPS게임에서는 이미 많이 쓰이고 있는 기술 • 기본적으로는 서버 동기화 기반 (A+P system) • Lag으로 인한 불쾌함을 최소화 하기 위해 강한 일관성을 버리고 • 유저에게 최대한의 공정함을 주기 위해 최종 일관성을 흉내낸 방법
  51. 51. 게임 로직과 결정성 (Determinism)
  52. 52. 게임 로직과 결정성 • 결정형 (deterministic) 게임 로직 • 동일한 입력에 대해 항상 동일한 결과가 나올 수 있는 게임 로직 • 원격지간 동기화시 입력만 맞추면 동일한 결과 보장 • 동기화 설계가 쉬워질 수 있음을 의미 • (참고) deterministic physics* • 랜덤의 요소가 존재한다면? • (예) 스타크래프트의 해병 라이플 데미지가 6~10 랜덤일 경우 • 피격대상의 히드라 HP가 8 남은 상태라면? • 어떤 경우에는 히드라가 살고, 어떤 경우에는 죽게 됨 (운빨 ㅈ망겜) • 비결정성인 것 같지만…
  53. 53. 난수와 결정성 • 사실 컴퓨터에서 생성하는 난수는 Pseudo Random Number • 어떤 초깃값(SEED)를 이용하여 이미 만들어진 메커니즘을 통하여 생성되는 수로 무작위처럼 보이는 가짜 난수 • 즉, 초기 SEED 값만 같으면 똑같은 난수가 생성됨 (Deterministic!) • 처음 SEED 동기화 후 각자 시뮬레이션해도 같은 결과(난수)가 나옴 사실 님들의 게임 운빨은 결정되어 있음
  54. 54. 난수 동기화 • SEED만 맞추면 망고땡인가? • 의사난수 생성기는 상태가 있음을 의미 • 호출 할 때마다 상태가 바뀜 • 직전에 생성된 난수의 일부를 SEED로 사용 • 즉, 랜덤 생성 함수 호출 과정(횟수)이 같아야 결정성이 보장됨 • 특정 서버(월드) 프레임 번호를 랜덤 SEED로 사용하면 난수 동기화가 쉬워짐 • 멀티스레드 게임 로직에서는 동일한 시뮬레이션 결과를 기대할 수 없음 • 스레드별로 PRNG를 둔다고 해도, 게임 로직이 여러 스레드에서 도는 경우
  55. 55. 멀티스레드와 결정성 • 동일한 게임 로직을 멀티스레드의 형태로 처리한다면? • Lock-Step 계열의 동기화가 가능한가? 서버 되감기시 문제 없는가? • 게임 로직이 멀티스레드여야만 하는 경우는? • 수만개의 액터를 동시에 시뮬레이션해야 하는 게임? • A + P 시스템을 극단적으로 사용할 수밖에 없는 상황인 경우: MMORPG? • 비결정성 • 똑같은 입력이 주어지더라도 다른 시뮬레이션 결과가 나올 수 있음 • 멀티스레드 게임로직은 정확히 어떤 순서로 실행될지 알 수 없음 • NP-Hard 문제 (웰컴투더헬: 최악의 경우 모든 가능성을 다 조사해봐야…)
  56. 56. 부동소수점과 결정성 • 같은 물리 계산식인데 상대 플레이어 머신에서는 다른 결과가? • 입력과 로직이 같은데 결과가 다르다? 흠좀무… • 다음중 하나라도 어긋나면 부동소수점 결정성이 깨질 수 있음 • CPU 아키텍처, OS, 컴파일러 종류 및 최적화 수준, 빌드종류(debug/release) • 특히 크로스플랫폼 멀티플레이 게임 제작시 주의 필요
  57. 57. 메모리와 결정성 • 주소 값으로 인한 의도하지 않은 비결정성 • C++ STL 컨테이너 내의 정렬 문제 • default sort는 원래의 순서를 보존하지 않음 (cf: stable_sort) • 주로 포인터 값을 기준으로 비교할 때 발생 • 포인터 값을 key로 사용하는 경우 항상 주의 (즉, 주소를 해시하는 경우) • 초기화되지 않은 메모리가 결정성에 영향을 주는 경우 • struct의 경우 alignment에 의해 멤버 사이의 공간에 채워진 값이 다름 • Padding까지 깔끔하게 초기화 하기 위해서는 memset() • 직접 바이너리 비교 또는 해시를 통한 정렬 주의
  58. 58. 정리 • 최종 일관성은 유용한 도구의 하나 • No Silver Bullet • 게임 특성에 따라 일관성 vs 가용성 선택 • 동시에 만족하는 경우는 없으니 과감히 포기 • 전송해야 하는 물리 상태의 양이 많다면 입력만으로 동기화가 가능한 lock-step이 유리하나, 그 이외의 경우에는 서버 동기화가 대부분 유리 • 동기화 메커니즘 설계시에는 항상 결정성을 고려 • 이도저도 귀찮으면 그냥 서버에서 모두 동기화하고 클라는 알아서 보정
  59. 59. 참고 자료 • Dead Reckoning: https://en.wikipedia.org/wiki/Dead_reckoning • Raft: https://raft.github.io/ • Paxos: https://en.wikipedia.org/wiki/Paxos_(computer_science) • CAP theorem: https://people.eecs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf • PARCELC: https://en.wikipedia.org/wiki/PACELC_theorem • NoSQL: https://www.slideshare.net/akleinbe/the-rise-of-nosql • Eventual Consistency: https://en.wikipedia.org/wiki/Eventual_consistency • Eventual Consistency for TERA : http://download.enmasse.com/documents/201205-gdm-tera.pdf • Consistency Model: https://en.wikipedia.org/wiki/Consistency_model • Lag Compensation: http://www.gamedonia.com/blog/lag-compensation-techniques-for-multiplayer-games-in-realtime • NetCode for Overwatch: https://www.youtube.com/watch?v=vTH2ZPgYujQ https://www.youtube.com/watch?v=H0zbpPCdhGk • Server Rewind for FPS Games: https://kotaku.com/5869564/networking-how-a-shooter-shoots • Server Rewind for Projectiles: https://www.gamasutra.com/blogs/NeemaTeymory/20160906/280377/Why_Making_Multiplayer_Games_is_Hard_Lag_Compensating_Weapons_in_M echWarrior_Online.php • Deterministic Physics: https://gafferongames.com/post/deterministic_lockstep/ • Floating-point Determinism: https://gafferongames.com/post/floating_point_determinism/ • Rollback Networking for Inversus: http://blog.hypersect.com/rollback-networking-in-inversus/
  60. 60. 감사합니다.
  61. 61. 이어지는 세션 광고 • 게임 동기화 자체에 대한 사례와 실전 팁들을 좀 더 알고 싶으시면 • 게임플레이 동기화 개론, 11시 국제회의장, 넥슨 송창규 • 이동/공격 동기화, 리얼타임 네트워킹, 해킹과 보안, 락스텝과 시뮬레이션 • 애니메이션/연출 그리고 조작감, Dedicated Server, 난입과 롤백 • CAP / NoSQL의 실전사례에 대해 관심 있으시면 • 듀랑고 / NoSQL위에서 MMORPG개발하기, 11시 1994홀, 넥슨 최호영
  62. 62. 보너스 • Lock-Step은 점점 쓰이는 곳이 없지만 • 동기화에 관심 많은 분들은 직접 한 번 구현해보는 것이 많은 도움이 됨 • 많은 예외 상황에 대한 통찰을 주기도 하고 • 업계 신참들에게는 자신의 실력 향상을 위한 좋은 기회가 되기도 함 • 그래서, 준비했습니다: https://github.com/gasbank/laidoff • 서버 되감기 또는 락스텝으로 고쳐볼 수 있는 장난감 프로젝트

×