[design-patterns] 개념적으로 게임에서 재생은 어떻게 작동합니까?

게임에서 재생이 어떻게 구현되는지 궁금합니다.

처음에는 게임에서 수행 된 모든 플레이어 / ai 액션의 명령 목록 만있을 것이라고 생각했고, 게임을 ‘재생’하고 엔진이 평소대로 렌더링되도록했습니다. 그러나, 나는 FPS / RTS 게임에서의 리플레이를 살펴 보았으며,주의 깊게 검사했을 때 파티클과 그래픽 / 가청 글리치와 같은 것들도 일관됩니다 (그 글리치들은 일반적 으로 일관됩니다).

어떻게 이런 일이 발생합니까? 고정 카메라 앵글 게임에서는 전체 장면의 모든 프레임을 스트림에 기록 한 다음 스트림을 다시 재생하지만 카메라를 일시 중지하고 이동할 수있는 게임에는 충분하지 않습니다. 주위에. 장면의 모든 위치를 모든 시점에 저장해야합니다 (아니요?). 따라서 파티클과 같은 것에는 많은 데이터가 필요합니다. 이는 게임하는 동안 게임 성능을 크게 끌어내는 것 같습니다.



답변

처음 생각이 맞았다 고 생각합니다. 재생을 만들려면 난수 생성기의 초기 시드와 함께 사용자로부터받은 모든 입력 (받은 프레임 번호와 함께)을 저장합니다. 게임을 재생하려면 저장된 시드를 사용하여 PRNG를 재설정하고 게임 엔진에 동일한 입력 시퀀스 (프레임 번호와 동기화)를 공급합니다. 많은 게임이 프레임 사이의 시간에 따라 게임 상태를 업데이트하므로 각 프레임의 길이를 저장해야 할 수도 있습니다.


답변

스타 크래프트와 스타 크래프트 : 브루드 워에는 리플레이 기능이있었습니다. 경기가 완료된 후 나중에 볼 수 있도록 리플레이를 저장하도록 선택할 수 있습니다. 재생하는 동안지도를 스크롤하고 단위와 건물을 클릭 할 수 있지만 동작을 변경할 수는 없습니다.

원래 게임에서 플레이 한 경기의 리플레이를 본 기억이 있지만 Brood War에서는 리플레이를보고있었습니다. 익숙하지 않은 사람들을 위해 Brood War에는 모든 원래 유닛과 건물뿐만 아니라 다양한 새 건물이 포함되어 있습니다. 원래 게임에서 플레이어는 컴퓨터가 쉽게 대응할 수없는 유닛을 만들어 컴퓨터를 물리 쳤습니다. Brood War에서 리플레이를했을 때 컴퓨터는 다른 유닛에 접근 할 수 있었으며,이 유닛은 플레이어를 물리 치고 생성하는 데 사용되었습니다. 따라서 동일한 재생 파일로 인해 Starcraft의 버전에 따라 다른 승자가 발생했습니다.

나는 항상 그 개념이 매혹적인 것을 발견했다. 재생 기능은 플레이어의 모든 입력을 기록하여 작동하는 것처럼 보였으며 컴퓨터는 매번 동일한 방식으로 자극에 반응한다고 가정했습니다. 플레이어 입력이 오리지널 스타 크래프트 리 플레이어에 공급되었을 때, 게임은 원래 경기에서와 똑같이 진행되었습니다. Brood War replayer에 동일한 정확한 입력이 공급되면 컴퓨터는 다르게 반응하고 더 강한 유닛을 만들어 게임에서 승리했습니다.

재생 엔진을 작성하는 경우 명심해야 할 사항입니다.


답변

두 가지 주요 방법이 있습니다.

  1. 말한대로 이벤트 저장 (플레이어 / AI 액션 등)
  2. 저장 상태 (전체 게임 상태, 객체의 fe 위치, 연속 순간).

당신이하고 싶은 일에 달려 있습니다. 일반적으로 훨씬 적은 메모리를 사용하므로 이벤트 저장이 더 좋습니다. 반면에 다른 속도와 다른 시작 지점에서 재생할 수있는 재생을 제공하려면 상태를 저장하는 것이 좋습니다. 상태를 저장하는 경우 모든 이벤트 후에 또는 초당 12 회 또는 25 회만 fe를 저장할지 여부를 결정할 수 있습니다. 이렇게하면 재생 크기가 줄어들고 되감기 / 빨리 감기가 더 쉬워 질 수 있습니다.

“상태”는 그래픽 상태를 의미하지 않습니다. 단위 위치, 자원 상태 등과 같은 것. 그래픽, 파티클 시스템 등과 같은 것은 일반적으로 결정 론적이며 “애니메이션 X, 시간 Y : Z”로 저장 될 수 있습니다.

때로는 리플레이가 부정 행위 방지 체계로 사용되기도합니다. 그렇다면 이벤트를 저장하는 것이 가장 좋습니다.


답변

기술적으로 엔진을 결정 론적으로 작성해야합니다. 게임에서 캐릭터가 상대방의 팔을 목표로하고 무기를 발사한다고 가정하면 모든 경우에 동일한 양의 피해가 상대방에게 적용되어야합니다.

폭탄이 X 위치에서 폭발한다고 가정하면, 그 폭발에 의해 생성 된 입자는 항상 동일한 시각적 결과를 가져야합니다. 임의성이 필요한 경우 임의의 숫자 세트를 작성하고 게임을 플레이 할 때 시드 값을 선택한 다음 해당 시드 값을 재생에 저장하십시오.

일반적으로 게임에서 임의성을 갖는 것은 나쁜 생각입니다. 멀티 플레이어와 같은 경우에도 플레이어는 폭발을 볼 수있는 절반을 가질 수 없지만 다른 플레이어는 단순한 임의의 값을 얻지 못했기 때문에 볼 수 없습니다.

모든 것을 결정 론적으로 만들면 괜찮을 것입니다.


답변

초기 상태 와 타임 스탬프가 있는 일련의 동작이 주어지면 기록 된 동작이 재생되도록 가정되므로 시퀀스를 진행하면됩니다.

임의의 이벤트가 정확히 동일하게 발생 하도록하려면 시드 된 의사 난수를 사용하고 시드 를 재생 파일에 저장 하십시오.

동일한 알고리즘을 사용하여 시드에서 난수를 생성하는 한 게임 상태의 전체 스냅 샷 없이도 라이브 게임에서 발생한 것처럼 모든 이벤트를 다시 만들 수 있습니다.

이를 위해서는 순차적으로 리플레이를 시청 해야 하지만 게임 리플레이에서는 일반적으로 정상입니다 (Starcraft 2 참조). 타임 라인에 임의 액세스를 허용하려는 경우 설정된 간격 (예 : 1 분)으로 전체 상태 스냅 샷 을 생성하여 설정된 세분성으로 타임 라인을 뛰어 넘을 수 있습니다.


답변

NVidia PhysX (게임에서 자주 사용되는 물리 시뮬레이션 엔진)는 시간이 지남에 따라 실제 장면의 전체 상태를 기록 할 수 있습니다. 여기에는 게임 엔진의 구동 입력이 통합되어있어 다른 사람들이 제안한대로 임의의 숫자 시드를 추적 할 필요가 없습니다. 이 장면 덤프를 가져 오면 외부 도구 (NVIdia 제공)에서 재생할 수 있으며 실제 모델의 문제를 추적하는 데 매우 유용합니다. 그러나 동일한 물리 스트림을 사용하여 그래픽 엔진을 구동 할 수도 있습니다. 그러면 그래픽을 구동하는 물리 만 기록되므로 일반적인 카메라 제어가 가능합니다. 많은 게임에서 여기에는 파티클 효과가 포함됩니다 (PhysX에는 매우 정교한 파티클 시스템이 포함되어 있습니다). 사운드에 관해서는 (사운드 스트림으로) 그대로 녹음 된 것 같습니다.


답변

당신의 독창적 인 아이디어는 옳고, 매우 복잡한 효과에 대해서는 독점적으로 기억되지 않습니다. 예를 들어, 워크래프트 3 재생 시스템은 임의의 효과 등의 경우 애니메이션 상태 또는 파티클 효과를 저장하지 않습니다. 또한 대부분의 시스템에서 MOST는 시작점에서 결정적인 방식으로 계산할 수 있습니다. 랜덤 변수 (예를 들어 랜덤 오프셋을 제공하는 파티클 폭발)를 사용하는 경우, 이펙트 시간과 랜덤 시드 만 있으면됩니다. 그런 다음 실제로 어떤 결과가 나올지 알지 않고도 효과를 다시 생성 할 수 있습니다. 결정적인 코드 경로를 거치는 것을 알기

순전히 개념적으로 생각하여 이벤트 타임 라인을 재생하려면 사용자 작업 만 있으면됩니다. 랜덤 변수의 경우를 제외하고 프로그램은 정확히 같은 방식으로 반응합니다. 이 시나리오에서는 무작위성을 무시하거나 (효과가 정확히 동일하게 보이는지 또는 무작위로 재생성 할 수 있는지에 상관없이) 시드 값을 저장하고 무작위성을 위조 할 수 있습니다.