번외편
1편 : 스크립트로 보는 알만툴
0. 들어가기 전에
이번에는 번외편입니다. 써드파티 스크립트들에 대한 이야기가 아닌 RPG Maker 시리즈에 기본적으로 적혀있는 스크립트에 대해서 이야기 해볼까 합니다. 스크립트가 어떤 흐름으로 처리가 되고, 각 RGSS 버전별로 어떤 차이가 있는지에 대해서 간단히 이야기 해보도록 하겠습니다. 물론 이 게시물은 강좌가 아니기 때문에 세세한 부분까지 다루지는 않겠습니다만, 일단 알아둔다면 대충 어떤 흐름으로 스크립트가 돌아가는지 알 수 있으므로 도움이 되리라 생각합니다.
1. RPG Maker XP(RGSS)에서의 스크립트
위에 보이는 이미지는 RPG Maker XP(이하 XP)의 스크립트 에디터입니다. 좌측에 섹션 리스트에는 XP 구동을 위해서 사용되는 스크립트 코드 목록이 있습니다. 해당 섹션을 선택하면 그 안에 적혀있는 내용을 확인 할 수 있습니다.
게임을 실행시키면 Library가 담겨진 RGSS103J.dll를 읽고 스크립트가 담겨진 Scripts.rxdata를 읽는데, 그 순서는 섹션 목록에서 보여진 바와 같이 위쪽의 것부터 차례대로 읽어드립니다. 읽어들이는 순서야 위에서 아래로 읽습니다만, 함수나 클래스, 모듈 내부의 내용은 처리되지 않기 때문에 처음 실행되는 스크립트 코드는 가장 하단에 위치한 Main 섹션의 내용입니다.
Main 섹션의 내용을 살펴보면, 처음 시작할 씬(여기서는 Scene_Title)에 해당하는 객체를 글로벌 변수인 $scene에 대입하고 $scene 값이 nil이 되기 전까지 해당 객체의 main 메서드를 무한반복 처리하는 것을 볼 수 있습니다.
여기서 만약 반복처리를 해주지 않게 된다면, 객체의 main 메서드를 한 번 처리한 이후 그 아래쪽으로 적혀져 있는 코드들을 읽어들이면서 처리하고 모든 섹션을 다 읽고 처리했다면, 프로그램이 종료 됩니다.
이벤트를 하나 작성해서 스크립트에 $scene = nil 을 적어 봅시다. 그리고 main 섹션 아래에 빈 섹션을 하나 추가하고 p '끝' 이라고 적습니다. 게임을 실행한 다음 이벤트를 작동시키면 프로그램이 종료되면서 "끝"이라는 내용이 적힌 팝업창이 뜨는 것을 확인 할 수 있습니다.
이런 반복 처리는 RPG Maker만의 특징이 아닙니다. 일반적으로 시작시 1회 처리하고 종료되는 형태가 아닌 이상 이러한 반복처리를 하는 형태로 프로그램은 구성되어 있습니다. 이 반복처리야 말로 RPG Maker 스크립트의 처음이자 끝이라 할 수 있습니다.
일단 Main 섹션에 도착해서 반복처리를 시작하게 되면, 그 아래쪽에 있는 섹션은 프로그램이 종료될 때 까지 읽어들이지 않은 상태가 됩니다. 이것이 새로 스크립트를 추가할 때 항상 Main 섹션의 위에 추가하는 이유입니다.
또한 위쪽의 섹션부터 읽어들이기 때문에 기존의 스크립트 내용을 재정의하거나, 연동해서 작동하는 스크립트는 위치가 잘 못 되었을 경우 오작동을 하게 됩니다.(나중에 읽어들인 내용이 먼저 읽어 들인 내용을 재정의 합니다.)
스크립트가 충돌날 때 그 위치를 위 아래로 조정하면서 문제를 해결하시는 분들이 계신데 근본적인 해결책이 되지는 못합니다. 우리가 스크립트 충돌이라 부르는 경우는 대개 서로 재정의해서 발생하는 경우가 대부분이기 때문에 위치를 변경해서 오류 메세지가 팝업되지 않더라도 모든 문제가 해결된 것이 아니라 재정의 순서가 바뀌어 오류메세지가 팝업되었을 때 먹통된 스크립트가 먹통되지 않았던 스크립트와 서로 바뀐 것일 뿐입니다. 스크립트가 충돌이 난다면 일단 두 스크립트의 충돌 부분을 합쳐주거나, 어느 한 쪽을 과감히 포기하는 것만이 해결법입니다.
그럼 반복처리 되는 내용을 좀 더 세부적으로 들어가 보도록 하겠습니다. 일단 첫 씬으로 대입된 Scene_Title 클래스로 가보면 main 메서드를 확인 할 수 있습니다. $scene 값이 nil이 될 때까지 처리해야 하는 함수내용이 바로 여기에 적혀있는 이 내용입니다.
main 함수에서 처리하는 내용을 살펴보니 일단 전투테스트인지 여부를 살펴보고(전투 테스트인경우 필요한 데이터베이스와 오브젝트를 로드한 다음 Scene_Battle로 넘어갑니다.), 각종 데이터베이스와 오브젝트 등을 로드한 다음 $scene에 대입된 객체가 자기 자신인 동안(if $scene != self ; break end) 반복적으로 그래픽을 갱신하고(Graphics.update), 입력 정보를 갱신(Input.update)하고, update 함수를 처리하는 것을 볼 수 있습니다.
이렇게 하나의 씬 안에서도 반복처리가 이루어 지며, $scene에 다른 객체가 대입되면(예, $scene = Scene_Battle.new) 또 Main 섹션의 반복처리의 내용대로 해당 객체의 main 메서드를 반복합니다.
2. RPG Maker VX(RGSS2)에서의 스크립트
그럼 이번에는 RPG Maker VX(이하 VX)의 스크립트 에디터를 열어보겠습니다. VX라면 뭔가 특벌할 것 같아 보이지만, 사실 별반 다르지 않습니다. 사용하는 ruby 버전마저 1.8x로 동일하기 때문에 표준 라이브러리가 변경된 것도 없습니다. 다만 RGSS는 RGSS2로 버전업을 했기 때문에 편입함수나 모듈 등의 내용은 일부 변경되었습니다. 여기서는 RGSS 라이브러리에 대해서 다룰 것은 아니므로 이 이야기는 여기서 멈추고 스크립트 에디터를 보도록 하겠습니다.
일단 보시면 전반적으로 XP와 동일합니다. 이번에도 역시 Main 섹션까지 내려와서 반복처리하는 부분이 보입니다.
그럼 이번에도 역시 시작 씬인 Scene_Title 로 이동해 보면 위와 같습니다. XP와 다른 점은 main 씬에서 전투테스트 여부만 적성되어 있는 것을 볼 수 있습니다. 일단 XP와 동일하게 전투 테스트인 경우에는 battle_test 함수로 이동하고, 아닌 경우는 super 클래스의 main 함수를 호출합니다.
Scene_Title의 super 클래스인 Scene_Base 로 이동해 보면 XP에서처럼 main 함수에서 반복처리를 하고 있는 것을 살펴볼 수 있습니다. Scene_Title에서는 이곳에 적혀있는 대로 start 함수에서 XP에서 처럼 데이터 베이스와 게임 오브젝트를 로드/생성 하고 역시 반복처리를 하게 됩니다.
XP와 VX의 큰 차이점이 바로 이것에 있습니다. VX에서는 Scene_Base를 비롯한 super 클래스를 미리 작성해 두었기 때문에 상속받는 하위 씬의 경우 특별한 경우가 아니라면, XP에서 처럼 모든 씬 클래스마다 main 함수를 작성해두지 않아도 됩니다. 스크립터의 입장에서는 반복된 코드작성이 사라지게 되는 것이기 때문에 편하지만, XP에 비해 비교적 더 복잡해진 계승구조로 인해 입문자들에게는 장벽이 되기도 합니다.
3. RPG Maker VX Ace(RGSS3)에서의 스크립트
그럼 마지막으로 RPG Maker VX Ace(이하 Ace)를 살펴보도록 하겠습니다. 이번 역시 동일하게 Main 섹션으로 내려와 시작하게 됩니다. Main 섹션의 내용은 겉보기엔 기존의 XP와 VX에서 보아오던 것과는 사뭇 다른 내용입니다. rgss_main {} 이라 적혀있는데, 이는 따로 ruby 표준 라이브러리에는 없는 내용으로 RGSS3로 버전업 되면서 추가된 편입 함수 입니다. 대단한 내용은 아니고, 그저 Ace로 넘어오면서 씬 처리를 SceneManager 모듈에서 관리하게 되었기 때문에 일단 SceneManager 의 인스턴스 메서드인 run 을 실행시키는 모습입니다.
섹션에서 SceneManager를 선택해서 모듈의 내용을 보면 여기에도 역시 반복처리가 보입니다. 기존의 XP, VX와는 달리 글로벌 변수가 아닌 SceneManager 내부의 인스턴스 변수에 씬 객체를 생성합니다. 때문에 이전과 같이 씬을 변환하기 위해서 글로벌 변수인 $scene 을 찾을 수가 없게 되었습니다. 이젠 새로운 씬을 불러오기 위해서는 SceneManager의 call 메서드를 사용해서 접근해야 합니다.
처음 대입하는 씬의 경우 이것이 테스트 전투인지를 판별하는 것을 볼 수 있습니다. 이 내용들은 XP나 VX에서는 Scene_Title에서 처리하던 내용입니다. 반복처리 하기 이전에 DataManager.init 라고 적혀 있는 것은 데이터베이스와 게임 오브젝트를 로드/생성 하는 등의 내용을 담고 있는데, 이 또한 Scene_Title에서 처리하던 내용임을 알 수 있습니다.
그 결과 Scene_Title 클래스 내부에서는 더 이상 main 함수를 재정의 하지 않는 것을 볼 수 있습니다. 별도의 재정의가 없기 때문에 super 클래스인 Scene_Base의 내용을 그대로 처리합니다. 예외 적으로 재정의하던 부분들이 정리 되면서 VX 보다 한결 깔끔해진 모습입니다.
Ace에서는 이처럼 보다 각 부분들이 세분화 되었을 뿐만 아니라, 씬 처리에서 많은 부분을 담당하던 내용들을 Window 클래스 내부로 이전하여 보다 간결한 코드 작성을 꾀하고 있습니다. XP, VX 유저들은 처음 접했을 때 다소 당황하는 부분이기도 합니다.
이 뿐만 아니라, 씬의 종료시 생성된 모든 인스턴스 변수를 일괄 종료시켜 기존의 윈도우 종료처리를 별도로 하지 않아도 되도록 한 점이라든지, 각종 부분에서 심볼(:name)을 사용하여 보다 알아보기 쉬우면서도 빠른 처리를 꾀한 모습도 보입니다. 많은 부분에서 기능적인 향상 뿐만 아나리 스크립터들이 편하도록 개선되었습니다.
하지만, RPG Maker 주 사용층이 프로그래밍을 모르는 일반인이다보니, 이러한 노력은 일반 사용자들은 잘 느끼기 힘든 부분이기도 합니다. 때문에 기본 기능을 보다 세세한 곳 까지 설정할 수 있도록 증대시켰습니다만, 사용 가능한 써드파티 스크립트가 적다는 이유로 사용 툴로는 잘 선택되지 않는 듯 합니다.
4. 나오며
ruby문법을 막 알아도 막상 스크립트 에디터를 켜고 나면 뭐가 뭔지, 어디서 부터 봐야하는지 잘 알기 힘듭니다. 특히 맨땅에 헤딩해서 기본적인 지식이 부족한 경우일 수록 심하고, 특히 이 커뮤니티에는 이런 부류가 많습니다.(사실, 제가 그랬습니다.;;)
스크립트 창을 열고 어디서 부터 봐야 할지 모르는 사람이라면, 이 글을 읽고 한번 순서대로 쭉 따라가 보는 것이 RPG Maker 스크립트가 어떤 구조로 작성되어 있는지에 대한 이해를 높이는 한 방법이 될 수 있습니다.
갑자기 작성한 번외편이지만, 이전부터 한번쯤은 작성해 보고 싶었던 내용인 동시에 기획연재로 이전을 자축하는 의미로도 괜찮겠다는 생각에 작성하게 되었습니다. 부족한 부분이나 잘 못 기술된 내용에 대해서는 피드백 주시면 수정하도록 하겠습니다. 그럼 다음에는 번외편이 아닌 다른 내용으로 찾아뵙겠습니다.