2019년 3월 3일 일요일

[20190303] A lot of work

경사로운 3.1 절 100주년을 보냈습니다.
어릴적부터 가져왔던...
"어째서 독립유공자들은 고생은 고생대로 하고 저리도 힘든 삶을 살아야하나"
...라는 문제의식을 다소나마 해소할 수 있었네요.

아직도 많이 남은 부조리들이 잘 정리되면 좋겠습니다.
( '_')y-~


작업 이야기로 들어가볼까요.

이 일지는 2019년...
2월 12 ~ 15, 18~ 22, 25, 26, 28일
3월 2, 3일
...에 있었던 작업을 대상으로 합니다.

작업을 진행하다가, 추가 작업이 발굴되고, 다시 발굴되고, 또 발굴되어서 13일간의 작업으로 이어졌습니다.

작업 내역은...
  1. Spawn Process 정립 및 적용
  2. 모든 Actor를 위한 Action Build Process 추가
  3. Actor별로 특수화 되어 있던 A.I State를 공용으로 정리
  4. Table 에서 A.I 세부 옵션들을 지정가능하게 조정
  5. Actor들이 작동 가능한 Game Master Turn State 를 Table에서 지정
  6. Trigger 관련 Game Master State 보강
  7. Trigger A.I 에 이동기능 추가
  8. 전체 Trigger A.I Refactoring
  9. Monster 추가 : Fallen Wizard Brown
...입니다.

Dot 조금 그리고 막대한 양의 Refactoring 작업이 전부라서 보여드릴 것들은 얼마 없습니다. 그리고...


200개 가까이 commit 이 이루어졌기 때문에 일일이 설명할수는 없습니다.
그리하여 지난 일지와 비슷하게 작업의 흐름을 설명 해볼까 합니다.



1. 발단

작업은 아주 맘편하게, 번아웃이 지나가길 기다리며 시작되었습니다.
우선 Dot를 찍었습니다.

< f.w.b idle_2 x1 >

< f.w.b idle_2 x4 >

< f.w.b idle_2 x8 >

( 앞서 올라온 잡설에 이 녀석의 animation이 여럿 있기 때문에 간단히 넘어갑니다. )

이어서 진행된 A.I 작업에서 일이 꼬이기 시작합니다.

새로 만들어질 A.I 는 특별함을 가져야만 했습니다.
이 녀석의 존재 이유는 Boss전에서 마주할 함정소환 패턴의 연습 상대가 되어주는 것입니다. 단순한 형태일지라도 Boss가 하는 기능과 비슷한 기능을 소화 해야만 했습니다.

A.I를 작성해서 함정을 뿌려 봤습니다.


잘 작동 하는군요. 그런데... 재사용성이 0 입니다.

앞서 만들었던 Monster나 Item 을 실시간으로 뿌리는 기능들도 모두 전용 Code 로 이루어져 있습니다.

Hard한 Code를 적당히 돌려 쓰는 것은 얼마든지 가능합니다. 그때 그때 고쳐가면서 조금씩 확장해도 문제는 없겠죠.
하지만 이 게임은 Actor가 어떤 행동을 할수 있다면, 반드시 같은 행동을 Silent Action 으로도 처리 할 수 있어야 합니다.


여기서 Silent Action이 무엇인지에 대해서 간단히 짚고 가겠습니다.

이 Game은 시야가 밝혀진 곳과 밝혀지지 않은 곳이 있습니다.
그리고 모든 기능은 Player를 우선으로 진행됩니다.
만약에 밝혀지지 않은 곳에서 Actor들간에 공방이 발생하거나, 무언가를 Spawn 한다면 어떨까요?
보이지도 않는곳에서 벌어지는 일 때문에 유저는 영문도 모르고 연출 시간동안을 멀뚱히 대기해야 합니다.
이동중이었다면 칸을 이동할 적마다 뚝 뚝 끊어지는 것으로 보이겠죠.
이런 상황을 피하기 위해서 시야 밖의 Actor는 시간을 점유하는 연출을 하지 않고, 한 tick 안에 모든 처리를 끝내서 유저가 기다리지 않게 합니다.
이걸 Silent Action이라 부르고 있습니다.


즉 Actor가 가진 각각의 행동은 연출이 포함된 처리와 포함되지 않은 처리 두개가 하나의 짝을 이루게되는 겁니다.

행동이 많아봐야 10개 정도 요구된다면, Hard 하게 Code 를 작성해도 괜찮을지 모릅니다. 하지만 우리는 모두 알고 있죠. 그럴리가 없습니다.


2. 전개

그러면 어떻게 해야 할까?
우선 각각의 A.I에 작성된 전용 Code가 이런 일을 해서는 안됩니다. 흔히 "일반화" 라고 하는 작업이 필요하게 되어버렸습니다.

기능을 일반화 하기 위해서는 규격이 필요하고 규격을 만들려면 요구사항을 모아야 합니다.

그 첫 단계로 "Spawn Info Table" 이 추가 됩니다.
첫 "일반화" 대상으로 최근에 작업한 함정 소환 기능을 선택했습니다.
Data를 Table로 말끔히 털어내고 관련 Code를 정리 합니다.
이어서 Monster Spawn.
마지막으로 Item Spawn 기능이 작업 당합니다.

진행하다보니 주어진 위치를 기준으로 Spawn 될 장소를 뽑아내는 기능을 Table에서 지정가능해야 하다는 것을 알게 되었습니다.
알게 되었으니 만듭니다.

< dir8, 1Loop, Linear, spawnx3 >

< dir8, 1Loop, Random, spawnx3 >

< dir1, 3Loop, Linear, spawnx3 >

< bsp, 2Loop, Random, spawnx4 >

이 밖에도 많은 기능들이 차근 차근 작업되어 모두 Table로 빠져나왔습니다.


3. 절정

다음 작업은 만들어진 기능들을 Common Action에 포함시키고, Silent Action 으로 만드는 겁니다.

이 작업의 핵심은...
"시간을 점유하고 연출을 동반하는 기능" 과 "Silent Action" 은 서로 오차가 없어야 한다는 겁니다. 그러려면 주요 기능을 잘 정리해서 양쪽이 연출 이외에는 동일한 기능을 사용해서 작동하게 해주어야 합니다.

Server와 Client가 Lib를 공유하는 경우와 비슷한 느낌입니다.


그런데 작업을 하려고 보니 큰 문제가 있습니다.
Common Action Generator와 Silent Action Processor에 작업을 해야 하는데 이녀석들은 모두 Monster 전용입니다.

게다가 Common Action Generator를 적용하려면 Game Master A.I 가 구동하는 Turn Management Rule 에 맞게 움직여야 하는데, Trigger는 이것을 위한 준비가 전혀 되어 있지 않습니다. @_@

기능이 여기까지 올줄 모르고 가급적 야비롭게 줄타기 코드를 작성해왔는데... 속죄의 시간이 왔습니다.
대규모 Refactoring의 시간입니다.

먼저 Monster 전용으로 만들어진 기능들을 BaseActor 기준으로 사용가능하게 바꾸고 중복 기능을 제거합니다. ( 지옥 같은 rename 시간이었습니다. )
공용 기능들이 BaseActor 기준으로 작동한다면 각 Actor들이 있어야할 이유 또한 줄어듭니다. Actor의 종류를 줄입니다.
각 Actor를 구분해서 작동하던 Game Master A.I 의 Turn Management Rule 역시 Actor구분의 중요도가 감소합니다.
적용될 Rule 정보를 Table로 빼내서 개별 Actor에 대한 의존성을 제거합니다.

.
..
...
아이고 적으려니 끝이 없네요.
여기서 작업 내역에 있는 대부분의 일이 이루어졌습니다.

Trigger A.I 전체가 Refactoring 되었고
Monster A.I 의 상당부분도 Refactoring 되었습니다.
많은 기능들이 통합되고 사라졌습니다.


4. 결말

사실상 Game의 골격이 완성되었다고 보면 될것 같습니다.

그리고 마지막으로 "Fallen Wizard Brown" 의 A.I 를 위해 Golem Crystal 의 A.I 를 조금 손봤습니다.


5. 뒷 이야기

본래 여기까지 Code를 끌어올릴 생각은 없었습니다.
Silent한 기능들이 필요 없었다면, Hard 하지만 유지 가능한 수준의 Code를 마지막 까지 끌고 갔을 겁니다.

1인 개발을 해보니 게으름이 약간 가미된 코드를 선호하게 되었습니다.
디버깅 하기 좋더군요. @_@
추상화 수준이 낮은 코드가 편하달까요.

하지만 필요한 곳은 추상화 해야만 하겠죠. 그런 취지의 작업이었습니다.

여담으로 Monster "Fallen Wizard Brown" 추가 작업은 실패 입니다.
A.I 구상을 위해 머리를 여러모로 쥐어짜봤지만 일반 몹으로 만나기에는 상당히 불합리한 녀석이라고 결론 내렸습니다.
디자인을 조정하고 몬스터 등급을 올리거나. 좀 더 단순하게 작동하도록 조정해야 할겁니다.

작업을 신나게 해놓고 실패라니. 이것 참 재미있네요.



다음 일지는 가급적 빠르게 작성할 생각입니다.
쌓이니까 복기 할 것이 많아서 작성이 너무 힘드네요.

미세먼지가 저의 좁은 세상을 뒤덮고 있습니다.
휴식을 가지고 싶다고 간절히 바라고 있는데 이 녀석들은 정말 자비롭지 않네요.
얼른 긴 산책을 나가고 싶습니다.

미세먼지는 1급 발암물질이랍니다.
다들 마스크 꼭 쓰시고, 공기 청정기도 꼭 사용하세요.

전 밤을 꼴딱 새운 관계로 쉬러 갑니다.
( '_')y-~

> 글을 많이 고쳤습니다. 세어보진 않았지만 제법 많았으니까 대충...
> 20번
> ...으로 해두겠습니다. o_o
> 또 고칠지 몰라요.
> 공돌이 문돌이 스위치 갈아 넣는데 너무 오래 걸린다. 후우.
> 아이고 빡셔라.

댓글 없음:

댓글 쓰기