기본 콘텐츠로 건너뛰기

'Doom'의 적, 전투 시스템에 대한 분석

    목차





▲이 글의 대부분은 Game Maker's Toolkit의 What We Can Learn From Doom 영상에서 인용하였습니다.

1993년 출시된 '이드 소프트웨어'의 '둠'은 FPS게임의 역사의 큰 획을 그었습니다.
둠이 재밌는 게임으로 느껴지는 이유에는 여러가지가 있을 것입니다. 비선형적인 레벨 디자인, 다양하고 개성있는 무기들이나 그 당시에 획기적인 그래픽이 될 수도 있겠죠.

하지만 이 글에선 둠의 아이덴티티인 전투, 적에 대해 알아보겠습니다. 둠을 플레이하다 보면 플레이어들은 마치 춤을 추는 듯한 움직임을 보여줍니다. 이런 움직임은 현대의 현실감있는 FPS게임과는 확연히 다른 움직임입니다.
플레이어들은 실시간으로 적의 공격을 피하고, 빠르게 움직이면서 어떤 적을 사격할지, 어떻게, 어디로 움직일지 고민하고 선택합니다.


플레이어들이 그런 화려한 움직임을 만들게 하는 요인 중 하나는 둠의 몬스터들입니다.
신참 시절 둠의 레벨 디자인을 개발했던 2K게임즈의 'Matthias Worch'는 둠의 완성도가 높았는 이유는 모든 적들의 차이가 분명하고, 일관성이 있고 알아보기 쉬운 행동 습관들 가졌기 때문이라고 설명했습니다.

둠의 몬스터들은 개성이 있습니다.
좀비맨과 샷건 가이는 체력이 적지만 히트스캔 방식의 공격을 합니다.
임프는 천천히 날아오고 피할 수 있는 파이어볼을 발사합니다.
데몬은 플레이어를 쫓아와서 근접 공격을 합니다.
로스트 소울은 플레이어에게 직선으로 날아옵니다.
카코데몬과 바론 오브 헬은 각각 체력이 400, 1000 정도로 중간 보스급의 역할을 맡고 있습니다.

이런 디자인을 데우스 엑스의 'Harvey Smith'디자이너는 '직각의 유닛 차별화'라고 언급했습니다.
이것은 게임의 유닛을 디자인 할 때 완전히 독특한 속성(좀비맨의 히트스캔 공격, 임프의 파이어볼 등)을 가져야 하고, 조금 더 강하거나 약한 버전이 있으면 안된다는 의미 입니다.

이런 디자인은 플레이어로 하여금 훨씬 전략적이고 생동감있는 플레이를 하게 해줍니다.

예를 들어, 둠의 임프나 카코데몬의 공격은 강력하지만 플레이어가 피할 수 있습니다. 하지만 좀비맨이나 샷건 가이의 공격은 히트스캔 방식이기 때문에 이들을 먼저 처리하는 것이 수월하다는 것을 알 수 있습니다.
또한, 로스트 소울이나 임프는 플레이어를 좌우로 움직이게 하고, 데몬은 플레이어를 앞뒤로 움직이게 만듭니다. 이런 시스템이 플레이어를 '춤 추는 듯이 움직이게 하는' 방법입니다.


또한 둠은 다양하고 개성있는 무기들이 있습니다. 이 다양한 무기들은 플레이어에게 다양한 전략적 선택의 길을 만들어줍니다.
샷건은 좁은 구역이나 상대적으로 약한 적들에게 유용하며, 체인건은 빠른 연사력으로 많은 적들을 상대할때 유용합니다.
그 외에도 매우 강력하지만 적이 피할 수 있는 로켓 런처나 근접 무기인 전기톱, 매우 강력한 무기인 BFG9000등 플레이어들은 상황에 맞는 무기를 사용하는 것에 새로운 재미를 느낄 수 있습니다.

그리고 둠의 몬스터들은 각각의 '경직확률'이란게 있습니다. 몬스터들은 플레이어가 공격 했을 때 이 확률에 따라 공격을 하지 못합니다.
좀비맨 약 78%, 임프 약 70%
카코데몬 50%, 바론 오브 헬 19% 등등 각각의 몬스터들은 자신만의 경직에 걸리는 확률이 있습니다.
플레이어들은 이런 시스템을 무기 선택에 활용하기도 합니다. 체력이 많고  50%라는 상대적으로 높은 경직 확률을 가지고 있는 카코데몬에게는 체인건이 유리하고, 낮은 경직치를 가진 적에게는 보다 연사력이 낮은 대신 공격력이 높은 무기를 선호합니다.



둠의 적들을 공격력과 속도를 기준으로 그래프화 시켜 본다면 이런 그림이 나올 것입니다. 그래프는 적들을 매우 넓은 영역에 표시하고 있습니다. 이것을 'Will Wright'는 'possibility space(가능성의 영역)'이라고 표현했습니다.
이 가능성의 영역이란 플레이어가 할 수 있는 일들, '플레이어가 닥치게 될 일들의 다양성'이라고 표현될 수도 있습니다.
많은 비판을 받고 있는 FPS게임에선 이런 가능성의 영역이 매우 좁다는 것을 느끼게 될겁니다. '톰 클랜시의 더 디비전'이란 게임에서도 적의 종류는 정해져있고 늘어나는 HP가 이 게임을 훨씬 지루하게 만든다는 비판을 받기도 했습니다.


또한 많은 게임에서 적의 종류를 매우 다양하게 만드는 경우가 있는데, 둠의 적은 모두 7가지입니다.
위에서 말한 좀비맨, 샷건 가이, 임프, 데몬, 로스트 소울, 카코 데몬, 바론 오브 헬이 그들이죠.
흥미로운 점은 프리스턴 대학의 George A. Miller는 1956년 "The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information"라는 논문에서 인간의 단기기억은 7±2가지의 요소를 기억할 수 있다고 말했습니다.

이렇게 적은 종류의 적은 플레이어에게 각각의 적들의 분명한 특징이나 파훼법을 알 수 있게 도와주었고, 플레이어에게 그냥 막 쏘는 게임이 아닌, 정확하게 판단하고 전략적인 선택을 요구하는 게임이 되게 해주었습니다.

둠의 적들의 디자인 또한 그것을 도와주었습니다. 그들은 모두 개성있게 디자인 되었으며, 한눈에 봐도 다른 모습을 가지고 있습니다. 플레이어들은 어떤 방에 들어가도 어떤 적과 싸울지 한눈에 파악할 수 있었고 그에 따른 선택의 방향도 달라졌습니다.
원형의 모습을 한 카코 데몬은 말할 것도 없고, 뿔이 튀어나온 갈색의 악마인 임프와 불타고 날아다니는 해골 또한 등장합니다.













다시 처음으로 돌아가서, 둠의 적들은 개성이 강하고 이해하기 쉽습니다. 그들은 파이어볼을 날리거나, 샷건을 쏘고, 플레이어에게 돌진합니다.
많은 게임에서 게임의 난이도나 개성을 넣기 위해 새로운 적을 추가했다면, 둠에선 이런 이해하기 쉽고 개성있는 몬스터들을 조금 다르게 배치하고, 다른 맵에 위치시키기만 하면 됩니다.
예를 들어, 상대적으로 넓고 임프와 좀비맨이 많이 배치된 맵에서는 맵을 빙빙 돌면서 먼저 좀비맨들 처리하고, 임프를 처치하는 전략이 필요하게 될 것이고, 미로같은 맵에 데몬이 배치되었다면 샷건을 사용하는 것이 그 전략이 될 것입니다.


이처럼 둠은 매우 적은 숫자의 개성이 강한 적들을 매우 흥미롭게 배치하여 플레이어에게 전략적 선택을 유도하면서 새로운 느낌과 움직임을 주고, 난이도를 조절하였습니다.
이것으로 둠이 후세대 게임들에게 게임의 적과 전투를 어떻게 디자인할 것인지 알려주었고, 하프라이프2나 헤일로 처럼 훌륭한 게임을 만들어 주었습니다.


댓글

이 글도 관심 있으실 것 같아요!

놀이의 4대 요소 (Agon(아곤), Mimicry(미미크리), Ilinx(일링크스), Alea(알레아))

네덜란드의 고전 학자인 '요한 하위징아'의 저서인 「호모 루덴스 」에서 인간을 '유희의 인간'이라고 칭했습니다. 프랑스의 '로제 카유아'라는 학자는 「호모 루덴스 」의 이론을 발전시켜 그의 저서인 「놀이와 인간」 (원제 「 Man, plays and games 」) 에서 ‘놀이의 4대 요소’를 말했습니다. 저자는 그것을 아곤, 미미크리, 알레아, 일링크스로 소개했습니다. 이 네 가지 놀이의 요소는 인간의 모든 유희, 놀이에서 발전되어 현대의 비디오 게임에서도 매우 중요한 이론으로 알려져있습니다. 먼저, 아곤(Agon), 경쟁 아곤은 놀이의 주체와 객체간의 경쟁을 의미합니다. 사람들은 경쟁에서 승리함으로써 성취감을 얻고, 우월감을 느끼게 합니다. 이 아곤을 현대의 게임에 대입 시켜보면 경쟁은 최근 가장 많이 플레이 하는 게임 중 하나인 ‘배틀 그라운드’나 ‘리그 오브 레전드’같은 게임들도 경쟁에 기반이 되어있고, 혼자 플레이 하는 게임에서도 자기 자신과의 경쟁, AI와의 경쟁 등이 포함되어있습니다. 예를 들어, 슈퍼 마리오 같은 게임에서도 플레이어들은 어떻게 이 게임을 더 빨리 클리어하기 위해 경쟁하고, 더 많은 점수를 받기 위해 노력합니다. 또한 비교적 MMR시스템이 잘 짜여져있는 '리그 오브 레전드'같은 AOS게임에서도 플레이어의 등급을 결정하는 랭크 게임 시스템이 중점적으로 돌아가고 있고, '오버워치'의 경쟁전 등 많은 게임에서 이런 경쟁을 유도하는 시스템을 만들어 놓았습니다. 게임을 계속 플레이하게 만드는 가장 큰 요소가 아곤입니다. 많은 게임에서 플레이어의 경쟁을 어떻게 잘 이끌어 나갔느냐에 따라서 그 게임의 성공이 나뉠 수도 있습니다. 미미크리(Mimicry), 역할 미미크리는 역할을 의미합니다. 사람들은 실제 세계에서 하지 못하는 일들을 놀이에서 느끼면서 큰 기쁨을 느낄 수 있습니다. 이 역할은 롤플레...

FastAPI 실시간 영상 스트리밍 OpenCV

  FastAPI와 OpenCV를 활용한 실시간 영상 스트리밍 Permalink 실시간 영상을 스트리밍 하는 방법을 찾던 중 파이썬 FastAPI를 활용한 방법을 시도 해보았다. 필수 라이브러리 Permalink 필요한 것은 Python3.9버전 (애플 M1칩셋 맥북에어에서 3.8 버전으로 시도 해보니 OpenCV라이브러리 설치에서 문제가 발생했었다) FastAPI uvicorn OpenCV 정도면 될 것 같다. 라이브러리들은 모두 설치 되었다고 가정 하고, 예제 코드 Permalink # main.py # 라이브러리 import # StreamingResponse를 가져와야함 from fastapi import FastAPI from fastapi.responses import StreamingResponse # cv2 모듈 import from cv2 import get_stream_video # FastAPI객체 생성 app = FastAPI () # openCV에서 이미지 불러오는 함수 def video_streaming (): return get_stream_video () # 스트리밍 경로를 /video 경로로 설정. @ app . get ( "/video" ) def main (): # StringResponse함수를 return하고, # 인자로 OpenCV에서 가져온 "바이트"이미지와 type을 명시 return StreamingResponse ( video_streaming (), media_type = "multipart/x-mixed-replace; boundary=frame" ) # cv2.py import cv2 def get_stream_video (): # camera 정의 cam = cv2 . VideoCapture ( 0 ) while True : ...

Python FastAPI 알아보고 설치하고 초기 설정 해보기

  Python FastAPI, 설치하고 초기 설정 해보기 Permalink 파이썬 웹 서버를 만들어야 하는 일이 생겼늗데, 최대한 빠르고 안정적인 서버를 선택 해야했다. 그래서 기존에 사용하던 Flask보다 훨씬 빠르다고 하는 FastAP를 사용해보기로 했다. ❓ FastAPI란? Permalink 👉 FastAPI 공식 한국어 페이지  https://fastapi.tiangolo.com/ko/ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트에 기초한 Python3.6+의 API를 빌드하기 위한 웹 프레임워크입니다. FastAPI는 파이썬에서 사용 가능한 웹 프레임워크 중 하나인데, Flask나 Django보가 훨씬 빠른 속도를 보여준다고 하고, 확인 해봐야 하겠지만 Go언어와도 비슷한 속도를 보여준다고 한다. 또, 쉽고 간결한 코드, 200% ~ 300% 까지 증가하는 개발 속도를 기대할 수 있다고 하는데, 시작 해보자! 👏 Permalink FastAPI 설치 Permalink 먼저 공식 사이트에선 pip를 이용해 설치 하라고 나와있는데, 나는 anaconda를 이용해서 설치를 했다. bash $ pip install fastapi anaconda 사용 시 $ conda install fastapi 그리고 ASGI서버도 필요해서 같이 설치하라고 하는데, Univorn을 설치 해보자. bash $ pip install uvicorn[standard] anaconda 사용 시 $ conda install uvicorn FastAPI 예제 Permalink 설치가 완료되면 이렇게 vscode에서 FastAPI() 클래스가 자동 완성 되는걸 확인할 수 있다. 그리고 정말 간단히 API를 만들 수 있는데, main.py 파일을 만든 후에 from typing import Optional from fastapi import FastAPI app = FastAPI () @ app . get ( "/"...