이전에 배운 것
- 게임 : 규칙이 정확해야 한다 (규칙이 없다면 시뮬레이션)
- 게임엔진 : 게임을 많이 만들고, 로직이 복잡해지면서 프로그램을 가급적 재활용하고 데이터(맵)만 바꾸면서 게임을 쉽게 만들기 위해서 사용한다
- 미래의 게임이 어떻게 될 수 있을까?
Architecture?
- 게임에서는 룰, 로직의 계산이 필요하다
- 플레이어의 입력을 받아야한다
- 그 결과를 비디오로 출력해야 한다 (렌더링) ⇒ 이러한 과정을 진행하기 위한 구조!
- 필요한 것?
- Interactive Processing
- 이게 구현된 구조를 알아야 함
💡 RealTime Sofeware
- 게임은 RealTime이어야 한다 → RealTime이 뭘까?
- 반응이 즉각적으로 온다 ?
- 컴퓨터에서는 0초라는 것이 없음. 어느정도의 시간이 필요하다
- 하나의 게임에는 수천, 수만개의 연산이 필요하다
- RealTime의 정의가 뭘까?
- 데이터 획득(data acquisiton), 반응이 일정한 시간 안에 해결된다 → Time Critical한 성질이 있다
RealTime 구성요소
- data acquisition module : 입력을 사용자로부터 받거나, 다른 플레이어에게 받을 수도 있다. Ai나 맵의 데이터를 받아올 수도 있다.
- Display / Computation : 어떤 변화값을 계산하고 화면에 보여준다
- Interaction module : 공격하거나 도망가는 행동을 한다
게임에서 RealTime을 보여주기 위해서는
- 보통은 0.2초, 초당 10번 계산되면 사람이 인식하지 못한다
- 하지만 테니스게임, 드라이브 게임 같이 즉각적인 반응이 필요한 경우엔 time frame 값이 높을수록 좋다. 100~150 fps에서 좋은 성적을 보인다
- → 초당 100~150번의 연산을 해야 한다
게임을 만들 때 고려할 점
- realtime으로 동작해야 한다
- 다양한 컴퓨터 스펙에서 동작할 수 있도록 해야 한다
- 게임이 재밌어야 한다
- 전체적인 예측을 맞추고, 특정 순간에는 예상치 못한 행동을 하도록 해야 한다
- 시뮬레이션, 렌더링 부분이 존재하고 입력값이 부차적으로 존재한다
요구조건
- 실제 게임을 프로그래밍하기위해 뭐가 필요할까?
- 게임이 지속적으로 변화해야 함
- 변화한 내용이 사용자에게 보여져야 한다
Architecture 고려사항
- 계속해서 업데이트해야한다
- 병렬 컴퓨팅을 어떻게 쉽게 구현해야 할까?
- 랜더링, 업데이트, 사용자 입력에 대한 변화되는 이런 과정들이 병렬적으로 돌아가야 하기 때문에
- 엄청 좋은 컴퓨터에서는 쉽겠지만, 그렇지 않은 경우를 생각해야 한다
💡 1. Single Loop Coupled Approch
- input이 있는지 확인하고 없으면 그대로 출력한다. input이있으면 그 변화를 계산한다
- 장점
- 단순하다.
- 업데이트 한 번에 랜더링 한번을 하므로 밸런스가 유지된다
- 단점
- 병목현상이 발생할 수 있다 (갑자기 엄청 많은 몬스터가 등장하면 게임이 멈춰버린다!)
- 업데이트, 렌더링, 또는 입력에 시간을 너무 많이 써서 모든 처리가 끝난 뒤에야 한번에 렌더링이 된다.
- 게임 월드가 복잡해질수록 2배 이상으로 복잡해진다
- 빠른 컴퓨터는 루프가 빨리돌고, 느린 컴퓨터는 루프가 너무 느려지는 현상이 발생한다
- 초창기에서 많이 썼지만 병목 현상 문제!
SingleLoop 속도 문제
- 업데이트
- 빠르다고 너무 많이 계산하고, 느리다고 너무 적게 계산하지 않고 일정한 횟수만큼 업데이트해야 한다
- 초당 10번에서 25번 사이!
- 렌더링
- 빠르면 빠를수록 좋다.
- 최소 30프레임. 가능하면 100프레임 이상!
⇒ 업데이트는 일정한 횟수만큼, 렌더링은 가능하면 빠르게 진행하기 위해 어떤 구조를 써야할까?
속도문제를 어떻게 해결할까?
- Update
- worldclock 을 사용한다 : 이전 시간부터 현재 시간까지 변화한 값을 계산한다
- Render
→ Single Loop with World Clock
→ 이걸로 충분할까? AI같은 부분은 장기적으로 느리게 업데이트해줘도 된다.
💡 2. Multi-Thread Approach
- 업데이트와 렌더링이 멀티쓰레드로 병렬적으로 발생한다
- 문제점
- 왜 빠르게 해야할까?
업데이트의 2가지 타입
- AI Update : 전략이나 좀 천천히해도되는 업데이트
- Visual Update : 캐릭터가 움직일 때 . 애니메이션과 관련된 업데이트
→ AI 같은건 독립적으로 천천히 계산하고 보이는거만 빠르게 계산하기
→ 더 부드럽게 보여줄 수 있다
멀티스레드 접근은
- 멀티스레드, 멀티프로세싱이 가능한 PC에서만 사용할 수 있다
- 속도나 빈도가 불규칙적이다 : 중간 스레드들간의 소통을 알 수없다.
- 두 개의 loop이 서로 다른 속도를 가지게 되는 경우를 처리할 수 있다
Decoupled Single Thread
- 멀티스레드 접근을 어떻게 구현할까?
- 렌더링이 계속 돌다가 시간이 어느정도 이상 지나면 업데이트, 렌더링을 진행함
- 장점 : 업데이트가 천천히 되는 경우 등에 잘 대응할 수 있다
- 단점 : 렌더링이 멈춰버리는 현상 발생할 수 있다
지금까지 요약
- 2개의 모듈 (업데이트/렌더링) , 3개의 타입
- AI simulation : 천천히 되도 된다
- 애니메이션 시뮬레이션 : 렌더링에 의존
- 렌더링 : 가급적 빨리!
이제 자세하게 게임 구조를 알아보자
게임 구조를 구성하는 것
- player, update, rendering
💡Update에서 변경하는 것
- 게임 월드 : 대부분 정적인 것 (자연물, 건물) 위치가 이동되거나 상태가 바뀌는.
- NPC : 인공지능이 조작해서 게임 세계를 변화시킴
- 플레이어 : 사용자의 입력에 의해 변경되는 부분
1. 플레이어 업데이트
- 입력을 받아 플레이어 데이터를 업데이트한다
- 프로세스
- 사용자의 입력을 체크한다 (물리적 장치로 시작해서 추상적 장치로)
- 액션으로 mapping한후 가능한지 확인한다
- 가능하면 플레이어 데이터를 업데이트한다
2. 게임월드 업데이트
- 게임 월드의 구성요소
- passive : 정적인 오브젝트. 유저의 인풋에 따라 변화하기도 함그냥 건물, 아이템
- active : 시간이나 주변 환경에 의해 변화함. 강물이 흘러가는 현상
- 월드 데이터들을 관리하는 것이 게임월드 업데이트의 주요 업무
- Behavior Processing
- passive는 단순한데 active는 어렵다
- 단순한 상호작용도 있지만 복잡한 행동을 보일 수도 있다
- 프로세스
- 주변 데이터를 선택한다
- 주변 상황에 의해 변화하는 active 데이터들을 업데이트한다
- 월드를 업데이트한다
- 월드를 프로그래밍한다면
- 주변 데이터를 어떻게 가져올부지
- ai?
- behavior를 업데이트 하는 부분
💡 Presentation of Game
- 월드, 플레이어, NPC(인풋이 AI로부터 온다는것말고는 플레이어와 동일) 업데이트를 모두 하고나면, 게임을 보여줘야 함
- 목적 : 이 게임이 그럴듯하다, 개연성 있고 믿을만하도록 보여줘야 한다 → willing suspension of disbelief : 게임이 진짜라고 생각하지는 않지만 현실성을 의심하지 않는다
- 어떻게 ?
- 스토리라인이 의미가 있어야 함
- 믿을만하게 표현되어야 함
- 무엇을 보여줄까?
- 게임 월드를 실시간으로 렌더링해야 한다
- 현실과 비슷하게 보여준다
Rendering Process
- Update와 똑같이 World, NPC, Player
1. World Rendering
- 목적
- 문제
-
세계가 크고 복잡함
-
씬 처리가 필요함 (그대로 그리면 너무 오래걸림)
→ 클리핑, 컬링, 가시성, LOD 등의 계산
(에디터, 설정 모드가 따로 있어서 필요한 부분만 그리도록 해준다)
- 프로세스
- 씬을 선택한다 (어떤 맵, 공간을 그릴까?)
- 얼마나 자세히 그릴지 선택한다
- 최적화하여 표현한다
- 소리, 햅틱, 모션은 어떻게 표현할까?
- 물리와 연결되어 있다 → 물리엔진을 렌더링과 따로 두고 처리하려고 하고 있다
2. NPC Rendering, Player Rendering
- 월드 렌더링과 거의 같지만 애니메이션만 추가된다
요약
- 시뮬레이션 - 렌더링 구조
- 업데이트의 타입
- world, NPC, player
- 렌더링에서는 LOD , 컬링
- 시뮬레이션에서 충돌 처리를 위해 zone 개념을 사용한다
- 가까이 있는 것만 잘 보이고, 멀리있는건 대충 계산하는 방법도 사용한다
- 다음시간에는 게임 프로덕션 이슈에 대해 알아보자