최애의 관리자 — 게임 데이터 동기화와 다국어화 파이프라인 재구축
최애의 관리자
2편을 올린 뒤로 한동안 블로그를 안 썼다. 그 사이 커밋은 계속 쌓였고, 막상 다시 보니 “새 기능을 만들었다”기보다 “데이터를 믿을 수 있게 만드는 작업”이 훨씬 많았다.
특히 3월 31일부터 4월 중순까지는 최애의 관리자 안쪽을 꽤 많이 갈아엎었다. 거울 던전 테마팩, 이벤트, 인격/EGO 데이터, 키워드 메타, 다국어 표시까지 한 번에 얽혀 있었다. 겉으로 보면 카드 위치 조정이나 모달 리디자인 같은 UI 작업도 많았는데, 실제로 오래 걸린 건 “이 텍스트가 어디서 온 거냐”를 끝까지 추적하는 일이었다.
테마팩 카드부터 시작했는데, 결국 데이터 문제였다
처음에는 거울 던전 테마팩 카드가 마음에 안 들어서 손을 댔다. 이름 위치가 어색하고, 이미지가 잘리고, 일부 테마팩은 보스 이미지를 어떻게 얹을지 애매했다.
그래서 테마팩 카드 이미지를 바꾸고, 텍스트 그림자를 넣고, Pretext로 폰트 크기를 자동 조절하게 했다. 감정에 홀리는 것 같은 특정 테마팩은 보스 이미지 오버레이도 따로 처리했다.
그런데 이런 걸 고치다 보면 금방 UI 문제가 아니라 데이터 문제가 된다. 이름이 길 때 줄바꿈을 막아야 하는지, 효과 설명은 사람이 정리한 문장이어야 하는지, 게임 원본에서 가져온 텍스트를 그대로 써야 하는지 계속 부딪힌다.
결국 이때부터 방향을 다시 잡았다. 사람이 보기 좋게 한 번 다듬는 것도 필요하지만, 기본값은 게임 데이터 원본이어야 한다. 그래야 새 패치가 들어와도 다시 손으로 전부 고치지 않는다.
sync 스크립트를 TypeScript로 다시 쓴 이유
4월 8일쯤부터는 동기화 스크립트를 제대로 정리했다.
인격 sync를 TypeScript로 다시 쓰고, 한국어/영어/일본어 로케일 파일을 같이 읽게 했다. identities, sinners, ego, keyword_meta에 name_en, name_jp 같은 필드를 붙이고, 게임 클라이언트 JSON에서 직접 비교할 수 있게 만들었다.
이 작업이 귀찮았던 이유는 단순히 컬럼을 추가하는 게 아니었기 때문이다.
예를 들어 스킬 파일은 오래된 Json (Text) 경로에도 있고, 최신 kr, en, jp 폴더에도 있다. 어떤 파일은 .txt인데 JSON처럼 생겼고, 어떤 파일은 중첩 구조가 다르다. 그래서 그냥 “파일 하나 읽어서 upsert”가 아니라, 폴더를 뒤지고, 패턴을 걸고, 실패하면 dry-run에서 먼저 보이게 해야 했다.
이때부터 sync 스크립트의 기준을 이렇게 잡았다.
- 먼저 원본 게임 데이터를 읽는다.
- DB에 있는 값과 비교한다.
- dry-run으로 바뀔 내용을 보여준다.
- 사람이 보고 납득하면
--fix로 반영한다.
당연한 얘기처럼 보이지만, 데이터가 수백~수천 행으로 늘어나면 이 차이가 크다. 바로 DB에 쓰는 스크립트는 편하지만, 한 번 잘못 돌리면 어디가 틀렸는지 찾는 시간이 더 든다.
다국어화는 번역 파일보다 렌더링 타이밍이 더 어려웠다
영어/일본어 지원도 이때 들어갔다. 처음에는 문자열만 바꾸면 될 줄 알았는데, 실제로는 SSR과 hydration 쪽이 더 힘들었다.
처음 접속했을 때 한국어가 잠깐 보였다가 영어로 바뀌는 문제가 있었다. 언어 전환 때 router.refresh()를 썼다가 전체가 다시 렌더링되는 느낌도 났고, cookies(), use cache, proxy header가 서로 부딪히는 경우도 있었다.
몇 번 돌고 나서야 방향이 잡혔다. 언어는 클라이언트에서 나중에 맞추는 값이 아니라, 서버가 첫 렌더링부터 알아야 하는 값이어야 했다. 그래서 proxy rewrite 기반으로 언어를 태우고, 페이지가 처음부터 해당 언어로 나오게 만드는 쪽으로 정리했다.
이건 블로그에 쓰면 별거 아닌 것처럼 보이지만, 직접 보면 꽤 신경 쓰인다. 페이지가 빠른데 첫 0.2초 동안 다른 언어가 보이면 완성도가 확 떨어진다.
AI 요약도 결국 데이터 품질 문제였다
인격 상세 페이지의 AI 요약도 많이 고쳤다. 모델을 바꾸고, 스트리밍을 붙이고, 프롬프트를 수정한 것도 있지만 제일 중요한 건 입력 데이터였다.
영어 페이지에서 AI 요약을 누르면 영어 스킬명과 패시브 설명이 들어가야 한다. 일본어 페이지면 일본어 데이터가 들어가야 한다. 키워드 칩도 한국어 기준으로만 찾으면 안 되고, 브래킷 키워드를 역매핑해서 툴팁까지 맞춰야 했다.
처음에는 모델이 이상하게 요약한다고 생각한 적도 있었는데, 결국 모델 탓이 아닌 경우가 많았다. 프롬프트에 잘못된 프레임 인덱스나 잘못 매칭된 키워드를 넣으면 모델은 그걸 기반으로 그럴듯하게 틀린다.
이때 배운 건 단순하다. AI 기능은 “모델을 붙였다”에서 끝나지 않는다. 모델 앞단의 데이터 선택이 틀리면 결과도 틀린다.
이 구간을 지나고 나서
이 작업들은 화려한 신기능은 아니었다. 하지만 이후에 새 인격이나 EGO가 들어와도 업데이트를 반복할 수 있는 기반이 됐다.
지금 돌아보면, 최애의 관리자가 한국어 팬 사이트에서 다국어 데이터 아카이브로 넘어가기 시작한 시점이 이 구간이었다. 화면은 비슷해 보여도 안쪽에서는 “원본 데이터 → 로케일 → DB → UI → AI 요약”의 흐름을 다시 묶고 있었다.
커밋으로 보면 e517be1, d420c99, 9ced9dc, 02602b7, f49c482, 374c017 근처의 작업들이다. 한 줄로 쓰면 “i18n 추가”지만, 실제로는 꽤 긴 삽질이었다.
