지속적인 온라인 게임에서 플레이어의 상태를 얼마나 자주 저장합니까?


9

온라인 게임에서 사람들은 원할 때마다 로그온 및 로그 오프를 선호합니다. 일반적으로 게임 업적은 서버에 완벽하게 저장됩니다. 그것은 달성하기 어렵지 않지만, 나는 의미 있고 확장 가능한 효율적인 방법으로 어떻게 할 수 있는지 궁금합니다.

플레이어의 좌표와 상태를 보낼 때마다 저장하는 것이 합리적입니까? 내 node.js 서버는 응답을 차단하지 않고 쉽게 할 수 있으며 Mongo 데이터베이스를 사용하고 싶지만 1 초에 한 번 그리고 서버 전체 이벤트에서 한 번에 모두 수집하는 것이 더 적절할까요?


게임 상태를 10 초마다 저장합니다. 나는 이것으로 충분하다고 생각합니다. (그리고 512MB RAM이있는 넷북에서 MMORPG 서버를 실행하고 있습니다).
jcora

답변:


10

월드 오브 워크래프트와 같은 전통적인 MMORPG를 생각했습니다.

각 플레이어의 모든 명령과 자율적 인 것 (예 : NPC) 후에 저장

  • 지속적인 백업. 서버는 언제든지 다운 될 수 있으며 게임 상태는 그 순간까지 (또는 가능한 한 최근에) 저장됩니다.
  • 서버 성능에 미치는 영향; 데이터베이스가 다른 서버에 있더라도 비 차단 (예 : 다른 스레드) 인 경우에도 처리하지 않습니다. 당신이 말한 것처럼 차단되지 않으면 다른 스레드가 처리해야하며 다른 스레드가 차지할 수있는 스레드입니다.
  • 디스크 I / O가 증가하여 위험 / 오류 발생률이 증가합니다. 수명이 짧아 스토리지에 SSD를 사용하는 경우 특히 문제가됩니다.
  • 데이터베이스를 다른 서버로 오프로드하면 대역폭이 증가합니다. 대역폭을 지불하는 경우 문제가 될 수 있으며 별도의 네트워크 카드가 아닌 경우 플레이어 트래픽 처리에 더 적합한 리소스를 사용하고 있습니다.
  • 서버가이 명령의 상태를 저장하는 데 점점 더 뒤쳐지면 어떻게됩니까? 즉, 저장할 수있는 것보다 많은 명령이 들어 오면 대기열에 쌓입니까? 이 대기열이 오버플로되어 오류가 발생합니까? 대기열을 잡을 수 있도록 모든 것을 중지합니까?
  • 이 방법은 간단하게 들리지만 신중하게 계획해야 할 것 같습니다. 예를 들어, 서로 의존하는 연속 명령을 함께 저장해야합니다. 그렇지 않으면 명령 중간에 오류가 발생할 수 있으며 하나만 저장되고 다른 하나는 저장되지 않습니다. 두 명의 플레이어가 거래를 수행하고 두 개의 명령이 디스크에 저장되어 있는지 "수신자에게 항목 1 추가"및 "발송인으로부터 항목 1 빼기"를 고려하십시오. 첫 번째 명령 이후에 두 번째 명령이 저장되기 전에 오류가 발생하면 항목이 중복 된 것입니다. (주문이 역전 된 경우 상품이 분실 된 것입니다)

모든 것을 주기적으로 저장하십시오

  • 장애가 발생하면 서버가 다소 오래된 것입니다. 바라건대 저널링 된 접근법과 같은 것을 사용하기 때문에 가장 최근의 스냅 샷은 최소한 전체적이고 일관성이 있으며 모든 활성 플레이어는 같은 시간 동안 다시 설정됩니다.
  • 어떤 데이터베이스 시스템을 사용하든 일괄 업데이트를 최적화하면 한 번에 하나씩 업데이트하는 것보다 효율적입니다 (오버 헤드가 적음).
  • 이진 파일 시스템을 대신 선택하면이 방법은 간단합니다. 새 파일을 만들고, 메모리를 덤프하고, 끝에 백업이 완전히 완료되었음을 알리는 마커를 던집니다. 하나의 백업이 완료되면 이전 백업을 삭제하십시오.
  • 백업 프로세스는 다른 섹션의 마지막 글 머리표에 언급 된 내용 (예 : 분할해서는 안되는 연속 명령의 중간 저장)을 고려해야합니다. 전체 데이터 세트를 잠그고 디스크에 덤프 한 후 잠금을 해제 할 수 있지만 시간이 얼마나 걸리면 게임이 상당히 일시 정지되거나 느려질 수 있습니다.

로그 아웃시 문자 저장 (다른 것을 저장하지 마십시오)

  • 플레이어에게 가장 중요한 것은 자신의 아이템, 획득 한 기술, 친구 목록 등을 포함한 캐릭터입니다. 그들이 몬스터를 죽이고 전리품이 그들 앞에지면 서버가 고장 나면 전리품을 집어 올릴 기회가 없어서 약간의 상처를 입을 것입니다. 중요한 물건 만 저장하고 작은 물건을 땀 흘리지 마십시오. 예를 들어 NPC의 위치를 ​​저장하지 마십시오. 서버가 다운되면, 다시 시작할 때 서버가 있어야하는 일반 영역에 스폰됩니다. 물론 예외는 어떤 이유로 든 "스마트 한"NPC에 대해서는 예외입니다. 서버가 다운되었을 때였습니다.
  • 또한 플레이어는 한 번에 너무 많은 시간 동안 로그인하지 않아야합니다 (여기서 "로비로 돌아가는 것"을 로그 아웃하는 것으로 간주합니다). 그들은 결국 화장실에서 휴식을 취하거나 음식을 얻거나 부모 / 친구 / 무엇이든지 잠을 방해해야합니다. 따라서 실제로 하드 코어 게이머에게도 8 시간 이상 실제로는 논스톱으로 로그온해서는 안됩니다. "플레이어"가 정말 오랫동안 로그온 한 경우, 여러 사람이나 봇일 가능성이 높으며, 어느 쪽도 바람직하지 않거나 정상이 아닙니다.
  • 또한 로그 아웃 프로세스는 이미 위에서 언급 한 연속 명령과 같은 사항을 확인해야합니다. 기본적으로 캐릭터를 압축해야하므로 디스크에 덤프하는 것이 가장 좋은 시점입니다.

결산 생각

  • 분명히 나는 ​​마지막 접근 방식에 찬성하지만 세 가지 모두에 대해 편견을 없애려고 노력했습니다.
  • 처음 두 가지 방법 중 어느 것이 더 낭비적인지를 말하기는 어렵습니다. 첫 번째 방법을 사용하면 캐릭터가 여러 이동 명령을 보내면 각각 하나의 디스크로 저장되고 덮어 쓰기됩니다. 그러나 두 번째 방법을 사용하면 인구의 절반이 서있는 경우 마지막 백업 작업 이후 정확히 동일하더라도 위치가 디스크에 저장됩니다. 세 번째 경우, 누군가가 로그온하고 즉시 로그 오프 할 수는 있지만, 플레이어에 대한 많은 것들이 변경되어 낭비가 최소화되는 것처럼 보입니다.
  • 이는 장애 발생시 전적으로 백업을위한 것이며 실패를 최소화해야합니다. 이 예외 상황을 처리하는 것이 좋지만 결국 서버에 장애가 발생하면 일부 데이터가 손실되고 일부 플레이어가 화를냅니다. 따라서 가능한 모든 방법, 가장 간단하거나 최선이라고 생각되는 것을 구현하고 계속하십시오.
  • 이것을 기본 저장으로 사용하지 마십시오. 서버 응용 프로그램에 멋진 종료 버튼을 넣으면 연결이 정상적으로 닫히고 모든 것이 데이터베이스에 기록됩니다. 정상적으로 사용하십시오.

마지막으로,이 조언을 절대적인 진실로 받아들이지 마십시오. 멀티 플레이어 백업 시스템을 작성하지 않았습니다. 내가 하고 내가 이런 생각보다 내 생각을 쓴 이유 인 온라인 "게임", 작업,하지만 난 아직이 구현의 무대에 못 했어. 따라서 이것은 실제 경험이 없지만 주제에 대한 많은 지식을 읽고 수집 한 후에 작성되었습니다.


4
내가 개인적으로 관찰 한 상업적 MMO에서이 세 가지를 모두 사용합니다. 보스 킬 / 약탈 / 거래와 같은 중요한 사건과 행동 후에 주기적으로 중요하지 않은 행동을 놓치지 않도록하고 장기간 로그인 한 사람들을 처벌하지 않도록 저장하고 항상 로그 아웃하십시오. 하나의 단일 방법으로는 충분하지 않습니다. 이러한 모든 방법은 하드웨어 오작동이있는 경우 투명하게 백업 및 복원되는 기본 SQL 스타일 데이터베이스를 사용합니다.
NtscCobalt

@NtscCobalt- "SQL 스타일 데이터베이스"까지 당신과 함께있었습니다. SQL이 정말로 요구 사항입니까? NoSQL은 어떻습니까?
beatgammit

@tjameson 글쎄, 내 의견은 NoSQL을 만지기 전에 작성되었습니다. 나는 당신이 당신 자신의 형식을 굴려서는 안된다고 말하려고했지만 어쨌든 스키마를 미리 알고 (또는 게으르고 Entity-Key-Value를 사용해야 함) 일관성이 더 중요하기 때문에 여전히 SQL을 권장합니다. 그 데이터를 분할하는 능력. 자세한 내용은 stackoverflow.com/questions/7339374/… 를 참조하십시오 .
NtscCobalt

1

나는 그것이 게임의 유형과 플레이어와 서버 사이의 트래픽 양에 달려 있다고 가정합니다.

MMORPG에서는 정보를 서버에 보낼 때마다 플레이어 위치를 저장하는 것이 이치에 맞지 않습니다. 말하자면 플레이어의 현재 데이터가 '이야기'일 때 업데이트하는 것이 더 합리적입니다. 또한 새로운 영토로 건너 가거나 보스를 물 리치거나 상점을 떠나는 등의 주요 이벤트에서 플레이어의 상태를 저장하는 것이 좋습니다.

턴 기반 게임에서는 턴이 끝날 때마다 그리고 상대방의 턴 후에 (건강 상실, 주문 효과 등) 플레이어의 상태를 저장하는 것이 좋습니다.

다시 한 번 대답은 전적으로 서버의 규모와 기능에 달려 있습니다. 품질을 유지하면서 최상의 균형을 찾아 최대한 최적화하는 것이 중요합니다.


1

그들이 로그 오프 할 때 유일한 관심사는, 로그 오프 나 연결 해제로 인해 더 이상 게임 세계에 존재하지 않는 조건이 발생할 때 위치를 저장하는 것입니다.

참고로, 나는 클라이언트가 서버에 위치를보고하거나 적어도 어떤 형태의 서버 측 위생 상태 검사를하지 않으면 다소 조심할 것입니다. 그래도이 위치가 이미있는 경우 클라이언트에서 직접 데이터를 가져 오는 것에 대해 걱정할 필요가 없으므로 로그 오프시 해당 위치를 저장하거나 연결을 끊을 수 있습니다.


따라서 position 및 XP와 같은 값으로 서버에 정기적으로 업데이트를 보내야합니다. 더 오래두면 플레이어가 실제로보고 된 델타를 랙에 올렸는지 여부에 대해 더 논쟁의 여지가 있습니다. 이러한 "체크인"기간을 제한하면 모니터링 / 제어가 훨씬 쉬워집니다.
엔지니어

오래 실행되는 브라우저 게임에서 정확히 플레이어가 로그 오프 한 시점을 알려주는 문제는 실제로 사소한 것이 아닙니다.
Lanbo

나는 그것이 사소한 것이 아니라는 데 동의하지만, 아바타가 더 이상 나타나지 않을 때를 결정하기 위해서라도 대부분의 게임에서 어쨌든 해결 해야하는 문제입니다. 일단 완료되면, 해당 시나리오에 연결하고 마지막 유효 위치를 저장하는 것은 비교적 간단한 문제입니다.
Lunin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.