17

Click here to load reader

[0820 석재호]게임 입력의 기록 및 재생

Embed Size (px)

Citation preview

Page 1: [0820 석재호]게임 입력의 기록 및 재생

게임 입력의 기록 및 재생

데브루키 꿜라 석재호

GPG 2 권 1.16

Page 2: [0820 석재호]게임 입력의 기록 및 재생

입력기록

게임에서 일어났던 모든 일들을 그대로 재연한다

- 버그 재현- 게임플레이의 재생- 최적화 측정- 게임 동영상 작성

Page 3: [0820 석재호]게임 입력의 기록 및 재생

버그의 재현 잡아내기 힘든 OS, HW, 사용자 입력 관련 버그 잡

비디오로 찍는 방법 .. 기껏해야 60프레임 ?

밀리초 수준의 버그를 잡을 수 없다

프로그램 자신이 모든 입력을 기록한다면 간단하다

Page 4: [0820 석재호]게임 입력의 기록 및 재생

버그의 재현 버그의 추적 시 주의사항

– ‘ ’ 게임이 죽는 순간 의 입력을 확실히 기록한다

– WIN32 의 경우 구조화된 예외 처리부를 이용해 이에 대한 간단한 해결이 가능하다

Page 5: [0820 석재호]게임 입력의 기록 및 재생

구조화된 예외 처리부Structured Exception Handler(SEH)

C++ 이 언어 차원에서 예외처리 (try, catch) 문법을

제공하는 것에 반해 C 언어는 지원이 안됨Visual C++ 컴파일러 차원에서 지원되는 예외처리

문법을 사용 -> 이것이 SEH VC++ 이므로 윈도우 환경 하에서만 사용 가능

Page 6: [0820 석재호]게임 입력의 기록 및 재생

게임 플레이의 재생 다른 말로 리플레이 저장

게임을 하기 전에 리플레이를 저장하겠다고 마음먹고 시작하는 일은 거의 없다

– 게임플레이는 항상 기록되어야 한다– 기록된 정보의 저장 여부는 유저의 몫이 되는 것이 좋다

Page 7: [0820 석재호]게임 입력의 기록 및 재생

최적화 측정 최적화 전후의 성능차이를 구체적으로 측정 프레임율에 영향을 미치는 변수는 무수히 많다– 한 프레임만의 시간은 의미가 없으며

눈으로 보고 느끼는 방식은 신뢰도가 낮다

동일한 기록을 여러 번 재생하면서 게임의 성능을

상세히 기록하면 매 재생 사이의 미묘한 차이를 쉽게 알 수 있다

– 평균 프레임율 , 최악 프레임율 , 프레임율 변화 추세등

Page 8: [0820 석재호]게임 입력의 기록 및 재생

게임 동영상 작성 역시 입력 기록 방식 이용 60 프레임의 동영상 작성 시 엔진의 갱신도

60 프레임에 맞추고 각 프레임 저장 입력 재생 시스템도 동기화

멀티플레이 게임 , 특히 RTS 에서 네트워킹 모델로

입력 기록 및 재생 많이 사용

Page 9: [0820 석재호]게임 입력의 기록 및 재생

기록 및 재생에 필요한 것 게임을 예측 가능하게 만들 것– 작업 전환의 타이밍 등에 영향 받는 것은

예측 가능하지 않은 것– 프레임 당 게임 갱신 횟수는 가변적– 렌더링 함수가 게임의 상태를 변화시킨다면

갱신 루프와 렌더링 루프가 가변적으로 얽히게 된다– 렌더링함수와 갱신루프가 동일한 난수발생기 이용– Fog 를 렌더링 시에만 갱신– 초기화 되지 않은 지역변수 , 함수의 결과 반환– 사운드 HW 의 비동기적 재생 처리

Page 10: [0820 석재호]게임 입력의 기록 및 재생

기록 및 재생에 필요한 것 초기상태 유지– 게임의 시작 , 저장된 게임 불러오기에서 일관성 있는

상태로 시작되도록 해야 함• 게임의 행동방식이 변하지 않도록 예측가능성 보장

– 일관성을 깨는 예 : 부동소수점 문제• 모든 정보를 일관적으로 저장해도 재계산 시 다른 결과 가능• 최적화 옵션을 켠 릴리즈와 디버그의 계산 방식이 상이• 컴파일러 옵션으로 문제 최소화 가능하지만 , 해결은 불가능

Page 11: [0820 석재호]게임 입력의 기록 및 재생

난 수 예측가능한 게임에서도 난수를 사용할 수 있다– rand() 가 진정한 난수 발생기가 아니기에 가능

• 선형합동법 등의 단순한 알고리즘을 통해 난수 생성– 대부분의 난수 발생 알고리즘은 완전히 재생 가능

• 시드값을 바꿀 때마다 저장하면 재현이 가능하다

rand() 의 문제점– 렌더링 코드와 갱신 코드 모두 rand() 를 사용할 때

갱신 당 프레임 수가 가변적이라면 예측 불가능해짐– rand() 의 작동 방식이 플랫폼마다 다를 수 있다– 저장 후 로드 시 저장할 당시의 시드값으로 난수열을

다시 초기화 시키는 것이 불가능

Page 12: [0820 석재호]게임 입력의 기록 및 재생

– 난 수 결 론

이식성과 재초기화 가능한 난수 클래스를 만들어 쓴다

rand() rand() 를 사용하지 않는다

렌더링과 갱신 루프가 서로 다른 난수 객체를 사용한다

Page 13: [0820 석재호]게임 입력의 기록 및 재생

입력들 입력의 기록과 재생 문제– 입력장치 , 디스크 , 네트워크로부터의 입력 , 경과 시간

모든 입력이 하나의 입력 시스템을 거쳐가도록– 필요한 곳마다 직접 OS 함수 호출하는 것을 배제– 각 프레임 시작지점에서 모든 입력장치 정보 기록

#define 이용해 OS 함수 호출 코드 작성을 방지ex) #define GetKeyState “ ”이 함수 쓰지 마세요

Page 14: [0820 석재호]게임 입력의 기록 및 재생

입력들 네트웍

… 게임의 재연을 가능하게 하려면 (중략 ) 그러면 네트 웍에

…연결되어 있지 않아도 게임을 재연할 수 있다 네트웍이 56K 모뎀으로 연결되어 있다고 해도

게임을 하다 보면 시간당 수 메가바이트 (!!!) 의 데이터를

받게 된다 이 정도의 커다란 데이터 스트림이라면 기록하는 것이

…부담스러울 수도 있지만 기록함으로써 얻는 이득은 비용에 비해 훨씬 크다고 할

수 있다

( 이상 본문 발췌 )

Page 15: [0820 석재호]게임 입력의 기록 및 재생

입력들 시간도 입력으로 간주– 게임 내 시간을 기록함으로써 특정 이벤트를

특정 시간에 발생시키는 등의 동작 가능– 게임 내 시간은 게임 엔진에게 물어야 한다

timeGetTime() 같은 OS 함수들은 막아놓는다

게임 진행 전반에 대한 입력을 모두 기록– 게임 메뉴 , 옵션 화면 등 모든 지점에서 버그추적 가능

– 기록된 입력의 저장 단위는 지점마다 적절한 형태로

Page 16: [0820 석재호]게임 입력의 기록 및 재생

결 론 모든 입력들은 단일한 입력시스템으로 집중해 일관성을 보장한다

모든 입력을 항상 기록하며 다운이나 사용자요청 등에 대비해 영구적인 장소에 저장한다

부동소수점 최적화나 코드 내 버그는 릴리즈빌드에서 게임의 동작을 바꾸거나 예측 불가능하게 만들 수 있다

rand() 를 피하고 커스텀 난수 객체를 만들어 쓰자

렌더링 함수 내에서 게임 상태를 변경하지 말자

입력과 함께 게임 상태 일부를 저장하면 디버깅이 보다편해진다

Page 17: [0820 석재호]게임 입력의 기록 및 재생

감 사 합 니 다