이 시리즈는 제가 개인 프로젝트 등을 제작하면서 배운 프로그래밍/CS 지식을 정리해둔 시리즈입니다.
나는 xnb.js라는 xnb 파일 조작 라이브러리를 개발하고 있다.
이 라이브러리는 xnb 파일을 언팩 및 패킹할 수 있는 콘솔 프로그램 XnbCli를 기반으로 제작되었다. 현재는 xnb.js 1.1.0이 릴리즈된 상태고, 1.2 업데이트를 제작하고 있다.
xnb.js 라이브러리를 체험할 수 있게, web xnb converter도 같이 제작하여 서비스하고 있는 상태다.
이 블로그에서 처음 xnb.js를 소개하는 것이라 간단한 개발 동기를 소개하겠다.
xnb.js는 내 또다른 프로젝트인 Stardew Dressup을 위해 제작되었다. Stardew Dressup은 스타듀 밸리라는 게임의 플레이어 커스터마이징을 시뮬레이션할 수 있는 웹 어플리케이션인데, 이 웹 앱의 기능 중 xnb 파일을 불러넣어서 의상의 텍스처를 변경할 수 있는 기능을 구현할 예정이다.(스타듀밸리에는 리텍스처라고 해서, 게임 내에 데이터를 저장한 xnb 파일을 다른 파일로 교체해서 데이터를 바꾸는 생태계가 존재한다.)
하지만 xnb 파일을 언팩할 수 있는 라이브러리는 세상에 존재하지 않았고, 결국 직접 제작할 수밖에 없었다. 다행이도, 자바스크립트로 제작되었고 LGPL 3.0 라이선스를 채택한 XnbCli가 있었기 때문에, 이를 개작하여 xnb.js라는 라이브러리를 제작하였다.
xnb.js는 브라우저에서도 xnb 파일을 다룰 수 있으며, 이를 통해 다양한 xna game studio/monogame 기반 게임의 유틸리티 웹 어플리케이션을 제작할 수 있음이 기대된다. 또한, 데스트탑이 없는 유저들 역시 스마트폰으로 웹 어플리케이션을 이용할 수 있기 때문에 진입장벽이 해소되는 효과 역시 가진다.
xnb.js 1.2에서는 다음과 같은 기능이 추가된다.
현재는 png 파일 단독으로 xnb 파일로 변환하는 기능을 완료하였고, 2번째 기능을 제작 중이다.
기존까지 png 파일은 단독으로 xnb 파일로 패킹할 수 없다고 알려져 있고, 실제로도 그래 왔다. png 파일을 xnb 파일로 변환하기 위해서는, 다음의 과정이 수행되었다.
png 파일 단독으로 xnb 파일로 패킹할 수 없는 이유는 xnb 파일로 패킹할 때 헤더 데이터가 존재해야 했기 때문이다. 하지만, xnb 파일을 언팩하다, 모든 xnb 헤더 파일은 동일하다는 것을 알게 되었고, 헤더 파일을 xnb.js에서 주입할 수 있으면 png 파일 단독으로 xnb 파일로 만들 수 있을까 생각했다.
모든 png 텍스처 파일 기반 xnb 파일의 헤더는 다음의 데이터를 가지고 있다.
실제로 게임에서 xnb 파일을 읽을 때 유효하게 작용되는 것은 readers와, content의 format 데이터이다. 타겟이 pc가 아닌 안드로이드 스타듀밸리에서 pc 스타듀밸리 헤더 기반 xnb 파일을 읽을 수 있기 때문이다.
readers의 type은 xnb 파일에 저장된 데이터의 타입을 의미하는데, png 파일은 텍스처 데이터이므로, Microsoft.Xna.Framework.Content.Texture2DReader를 사용한다. type에 있는 PublicKeyToken은 공용 키 토큰으로, 타입 리더의 어셈블리의 서명 같은 것이라고 생각하면 된다. Microsoft.Xna.Framework의 공용 키 토큰은 842cf8be1de50553으로 고정되어 있다.
content의 format은 텍스처 데이터가 어떻게 저장되어 있는지를 나타내는 포맷으로, 그 종류는 다음과 같다.
모든 png 파일은 32bit rgba 포맷을 사용하므로, 0을 포맷 값으로 가진다.