Game Data Compiler — 엑셀과 구글 스프레드시트에 적은 게임 데이터를 검증하고, 런타임이 그대로 싣는 데이터와 그것을 읽는 코드로 빌드합니다.
엑셀을 읽어 게임 데이터로 만드는 스크립트는 어렵지 않습니다. 아마 이미 있을 것입니다.
어려운 것은 그 뒤입니다. 컬럼이 하나 늘고, 서버가 Go로 가고, 기획자가 빈 칸에 -를 적고,
라이브가 시작됩니다. 그때부터 그 스크립트는 누군가의 상시 업무입니다.
Tabbit이 대신하는 것이 그 상시 업무입니다. 시트는 그대로 둡니다.
데이터를 적는 사람은 지금 쓰는 워크북에 지금처럼 적고, 코드를 쓰는 사람은 생성된 타입을 씁니다. 그 사이에 있던 스크립트가 하던 일 — 검증, 참조 확인, 사이드 분리, 코드 생성, 데이터 빌드, 로딩 — 을 한 실행이 맡습니다.
옮겨오는 단위는 테이블 하나입니다. 시트를 한 셀도 고치지 않고 테이블 하나만 JSON으로 내보내 지금 쓰는 파일과 대조하는 것이 첫걸음이고, 그동안 기존 변환은 그대로 돕니다 — 기존 파이프라인에서 옮겨오기에 네 단계로 있습니다.
규칙은 하나입니다. :가 붙은 셀은 데이터가 아니라 표의 뼈대입니다.
tabbit --recipe recipe.jsonawait GameData.ReadAllAsync("./data");
var sword = GameData.Item.FindByIndex(1);
sword.Name; // Short Sword
sword.ItemCategoryByCategoryId.Name; // Weapon ← 조회를 한 번 더 하지 않습니다
sword.GradeField; // Grade.Common시트에는 카테고리 번호만 적혀 있는데 코드에서는 그것이 가리키는 행이 바로 옵니다. 레코드 타입, 조회 함수, 데이터 파일, 그 파일을 읽는 리더가 함께 나옵니다.
C#(.NET과 유니티), TypeScript, C++, C, Go, Rust, Python, Java, Kotlin, Swift, Lua, Ruby, PHP, Dart, 언리얼 모듈이 같은 시트에서 나옵니다 — 언어마다 나란히 놓은 문서에서 자기 언어를 고르면 됩니다.
기획자가 빈 칸에 -를 적어서 변환이 깨진 적.
-는 「없음」의 정식 표기입니다. 타입 끝에 ?를 붙이면 빈 칸도 값입니다. 앞뒤 공백은 지워집니다.
카테고리 하나를 지웠는데, 그것을 가리키던 아이템 40개를 아무도 몰랐던 적.
foreign이라고 적은 컬럼은 없는 키를 빌드가 거부하고, 어느 시트 어느 셀인지 함께 보고합니다.
드롭률이 클라이언트 데이터에 그대로 들어가 있던 적.
컬럼에 s 하나면 됩니다. 클라이언트가 받는 파일에는 그 컬럼이 아예 없습니다.
누가 컬럼 순서를 바꿔서 값이 한 칸씩 밀려 읽힌 적. 컬럼은 이름이 아니라 태그로 저장됩니다. 태그를 달아 두면 추가·삭제·이름 변경·순서 변경을 이미 배포된 빌드가 그대로 읽습니다.
데이터 패치가 중간에 끊겨 빈 테이블이 된 적. 전부 읽고 참조까지 연결한 다음 한 번에 교체합니다. 실패하면 이전 데이터가 그대로 남습니다.
서버는 Go, 클라이언트는 C#, 툴은 Python이라 리더를 세 번 유지한 적. 같은 시트에서 전부 나옵니다.
로딩 중 프레임이 끊기는 것이 JSON 파싱과 그 쓰레기 때문이었던 적. 같은 게임 데이터가 JSON으로 14.08 MB, Tabbit으로 0.51 MB입니다. 로드는 45.3 ms에서 12.6 ms, 할당은 절반 이하입니다. 95,490행짜리 성장 테이블의 컬럼 넷이 파일에서 차지하는 것은 234바이트입니다 — 값을 하나도 빠뜨리지 않고 그렇습니다(벤치마크).
「이 값 누가 바꿨어?」를 물어본 적. 셀 단위로 남습니다. 그리고 이번 변경이 데이터만 올려도 되는 것인지 코드까지 배포해야 하는 것인지 커밋마다 보고합니다 — enum을 잘못 내보내면 게임은 크래시하지 않고, 로그에도 아무것도 남지 않습니다.
| 무엇 | 얼마나 |
|---|---|
| 배우는 것 | 특수문자 두 개. :와 # |
| 시트 고치기 | 안 고칩니다. Tabbit의 규칙으로 쓰이지 않은 시트도 읽습니다 |
| 설치 | 압축 풀기. .NET 런타임도 필요 없습니다 |
| 시작 범위 | 테이블 하나. 선언 셀을 적은 자리만 읽으므로 같은 워크북의 다른 시트는 대상이 아닙니다 |
| 되돌리기 | 생성 폴더와 recipe를 지우면 끝입니다. 새로 설치한 라이브러리가 없습니다 |
| 라이선스 | MIT. 시트에서 생성된 코드와 데이터는 그것을 만든 프로젝트의 것입니다 |
되돌리기까지 포함한 순서는 옮겨오기에 있습니다. 대조와 검증을 붙이는 동안 기존 변환은 계속 돌고, 그 뒤로는 워크북 하나가 옮기는 단위입니다.
릴리즈에 Windows, Linux, macOS의 x64와 arm64가 올라갑니다. 내려받아 압축을 풀면 끝입니다(설치).
tabbit --new-recipe my-recipe.json --template unity
tabbit --recipe my-recipe.json--template은 unity · client-server · web · server · unreal · ci 중에서 고릅니다.
설정마다 무엇을 위한 것이고 언제 바꾸는지 주석이 붙어 있습니다.
| 어느 쪽이신가요 | 어디부터 |
|---|---|
| 시트에 데이터를 적는 분 | 기획자용 빠른 시작 — 알아야 하는 특수문자는 두 개입니다 |
| 도구를 붙이는 분 | 개발자용 빠른 시작 — 설치부터 코드에서 읽기까지 |
문서 사이트에 전부 있습니다. 저장소에서는 문서 목록이 같은 자리입니다.
| 문서 | 내용 |
|---|---|
| 시트 한 장으로 시작하는 예제 | 시트에 적을 수 있는 세 가지와 그것이 되는 것 |
| 시트 작성 | 데이터 배치, 이름 규칙, 지원 타입 전부 |
| 시트가 코드가 되는 모습 | 시트 하나와 생성된 코드를 언어마다 나란히 |
| CLI · Recipe 파일 | 실행 방법과, 어디서 읽고 어디로 출력할지 |
| 옮겨오기 | 지금 쓰는 변환을 끄지 않고 테이블 하나부터 대조하며 넓히는 순서 |
| 언어별 가이드 | 생성된 코드를 프로젝트에 적용하는 방법 |
| Summary와 히스토리 | 누가 언제 무엇을 바꿨는지, 그리고 이번 변경으로 무엇이 나가야 하는지 |
| 기능 · 벤치마크 | 하는 일 전부와, 형식별 크기·로드 비용 |
| 트러블슈팅 | 빌드 실패 시 실제 출력 메시지를 기준으로 |
버그와 제안은 이슈로 알려주세요. 개발과 테스트 방법은 아키텍처와 개발에, 보안 문제는 SECURITY.md의 절차에 있습니다. 변경 내역은 CHANGELOG.md입니다.
코드와 문서는 MIT입니다. 생성된 코드와 테이블 리더도 동일하고, 시트에서 생성된 코드와 데이터의 소유권은 그것을 만든 프로젝트에 있습니다.
이름과 로고는 다릅니다 — 브랜드 자산의 이용 조건. 가리키는 데는 마음껏 쓰시고, 후원이나 제휴로 읽힐 자리에는 두지 말아 주십시오.