🍰 디저트 아틀리에

이스케이프 뒤에 숨어 있던 오타 두 개

띄어쓰기를 점검해 달라는 요청을 받고 라벨 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개를 눈으로 봤으면 저도 못 찾았을 겁니다.

← 개발노트 목록