SheetForge — Unity를 위한 시트 기반 데이터 파이프라인
SheetForge는 스프레드시트(Google 시트 또는 로컬 TSV/CSV/xlsx)를 강타입 C# 클래스와, 게임이 안정적인 주소로 로드하는 베이크된 ScriptableObject로 바꾼다.
모든 셀은 임포트 시점에 검증된다. 잘못된 값은 런타임에 그 행이 처음 사용될 때가 아니라 임포트할 때 잡힌다. 탭·행·컬럼과 제안된 수정 방법을 담은 문장으로 보고된다. 파이프라인은 컴파일러처럼 동작한다: 한 번의 패스로 모든 에러를 수집하고, 완전히 깨끗한 시트로부터만 불변(immutable) Definition을 조립한다.
시트는 항상 단일 진실 공급원(single source of truth)이며, 베이크된 SO는 조회용 캐시에 불과하다. 그 주위로:
- 라운드트립. 임포트에는 역방향 경로가 있다: Export/Push는 구조를 보존하면서 값을 시트로 다시 기록한다.
- 에디터 내 작성. 에디터 내 작성 창 — 데이터 스튜디오 — 이 Ctrl+Z undo와 함께 시트를 편집한다.
- 현지화된 UI. 제품 UI는 10개 언어로 제공된다.
- 플러그인을 통한 확장. 플러그인은 Core를 수정하지 않고도 셀 타입·검증 규칙·그래프 엣지·임포트 소스를 추가한다. 그 경계는 C# 컴파일러로 강제된다.
공개 API는 작성 커널(authoring kernel)이다: 노드 그래프 캔버스와 같은 두 번째 작성 표면은 Core나 Editor 변경 없이 그 위에 구축할 수 있다 — 작성 커널 참고.
요구 사항: Unity 6와 Addressables 패키지(com.unity.addressables) — 런타임 로드는 주소 기반이다. 에셋은 이 패키지 없이도 컴파일되지만, 설치되기 전까지 파이프라인은 잠긴 채로 남는다. 안내에 따른 설치 과정은 시작하기에서 다룬다.
동작 방식 (한눈에 보기)
ENTRANCES TRUTH EXITS
┌───────────────────────────┐ ┌──────────────────┐ ┌───────────────────────────────┐
│ Google Sheets (SheetsApi/ │ │ │ │ Strongly-typed C# classes │
│ ExportUrl) │──▶│ Immutable IR │──▶│ (codegen, last stage) │
│ Local TSV / CSV / xlsx │ │ (Definitions) │ │ Per-tab Database SO (bake) │
│ Data Studio (in-editor │ │ │ │ → Addressables address │
│ authoring, WYSIWYG) │ │ built ONLY if │ │ "SheetForge/{tab}" │
│ Custom source providers │ │ validation is │ │ Export / Push back to the │
│ (plugin, e.g. DB/REST) │ │ 100% clean │ │ sheet (round-trip) │
└───────────────────────────┘ └──────────────────┘ └───────────────────────────────┘모든 입구(entrance)는 동일하게 검증된 IR을 생성하며, 모든 출구(exit)는 그로부터 파생된다. 어디서든 에러가 하나라도 있으면 출력이 전혀 생성되지 않는다 — 부분 조립은 없다.
모든 에러는 다음을 알려준다:
- 어디서 — 탭 · 행 · 컬럼 문자와 필드명
- 무엇이 — 문제가 된 값
- 왜 — 위반된 규칙
- 어떻게 — 실행 가능한 제안
이는 팀이 테이블마다 직접 작성해야 했을 것 — 파서, 검증기, 코드 생성기, 로딩 경로 — 을 대체한다.
주요 수치
- 50,000행 × 20컬럼 임포트 ≈ 라이브 에디터(Mono)에서 628 ms; 180k개의 참조 셀을 가진 50개 탭 × 2,000행 ≈ 294 ms.
- 구조화된 에러 코드 — 완전한 검증 참조.
- 전체 제품 UI(메뉴, 작성 창, 대화상자, 리포트, 툴팁)에 대해 10개 언어.
- 테스트 스위트: 헤드리스 .NET 테스트와 Unity EditMode 테스트로 이루어진 이중 하니스, 실패 0건 — 정확한 수치는 기능 및 제한 ▸ 릴리스 시점 검증 상태에 있다.
문서 지도
| 페이지 | 다루는 내용 |
|---|---|
| 시작하기 | 요구 사항(Unity 6, Addressables), 설치, 설정, 첫 임포트, 데모 씬 |
| 핵심 개념 | 시트 = 단일 진실 공급원, IR, 파이프라인 단계, 캐시로서의 베이크된 SO, baseline, 자동 임포트 체인 |
| 시트 문법 | 마커(@name/@type/@desc/@overlap/@style/@enum/@loc), 전체 타입 시스템, enum 정의 시트, 표기 규칙 |
| 데이터 스튜디오 | 작성 표면 — 조회, 검색, 셀 편집, 구조 편집, 레코드 캔버스, Ctrl+Z, 사전 검증 |
| 소스, 내보내기 및 Push | 로컬 및 Google 소스, 프로바이더 설정, Export 라운드트립, Push 안전장치, 시트에 기록되는 드롭다운 |
| Google 시트 설정 | 서비스 계정과 JSON 키 생성, 시트 공유, SheetForge가 키를 가리키게 하기 |
| 현지화 | 10개 언어 UI, 사용자별 언어, 메뉴 재생성, 번역 추가 |
| 현지화 시트 | 게임 텍스트를 시트로 관리하기 — @loc 로케일 컬럼, LocRef 참조, 키 상수, Unity Localization StringTable 브리지, 번역 워크플로우 |
| 플러그인 작성 | 16가지 플러그인 계약(셀 타입, 검증기, 엣지, 마커, 템플릿, 캔버스 오버라이드, 코드 레지스트리, 테마, 선언적 작성 표면, UI 문자열, 파이프라인 관찰자, 소스, 스튜디오 위젯/액션/셀 에디터/패널) + 자체 표기법에 완전한 참조 등가성을 부여하는 옵트인 capability — Core 수정 없이 도메인 추가 |
| 작성 커널 | 공개 엔진 API 위에 두 번째 작성 표면(예: 그래프 캔버스) 구축하기 |
| API 참조 | 완전한 공개 API 표면 — 어셈블리별 모든 공개 타입 |
| 기능 및 제한 | 무엇이 되고, 무엇이 안 되며, 왜 그런지에 대한 완전한 목록 |
| FAQ 및 문제 해결 | 첫 실행과 연동 과정의 문제, 그리고 그 해결 방법 |
| SheetForge Web | 브라우저 컴패니언 — WebAssembly로 컴파일된 동일한 코어, 작성/검증/리플렉션 패리티, 언제 사용하는지 |
| 웹 플러그인 마켓 | 레지스트리에서 플러그인 설치(원클릭, 해시 고정), 호환성 게이트, GitHub URL로 미검수 플러그인 사이드로딩, Unity 내 마켓 창 |
| 웹 Google 시트 액세스 | 배포된 사이트에서 자신의 OAuth로 Google 시트를 읽고 쓰기, 그리고 로컬 전용 서비스 계정 키 규칙 |
SheetForge Web (컴패니언)
web.sheetforge.workers.dev의 컴패니언 웹 앱이 작성, 검증, 시트 리플렉션을 브라우저로 가져온다.
이 앱은 재구현이 아니라 동일한 C# 코어를 WebAssembly로 컴파일한다 — 그래서 파서와 검증기는 Unity 에셋과 결코 어긋날 수 없으며, Unity에서 빌드한 플러그인 DLL도 수정 없이 그대로 로드된다. 코드젠과 베이크는 여전히 Unity 전용 책임으로 남고, 웹의 출력물은 리플렉션된 시트다.
위의 웹 페이지 세 개는 이 앱과 그 플러그인 마켓, 그리고 Google 시트 액세스를 다룬다. IntId@Tab 참조 패리티를 포함해 이 사이트의 모든 시트 문법 규칙은 브라우저에서도 동일하게 유지된다.
설계 원칙
- 시트가 정본(canonical)이다. SO를 직접 편집하는 것은 워크플로우가 아니다. 모든 것은 시트와 재임포트 검증을 거친다. (임시 런타임 실험을 위한 "테스트 편집" 토글이 존재하지만, 이는 결코 다시 기록되지 않으며 재임포트 시 사라진다.)
- 모든 것을 수집하고, 깨진 것은 아무것도 조립하지 않는다. 검증은 첫 번째 에러에서 멈추지 않으며, 에러가 하나라도 있으면 출력이 없다는 뜻이다 — "하나 고치고 재임포트"를 반복하는 대신, 완전한 목록을 한 번에 고친다.
- WYSIWYG 작성. 데이터 스튜디오에서는 스테이징하는 모든 것이 실제로 반영될 모습 그대로 즉시 표시된다 — 시트에 기록하기도 전에 추가된 컬럼이 나타나고 삭제된 행이 사라진다.
- 완전 자동. 작성 작업 이후, 코드젠 → 재컴파일 → 베이크는 도메인 리로드를 거치는 동안 별도로 재트리거할 필요 없이 완료된다.
- 개방-폐쇄 확장(open-closed extension). 새로운 셀 타입, 검증 규칙, 그래프 엣지, 임포트 소스는 등록을 통해 합류하며 — 파이프라인 자체는 결코 수정되지 않는다.
- 문서화된 한계. 제품이 할 수 없는 것은 할 수 있는 것만큼 정확하게 문서화된다. 기능 및 제한을 참고하라.
- 오픈 데이터(Open data). 진실은 평범한 TSV/CSV/xlsx 파일이거나 Google 시트이며, 어떤 도구로도 읽을 수 있다. SheetForge를 제거해도 파이프라인만 사라질 뿐, 데이터는 남는다.