게임 소프트웨어 공학/캐릭터 출발

Posted at 2009/04/30 15:13// Posted in gamedev
1. 액터 찾기: 기능 모델링
&호스트 유저&는 -키보드:방향키-> 를 사용해 |게임|내 (호스트 플레이어를 움직인다)

2. 유스 케이스 찾기: 동적 모델링
&호스트 유저&는 -키보드:방향키-> 를 사용해 |게임|내 (호스트 플레이어를 움직인다)

3. 유스 케이스 시나리오 작성: 동적 모델링
  1. 호스트 유저는 키보드의 방향키를 누른다
  2. 호스트 플레이어의 이동 방향은 현재 카메라 시점이 적용되어 결정된다.
  3. 호스트 플레이어의 목표 이동 거리는 네트워크를 고려해 적당한 거리가 선정된다.
  4. 호스트 플레이어는 이동 애니메이션이 재생한다
  5. 호스트 플레이어의 이동 애니메이션이 시작되면 서버로 이동 패킷을 보낸다
  6. 호스트 플레이어의 이동 방향으로 목표 이동 거리 만큼 이동한다.
  7. 현재 카메라 시점이 변경되면 호스트 플레이어의 이동 방향을 바꾸고 서버로 이동 패킷을 보낸다.
  8. 호스트 플레이어의 이동한 거리가 목표 이동거리보다 많으면 멈추고 서버로 도착 패킷을 보낸다.
4. 유스 케이스 시나리오 예외
  • 사망중 출발 못함
  • 다운중 출발 못함
  • 공격중 출발 못함
  • 스킬중 출발 못함
  • 스턴중 출발 못함

5. 유스케이스 사건 추적도

호스트 유저       게임 시스템     리모트 서버
    |                  |              |
    | - 방향키 누름 -> |                      |
    | <- 이동 애니 --  | - 이동 패킷 -> |
    | <- 위치 이동 --  |                      |
    | - 카메라 조작 -> |                      |
    | <- 방향 변경 --  | - 이동 패킷 -> |
    | <- 목표 도착 --  | - 도착 패킷 -> |

헉헉-_-
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/04/30 15:13 2009/04/30 15:13
다음은 Window 시스템의 전형적인 모양이다.


class Window:
def __init__(parent):
"생성시 부모에 자신을 추가한다"
self.parentRef = ref(parent) # 부모-자식간 재귀 레퍼런스 방지
self.children = []

if parent:
parent._AppendChild(self) # 부모가 있다면 자식으로 추가한다.

def Close(self):
"닫기: 부모로부터 자신을 제거한다"
parent = self._GetParent()
if parent:
parent._RemoveChild(self)

def _AppendChild(self, child):
"자식을 추가한다"
self.children.append(child)

def _RemoveChild(self, child):
"자식을 제거한다"
self.children.remove(child)


복잡한 형태라도 윈도우 구조를 사용하면 간편하게 구현된다.

꽤나 복잡한 형태의 윈도우 조합 중 하나가
퀵 스킬 아이콘 슬롯였는데...

생각외로 의외로 복잡하다.

1) 일단 아이콘이 보여야 하고
2) 버튼처럼 선택이 되어야 하며
3) 쿨타임 애니메이션을 보여줄 수 있어야 하고
4) 쿨타임이 끝나면 번쩍하는 애니메이션이 나오며
5) 버프 스킬이라면 사용중이라는 애니메이션을 보여주어야 하고
6) 토글 스킬이라면 토글OFF 상태애니메이션과 토글ON 상태 애니메이션을 구분해서 보여주어야 한다.

실제로는 좀더 많은 기능이 있지만
비주얼적인 특성은 이러하다.

만드는 방법은 두가지이다.
1)  모든 기능을 포함한 새로운 컨트롤을 만든다.
2)  기존에 만든 컨트롤을 조합해서 만든다.
지금까지는 Window 구조를 사용해서 2번식으로 만들어왔다.


class QuickSkillSlot(Window):
def __init__(self, parent):
Window.__init__(self):
self.iconBox = IconBox(self)
self.button = Button(self)
self.coolTimeAniBox = AniBox(self)
self.usableAniBox = AniBox(self)
self.usingAniBox = AniBox(self)
self.toggleOnAniBox = AniBox(self)
self.toggleOffAniBox = AniBox(self)


아-_- 아름다워라...

지금까지는 윈도우 트리 구조를 사용해서 바로 렌더링했기 때문에
별 문제가 없었다.

문제는 최근 겜브료의 프레임 렌더링 시스템으로 포팅하면서 발생했다.
사실 게임에 있어 복잡한 부모-자식 구조는 그닥 필요한게 아니다. 맞는말이다.
렌더링 관점에서만 보면 하나의 화면 뷰에 화면 요소 목록만 있는 것이 렌더러 입장에서는
제일 단순하며 아름답다. 화면 뷰순서 바꾸는 정도면 충분한 배려라고 볼 수 있다.

그렇다면 어떻게 이 둘의 구조를 만족시킬 수 있을까?

물론 해답은 명백했다.
루트 윈도우 바로 아래에 있는 메인 윈도우들은 화면뷰로 만든다.
메인 윈도우는 아래 자식들을 탐색해 화면 요소 리스트를 뽑아내 등록하면 된다.

말은 쉬운데...
왜 막상 코딩에 들어가면 잘 안되는 것인지... orz;


그래서 머리속 생각을 정리해보기로 했다.

가장 무식한 구현은 간단하다.
매 프레임마다 모든뷰를 지우고 화면 뷰와 그에 따른 화면 요소 리스트를 구축하는 것이다.
하지만 모든 윈도우를 탐색하는건 매프레임하기에는 너무 부담된다.

두번째 방법-_- 흠...
루트 윈도우에 등록되는 녀석들은 화면 뷰를 만든다.
그 자식들에게 화면뷰를 모두 전달해 각자의 화면 요소들을 등록시킨다.
만약 자기가 제거된다면 화면뷰에서 자신이 갖고 있는 화면 요소들을 제거한다.

웃 -_-); 왠지 그럴싸한데...

일단 구조만 잡아본 프로토타입~~

more..



이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/04/02 13:17 2009/04/02 13:17

클라이언트 자동화 테스트에 대해

Posted at 2009/03/29 18:34// Posted in gamedev
프로그램에는 많은 버그들이 살고 있습니다.
버그들을 제거하기 위해서는 테스터가 필요합니다.
하지만 프로그램의 모든 기능을 비롯해 지금까지 나온 모든 버그들을 완벽하게
점검해주는 건 쉬운 일이 아닙니다.

그러므로 프로그래머에겐!
프로그램을 자동으로 테스트해주는 로봇이 필요합니다!

메이드 복을 입은 로봇 커피도 타주고 밥도 타다주고 하면서
프로그램 테스트를 해준다면 더욱 좋겠지만...
이건 미래의 목표로 남겨두기로 하고...

내 옆에 놀고 있는 고물 X노트 노트북이
내가 일하고 있는 사이 프로그램 테스트를 해준다면
버그로 인한 노화 걱정을 덜 수 있을겁니다.


테스트 로봇의 필요성은 알고 있지만...
그것을 만드는 일은 쉬운 일이 아닙니다.

물론 입력후 바로 출력을 토해내는 다음과 같은 프레시맨 코드라면

def plus(a, b):
return a + b

assert(plus(3, 5)==8)

쉬울지도 모르겠습니다만...;

아이디에 "빗자루"를 입력하고, 비밀번호에 "하하하"를 입력한다음
로그인 버튼을 눌러 비밀번호가 틀렸다고 나오는지를 확인해라.

위와 같은걸 만들려면 좀 정신이 멍해집니다.

첫번째 이유는 GUI 때문이라고 생각됩니다. 로그인 버튼이 어딨는지 모르니 -_-)>
하드 코딩으로 좌표를 찍는 구닥다리 MMORPG 로봇 방식이라면 UI 디자이너가 아웃라인을 바꿔버리는 순간 미칠듯한 테스트 실패 에러를 보게 될겁니다. 이렇게 되면 하기 싫어지겠죠.

아! 버튼이미지를 화면상에서 찾아 클릭하는 방법은 어떨까요?
테스트 실패 에러 역시 스크린샷으로 대조하고?

... 직업으로 MMORPG 로봇을 만드는 일을 하고 있다면 도전해볼만 하겠습니다만...
자기가 작성한 프로그램을 저렇게 테스트하다가는 지쳐버릴겁니다.

두번째 이유는 위의 작업이 넌블럭 작업이라는 겁니다.
책에서 나오는 대부분의 테스트 코드는 입력후 즉시 결과가 나오는 블럭 방식이더군요.
하지만 위의 형태는 로그인 버튼을 누르고 한참후에 비밀번호가 틀렸다는게 나옵니다.
함수 호출후 결과값 비교하는걸로 안된다는거죠.

경우에 따라서는 로그인 버튼을 누르는 과정 자체가 메시지일수도 있습니다.


아아 차라리 서버 프로그래머면 쉬울텐데 ... orz;

어-_-)? 가만... 서버는 왜 쉽지?

서버는 그냥 텍스트 기반 프로토콜 쓴 다음에 테스트용 더미 클라이언트를 만들면 끝이기 때문이죠.


client = Client()
assert(client.Test("login 빗자루 하하하", "wrong_password"))



웃 -_-)!

생각해보니 테스트용 더미 서버를 만들면 되겠더군요.

1. 클라이언트 실행시 바로 테스트용 서버에 접속합니다.
2. 클라이언트에서 발생한 로그는 모두 테스트 서버로 보냅니다.
3. 테스트 서버에서는 클라이언트에 무슨일을 하라는 명령을 보냅니다.
4. 클라이언트는 서버에서 받은 명령을 수행합니다.

와하하 -_-)/ 잘 될지는 모르겠지만... 한번 도전해봐야겠습니다.






이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/03/29 18:34 2009/03/29 18:34

으햐햐 ~(-_-)~ 겜브료 터레인~

Posted at 2009/02/21 17:16// Posted in gamedev
이틀동안의 삽질끝에
터레인을 지원하면서도 달랑 레이어 4장만 되는
겜브료 악랄한 기능을 수정해서 8장까지 확장했습니다.

첫날은 소스 백업안하고 진행하다가 잘못 건드리는 바람에 쉐이더 컴파일 에러로 실패-_-
둘째날은 전날의 실패를 교훈삼아 SVN 으로 등록한 다음 어제 수정한 코드를 하나씩 넣어가면서
작업한 끝에 ... 블렌드맵 설정에 아주 작은 실수로 인해 8시간 정도 디버깅(-_-) 노력을 제물삼아
드디어 기술적인 구현에 성공했습니다. >ㅁ< 꺄햐햐

겜브료측에서 1년이나 질질끌면서 수정을 안해주던 부분인지라..
뭔가 완전 꼬였나 생각했는데...; 놀랍게도(!) 거의 다 코딩이 되어있더군요 -_-
투자한 48시간에 비해 수정한 코드가 20줄 정도랄까요
(좀 허망한 생각이... orz; )

...

아마 제 생각으로
프로그래머는 다 작업해놓고 런칭하려는데~

QA 쪽에서 4 레이어 베이스+디테일+노말+패러럴 해서
텍스쳐 16장 혼합이  하드웨어 최소 조건이므로
8 레이어로 확장하게 되면 실행이 안될수도 있다.
그러므로 일단 4레이어로 가자 라는 식으로 막아놓은 듯 합니다.

이해가 안가는 것은
겜브료 자체가 노드 결합 쉐이더 생성 방식인지라...
게임 개발사가 엄한 짓만 안하면 문제가 없거든요 -_-)r
사실 노말맵 잘쓰기도 어려워 아예 제끼고 있는 상황인데 orz;;
그냥 주의해서 사용하라고 하지 TㅁT)

...

어쨌든 저 기술적인 구현을 작업자들도 쓸수있게하려면
오늘부터는 c# 의 세계에 빠져야 하는데-_-
하아...

python 쓰다가 c# 보니 뭐라 말이 안나오네요.
... (-- ); 문법도 지저분하고... 연동도 지저분하고... 코드도 지저분하고...

c# 에서 c++ DLL 디버깅이 안되서 고생했는데...
http://lohengrin.egloos.com/1787447 의 글을 보니
옵션/디버그/비관리 코드 디버깅을 체크해주면 작동하네요 ~(-_-)~


ps.
작년 12월에 자료실에 올라온거 보니 겜브료에 python 바인등을 하고 있는것 같드라구요
느무느무 좋은것 같아요 ㅋㅋ

불과 며칠전에 NiPointer - swig 연동하느라 고통받았던거만 빼면 말이죠 - _-)y- ~
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/02/21 17:16 2009/02/21 17:16

게임 개발 폴더 구조

Posted at 2009/02/05 18:54// Posted in gamedev
== 개발 폴더 구조 ==
*dev/
*dev/bin/ 소스 컴파일 결과물
*dev/src/ 소스
*dev/res/ 리소스
*dev/script 스크립트
*각종DLL

== 테스트 폴더 구조 ==
*test/
*test/bin/ 소스와 스크립트 컴파일 결과물
*test/res/ 리소스
*error_reporter.exe 에러 리포터
*각종DLL

== 라이브 폴더 구조 ==
*live/
*live/bin/ 소스와 스크립트 컴파일 결과물
*live/pack/ 리소스 패키징 결과물
*patch.exe 패치
*patch.ver 패치 버전
*patch_restarter.exe 패치 업데이트를 위한 재실행 프로그램
*error_reporter.exe 에러 리포터
*각종DLL

이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/02/05 18:54 2009/02/05 18:54

게임 제작 필수 요소에 대해서 ~(-_-)~

Posted at 2009/01/29 19:37// Posted in gamedev
게임을 만들기 시작한것도 이제 어언 만 10년이 지난것 같습니다
- _-)y- 하아

...

요즘 프로그래밍을 하다보면
유행이 돌고 돈다고 하는 것처럼 ~(-_-)~
왠지 10년전 만들었던 루틴을 또 만들고 있는 듯한 느낌이 들때가 있습니다.

물론 한번 만들어본거라
다시 만드는건 큰 문제가 되지 않지만
뭔가 빠진 듯한 생각이 드는 경우가 많네요.

왠지 예전에 했던 신선한 생각 하나하나를 잊어버리는게
좀 아까운것 같아 지금 부터라도 정리를 남겨놓으려고 합니다.

~(-_-)~ 햐햐





이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/01/29 19:37 2009/01/29 19:37

게임 배경 그래픽 분석 블로그

Posted at 2007/06/02 21:56// Posted in gamedev
http://blog.naver.com/blue9954?Redirect=Log&logNo=50005604167

장문의 글을 썼으나; 사라져서 링크만 남김-_-;
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/06/02 21:56 2007/06/02 21:56

게임 엔진 선정 작업중

Posted at 2007/04/13 13:52// Posted in gamedev
원래는 이전에 만들었던것에 추려서 해보려고 했습니다만...

유지 보수 작업에 ...;
결혼 준비에...;

정신이 없다보니... = =)~;
진도가 잘 안나가더라구요.
베이스 부분은 반년정도 집중해서 코딩하고
다시 일년정도 실제 작업들어가면서 정리해야하는데
과연 나에게 그만한 시간이 주어질까라는 생각이 문득 들더군요 (-_-);

공개 엔진부터 상용 엔진을 두루두루 살펴보고 있는중입니다.

공개 엔진의 경우에는 민기군이 좋다고 한 nebula2 device 와 ogre 를 살펴보았는데...
nebula2 의 경우 개념이나 python 에 대한 전폭적인 지원같은건 참 좋더군요.
SVN checkout 다운로드도 신선하고;
wxPython 을 이용한 빌더도 괜찮더라구요.
컴파일을 싹 하고 ~(-ㅁ-)~ 튜트리얼 실행도 완료!

그. 런. 데.
문제는 내장된 튜트리얼 2개 외에는 (-_-); 예제를 찾아볼수가 없더군요.
레퍼런스만 가지고 코딩하는건가 ... 한 일주일 틈틈히 검색했지만
다들 "헤헤-_- 그런거 없어. 알면서 *-ㅂ-*)~" 라는; 글만 검색...;

ogre 의 경우는 꽤 놀랐습니다. 인스톨 설치도 지원하고요;
예제가 상당히 많더군요. 튜트리얼 사이트도 여러개이고....
신그래프 기반에 소스도 깔끔하더라구요.

신그래프하니 예제에 잠깐 다뤄봤던 겜브료가 생각나더군요.
그것도 참 괜찮았지라는 생각이 들면서 이것저것 확인해보는 중입니다.
일단 미들웨어로 쓰기에 적당한 가격에 모양은 괜찮은데...

단점이라면 너무 툴에 의존적인거랄까요;
그렇다고; 맥스 완전 그대로도 아니고= =);
맥스 파티클은 흑흑 = =); 이라는 그래픽 아저씨들 이야기도 있고...
쓰다보니 그래니도 쓰기는 귀찮아도 애니메이션 하나는 죽이는데라는 생각도 들고 흑흑 T_T);
( ... 그래니는 예제랑 하드웨어 지원만 좀더 신경써주면 잘팔릴텐데 말이죠; ... )

요즘 인기 있는 모 엔진은; 거의 로열티 받게다는 생각인것 같던데...
뭐; 돈을 못 벌면 그만이지만...; 돈 벌 경우에는 상당히 문제가 복잡해진다는걸 아는지;
다들 엄청난 가격에 로열티없이 구입하는건지 궁금하더라구요. -_-)~ 냠냠

이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/04/13 13:52 2007/04/13 13:52
준비물
게임을 만들때 가장 먼저 만들어야 할것은 기본적인 뼈대 입니다.

이걸 앞으로 GameFrameWork 라고 부르도록 하겠습니다 ~(-_-

class GameFrameWork
{
};


GameFrameWork 가 갖추어야할 가장 중요한 요건은 플랫폼 독립적이어야 합니다. 플랫폼 독립적으로 만들면 리눅스나 맥, XBOX, PS 등에서 돌릴 수 있다는 장점이 있습니다. 설령 여러가지 플랫폼을 지원할 생각이 없다할지라도 게임을 만드는 과정에 수많은 예제나 테스트 유닛을 만들어야 하는데 그때마다 윈도우를 만들고 DirectX 를 초기화하는 일은 매우 귀찮은 일이므로 가능하면 플랫폼 의존적인 요소를 안보이게 해두는 것이 좋습니다.

게임 프레임 워크에 필요한 요소를 간단히 생각해보면
  • 시작
  • 몸통

이렇게 3가지로 나누어질 수 있습니다.

실제 돌아가는 로직을 구현해보면...

class GameFrameWork
{
public:
    void Run()
    {
        if (__Startup())    // 시작
        {
            __MainLoop();   // 몸통
        }
        __Cleanup();         // 끝
    }
    ... 생략 ...
};

이런 느낌이죠 ~(-_-)~

게임을 시작하고 나서 캐릭터를 만들고 움직이고 종료하는 일은 프레임 워크 외부에서
지정해주어야 하므로 __OnStartup, __OnIdle, __OnCleanup 을 미리 만들어 둡니다.

class GameFrameWork
{
public:
    void Run()
    {
        if (__Startup())
        {
            __MainLoop();
        }
        __Cleanup();
    }

protected:
    virtual bool __OnStartup()
    {
        return true;
    }
    virtual void __OnIdle()
    {
    }
    virtual void __OnCleanup()
    {
    }


private:
    bool __Startup()
    {
        return __OnStartup();
    }
    void __Cleanup()
    {
        __OnCleanup();
    }
    void __MainLoop()
    {
        __OnIdle();
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    GameFrameWork test;
    test.Run();
    return 0;
}


게임 프레임 워크 일차 완료입니다~
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/04/08 14:45 2007/04/08 14:45
Tag