SlideShare une entreprise Scribd logo
1  sur  64
Télécharger pour lire hors ligne
슈퍼 클래스 :
단순함을 유지하여 개발생산성 향상시키기

Super-class based game object system

              ㈜소프트네트
                  김성익
               noerror@softnette.com
목차
01. 지향점
02. 개발 관점의 변화 추적
03. 슈퍼클래스 소개
04. 슈퍼클래스 기반 게임 오브젝트 시스템
05. 기타 사례 및 아이디어
06. 결론
07. Q&A
지향점
1. 납득 가능한 기획적 명세는 가능한 모두 구현하자
생산성, 확장성, 재사용성
2. 빠르게 개발하되 코드의 품질을 일정 수준 이상으로 유지
하자
단순화, 표준화
 성능, 우아함




솔루션 : 개발 역량을 높이거나 더 오래 일을 하거나 ??
개발 관점의 변화 추적
절차적에서 객체지향적으로
  일반화된 효과적이고 유연하며, 확장성 높은 개발
  추상화, 상속
  fread(header, 1, len, fp);
  f->Read(&header, len);

     CreateTextureFromMemory(ptr, size, pTexture);
     CreateTextureFromFile(fp, &pTexture);
     CFileIO* f1 = CMemIO::Create(ptr, size);
     CreateTextureFromFile(f1, &pTexture);
     CFileIO* f2 = CStdIO::Open(L"checkbox.dds");
     CreateTextureFromFile(f2, &pTexture);
     CFileIO* f3 = CHttpIO::Open(L“http://softnette.com/checkbox.dds");
     CreateTextureFromFile(f3, &pTexture);


#Object Oriented Programming
개발 관점의 변화 추적
절차적에서 객체지향적으로
재 사용성 확장성을 위한 적절한 설계가 요구됨
구성 및 설계에 따른 시행 착오와 정비로 인한 개발 지연
복잡도가 높아질수록 개발 효율이 떨어짐
개발 관점의 변화 추적
자료주도적으로
프로그래머 의존도 축소
개발 관점에서 생산성 향상
확장성
개발 관점의 변화 추적
자료주도적으로
스크립트
손쉽게 프로그램과 연동 가능
높은 유연성
개발 관점의 변화 추적
자료주도적으로
스크립트
스크립트 자체의 접근성
비 프로그래머가 작성한 스크립트의 품질과 오류
디버깅 이슈
활용도가 높을 수록 성능 이슈
개발 관점의 변화 추적
자료주도적으로
그래프 편집
비 프로그래머들도 쉽게 접근
훌륭하게 시각화된 작업 환경
손쉬운 바인딩                                            Quartz composer

확장성




NDC2008: 차세대 게임 개발을 위한 실시간 비주얼 그래프 편집                                vvvv
              http://dev.ntreev.com/publications
개발 관점의 변화 추적
자료주도적으로
그래프 편집
개발 도구의 높은 편의성이 요구됨
기반 시스템 구축의 난이도 접근성
복잡도와 무관하게 양이 증가할수록 직관성 감소




                  vvvv video visualizer
개발 관점의 변화 추적
컴포넌트기반 시스템
객체를 컴포넌트 조합으로 구성
누구나 기능 조합 가능
다양한 구성이 가능




                                        NDC2010:M2아키텍처리뷰
GDC Canada 2009:Theory and Practice of Game Object Component
Architecture
개발 관점의 변화 추적
컴포넌트기반 시스템
비의존적, 독립적인 컴포넌트 제작의 난이도
개발 효율 저하
  덜(?) 직관적인 코드
  간접 참조의 스트레스
내부 통신으로 인한 성능 문제




             GDC Canada 2009:Theory and practi…
개발 요구사항
일반화도 잘 되면서 구조가 단순하고, 자료주
도적이며, 다양한 기능 조합도 가능하고,
개발 스트레스 없이 빠르게 개발 가능한 방법
이 목표입니다
슈퍼클래스
한마디로, 하나의 클래스에서 모두 구현
모두(?) 익숙하지만 지양하고 싶은 모델
슈퍼클래스기반 게임오브젝트
한마디로, 하나의 클래스에서 모두 구현
모두(?) 익숙하지만 지양하고 싶은 모델
역 발상으로 다기능을 지향
슈퍼클래스기반 게임오브젝트
한마디로, 하나의 클래스에서 모두 구현
모두(?) 익숙하지만 지양하고 싶은 모델
역 발상으로 극단적인 다기능을 지향
셰이더로 보는 사례
슈퍼 셰이더 사례 (aka. UberShader)
실시간 렌더링의 패러다임 변화
 고정 파이프라인에서 프로그래머블 셰이더 시대로
셰이더 시스템
 렌더링에 최적화된 프로세스 유닛
 단순한 구성, 대량의 프로세스 유닛 추구
 동적 분기 취약
 하나의 머트리얼은 하나의 셰이더 (혹은 technique)
셰이더로 보는 사례
조합이슈
float4 ps(PS_IN In) : COLOR
{
               return tex2D(DiffuseMapSampler, In.Texcoord0.xy);
}
float4 ps_light(PS_IN In) : COLOR
{
               return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * Lambert(In.Normal.xyz);
}
float4 ps_lightmap(PS_IN In) : COLOR
{
               return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * tex2D(LightMapSampler, In.Texcoord1.xy);
}

technique textureonly {
               pass p0 {
                              VertexShader = compile vs_3_0 vs();
                              PixelShader = compile ps_3_0 ps();
               }
}

technique light {
               pass p0 {
                              VertexShader = compile vs_3_0 vs();
                              PixelShader = compile ps_3_0 ps_light();
               }
}

technique lightmap {
               pass p0 {
                              VertexShader = compile vs_3_0 vs();
                              PixelShader = compile ps_3_0 ps_lightmap();
               }
}
셰이더로 보는 사례
조합이슈
그림자 기능 추가시 (두 배 증가)
float4 ps(PS_IN In) :   COLOR
{
               return   tex2D(DiffuseMapSampler, In.Texcoord0.xy);
}
float4 ps_light(PS_IN   In) : COLOR
{
               return   tex2D(DiffuseMapSampler, In.Texcoord0.xy) * Lambert(In.Normal.xyz);
}

float4 ps_lightmap(PS_IN In) : COLOR
{
               return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * tex2D(LightMapSampler, In.Texcoord1.xy);
}

float4 ps_withshadow(PS_IN In) : COLOR
{
               return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * ProjShadow(In.ShadowPos);
}

float4 ps_light_withshadow(PS_IN In) : COLOR
{
               return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * Lambert(In.Normal.xyz) * ProjShadow(In.ShadowPos);
}

float4 ps_lightmap_withshadow(PS_IN In) : COLOR
{
               return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * tex2D(LightMapSampler, In.Texcoord1.xy) * ProjShadow(In.ShadowPos);
}
셰이더로 보는 사례
조합이슈
그림자 기능 추가
스키닝 추가 (4배)
스펙큘러 마스크 (8배)
리플렉션 매핑 (16배)
UV스크롤 (32배)
노멀맵 (64배)
대단한 의지가 아니면 관리가 불가능
일정 시점 이상이 되면 셰이더의 난이도와 상관없이 작업 불가능한 상태
대부분 정책적으로 기능을 제한하는 방향으로
셰이더로 보는 사례
조합해법
코드 생성
그래프 편집
셰이더 조합 스크립트
UberShader

              Unreal3 Material Editor
셰이더로 보는 사례
UberShader
소스 코드는 유지하고 전처리를 통해서 기능 선택
 float4 ps(PS_IN In) : COLOR
 {
            float4 out = tex2D(DiffuseMapSampler, In.Texcoord0.xy);
 #ifdef _LIGHT
            out *= Lambert(In.Normal.xyz);
 #endif
 #ifdef _LIGHTMAP
            out *= tex2D(LightMapSampler, In.Texcoord1.xy);
 #endif
 #ifdef _SHADOW
            out *= ProjShadow(In.ShadowPos);
 #endif
            return out;
 }

 technique complete {
            pass p0 {
                        VertexShader = compile vs_3_0 vs();
                        PixelShader = compile ps_3_0 ps();
            }
 }
슈퍼클래스 특징
1. 요구사항을 구현함에 있어서 구조적인 부
담이 굉장히 적다
2. 쉽게 자료화 할 수 있다
3. 도구화할 수 있다
4. 표준화하여 다양한 파트에 적용할 수 있다
슈퍼클래스 적용 시나리오
이동하는 코드를 이용해 가상의 사례를 하나
구성해봅니다
void CActor::Move(const Vec &dv, int lv)
{
        float t = SweepTest(m_Pos, m_Radius, dv, NULL);
        m_Pos += dv * t;
}
슈퍼클래스 적용 시나리오
요구 사항 : 어떤 객체는 충돌이 없습니다
void CActor::Move(const Vec &dv)
{
        if (m_flags&_NOCOLLISION)
        {
               m_Pos += dv;
               return ;
        }

       float t = SweepTest(m_Pos, m_Radius, dv, NULL);
       m_Pos += dv * t;
}
슈퍼클래스 적용 시나리오
요구 사항 : 슬라이딩이 되어야 합니다
void CActor::Move(const Vec &dv, int lv)
{
           if (m_flags&_NOCOLLISION)
           {
                      m_Pos += dv;
                      return ;
           }

           Plane p;

           float t = CMomo::GetInstance().SweepTest(m_Pos, m_Radius, dv, &p);

           if (t < 1.0f)
           {
                      if (t > 0)
                                    m_Pos += dv * t;

                      if (lv < 3)
                      {
                                    Vec vr = dv * (1-t);
                                    float d1 = p.Distance(m_Pos) - m_Radius;
                                    Move(vr - p.Normal() * Vec::dot(vr, p.Normal()), lv+1);
                      }
                      return;
           }

           m_Pos += dv;
}
슈퍼클래스 적용 시나리오
요구 사항 : 슬라이딩 안 하는 객체도 있어요
void CActor::Move(const Vec &dv, int lv)
{
           if (m_flags&_NOCOLLISION)
           {
                      m_Pos += dv;
                      return ;
           }

           Plane p;

           float t = CMomo::GetInstance().SweepTest(m_Pos, m_Radius, dv, &p);

           if (t < 1.0f)
           {
                      if (t > 0)
                                   m_Pos += dv * t;

                      if ((m_flags&_SLIDING) && lv < 3)
                      {
                                 Vec vr = dv * (1-t);
                                 float d1 = p.Distance(m_Pos) - m_Radius;
                                 Move(vr - p.Normal() * Vec::dot(vr, p.Normal()), lv+1);
                      }
                      return;
           }

           m_Pos += dv;
}
슈퍼클래스 적용 시나리오
요구 사항 : 바닥에만 슬라이딩하게 해주세요.
바운딩도 필요합니다. 슬라이딩시 마찰력을
적용해주세요. 단, 무적상태가 아닐 때 만.
충돌할 때 이벤트를 발생시켜 주세요. 대미지
중 이동할 때는 충돌 지점에 파티클 좀 뿌려
주세요. 단,캐릭터가 HP10%이하인 경우만….
슈퍼클래스 적용 시나리오
요구 사항 : 바닥에만 슬라이딩하게 해주세요.
바운딩도 필요합니다. 슬라이딩시 마찰력을
적용해주세요. 단, 무적상태가 아닐 때 만.
충돌할 때 이벤트를 발생시켜 주세요. 대미지
중 이동할 때는 충돌 지점에 파티클 좀 뿌려
주세요. 단,캐릭터가 HP10%이하인 경우만….
NO PROBLEM
슈퍼 클래스기반 프로그래밍의 장단점
장점
1. 구조적으로 큰 부담 없이 기존코드를 유지하면
서 새로운 기능 추가 가능
기능 코드만 추가하고 객체를 생성할 때 선택적으로 해당
기능을 set 시켜주기만 하면 끝
2. 쉽고 단순하고 직관적
단점
1. 코드가 조잡해지는 느낌
2. 하드코딩 하는 느낌
인식의 전환
코드가 조잡해 보인다
어떤 식으로 구성하더라도 결과적으로 핵심 구현
로직이 다른 코드일까
현재 코드의 쾌적함을 위해 기획자와 명세를 협상
하고 있는 건 아닌지 성찰해봅니다
 “우리는 바닥에서만 슬라이딩은 불가능합니다. 끝”
약간 심적인 부담이 있겠지만 쿨~하게 구현해 주
는 것이 완벽한 프로그래머보다 멋진 프로그래머
솔루션 : 심리적인 해결. “조잡해 보이는 건 명세 탓!! 하지만 로직을
단순하고 멋지게 유지하는 것보다는 명세가 우선이다”라고 암시 암시 암시
인식의 전환
하드 코딩 같아 보인다
일관성을 유지하면서도 관리가 가능하게 작성된
코드라면 하드코딩과 다르다 (암시)
 if (m_Type == _WOLF && m_HP <= 10)
            PlaySound(L"아파");
 if ((m_Flags&_HURT_SOUND) && m_HP <= m_HurtsAlramHP)
            PlaySound(L"아파");

         void CGameRoom::LeaveRoom(CSession* session, bool graceful)
         {
                    if (!IsLobby())
                               NotifyLeaveMessage(session);
                    if (IsDungeon() && graceful == false)
                               session->ExitPenalty();
         }
         void CGameRoom::LeaveRoom(CSession* session, bool graceful)
         {
                    if (m_flags&_NOTIFY_LEAVE)
                               NotifyLeaveMessage(session);
                    if ((m_flags&_EXIT_PENALTY) && graceful == false)
                               session->ExitPenalty();
         }
슈퍼클래스화
하나의 클래스에 기능을 통합
인스턴스 생성시 기능 선택
자료화
자료 주도적으로 개발하려면 필수
슈퍼 클래스 구성 요소
기능 리스트
기능에 필요한 속성
컴포넌트기반 오브젝트 시스템과 유사
자료화
단순한 계층의 XML(혹은 jason)로 쉽게 표현가능
<actor>
  <player mask="_UPDATE,_RENDER,_GRAVITY,_USERCONTROL,_CHECKEVENTBOX,_MOUSEACTION">
    <pos>0 15</pos>
    <radius>0.5</radius>
  </player>
  <helper mask="_UPDATE,_RENDER,_STATIC">
    <pos>0 2</pos>
    <radius>0.4</radius>
    <color>ffffff00</color>
    <name>helper</name>
  </helper>
  <camera mask="_UPDATE,_CAMERA,_NOCOLLISION">
    <pos>0 10</pos>
    <follow>player</follow>
  </camera>
</actor>
도구화
기능 리스트 (on/off/enum)
기능이 set 되었을 때 필요한 속성/에디터객체

        1
            2
도구화
기능명시   <particlemask type="propertysheet" minheight="75" height="25%" headervisible="false">
          <shape text="형태">
            <_SHAPE text="타입" type="enum" items="빌보드;트레일;메시">랜덤</_SHAPE>
            <_COLOR text="색상" type="enum" items="상수;보간;화이트">화이트</_COLOR>
            <_ALPHA text="알파" type="enum" items="없음;상수;보간">없음</_ALPHA>
            <_SIZE text="크기" type="enum" items="기본;랜덤;랜덤보간">기본</_SIZE>
            <_ROTATE text="회전" type="enum" items="없음;상수;랜덤">없음</_ROTATE>
          </shape>
          <lifetime text="생성">
            <_DELAY text="생성지연" type="enum" items="없음;상수;랜덤;순차적">없음</_DELAY>
            <_LIFETIME text="라이프타임" type="enum" items="상수;랜덤">랜덤</_LIFETIME>
          </lifetime>
          <position text="위치">
            <_POSITION text="생성위치" type="enum" items="원점;랜덤구">원점</_POSITION>
            <_VELOCITY text="속도" type="enum" items="없음">없음</_VELOCITY>
            <_DIRECTION text="방향/목표" type="enum" items="없음;랜덤구;목표지점">없음</_DIRECTION>
            <_GRAVITY text="중력" type="bool">false</_GRAVITY>
          </position>

       <parameters type="propertysheet" height="100%">
          <general text="일반" mask="default">
            <COUNT text="생성갯수" type="int" min="1" singleStep="5">10</COUNT>
            <LOOP text="반복" type="bool">false</LOOP>
            <BLEND text="블랜딩" type="enum" items="알파블랜딩;가산;곱하기">가산</BLEND>
          </general>
          <billboard text="빌보드" mask="_SHAPE=빌보드">
            <TEXTURE text="texture" type="texture">check.bmp</TEXTURE>
          </billboard>
          <randomlifetime text="라이프타임" mask="_LIFETIME=랜덤">
            <LIFETIME_MIN text="min" type="float" min="0" singleStep="1">5</LIFETIME_MIN>
            <LIFETIME_MAX text="max" type="float" min="0" singleStep="1">10</LIFETIME_MAX>
          </randomlifetime>
          <constlifetime text="라이프타임" mask="_LIFETIME=상수">
            <CONSTLIFETIME text="lifetime" type="float" min="0" singleStep="1">5</CONSTLIFETIME>
          </constlifetime>
          <constcolor text="색상" mask="_COLOR=상수">
            <CONSTCOLOR text="색상" type="color">ffffff</CONSTCOLOR>
          </constcolor>
도구화
기능간의 관계
기능 간의 관계를 데이터 상에서 검증




 <shading text="셰이딩">
   <_NO_LIGHTING text="셰이딩안함" type="bool">false</_NO_LIGHTING>
   <_USE_SPECULAR text="스펙큘러채널" type="bool" enabletest="!_NO_LIGHTING">false</_USE_SPECULAR>
   <_RIMLIGHTING text="림라이트" type="bool" enabletest="!_NO_LIGHTING">false</_RIMLIGHTING>
 </shading>
도구화
클래스화
많은 기능 중에서 클래스에 필요한 기능한 툴 상에
서 표시
클래스는 데이터로만 존재
슈퍼클래스기반 게임오브젝트
   극단적인 사용 안을 제안합니다
    게임 객체를 하나의 오브젝트 타입으로 구성
    모든 게임 객체는 Actor
      데이터에 의해서만 기능 set / reset
    단순한 구조
      신입도 알 수 있어요




Note) 현재 이 구조로 프로젝트 진행하고 있습니다 (소프트네트)
슈퍼클래스기반 게임오브젝트
Actor(SuperActor)
모든 기능을 구현
 모든 객체는 길 찾기, Head tag, 동기화 등을 맘대로 활용 가능
 기능 추가하고 데이터 연동만 해주면 OK (신입도 할 수 있어요)
재사용성 Better (vs ObjectOrientDesign)
 “아이템 사라질 때 mob 사라질 때처럼 해주시면 안되나요 ?”
 “Re:그렇게 하세요”
직접 참조 OK (vs Component-based, OOD)
 메시 모델의 손의 위치를 사운드 출력 부에서 직접 참조
 카메라 객체에서 플레이어의 머리본의 TM을 직접 참조
 빠르고 직관적
슈퍼클래스기반 게임오브젝트
SuperActor
“구현부가 너무 비대해지지 않을까요 ?”
 구현부를 적절히 컴포넌트화한다면 납득할 수준으로 관
 리가 가능
 각 컴포넌트는 계층적이지 않기 때문에 단순하게 구성가
 능 (일반화의 제약도 없음)
 다만 과도하게 컴포넌트화하고 정리를 하는 것보다는 관리 가능한 수준에서
 느슨하게 처리하는 것을 추천
슈퍼클래스기반 게임오브젝트
SuperActor
“일일이 비트 검사하면 속도상 불이익이 있지 않을
까요 ?”
구현은 트리 구조를 이루게 됨
  그룹단위로 체크해서 최 상위에서 skip 하도록
  점프는 이동 하위에, 2단 점프는 점프 하위
좀 더 도전적으로 DOD로 확장가능(슈퍼클래스기
반 파티클 참조)
 #Data Oriented Design
 http://www.lameproof.com/zboard/zboard.php?id=bbs2&no=790
슈퍼클래스기반 게임오브젝트
SuperActor
“그럼 모든 속성도 가지고 있다는 건데, 메모리 낭
비가 심하지 않을지요” (필요한 경우 heap으로)
 template <class _Tx> class CValuePtr {
 public :
     CValuePtr() { m_Ptr = NULL; }
     ~CValuePtr() { if (m_Ptr != NULL) delete m_Ptr; }
     _Tx* operator-> () { if (m_Ptr == NULL) m_Ptr = new _Tx; return m_Ptr; }
 private :
     _Tx* m_Ptr;
 } ;
class      CActor {
private:
    struct _DIALOG {
         _DIALOG() { Shape = NULL; }
         ~_DIALOG() { if (Shape) delete   Shape; }
         float       OpenStep;
         Sphere*     Shape;               value = *node.FindChild(L"dialog_offset");
         float       Offset[2];           swscanf_s(value, L"%f %f", &m_Dialog->Offset[0], &m_Dialog->Offset[1])
    };                                    value = *node.FindChild(L"dialog_size");
    CValuePtr<_DIALOG> m_Dialog;          m_Dialog->Shape = new Sphere(Vec(0, 0), unicode::atof(value), 14);
} ;
슈퍼클래스기반 게임오브젝트
슈퍼 클래스 기반 게임 오브젝트 장점
단순한 구조로 빠른 개발이 가능
기능 추가가 용이하며 많은 코드 공유 가능
 소규모 여러 프로젝트에서 공유 가능
 사이드뷰 액션 게임과 TPS, 스포츠 게임이 같은 프로젝트
코드 관리 용이성
 데이터 검증으로 dead code 판단 가능
 Legacy code를 유지하면서 방어적으로 기능 교체
슈퍼클래스기반 게임오브젝트
슈퍼 클래스 기반 게임 오브젝트 장점
툴 연동 가능
 툴에서 필요한 기능만 활성하면 툴 상에서 인터렉션 가능
 툴 내 게임 플레이도 가능
 생산성 향상
(데모)
슈퍼클래스 기반 파티클
하나의 파티클 객체에서 모든 기능을 구현
표준화된 도구사용
절차
1. 데이터를 읽어서 사용되는 기능과 툴에서 세팅한 값들을
저장
2. 파티클 인스턴스 생성시 인스턴스에 초기값 세팅
3. 파티클 업데이트
슈퍼클래스 기반 파티클
생성 지연시간 예
       void CParticle::InitParticle(void *data, int count) const
       {
         for(int i=0; i<count; i++)
         {
            _PARTICLE* ptr = (_PARTICLE*)((char*)data + m_Pitch * i);
            char * extra = (char*)ptr + sizeof(_PARTICLE);

           if (m_InitMask&_DELAY_CONST)
           {
               ptr->curTime = - *(const float*)GetParam(_I_DELAY_CONST);
           }
           else if (m_InitMask&_DELAY_RANDOM)
           {
               const float* delayrandom = (const float*)GetParam(_I_DELAY_RANDOM);
               ptr->curTime = - Random(delayrandom[0], delayrandom[1]);
           }
           else if (m_InitMask&_DELAY_SEQ)
           {
               ptr->curTime = - *(const float*)GetParam(_I_DELAY_SEQ) * i;
           }
           else
           {
               ptr->curTime = 0;
           }
슈퍼클래스 기반 파티클
업데이트 예
비트 연산으로 기능 체크해서 구현
 bool CParticle::Update(float dt, void * data, int count, unsigned long updatemask) const
 {
   for(int i=0, off=0; i<count; i++, off+=m_Pitch)
   {
      _PARTICLE* p = (_PARTICLE*)((char*)data + off);

      p->curTime += dt;
      char * extra = (char*)p + sizeof(_PARTICLE);

      if (updatemask&_COLOR_BLEND)
      {
          unsigned long* blendcolor = (unsigned long*) GetData(extra, _U_BLENDCOLOR);
          p->color = LerpColor(blendcolor[0], blendcolor[1], p->curTime / p->lifeTime);
      }
      if (updatemask&_GRAVITY)
      {
          Vec3* vel = (Vec3*) GetData(extra, _U_VELOCITY);
          *vel += Vec3(0, -9.8f, 0) * dt; // 중력
      }
      if (updatemask&_VELOCITY)
      {
          const Vec3* vel = (const Vec3*) GetData(extra, _U_VELOCITY);
          p->pos += (*vel) * dt;
      }
슈퍼클래스 기반 파티클
메모리 문제
오프셋 테이블을 이용하여 최소의 용량만 사용
기능상 필요한 데이터만 할당
슈퍼클래스 기반 파티클
성능 문제
분기문(if)로 인한 제어 해저드
대량의 연산이 이루어지기 때문에 성능을 고려할
때는 민감한 사안




#control hazard
슈퍼클래스 기반 파티클
성능 문제
해법#1 자료지향설계(DOD)
bool CParticle::Update(float dt, void * data, int count, unsigned long updatemask) const
{
  _PARTICLE* p = (_PARTICLE*)((char*)data + off);
  int i;

  for(i=0; i<count; i++)
     p->curTime[i] += dt;

  if (updatemask&_COLOR_BLEND)
  {
      unsigned long* blendcolor = (unsigned long*) GetData(p, _U_BLENDCOLOR);
      for(i=0; i<count; i++)
         p->color[i] += LerpColor(blendcolor[i*2+0], blendcolor[i*2+1], p->curTime / p->lifeTime);
  }
  if (updatemask&_GRAVITY)
  {
      Vec3* vel = (Vec3*) GetData(p, _U_VELOCITY);
      for(i=0; i<count; i++)
         vel[i] += += Vec3(0, -5.0f, 0) * dt;
  }
  if (updatemask&_VELOCITY)
  {
      const Vec3* vel = (const Vec3*) GetData(p, _U_VELOCITY);
      for(i=0; i<count; i++)
         p->pos[i] += vel[i] * dt;
  }
슈퍼클래스 기반 파티클
성능 문제
해법#2 컴파일러 마법
도달하지 않는 코드, 상수연산은 제거됨
#include <windows.h>

inline void update(unsigned long mask)
{
    if (mask&1)
        ::Sleep(0xFF);
    if (mask&2)
        ::Sleep(0xF);
}

void main()
{
    unsigned long mask = rand();
    update(mask);
    update(2);
}
슈퍼클래스 기반 파티클
성능 문제
해법#2 컴파일러 마법
많이 호출되는 타입은 아래처럼
bool CParticle::Update(float dt, void * data, int count) const
{
    if (m_UpdateMask == (_COLOR_BLEND|_GRAVITY|_VELOCITY))
        return Update(dt, data, count, _COLOR_BLEND|_GRAVITY|_VELOCITY);
    else if (m_UpdateMask == _COLOR_BLEND)
        return Update(dt, data, count, _COLOR_BLEND);
    return Update(dt, data, count, m_UpdateMask);
}

해당 기능만 실행하는 코드 생성
BEST
슈퍼클래스 기반 파티클
슈퍼클래스 기반 파티클의 장점
다양한 조합의 파티클
손쉬운 도구 연동
이펙트 디자이너의 요구를 빠르게 반영 가능
 바로 구현 후 데이터 연동만 해 놓으면 OK
 “호혹시 파티클이 회오리 모양의 경로로 움질일 수 있을
 까요?” “네 만들어 드리겠습니다”
빠른 연산
 시스템이 단순하여 병렬화나 메모리 친화적인 다양한 최
 적화가 가능
슈퍼클래스 기반
유저 인터페이스 시스템
컴포넌트의 예외적인 명세
포스트 프로세싱 / 모션 컨트롤
자료 주도적인 구성
 셰이더 , 셰이더 변수, 블룸, 렌더 타겟,… 조합으로 패스
 정의
여러 패스
슈퍼클래스 기반 서버
일반적인 서버 구성
게임의 성격에 맞도록 서버를
구성
기본 모듈을 공유하는 서로
다른 프로젝트로 예상




     게임테크 2010:Extracting MMORPG Server Engine from TERA
슈퍼클래스 기반 서버
슈퍼 클래스 기반의 서버 구성
서버는 한 종류
데이터에 의해서 기능 명세
슈퍼클래스 기반 서버
슈퍼 클래스 기반의 서버 구성
서버는 한 종류
데이터에 의해서 기능 명세
다기능 서버
 게임 성격과 서비스 상황에
 맞도록 세팅
 인증+필드, 인증+던전, 던전
 인증+던정,필드 …
 기능 단위보다는 지역, 처리
 유저 수 기준
슈퍼클래스 기반 서버
클라이언트와 코드 공유
클라이언트의 게임 객체를 서버에서도 사용
 필요한 기능만 활성 가능하도록 제한
 “길 찾기 따로 만들어야 되나요 ?”
 “클라이언트에서 구현한 AI캐릭터를 서버에서 사용할 수
 없나요 ?”
 “서버용 데이터 안 만들고 애니메이션 이벤트 검증할 수
 있나요?”
 NO PROBLEM
정책적으로 클라이언트, 툴, 서버에서 게임 객체 공유 (소프트네트)
(데모)
결론
슈퍼 클래스를 이용하면
구조적인 복잡도가 낮아 직관적으로 구성 가능
단순한 구조로 설계 및 관리의 스트레스에서 해방
구현에 좀 더 집중 가능하며 개발 속도 개선
도구를 이용하여 프로젝트 개발 속도 개선

코멘트 : 우아하고 섹시하진 않지만 합리적으로 검토해 볼만
한 아이디어

슈퍼클래스, 상태 머신, 스크립트 3S 삼총사면 무서울 게 없습니다
감사합니다




강연자 이메일 noerror@softnette.com

Contenu connexe

Tendances

테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템QooJuice
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술YEONG-CHEON YOU
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현YEONG-CHEON YOU
 
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)내훈 정
 
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019devCAT Studio, NEXON
 
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018devCAT Studio, NEXON
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략YEONG-CHEON YOU
 
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기MinGeun Park
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해Nam Hyeonuk
 
[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희changehee lee
 
NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀승명 양
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술henjeon
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012devCAT Studio, NEXON
 
Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPSeungmo Koo
 
What is Game Server ?
What is Game Server ?What is Game Server ?
What is Game Server ?흥배 최
 
[KGC2011_박민근] 신입 게임 개발자가 알아야 할 것들
[KGC2011_박민근] 신입 게임 개발자가 알아야 할 것들[KGC2011_박민근] 신입 게임 개발자가 알아야 할 것들
[KGC2011_박민근] 신입 게임 개발자가 알아야 할 것들MinGeun Park
 
[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능Yongha Kim
 
게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPUYEONG-CHEON YOU
 
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012devCAT Studio, NEXON
 

Tendances (20)

테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
 
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
 
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략
 
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희
 
NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
 
Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCP
 
What is Game Server ?
What is Game Server ?What is Game Server ?
What is Game Server ?
 
[KGC2011_박민근] 신입 게임 개발자가 알아야 할 것들
[KGC2011_박민근] 신입 게임 개발자가 알아야 할 것들[KGC2011_박민근] 신입 게임 개발자가 알아야 할 것들
[KGC2011_박민근] 신입 게임 개발자가 알아야 할 것들
 
[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능
 
게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU
 
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
 

En vedette

NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁Yi-kwon Hwang
 
NDC 2015 삼시세끼 빌드만들기
NDC 2015 삼시세끼 빌드만들기NDC 2015 삼시세끼 빌드만들기
NDC 2015 삼시세끼 빌드만들기Hyunsuk Ahn
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010devCAT Studio, NEXON
 
Unite2015 probelight(150417)
Unite2015 probelight(150417)Unite2015 probelight(150417)
Unite2015 probelight(150417)SangYun Yi
 
7강 shader basic lighting_배포용 삭제버전
7강 shader basic lighting_배포용 삭제버전7강 shader basic lighting_배포용 삭제버전
7강 shader basic lighting_배포용 삭제버전JP Jung
 
물리 기반 셰이더의 이해
물리 기반 셰이더의 이해물리 기반 셰이더의 이해
물리 기반 셰이더의 이해tartist
 
[Ndc13]Ndc 2013 김동석:UDK로 물리기반 셰이더 만들기
[Ndc13]Ndc 2013 김동석:UDK로 물리기반 셰이더 만들기[Ndc13]Ndc 2013 김동석:UDK로 물리기반 셰이더 만들기
[Ndc13]Ndc 2013 김동석:UDK로 물리기반 셰이더 만들기동석 김
 
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화Jaeseung Ha
 
[0122 구경원]게임에서의 충돌처리
[0122 구경원]게임에서의 충돌처리[0122 구경원]게임에서의 충돌처리
[0122 구경원]게임에서의 충돌처리KyeongWon Koo
 
서비스중인 게임 DB 설계 (쿠키런 편)
서비스중인 게임 DB 설계 (쿠키런 편)서비스중인 게임 DB 설계 (쿠키런 편)
서비스중인 게임 DB 설계 (쿠키런 편)_ce
 
[160404] 유니티 apk 용량 줄이기
[160404] 유니티 apk 용량 줄이기[160404] 유니티 apk 용량 줄이기
[160404] 유니티 apk 용량 줄이기MinGeun Park
 
[160402_데브루키_박민근] UniRx 소개
[160402_데브루키_박민근] UniRx 소개[160402_데브루키_박민근] UniRx 소개
[160402_데브루키_박민근] UniRx 소개MinGeun Park
 
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현MinGeun Park
 
Kgc2012 온라인 게임을 위한 게임 오브젝트 설계
Kgc2012 온라인 게임을 위한 게임 오브젝트 설계Kgc2012 온라인 게임을 위한 게임 오브젝트 설계
Kgc2012 온라인 게임을 위한 게임 오브젝트 설계kgun86
 

En vedette (15)

NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
NDC15 - 사례로 살펴보는 MSVC 빌드 최적화 팁
 
NDC 2015 삼시세끼 빌드만들기
NDC 2015 삼시세끼 빌드만들기NDC 2015 삼시세끼 빌드만들기
NDC 2015 삼시세끼 빌드만들기
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
 
Lighting model
Lighting modelLighting model
Lighting model
 
Unite2015 probelight(150417)
Unite2015 probelight(150417)Unite2015 probelight(150417)
Unite2015 probelight(150417)
 
7강 shader basic lighting_배포용 삭제버전
7강 shader basic lighting_배포용 삭제버전7강 shader basic lighting_배포용 삭제버전
7강 shader basic lighting_배포용 삭제버전
 
물리 기반 셰이더의 이해
물리 기반 셰이더의 이해물리 기반 셰이더의 이해
물리 기반 셰이더의 이해
 
[Ndc13]Ndc 2013 김동석:UDK로 물리기반 셰이더 만들기
[Ndc13]Ndc 2013 김동석:UDK로 물리기반 셰이더 만들기[Ndc13]Ndc 2013 김동석:UDK로 물리기반 셰이더 만들기
[Ndc13]Ndc 2013 김동석:UDK로 물리기반 셰이더 만들기
 
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
 
[0122 구경원]게임에서의 충돌처리
[0122 구경원]게임에서의 충돌처리[0122 구경원]게임에서의 충돌처리
[0122 구경원]게임에서의 충돌처리
 
서비스중인 게임 DB 설계 (쿠키런 편)
서비스중인 게임 DB 설계 (쿠키런 편)서비스중인 게임 DB 설계 (쿠키런 편)
서비스중인 게임 DB 설계 (쿠키런 편)
 
[160404] 유니티 apk 용량 줄이기
[160404] 유니티 apk 용량 줄이기[160404] 유니티 apk 용량 줄이기
[160404] 유니티 apk 용량 줄이기
 
[160402_데브루키_박민근] UniRx 소개
[160402_데브루키_박민근] UniRx 소개[160402_데브루키_박민근] UniRx 소개
[160402_데브루키_박민근] UniRx 소개
 
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
 
Kgc2012 온라인 게임을 위한 게임 오브젝트 설계
Kgc2012 온라인 게임을 위한 게임 오브젝트 설계Kgc2012 온라인 게임을 위한 게임 오브젝트 설계
Kgc2012 온라인 게임을 위한 게임 오브젝트 설계
 

Similaire à NDC11_슈퍼클래스

NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스Sungik Kim
 
Implements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture ArrayImplements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture ArrayYEONG-CHEON YOU
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9진현 조
 
Domain Specific Languages With Groovy
Domain Specific Languages With GroovyDomain Specific Languages With Groovy
Domain Specific Languages With GroovyTommy C. Kang
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택JinTaek Seo
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기현철 조
 
120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장tedypicker
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기Yongha Yoo
 
Scala, Scalability
Scala, ScalabilityScala, Scalability
Scala, ScalabilityDongwook Lee
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019min woog kim
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 
Modern gpu optimize blog
Modern gpu optimize blogModern gpu optimize blog
Modern gpu optimize blogozlael ozlael
 
C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2Chris Ohk
 
DEVIEW-FULL-감독판.pptx
DEVIEW-FULL-감독판.pptxDEVIEW-FULL-감독판.pptx
DEVIEW-FULL-감독판.pptxhanbeom Park
 
Mean 스택을 사용한 IoT 개발
Mean 스택을 사용한 IoT 개발Mean 스택을 사용한 IoT 개발
Mean 스택을 사용한 IoT 개발Jay Park
 
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...종빈 오
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기jongho jeong
 

Similaire à NDC11_슈퍼클래스 (20)

NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스
 
Implements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture ArrayImplements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture Array
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9
 
Domain Specific Languages With Groovy
Domain Specific Languages With GroovyDomain Specific Languages With Groovy
Domain Specific Languages With Groovy
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
 
120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기
 
Scalability
ScalabilityScalability
Scalability
 
Scala, Scalability
Scala, ScalabilityScala, Scalability
Scala, Scalability
 
190821 delphi
190821 delphi190821 delphi
190821 delphi
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 
Modern gpu optimize
Modern gpu optimizeModern gpu optimize
Modern gpu optimize
 
Modern gpu optimize blog
Modern gpu optimize blogModern gpu optimize blog
Modern gpu optimize blog
 
C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2
 
DEVIEW-FULL-감독판.pptx
DEVIEW-FULL-감독판.pptxDEVIEW-FULL-감독판.pptx
DEVIEW-FULL-감독판.pptx
 
Mean 스택을 사용한 IoT 개발
Mean 스택을 사용한 IoT 개발Mean 스택을 사용한 IoT 개발
Mean 스택을 사용한 IoT 개발
 
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기
 

Plus de noerror

15_TextureAtlas
15_TextureAtlas15_TextureAtlas
15_TextureAtlasnoerror
 
11_웹서비스활용
11_웹서비스활용11_웹서비스활용
11_웹서비스활용noerror
 
NDC08_실시간비주얼그래프편집
NDC08_실시간비주얼그래프편집NDC08_실시간비주얼그래프편집
NDC08_실시간비주얼그래프편집noerror
 
KCGS11_실시간 피사계 심도 렌더링 개선 기법
KCGS11_실시간 피사계 심도 렌더링 개선 기법KCGS11_실시간 피사계 심도 렌더링 개선 기법
KCGS11_실시간 피사계 심도 렌더링 개선 기법noerror
 
11_통계 자료분석 입문
11_통계 자료분석 입문11_통계 자료분석 입문
11_통계 자료분석 입문noerror
 
11_빠른 개발 가능한 레벨 편집 시스템
11_빠른 개발 가능한 레벨 편집 시스템11_빠른 개발 가능한 레벨 편집 시스템
11_빠른 개발 가능한 레벨 편집 시스템noerror
 
11_SH를 이용한 실시간 투명 근사법
11_SH를 이용한 실시간 투명 근사법11_SH를 이용한 실시간 투명 근사법
11_SH를 이용한 실시간 투명 근사법noerror
 
ICON08_게임 애니메이션 최적화 기법
ICON08_게임 애니메이션 최적화 기법ICON08_게임 애니메이션 최적화 기법
ICON08_게임 애니메이션 최적화 기법noerror
 
08_Marching Cube Terrains
08_Marching Cube Terrains08_Marching Cube Terrains
08_Marching Cube Terrainsnoerror
 
08_게임 물리 프로그래밍 가이드
08_게임 물리 프로그래밍 가이드08_게임 물리 프로그래밍 가이드
08_게임 물리 프로그래밍 가이드noerror
 
08_플래시 맛보기
08_플래시 맛보기08_플래시 맛보기
08_플래시 맛보기noerror
 
08_애니메이션고등학교 게임과 특강
08_애니메이션고등학교 게임과 특강08_애니메이션고등학교 게임과 특강
08_애니메이션고등학교 게임과 특강noerror
 
08_Wxwidgets 소개
08_Wxwidgets 소개08_Wxwidgets 소개
08_Wxwidgets 소개noerror
 
07_PhysX 강체물리 입문
07_PhysX 강체물리 입문07_PhysX 강체물리 입문
07_PhysX 강체물리 입문noerror
 
07_스케일폼 소개
07_스케일폼 소개07_스케일폼 소개
07_스케일폼 소개noerror
 
07_Visual Shader Editor
07_Visual Shader Editor07_Visual Shader Editor
07_Visual Shader Editornoerror
 
06_HDR 소개
06_HDR 소개06_HDR 소개
06_HDR 소개noerror
 
06_게임엔진 활용팁
06_게임엔진 활용팁06_게임엔진 활용팁
06_게임엔진 활용팁noerror
 
06_게임엔진구성
06_게임엔진구성06_게임엔진구성
06_게임엔진구성noerror
 
06_자동차물리입문(1)
06_자동차물리입문(1)06_자동차물리입문(1)
06_자동차물리입문(1)noerror
 

Plus de noerror (20)

15_TextureAtlas
15_TextureAtlas15_TextureAtlas
15_TextureAtlas
 
11_웹서비스활용
11_웹서비스활용11_웹서비스활용
11_웹서비스활용
 
NDC08_실시간비주얼그래프편집
NDC08_실시간비주얼그래프편집NDC08_실시간비주얼그래프편집
NDC08_실시간비주얼그래프편집
 
KCGS11_실시간 피사계 심도 렌더링 개선 기법
KCGS11_실시간 피사계 심도 렌더링 개선 기법KCGS11_실시간 피사계 심도 렌더링 개선 기법
KCGS11_실시간 피사계 심도 렌더링 개선 기법
 
11_통계 자료분석 입문
11_통계 자료분석 입문11_통계 자료분석 입문
11_통계 자료분석 입문
 
11_빠른 개발 가능한 레벨 편집 시스템
11_빠른 개발 가능한 레벨 편집 시스템11_빠른 개발 가능한 레벨 편집 시스템
11_빠른 개발 가능한 레벨 편집 시스템
 
11_SH를 이용한 실시간 투명 근사법
11_SH를 이용한 실시간 투명 근사법11_SH를 이용한 실시간 투명 근사법
11_SH를 이용한 실시간 투명 근사법
 
ICON08_게임 애니메이션 최적화 기법
ICON08_게임 애니메이션 최적화 기법ICON08_게임 애니메이션 최적화 기법
ICON08_게임 애니메이션 최적화 기법
 
08_Marching Cube Terrains
08_Marching Cube Terrains08_Marching Cube Terrains
08_Marching Cube Terrains
 
08_게임 물리 프로그래밍 가이드
08_게임 물리 프로그래밍 가이드08_게임 물리 프로그래밍 가이드
08_게임 물리 프로그래밍 가이드
 
08_플래시 맛보기
08_플래시 맛보기08_플래시 맛보기
08_플래시 맛보기
 
08_애니메이션고등학교 게임과 특강
08_애니메이션고등학교 게임과 특강08_애니메이션고등학교 게임과 특강
08_애니메이션고등학교 게임과 특강
 
08_Wxwidgets 소개
08_Wxwidgets 소개08_Wxwidgets 소개
08_Wxwidgets 소개
 
07_PhysX 강체물리 입문
07_PhysX 강체물리 입문07_PhysX 강체물리 입문
07_PhysX 강체물리 입문
 
07_스케일폼 소개
07_스케일폼 소개07_스케일폼 소개
07_스케일폼 소개
 
07_Visual Shader Editor
07_Visual Shader Editor07_Visual Shader Editor
07_Visual Shader Editor
 
06_HDR 소개
06_HDR 소개06_HDR 소개
06_HDR 소개
 
06_게임엔진 활용팁
06_게임엔진 활용팁06_게임엔진 활용팁
06_게임엔진 활용팁
 
06_게임엔진구성
06_게임엔진구성06_게임엔진구성
06_게임엔진구성
 
06_자동차물리입문(1)
06_자동차물리입문(1)06_자동차물리입문(1)
06_자동차물리입문(1)
 

NDC11_슈퍼클래스

  • 1. 슈퍼 클래스 : 단순함을 유지하여 개발생산성 향상시키기 Super-class based game object system ㈜소프트네트 김성익 noerror@softnette.com
  • 2. 목차 01. 지향점 02. 개발 관점의 변화 추적 03. 슈퍼클래스 소개 04. 슈퍼클래스 기반 게임 오브젝트 시스템 05. 기타 사례 및 아이디어 06. 결론 07. Q&A
  • 3. 지향점 1. 납득 가능한 기획적 명세는 가능한 모두 구현하자 생산성, 확장성, 재사용성 2. 빠르게 개발하되 코드의 품질을 일정 수준 이상으로 유지 하자 단순화, 표준화 성능, 우아함 솔루션 : 개발 역량을 높이거나 더 오래 일을 하거나 ??
  • 4. 개발 관점의 변화 추적 절차적에서 객체지향적으로 일반화된 효과적이고 유연하며, 확장성 높은 개발 추상화, 상속 fread(header, 1, len, fp); f->Read(&header, len); CreateTextureFromMemory(ptr, size, pTexture); CreateTextureFromFile(fp, &pTexture); CFileIO* f1 = CMemIO::Create(ptr, size); CreateTextureFromFile(f1, &pTexture); CFileIO* f2 = CStdIO::Open(L"checkbox.dds"); CreateTextureFromFile(f2, &pTexture); CFileIO* f3 = CHttpIO::Open(L“http://softnette.com/checkbox.dds"); CreateTextureFromFile(f3, &pTexture); #Object Oriented Programming
  • 5. 개발 관점의 변화 추적 절차적에서 객체지향적으로 재 사용성 확장성을 위한 적절한 설계가 요구됨 구성 및 설계에 따른 시행 착오와 정비로 인한 개발 지연 복잡도가 높아질수록 개발 효율이 떨어짐
  • 6. 개발 관점의 변화 추적 자료주도적으로 프로그래머 의존도 축소 개발 관점에서 생산성 향상 확장성
  • 7. 개발 관점의 변화 추적 자료주도적으로 스크립트 손쉽게 프로그램과 연동 가능 높은 유연성
  • 8. 개발 관점의 변화 추적 자료주도적으로 스크립트 스크립트 자체의 접근성 비 프로그래머가 작성한 스크립트의 품질과 오류 디버깅 이슈 활용도가 높을 수록 성능 이슈
  • 9. 개발 관점의 변화 추적 자료주도적으로 그래프 편집 비 프로그래머들도 쉽게 접근 훌륭하게 시각화된 작업 환경 손쉬운 바인딩 Quartz composer 확장성 NDC2008: 차세대 게임 개발을 위한 실시간 비주얼 그래프 편집 vvvv http://dev.ntreev.com/publications
  • 10. 개발 관점의 변화 추적 자료주도적으로 그래프 편집 개발 도구의 높은 편의성이 요구됨 기반 시스템 구축의 난이도 접근성 복잡도와 무관하게 양이 증가할수록 직관성 감소 vvvv video visualizer
  • 11. 개발 관점의 변화 추적 컴포넌트기반 시스템 객체를 컴포넌트 조합으로 구성 누구나 기능 조합 가능 다양한 구성이 가능 NDC2010:M2아키텍처리뷰 GDC Canada 2009:Theory and Practice of Game Object Component Architecture
  • 12. 개발 관점의 변화 추적 컴포넌트기반 시스템 비의존적, 독립적인 컴포넌트 제작의 난이도 개발 효율 저하 덜(?) 직관적인 코드 간접 참조의 스트레스 내부 통신으로 인한 성능 문제 GDC Canada 2009:Theory and practi…
  • 13. 개발 요구사항 일반화도 잘 되면서 구조가 단순하고, 자료주 도적이며, 다양한 기능 조합도 가능하고, 개발 스트레스 없이 빠르게 개발 가능한 방법 이 목표입니다
  • 14. 슈퍼클래스 한마디로, 하나의 클래스에서 모두 구현 모두(?) 익숙하지만 지양하고 싶은 모델
  • 15. 슈퍼클래스기반 게임오브젝트 한마디로, 하나의 클래스에서 모두 구현 모두(?) 익숙하지만 지양하고 싶은 모델 역 발상으로 다기능을 지향
  • 16. 슈퍼클래스기반 게임오브젝트 한마디로, 하나의 클래스에서 모두 구현 모두(?) 익숙하지만 지양하고 싶은 모델 역 발상으로 극단적인 다기능을 지향
  • 17. 셰이더로 보는 사례 슈퍼 셰이더 사례 (aka. UberShader) 실시간 렌더링의 패러다임 변화 고정 파이프라인에서 프로그래머블 셰이더 시대로 셰이더 시스템 렌더링에 최적화된 프로세스 유닛 단순한 구성, 대량의 프로세스 유닛 추구 동적 분기 취약 하나의 머트리얼은 하나의 셰이더 (혹은 technique)
  • 18. 셰이더로 보는 사례 조합이슈 float4 ps(PS_IN In) : COLOR { return tex2D(DiffuseMapSampler, In.Texcoord0.xy); } float4 ps_light(PS_IN In) : COLOR { return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * Lambert(In.Normal.xyz); } float4 ps_lightmap(PS_IN In) : COLOR { return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * tex2D(LightMapSampler, In.Texcoord1.xy); } technique textureonly { pass p0 { VertexShader = compile vs_3_0 vs(); PixelShader = compile ps_3_0 ps(); } } technique light { pass p0 { VertexShader = compile vs_3_0 vs(); PixelShader = compile ps_3_0 ps_light(); } } technique lightmap { pass p0 { VertexShader = compile vs_3_0 vs(); PixelShader = compile ps_3_0 ps_lightmap(); } }
  • 19. 셰이더로 보는 사례 조합이슈 그림자 기능 추가시 (두 배 증가) float4 ps(PS_IN In) : COLOR { return tex2D(DiffuseMapSampler, In.Texcoord0.xy); } float4 ps_light(PS_IN In) : COLOR { return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * Lambert(In.Normal.xyz); } float4 ps_lightmap(PS_IN In) : COLOR { return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * tex2D(LightMapSampler, In.Texcoord1.xy); } float4 ps_withshadow(PS_IN In) : COLOR { return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * ProjShadow(In.ShadowPos); } float4 ps_light_withshadow(PS_IN In) : COLOR { return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * Lambert(In.Normal.xyz) * ProjShadow(In.ShadowPos); } float4 ps_lightmap_withshadow(PS_IN In) : COLOR { return tex2D(DiffuseMapSampler, In.Texcoord0.xy) * tex2D(LightMapSampler, In.Texcoord1.xy) * ProjShadow(In.ShadowPos); }
  • 20. 셰이더로 보는 사례 조합이슈 그림자 기능 추가 스키닝 추가 (4배) 스펙큘러 마스크 (8배) 리플렉션 매핑 (16배) UV스크롤 (32배) 노멀맵 (64배) 대단한 의지가 아니면 관리가 불가능 일정 시점 이상이 되면 셰이더의 난이도와 상관없이 작업 불가능한 상태 대부분 정책적으로 기능을 제한하는 방향으로
  • 21. 셰이더로 보는 사례 조합해법 코드 생성 그래프 편집 셰이더 조합 스크립트 UberShader Unreal3 Material Editor
  • 22. 셰이더로 보는 사례 UberShader 소스 코드는 유지하고 전처리를 통해서 기능 선택 float4 ps(PS_IN In) : COLOR { float4 out = tex2D(DiffuseMapSampler, In.Texcoord0.xy); #ifdef _LIGHT out *= Lambert(In.Normal.xyz); #endif #ifdef _LIGHTMAP out *= tex2D(LightMapSampler, In.Texcoord1.xy); #endif #ifdef _SHADOW out *= ProjShadow(In.ShadowPos); #endif return out; } technique complete { pass p0 { VertexShader = compile vs_3_0 vs(); PixelShader = compile ps_3_0 ps(); } }
  • 23. 슈퍼클래스 특징 1. 요구사항을 구현함에 있어서 구조적인 부 담이 굉장히 적다 2. 쉽게 자료화 할 수 있다 3. 도구화할 수 있다 4. 표준화하여 다양한 파트에 적용할 수 있다
  • 24. 슈퍼클래스 적용 시나리오 이동하는 코드를 이용해 가상의 사례를 하나 구성해봅니다 void CActor::Move(const Vec &dv, int lv) { float t = SweepTest(m_Pos, m_Radius, dv, NULL); m_Pos += dv * t; }
  • 25. 슈퍼클래스 적용 시나리오 요구 사항 : 어떤 객체는 충돌이 없습니다 void CActor::Move(const Vec &dv) { if (m_flags&_NOCOLLISION) { m_Pos += dv; return ; } float t = SweepTest(m_Pos, m_Radius, dv, NULL); m_Pos += dv * t; }
  • 26. 슈퍼클래스 적용 시나리오 요구 사항 : 슬라이딩이 되어야 합니다 void CActor::Move(const Vec &dv, int lv) { if (m_flags&_NOCOLLISION) { m_Pos += dv; return ; } Plane p; float t = CMomo::GetInstance().SweepTest(m_Pos, m_Radius, dv, &p); if (t < 1.0f) { if (t > 0) m_Pos += dv * t; if (lv < 3) { Vec vr = dv * (1-t); float d1 = p.Distance(m_Pos) - m_Radius; Move(vr - p.Normal() * Vec::dot(vr, p.Normal()), lv+1); } return; } m_Pos += dv; }
  • 27. 슈퍼클래스 적용 시나리오 요구 사항 : 슬라이딩 안 하는 객체도 있어요 void CActor::Move(const Vec &dv, int lv) { if (m_flags&_NOCOLLISION) { m_Pos += dv; return ; } Plane p; float t = CMomo::GetInstance().SweepTest(m_Pos, m_Radius, dv, &p); if (t < 1.0f) { if (t > 0) m_Pos += dv * t; if ((m_flags&_SLIDING) && lv < 3) { Vec vr = dv * (1-t); float d1 = p.Distance(m_Pos) - m_Radius; Move(vr - p.Normal() * Vec::dot(vr, p.Normal()), lv+1); } return; } m_Pos += dv; }
  • 28. 슈퍼클래스 적용 시나리오 요구 사항 : 바닥에만 슬라이딩하게 해주세요. 바운딩도 필요합니다. 슬라이딩시 마찰력을 적용해주세요. 단, 무적상태가 아닐 때 만. 충돌할 때 이벤트를 발생시켜 주세요. 대미지 중 이동할 때는 충돌 지점에 파티클 좀 뿌려 주세요. 단,캐릭터가 HP10%이하인 경우만….
  • 29. 슈퍼클래스 적용 시나리오 요구 사항 : 바닥에만 슬라이딩하게 해주세요. 바운딩도 필요합니다. 슬라이딩시 마찰력을 적용해주세요. 단, 무적상태가 아닐 때 만. 충돌할 때 이벤트를 발생시켜 주세요. 대미지 중 이동할 때는 충돌 지점에 파티클 좀 뿌려 주세요. 단,캐릭터가 HP10%이하인 경우만…. NO PROBLEM
  • 30. 슈퍼 클래스기반 프로그래밍의 장단점 장점 1. 구조적으로 큰 부담 없이 기존코드를 유지하면 서 새로운 기능 추가 가능 기능 코드만 추가하고 객체를 생성할 때 선택적으로 해당 기능을 set 시켜주기만 하면 끝 2. 쉽고 단순하고 직관적 단점 1. 코드가 조잡해지는 느낌 2. 하드코딩 하는 느낌
  • 31. 인식의 전환 코드가 조잡해 보인다 어떤 식으로 구성하더라도 결과적으로 핵심 구현 로직이 다른 코드일까 현재 코드의 쾌적함을 위해 기획자와 명세를 협상 하고 있는 건 아닌지 성찰해봅니다 “우리는 바닥에서만 슬라이딩은 불가능합니다. 끝” 약간 심적인 부담이 있겠지만 쿨~하게 구현해 주 는 것이 완벽한 프로그래머보다 멋진 프로그래머 솔루션 : 심리적인 해결. “조잡해 보이는 건 명세 탓!! 하지만 로직을 단순하고 멋지게 유지하는 것보다는 명세가 우선이다”라고 암시 암시 암시
  • 32. 인식의 전환 하드 코딩 같아 보인다 일관성을 유지하면서도 관리가 가능하게 작성된 코드라면 하드코딩과 다르다 (암시) if (m_Type == _WOLF && m_HP <= 10) PlaySound(L"아파"); if ((m_Flags&_HURT_SOUND) && m_HP <= m_HurtsAlramHP) PlaySound(L"아파"); void CGameRoom::LeaveRoom(CSession* session, bool graceful) { if (!IsLobby()) NotifyLeaveMessage(session); if (IsDungeon() && graceful == false) session->ExitPenalty(); } void CGameRoom::LeaveRoom(CSession* session, bool graceful) { if (m_flags&_NOTIFY_LEAVE) NotifyLeaveMessage(session); if ((m_flags&_EXIT_PENALTY) && graceful == false) session->ExitPenalty(); }
  • 33. 슈퍼클래스화 하나의 클래스에 기능을 통합 인스턴스 생성시 기능 선택
  • 34. 자료화 자료 주도적으로 개발하려면 필수 슈퍼 클래스 구성 요소 기능 리스트 기능에 필요한 속성 컴포넌트기반 오브젝트 시스템과 유사
  • 35. 자료화 단순한 계층의 XML(혹은 jason)로 쉽게 표현가능 <actor> <player mask="_UPDATE,_RENDER,_GRAVITY,_USERCONTROL,_CHECKEVENTBOX,_MOUSEACTION"> <pos>0 15</pos> <radius>0.5</radius> </player> <helper mask="_UPDATE,_RENDER,_STATIC"> <pos>0 2</pos> <radius>0.4</radius> <color>ffffff00</color> <name>helper</name> </helper> <camera mask="_UPDATE,_CAMERA,_NOCOLLISION"> <pos>0 10</pos> <follow>player</follow> </camera> </actor>
  • 36. 도구화 기능 리스트 (on/off/enum) 기능이 set 되었을 때 필요한 속성/에디터객체 1 2
  • 37. 도구화 기능명시 <particlemask type="propertysheet" minheight="75" height="25%" headervisible="false"> <shape text="형태"> <_SHAPE text="타입" type="enum" items="빌보드;트레일;메시">랜덤</_SHAPE> <_COLOR text="색상" type="enum" items="상수;보간;화이트">화이트</_COLOR> <_ALPHA text="알파" type="enum" items="없음;상수;보간">없음</_ALPHA> <_SIZE text="크기" type="enum" items="기본;랜덤;랜덤보간">기본</_SIZE> <_ROTATE text="회전" type="enum" items="없음;상수;랜덤">없음</_ROTATE> </shape> <lifetime text="생성"> <_DELAY text="생성지연" type="enum" items="없음;상수;랜덤;순차적">없음</_DELAY> <_LIFETIME text="라이프타임" type="enum" items="상수;랜덤">랜덤</_LIFETIME> </lifetime> <position text="위치"> <_POSITION text="생성위치" type="enum" items="원점;랜덤구">원점</_POSITION> <_VELOCITY text="속도" type="enum" items="없음">없음</_VELOCITY> <_DIRECTION text="방향/목표" type="enum" items="없음;랜덤구;목표지점">없음</_DIRECTION> <_GRAVITY text="중력" type="bool">false</_GRAVITY> </position> <parameters type="propertysheet" height="100%"> <general text="일반" mask="default"> <COUNT text="생성갯수" type="int" min="1" singleStep="5">10</COUNT> <LOOP text="반복" type="bool">false</LOOP> <BLEND text="블랜딩" type="enum" items="알파블랜딩;가산;곱하기">가산</BLEND> </general> <billboard text="빌보드" mask="_SHAPE=빌보드"> <TEXTURE text="texture" type="texture">check.bmp</TEXTURE> </billboard> <randomlifetime text="라이프타임" mask="_LIFETIME=랜덤"> <LIFETIME_MIN text="min" type="float" min="0" singleStep="1">5</LIFETIME_MIN> <LIFETIME_MAX text="max" type="float" min="0" singleStep="1">10</LIFETIME_MAX> </randomlifetime> <constlifetime text="라이프타임" mask="_LIFETIME=상수"> <CONSTLIFETIME text="lifetime" type="float" min="0" singleStep="1">5</CONSTLIFETIME> </constlifetime> <constcolor text="색상" mask="_COLOR=상수"> <CONSTCOLOR text="색상" type="color">ffffff</CONSTCOLOR> </constcolor>
  • 38. 도구화 기능간의 관계 기능 간의 관계를 데이터 상에서 검증 <shading text="셰이딩"> <_NO_LIGHTING text="셰이딩안함" type="bool">false</_NO_LIGHTING> <_USE_SPECULAR text="스펙큘러채널" type="bool" enabletest="!_NO_LIGHTING">false</_USE_SPECULAR> <_RIMLIGHTING text="림라이트" type="bool" enabletest="!_NO_LIGHTING">false</_RIMLIGHTING> </shading>
  • 39. 도구화 클래스화 많은 기능 중에서 클래스에 필요한 기능한 툴 상에 서 표시 클래스는 데이터로만 존재
  • 40. 슈퍼클래스기반 게임오브젝트 극단적인 사용 안을 제안합니다 게임 객체를 하나의 오브젝트 타입으로 구성 모든 게임 객체는 Actor 데이터에 의해서만 기능 set / reset 단순한 구조 신입도 알 수 있어요 Note) 현재 이 구조로 프로젝트 진행하고 있습니다 (소프트네트)
  • 41. 슈퍼클래스기반 게임오브젝트 Actor(SuperActor) 모든 기능을 구현 모든 객체는 길 찾기, Head tag, 동기화 등을 맘대로 활용 가능 기능 추가하고 데이터 연동만 해주면 OK (신입도 할 수 있어요) 재사용성 Better (vs ObjectOrientDesign) “아이템 사라질 때 mob 사라질 때처럼 해주시면 안되나요 ?” “Re:그렇게 하세요” 직접 참조 OK (vs Component-based, OOD) 메시 모델의 손의 위치를 사운드 출력 부에서 직접 참조 카메라 객체에서 플레이어의 머리본의 TM을 직접 참조 빠르고 직관적
  • 42. 슈퍼클래스기반 게임오브젝트 SuperActor “구현부가 너무 비대해지지 않을까요 ?” 구현부를 적절히 컴포넌트화한다면 납득할 수준으로 관 리가 가능 각 컴포넌트는 계층적이지 않기 때문에 단순하게 구성가 능 (일반화의 제약도 없음) 다만 과도하게 컴포넌트화하고 정리를 하는 것보다는 관리 가능한 수준에서 느슨하게 처리하는 것을 추천
  • 43. 슈퍼클래스기반 게임오브젝트 SuperActor “일일이 비트 검사하면 속도상 불이익이 있지 않을 까요 ?” 구현은 트리 구조를 이루게 됨 그룹단위로 체크해서 최 상위에서 skip 하도록 점프는 이동 하위에, 2단 점프는 점프 하위 좀 더 도전적으로 DOD로 확장가능(슈퍼클래스기 반 파티클 참조) #Data Oriented Design http://www.lameproof.com/zboard/zboard.php?id=bbs2&no=790
  • 44. 슈퍼클래스기반 게임오브젝트 SuperActor “그럼 모든 속성도 가지고 있다는 건데, 메모리 낭 비가 심하지 않을지요” (필요한 경우 heap으로) template <class _Tx> class CValuePtr { public : CValuePtr() { m_Ptr = NULL; } ~CValuePtr() { if (m_Ptr != NULL) delete m_Ptr; } _Tx* operator-> () { if (m_Ptr == NULL) m_Ptr = new _Tx; return m_Ptr; } private : _Tx* m_Ptr; } ; class CActor { private: struct _DIALOG { _DIALOG() { Shape = NULL; } ~_DIALOG() { if (Shape) delete Shape; } float OpenStep; Sphere* Shape; value = *node.FindChild(L"dialog_offset"); float Offset[2]; swscanf_s(value, L"%f %f", &m_Dialog->Offset[0], &m_Dialog->Offset[1]) }; value = *node.FindChild(L"dialog_size"); CValuePtr<_DIALOG> m_Dialog; m_Dialog->Shape = new Sphere(Vec(0, 0), unicode::atof(value), 14); } ;
  • 45. 슈퍼클래스기반 게임오브젝트 슈퍼 클래스 기반 게임 오브젝트 장점 단순한 구조로 빠른 개발이 가능 기능 추가가 용이하며 많은 코드 공유 가능 소규모 여러 프로젝트에서 공유 가능 사이드뷰 액션 게임과 TPS, 스포츠 게임이 같은 프로젝트 코드 관리 용이성 데이터 검증으로 dead code 판단 가능 Legacy code를 유지하면서 방어적으로 기능 교체
  • 46. 슈퍼클래스기반 게임오브젝트 슈퍼 클래스 기반 게임 오브젝트 장점 툴 연동 가능 툴에서 필요한 기능만 활성하면 툴 상에서 인터렉션 가능 툴 내 게임 플레이도 가능 생산성 향상
  • 48. 슈퍼클래스 기반 파티클 하나의 파티클 객체에서 모든 기능을 구현 표준화된 도구사용 절차 1. 데이터를 읽어서 사용되는 기능과 툴에서 세팅한 값들을 저장 2. 파티클 인스턴스 생성시 인스턴스에 초기값 세팅 3. 파티클 업데이트
  • 49. 슈퍼클래스 기반 파티클 생성 지연시간 예 void CParticle::InitParticle(void *data, int count) const { for(int i=0; i<count; i++) { _PARTICLE* ptr = (_PARTICLE*)((char*)data + m_Pitch * i); char * extra = (char*)ptr + sizeof(_PARTICLE); if (m_InitMask&_DELAY_CONST) { ptr->curTime = - *(const float*)GetParam(_I_DELAY_CONST); } else if (m_InitMask&_DELAY_RANDOM) { const float* delayrandom = (const float*)GetParam(_I_DELAY_RANDOM); ptr->curTime = - Random(delayrandom[0], delayrandom[1]); } else if (m_InitMask&_DELAY_SEQ) { ptr->curTime = - *(const float*)GetParam(_I_DELAY_SEQ) * i; } else { ptr->curTime = 0; }
  • 50. 슈퍼클래스 기반 파티클 업데이트 예 비트 연산으로 기능 체크해서 구현 bool CParticle::Update(float dt, void * data, int count, unsigned long updatemask) const { for(int i=0, off=0; i<count; i++, off+=m_Pitch) { _PARTICLE* p = (_PARTICLE*)((char*)data + off); p->curTime += dt; char * extra = (char*)p + sizeof(_PARTICLE); if (updatemask&_COLOR_BLEND) { unsigned long* blendcolor = (unsigned long*) GetData(extra, _U_BLENDCOLOR); p->color = LerpColor(blendcolor[0], blendcolor[1], p->curTime / p->lifeTime); } if (updatemask&_GRAVITY) { Vec3* vel = (Vec3*) GetData(extra, _U_VELOCITY); *vel += Vec3(0, -9.8f, 0) * dt; // 중력 } if (updatemask&_VELOCITY) { const Vec3* vel = (const Vec3*) GetData(extra, _U_VELOCITY); p->pos += (*vel) * dt; }
  • 51. 슈퍼클래스 기반 파티클 메모리 문제 오프셋 테이블을 이용하여 최소의 용량만 사용 기능상 필요한 데이터만 할당
  • 52. 슈퍼클래스 기반 파티클 성능 문제 분기문(if)로 인한 제어 해저드 대량의 연산이 이루어지기 때문에 성능을 고려할 때는 민감한 사안 #control hazard
  • 53. 슈퍼클래스 기반 파티클 성능 문제 해법#1 자료지향설계(DOD) bool CParticle::Update(float dt, void * data, int count, unsigned long updatemask) const { _PARTICLE* p = (_PARTICLE*)((char*)data + off); int i; for(i=0; i<count; i++) p->curTime[i] += dt; if (updatemask&_COLOR_BLEND) { unsigned long* blendcolor = (unsigned long*) GetData(p, _U_BLENDCOLOR); for(i=0; i<count; i++) p->color[i] += LerpColor(blendcolor[i*2+0], blendcolor[i*2+1], p->curTime / p->lifeTime); } if (updatemask&_GRAVITY) { Vec3* vel = (Vec3*) GetData(p, _U_VELOCITY); for(i=0; i<count; i++) vel[i] += += Vec3(0, -5.0f, 0) * dt; } if (updatemask&_VELOCITY) { const Vec3* vel = (const Vec3*) GetData(p, _U_VELOCITY); for(i=0; i<count; i++) p->pos[i] += vel[i] * dt; }
  • 54. 슈퍼클래스 기반 파티클 성능 문제 해법#2 컴파일러 마법 도달하지 않는 코드, 상수연산은 제거됨 #include <windows.h> inline void update(unsigned long mask) { if (mask&1) ::Sleep(0xFF); if (mask&2) ::Sleep(0xF); } void main() { unsigned long mask = rand(); update(mask); update(2); }
  • 55. 슈퍼클래스 기반 파티클 성능 문제 해법#2 컴파일러 마법 많이 호출되는 타입은 아래처럼 bool CParticle::Update(float dt, void * data, int count) const { if (m_UpdateMask == (_COLOR_BLEND|_GRAVITY|_VELOCITY)) return Update(dt, data, count, _COLOR_BLEND|_GRAVITY|_VELOCITY); else if (m_UpdateMask == _COLOR_BLEND) return Update(dt, data, count, _COLOR_BLEND); return Update(dt, data, count, m_UpdateMask); } 해당 기능만 실행하는 코드 생성 BEST
  • 56. 슈퍼클래스 기반 파티클 슈퍼클래스 기반 파티클의 장점 다양한 조합의 파티클 손쉬운 도구 연동 이펙트 디자이너의 요구를 빠르게 반영 가능 바로 구현 후 데이터 연동만 해 놓으면 OK “호혹시 파티클이 회오리 모양의 경로로 움질일 수 있을 까요?” “네 만들어 드리겠습니다” 빠른 연산 시스템이 단순하여 병렬화나 메모리 친화적인 다양한 최 적화가 가능
  • 57. 슈퍼클래스 기반 유저 인터페이스 시스템 컴포넌트의 예외적인 명세 포스트 프로세싱 / 모션 컨트롤 자료 주도적인 구성 셰이더 , 셰이더 변수, 블룸, 렌더 타겟,… 조합으로 패스 정의 여러 패스
  • 58. 슈퍼클래스 기반 서버 일반적인 서버 구성 게임의 성격에 맞도록 서버를 구성 기본 모듈을 공유하는 서로 다른 프로젝트로 예상 게임테크 2010:Extracting MMORPG Server Engine from TERA
  • 59. 슈퍼클래스 기반 서버 슈퍼 클래스 기반의 서버 구성 서버는 한 종류 데이터에 의해서 기능 명세
  • 60. 슈퍼클래스 기반 서버 슈퍼 클래스 기반의 서버 구성 서버는 한 종류 데이터에 의해서 기능 명세 다기능 서버 게임 성격과 서비스 상황에 맞도록 세팅 인증+필드, 인증+던전, 던전 인증+던정,필드 … 기능 단위보다는 지역, 처리 유저 수 기준
  • 61. 슈퍼클래스 기반 서버 클라이언트와 코드 공유 클라이언트의 게임 객체를 서버에서도 사용 필요한 기능만 활성 가능하도록 제한 “길 찾기 따로 만들어야 되나요 ?” “클라이언트에서 구현한 AI캐릭터를 서버에서 사용할 수 없나요 ?” “서버용 데이터 안 만들고 애니메이션 이벤트 검증할 수 있나요?” NO PROBLEM 정책적으로 클라이언트, 툴, 서버에서 게임 객체 공유 (소프트네트)
  • 63. 결론 슈퍼 클래스를 이용하면 구조적인 복잡도가 낮아 직관적으로 구성 가능 단순한 구조로 설계 및 관리의 스트레스에서 해방 구현에 좀 더 집중 가능하며 개발 속도 개선 도구를 이용하여 프로젝트 개발 속도 개선 코멘트 : 우아하고 섹시하진 않지만 합리적으로 검토해 볼만 한 아이디어 슈퍼클래스, 상태 머신, 스크립트 3S 삼총사면 무서울 게 없습니다