띄어쓰기를 점검해 달라는 요청을 받고 라벨 500개를 뽑았습니다. 띄어쓰기보다 큰 게 나왔습니다.
개발노트 · 데이터 · 한글
“메뉴나 탭에서 띄어쓰기가 잘 안 된 부분을 찾아서 고쳐 달라.” 이런 요청은 눈으로 훑으면 반드시 놓칩니다. 그래서 게임을 띄워 놓고 모든 화면을 돌면서 짧은 한글 라벨만 자동으로 모았습니다.
const SEL = 'h1,h2,h3,b,strong,th,summary,.chip,.tab,label,option,dt,small';
for (const v of ["dashboard","plan","menu","inventory","rnd", …]) {
VIEW = v; render();
document.querySelectorAll(SEL).forEach(el => {
const t = el.textContent.trim();
if (t && t.length <= 18 && /[가-힣]/.test(t)) set.add(t);
});
}
500개가 모였습니다. 정렬해서 읽어 내려가는데 두 개가 눈에 걸렸습니다.
🎬 숯폼 릴스 🤍 단곰 적립 이벤트
「숏폼 릴스」와 「단골 적립 이벤트」여야 합니다. 마케팅 탭에 뜨는 광고 채널 이름이고, 게임을 하는 내내 보이는 자리입니다.
이상한 건, 이 오타가 지금까지 한 번도 안 걸렸다는 점입니다. 「숯폼」으로 소스를 검색해도 0건이 나왔습니다.
SHORTFORM: { name:"\u{5c22f}\u{5d3fc} \u{5b9b4}\u{5c2a4}", … }
LOYALTY: { name:"\u{5b2e8}\u{5acf0} \u{5c801}\u{5b9bd} \u{5c774}\u{5bca4}\u{5d2b8}", … }
이름이 유니코드 이스케이프로 저장돼 있었습니다. 언젠가 도구를 거치면서 한글이 이렇게 변환된 것으로 보입니다. 게임에서는 정상적으로 「숯폼 릴스」라고 출력되지만, 소스에는 한글이 한 글자도 없습니다.
그래서 이런 일이 벌어집니다.
글자 하나 차이였습니다.
| 코드 | 글자 | 맞는 글자 |
|---|---|---|
숯 | 숯 (불탄 나무) | 숙 숏 |
곰 | 곰 | 골 골 |
두 이름만 고치는 대신, 그 파일의 이스케이프된 이름을 전부 한글로 되돌렸습니다. 여섯 개 채널 이름이 이제 눈에 보입니다.
name:"SNS 피드" name:"숏폼 릴스" name:"블로그 체험단" name:"동네 전단지" name:"단골 적립 이벤트" name:"인플루언서 협업"
이제 다음에 오타가 생기면 검색으로 잡힙니다.
원래 요청이었던 띄어쓰기도 정리했습니다. 재료 이름은 전부 띄어 쓰는데 메뉴 이름 일부만 붙여 쓰고 있었습니다.
| 구분 | 전 | 후 |
|---|---|---|
| 재료 | 화이트 초콜릿 / 솔티드 캐러멜 | (이게 기준) |
| 메뉴 4개 | 라즈베리화이트초콜릿케이크 … | 화이트 초콜릿 · 솔티드 캐러멜 |
| 재료↔메뉴 | 바닐라빈 페이스트 ↔ 바닐라 빈 라떼 | 바닐라 빈 |
| 언어 선택 | English추가중 | English 추가 중 |
「추가중」은 게임의 다른 모든 곳(「판매 중」 「사용 중」 「자동 저장 사용 중」)과 어긋나 있던 유일한 자리였습니다. 의존명사 「중」은 띄어 쓰는 게 맞습니다.
검색으로 안 잡히는 데이터는 없는 것과 비슷합니다. 이스케이프, 인코딩, 압축 — 사람이 못 읽는 형태로 저장된 텍스트는 리뷰를 통과합니다. 리뷰할 수가 없으니까요.
이번 일 뒤로 원칙을 하나 더 얹었습니다. 사람이 읽는 글은 사람이 읽을 수 있는 형태로 저장한다. 파일 크기 몇 바이트보다, 오타를 3년 뒤에 발견하지 않는 쪽이 훨씬 값어치 있습니다.
그리고 「눈으로 훑어봐 달라」는 요청은 대체로 세어 보는 것으로 바꿔야 풀립니다. 500개를 눈으로 봤으면 저도 못 찾았을 겁니다.