Nebula3 Application Layer

이 포스트는 floh님의 블로그에 포스팅된 Nebula3 관련 내용을 번역한 글입니다. Nebula3는 Nebula2의 기본적인 아키텍쳐를 계승하지만 구현에서는 이전과 비교해 보면 여러 면에서 많이 다릅니다. 특히 세 개의 레이어로 구성되어 있는 점이 가장 큰 특징 중의 하나인데 이것은 이전의 망갈로(Mangalore)가 게임 엔진에 포함되었기 때문입니다. 그래서 이 세 개의 레이어에 대한 이해를 위해서 관련된 포스트들만 먼저 번역해서 올립니다.

Nebula3 Application Layer

http://flohofwoe.blogspot.com/2007/11/nebula3s-application-layer-provides.html

애플리케이션 레이어는 애플리케이션 프로그래머에게 표준화된 하이레벨의 게임 프레임워크를 제공한다. 이것은 Nebula2 엔진의 애플리케이션 프레임워크인 망갈로의다음 버전이 Nebula3에 통합된 것으로 수년간의 리팩토링의 결과이다.(one couldsay that this started with our very first big project "Urban Assault"10 years ago) 망갈로의 디자인은 안정적인 상태로 당분간 큰 변화는 없을 듯 하다. 망갈로를 잘 알고 있는 프로그래머면 N3의 애플리케이션 레이어도 쉽게 이해할 수 있을 것이다.

망갈로가 공식적으로 시작된 2003년은 (우리가) 독립적인 개발사는 몇 개의 타이틀을 동시에 여러 퍼블리셔와 작업함으로써 리스크를 분산시키는 것이 매우 중요하다는 것을 배운 해이다.(독일 퍼블리셔들은 불행히도 자주 파산하는 경향이 있기 때문이다.) 그래서망갈로의 중요한 디자인 목표 중 하나는 (사내에서) 다수의 팀이 각기 다른 장르의 게임 개발을 하는 공통적인 게임 애플리케이션 프레임워크를 제공하는 것이다. 그리고 가장 중요한 것은 게임 프레임워크로 작지만 완벽한 게임을 매우 짧은 기간에 마칠 수 있어야 한다는 것이다.(우리의 일반적인 "가장 작은 프로젝트"는 5명의 풀타임 개발자(두 명의 프로그래머와 두 명의그래픽 아티스트 그리고 한명의 레벨 디자이너)로 구성된 3개월짜리 프로젝트이다. 여기에 두 세개의 프로젝트당 프로젝트 매니저 한 명 추가). 간단히 말하면 몇 개의 "작은 프로젝트"를 동시에 개발하는 일은 하나의 큰 프로젝트를 하는것보다 몇배는 어렵다. 왜냐하면 전체 프로젝트 크기를 간단히 줄일 수 없는 게임 프로젝트의 많은 부분이 있기 때문이다. 컨텐츠측면에 있어 우리의 다중 프로젝트 전략을 위해서는 선행 조건이 필요했는데 자체 툴킷으로 엄격히 표준화된 에셋 파이프라인이 바로 그것이다. 왜냐하면 툴킷 때문에 실제 작업에시 오버헤드 없이 프로젝트들 간에  모델러와 애니메이터를 교환할 수 있기 때문이다.(역자 주: 모델링 후 애니메이션이 이루어지기 때문에 모델러와 애니메이터의 작업은 종속 관계를 가진다. 여러 개의 프로젝트 진행시 한 프로젝트의 모델링을 마친 모렐러들은 다른 프로젝트로 투입되는데 이런 작업이 잘 이루어지기 위해서는 툴킷을 이용한 표준화된 (그것도 엄격히!) 아트 에셋 파이프라인이 있기 때문이라는 이야기) (예를 들어 작은 프로젝트라도 몇 주에 모든 그래픽 에셋들을 빌드하거나 캐랙터 애니메이션 등을 직접 프로젝트들 간에 공유한다던가 혹은 인스턴스 캐릭터 애니메이터와 같은 키맨들이 다수의 프로젝트에 참여해서 며칠씩 돕는 것은 일반적으로 힘들다.)

망갈로(이제는 N3 애플리케이션 레이어)는 기본적으로 프로그래밍 도메인에서와 같은 문제점을 해결하기 위한 시도를 한다. 이것은 응용 프로그램 프로그래머가 최소한의 셋업 오버헤드만 가자고 새로운 프로젝트를 시작할 수 있도록 하거나 이 프로젝트의 게임플레이 구현을 주어진 시간과 예산에 맞추어 구현할 수 있도록 돕는 일과 같은 일이다. 다음 항목들은 망갈로의 중요한 특징들이다.
  • 프로젝트 첫 날부터 스크린상에 무엇인가 보일 수 있도록 완전하면서 포괄적인 기능을 제공한다.
  • 우리의 표준화된 레벨 디자인 및 모델링 작업 플로어와 통합 시킨다. 그리고 여기에다 공통적인 마인드셋, 숙어 - "사회적 인터페이스"를 프로그래머와 모델러/애니메이터 그리고 레벨 디자이너에게 제공한다.
  • 응용 프로그램에서 게임에 특화된 코드를 어덯게 작성해야 하는지에 대한 컨셉을 명확하게 정의한다.(이 때문에 망갈로 프로그래머는  새로운 게임 특징 구현을 하다 "어디에" 그리고 "어떻게" 라는 질문에 마주쳤을 때 상대적으로 결정을 쉽게 할 수 있다.)
  • 게임 로직 작업을 하는 팀의 프로그래머들이 서로의 작업을 방해하지 않도록 충분히 모듈화 되어 있다.
  • "NewGame","Continue Game", "Load Game" 그리고 "Save Game" 은 표준화된 특징이다. (중요한 점:Load/Save 기능은 시작부터 바로 작동하며 대부분은 프로그래머가 load/save 관련 코드를 한라인도 작성할 필요가없다.)
  • 차후 프로젝트에서는 (이전보다) 성장하여 재사용이 가능한 모듈 집합을 제공한다. (Mangalore와 비교할 때 N3Application Layer 에서는  "GameFeatures"라고 불리는 것으로 이 부분을 더욱 정형화 시켰다.)
애플리케이션 레이어는 다음의 기본적인 컨셉들이 구현되어 있다.
  • Entity: 게임 객체, Propertie와 Attribute들을 포함한다, Message를 사용하여 조작된다.
  • Property: 게임 로직의 개별 엔티티 관점에서의 처리.
  • Manager: 게임 로직의 전역적인 관점에서의 처리.
  • Attribute: key/value 쌍, 엔티티의 영속성을 구현.
  • Message: 엔티티간의 통신에 사용.
  • GameFeature: Properties, Managers, Messages 와 Attributes를 기능별로 그룹화 한 것.
Entity는적 우주선이나 플레이어 아바타 혹은 보물 상자와 같은 하나의 게임 객체를 의미한다. An important aspectof the Application Layer에서 중요한 것은 기능 추가를 위해서 Game::Entity 클래스를 서브 클래싱하는것이 아니라 Attributes와 Properties가 엔티티의 실제 게임 로직을 정의하도록 하는 것이다. 일찍이 복잡한 게임프로젝트에서 클래스 상속 계층을 통해서 게임 객체들을 모델링하게 되면  스파게티 상속, 상위 클래스의 비대화와 중복된 코드와같은 모든 타입의 문제점들이 야기되는 것이 뻔하다는 것을 배웠다. (let's say you do a traditional realtime strategy gamewith vehicle units, so you create a Vehicle class, and derive a GroundVehicle and an AirVehicle class, which can implement navigationon the ground and in the air respectively, but now you want to addcombat functionality, hmm... create a CombatGroundVehicle class, and a CombatAirVehicle class? Or would it be better to create a CombatVehicleclass and derive GroundCombatVehicle and AirCombatVehicle? But wait,some of the vehicles should gather resources instead of fighting... you get the general idea, I think every game programmer faces this problemvery early in his career).

이것이 Properties가 등장한 배경이다. 프로퍼티는 엔티티 객체에 연결되어 엔티티에 특정한 기능을 추가하는 작은 C++ 객체이다. 예를 들어 특정한 엔티티 타입이 렌더링 되어야 한다면 GraphicsProperty 가 연결되고, 게임 세계에서 튀고 굴러야 한다면 PhysicsProperty가 필요할 것이다. 만약 엔티티가 카메라를 조작해야 한다면 CameraProperty가 추가되는 식이다. 혹은 앞에서의 전략 게임이라면 다른 유닛 타입의 기능을 만들기 위해서 (엔티티와) 결합하는 GroundMovementProperty, AirMovementProperty, CombatProperty 그리고 GatheringProperty가필요할 것이다. 이상적으로는 Ideally, Properties는 상호간에 자율적이며 독립적이므로 제약없이 결합하는 것이가능하다. (실제 프로젝트에서는 어떤 Properties는 항상 다른 Properties에 의존하는 경우도 있다. 그러나 경험에비추어 볼 때 이러한 제약은 용인할만한 수준이다.) Properties는 위에서 언급한 상속의 문제를 잘 해결한다. 새로운엔티티는 Game::Entity 클래스를 상속해서 구현하는 것이 아니라 다수의 전문화된 프로퍼티들을 결합하여 정의한다.

해결해야 할 다음 문제는 인터페이스와 커뮤니케이션 문제이다. Properties는 같은 엔티티에 연결된 프로퍼티들 간의 통신이나다른 엔티티에 연결된 프로퍼티간의 통신을 위한 커뮤니케이션을 필요로 한다. 다른 프로퍼티의 C++ 함수를 호출하는 것은 프로퍼티클래스 간의 피해야 하는 수 많은 의존 관계를 야기 시킨다. 왜냐하면 이것은 곧바로 프로퍼티를 이용해서 해결한 엔티티 클래스의 상속 문제가 야기하는 것과 같은 제약의 결과로 이어지기 때문이다. 가상함수는 몇 개의 상위 클래스에 의존성을 국한시키기 때문에 이 문제 해결에 도움이 될 것 같기도 하다. 그러나 이것은 상속의 문제를 엔티티에서 프로퍼티로 옮길 뿐이다. Messages는 이러한 딜레마를 해결하기 위해서 사용된다. 메시지를 가상 함수호출의 다음 추상화 레벨로 생각해 보자. 가상함수 호출은 호출하는 쪽에서 타겟 객체와 베이스 C++ 인터페이스를 알아야 하지만 메시지는 단지 호출하는 쪽에서 엔티티 형태의 타겟 객체만 알면 된다. 특정 인터페이스는 몰라도 된다. 엔티티는 관심있는 Properties에게 Message를 경유시키고 Proeperties에서 궁극적으로 이 메시지를 처리하게 된다.  호출하는 쪽에서는 일반적으로 어느 Property가 Message를 처리하는지에 대해서 알지 못한다. 또 메시지가 처리 되었는지에 대해서도 알 수가 없다.

C#프로그래머라면 이제 손을 들고 이것들이 바로 Interface와 Delegate 그리고 Event의 용도라고 말할지도 모르겠다. 전적으로 맞는 말이다. 그런데 안타깝게도 우리는 C++로 일하고 있다. Application Layer는 추후에 더 최적화할만한 여지가 있다. 예를 들어 메시지 발송은 위임자 같은 메카니즘으로 최적화할 수도 있을 것이다.

Attributes는 엔티티에 부속된 키(key)와 값(value)의 쌍이다. 각 엔티티는 엔티티의 완전한 영속성을 정의하는 잘 정의된 속성집합을 가진다. 속성은 엔티티의 초기 상태를 설명하고 애플리케이션 레이어의 표준 로딩/저장 메카니즘을 사용해서 엔티티의 상태를저장하고 로딩하는데 사용된다. 대개 특정 프로퍼티는 엔티티 속성의 부분 집합에 사용된다. 일반적인 규칙은 특정한 속성에 대해서모든 프로퍼티에서 이 속성을 읽을 수는 있지만 조작은 하나의 프로퍼티에서만 해야 한다.

게임 애플리케이션의 많은 특징 중에서 어떤 것들은 엔티티 내부에서 처리하는 것 보다 (애플리케이션의) 어느 중심부에서 처리하는 것이 더 나은 것이있다.(우리의 초기 프로젝트들의 총체적인 코드 디자인은 모든 것이 엔티티가 아니라는 것을 이해하지 못해서 많은 고생을 했다. 예를 들어 사용자 입력을 다루거나 카메라를 조작하는 것은 대부분의 경우 하나의 중심부에서 처리하는 것이 여러 개의 프로퍼티에서 분산해서 처리하는 것보다 낫다. 여러 개의 프로퍼티에 분산되어 있는 경우 다른 프로퍼티와의 동기화와 커뮤니케이션에 많은 노력이 필요할지도 모르기 때문이다. 이러한 게임 로직의 전역적 관점이 Manager 클래스의 서브 클래스들이 놓여지는 곳이다. Manager 클래스는 전형적인 싱글레톤 객체로 보통 게임 코드 내 어디에서든 사용이 가능해야 할 필요가 있는 서비스를 제공한다.

마지막으로 GameFeature는 새로운 컨셉으로 Mangalore에는 존재하지 않았던것이다. GameFeatures라는 것은 단지 서로 관련있는 Properties, Managers, Messages 그리고Attributes (이들 모두 임의 선택 가능)로 구성된 소스 파일 묶음을 정적 라이브러리로 컴파일한 것에 대한 재치있는이름일 뿐이다.  GameFeatures의 대부분은 프로젝트간에 코드 재사용을 촉진하고 표준화하기 위한 기반들이다. 프로젝트시작시 리더 프로그래머는 여러 GameFeature 중에서 프로젝트에 적합한  것들을 가려내고 선택한다. 그리고(이상적인경우로) 새로운 기능들은 나중에 진행할수도 있는 프로젝트를 위해서 새로운 GameFeature에다 그룹짓는다.Application Layer에는 조작 가능한 아바타와 추적 카메라 그리고 주위 환경에 대한 외적 물리 작용이 있는 일반적인3D 응용프로그램 정도는 충분히 구현할 수 있는 몇 개의 표준 GameFeature가 같이 따라온다. 그러나 대화 시스템이나 일반적인 인벤트리 시스템, 혹은 이를테면 전형적인 본격 말타기 게임과 같은 훨씬 더 복잡한 것들을 만들 작정이다. ;)

ApplicationLayer는 물론 완벽하지도 또 모든 문제를 해결하는 것도 아니다. 예를 들어 기능들의 어떤 일부들은 Property로 가야할지 아니면 Manager로 가야 할지를 결정하기가 어려울 수도 있다. 또 우리가 자주 대면하는 전형적인 문제는 기능이 너무 작고 많은부분으로 분리되는 경우로 이것은 수 많은 그리고 너무 세분화되어 매우 잦은 커뮤니케이션을 요구하는 Property들이 만들어지는 결과를 낳는다.  이런 이유로 프로젝트에는 여전히 프로젝트 시작시 코드의 기본 기반을 정할 실용적인 리더 프로그래머가 필요하다.


by kimsama | 2009/02/05 10:57 | Nebula Device | 트랙백 | 핑백(1) | 덧글(0)

트랙백 주소 : http://kimsama.egloos.com/tb/1867945
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Linked at East Agent's Blo.. at 2009/02/08 23:16

... 니다. Nebula3 Render Layer : CoreGraphicsNebula3 Resource subsystemNebula3 Graphics subsystemNebula3 Application Layer작년 8월에 소스 코드가 릴리즈 되었을 때 올 2월 쯤에 애니메이션을 포함한 새로운 릴리즈가 있을 것이라는 이야기를 한 적이 있었는데(오프라인에서) 거의 그 ... more

:         :

:

비공개 덧글

◀ 이전 페이지다음 페이지 ▶