처음이라면 시작하기만 보면 되고, 설계 노트는 「왜 이렇게 되었는가」가 궁금할 때
읽는 것입니다.
설계 문서는 주제별로 spec/에 있습니다 — 아래 표는 그중 자주 찾는
것만 골라 둔 것입니다.
저장소로
빠른 시작
긴 문서를 읽기 전에 여기부터. 10분이면 엑셀 하나가 게임 코드에 도착합니다.
시작하기
| 문서 | 내용 |
|---|
| 설치 | 릴리즈 내려받기, 받은 파일 확인, 소스에서 빌드하기 |
| 용어 | 문서가 설명 없이 쓰는 말 들. 골든, 픽스처, 스위트, 와이어, 쿠킹 |
| 시트에 무엇을 적을 수 있나 | 테이블, enum, 상수셋, 매트릭스 네 가지와 각각이 무엇으로 생성되는지 |
| 시트 작성 | 선언 셀과 헤더 행, 경로 표기, 멀티 로우, 이름 규칙, 지원 타입, 서버/클라이언트 분리 |
| 시트가 코드가 되는 모습 | 시트 하나와 거기서 생성된 코드를 나란히. 언어는 탭에서 고릅니다 |
| CLI | 실행하는 방법과 명령줄 옵션 |
| Recipe 파일 | 데이터를 어디서 읽고 어디로 출력할지 정의하는 파일 |
| 옮겨오기 | 지금 쓰는 변환을 끄지 않고 테이블 하나부터 대조하며 넓히는 네 단계 |
쓰는 법
| 문서 | 내용 |
|---|
| 기능 | Tabbit이 하는 일 전체 |
| 언어별 가이드 | 생성된 코드를 각 프로젝트에 적용하고 사용하는 방법 |
| 검증 | C# 검증 코드. 실행 전, 테이블별, 전역, 런타임 네 단계와 공용 코드 |
| 내보내기 | 바이너리, JSON, 데이터베이스 출력과 바이너리를 사용하는 이유 |
| Summary와 히스토리 | 누가 언제 무엇을 바꿨는지 셀 단위로 추적하고 브라우저로 확인하기 |
| 편집기 | .tbs 의 문법 강조와 tabbit lsp — 진단 · 정의로 이동 · 호버 |
| 트러블슈팅 | 빌드 실패 시 실제 출력 메시지를 기준으로 문제를 찾는 방법 |
형식 — TCB
| 문서 | 내용 |
|---|
| 바이너리 형식 | .tcb 파일의 레이아웃과 스키마가 달라졌을 때의 보장 |
| 왜 컬럼 지향인가 | 이 형식이 맞는 상황과 맞지 않는 상황. Parquet, Arrow, FlatBuffers와의 차이 |
| 벤치마크 | 실제 게임 데이터로 측정한 크기, 로드 시간, CPU, 메모리 |
개정 기록
각 문서는 그 개정이 무엇을 바꿨고, 무엇을 바꾸지 않았는지 적습니다.
| 개정 | 내용 |
|---|
| v102 | 컬럼 인코딩과 암호화의 자리 |
| v103 | presence 비트맵. 값의 존재 여부를 와이어에 담습니다 |
| v104 | 조합 인코딩 9종에서 13종으로, 그리고 파일 암호화 |
| v105 | 비트폭 패킹. 설계 결정 셋을 계측이 뒤집은 기록 |
| v106 | 원소 presence 비트맵. 배열의 어느 자리에 값이 있는지 |
| v107 | 동적 배열 단일화. 파일이 오히려 2.5% 작아졌습니다 |
| MAC과 시그니처 | 변조 검출. 암호화가 변조 저항을 주지 않고 있던 자리 |
설계 노트
spec/의 문서들입니다.
사용법이 아니라 결정의 기록입니다. 무엇을 고쳤는지, 무엇을 거부했는지, 그리고 예측이 어디서
틀렸는지 적습니다.
값의 형태
| 문서 | 내용 |
|---|
| 중첩 필드 | 컬럼 여러 개를 레코드 하나로 접으면서 와이어 형식은 그대로 둔 방법 |
| 다중 중첩 | 멤버가 배열인 레코드와 배열의 배열. 깊이 제한을 없앤 근거 |
| 선언된 struct의 신원 | 두 테이블의 Reward가 같은 타입이 되는 것. 형식은 그대로이고 생성 코드가 전부 움직입니다 |
| 매트릭스 표 | 컬럼 이름이 행 id인 격자. long-form과 map을 채택하지 않은 이유 |
| 행렬 선언 검토 | 다섯 번째 선언 종류를 둘 것인가. 인코딩 이득이 없고 표기 이득이 있는 이유 |
| 매트릭스 선언 | :matrix 선언 셀의 시트 표기. 축의 키가 정수가 아니어도 되는 설계 |
| 가변 길이 레코드 배열 | 배열 길이를 행마다 다르게. 뒤에서만 자르는 이유 |
| 비트셋 | bitset 타입과 진법 리터럴. 엄격함이 의도 선언을 요구하는 이유 |
| 합성 값 타입 | 벡터, 회전, 색을 타입 추가가 아니라 레코드로 접는 이유 |
| 옵셔널 필드 | 타입 끝 ?의 설계. 존재 여부를 와이어에 담는 방법 |
| 빈 칸과 없음 | 빈 칸이 값과 없음을 겸하던 것을 표기 하나로 나누는 설계 |
| 원소가 없을 수 있는 배열 | T?[] · T[]? · T?[]?. 원소의 없음을 파일이 담는 설계 |
| 배열의 옵셔널 | 배열 컬럼들의 필수 표시가 엇갈릴 때 첫 원소가 전부를 정하는 이유 |
| 레코드 멤버별 옵셔널 | :requiredInObject가 검증 규칙이지 표현의 요구가 아닌 이유 |
읽기와 내기