· No.18
시작 예산에 1,240,000 이 들어 있었다 — 틀린 값이 아니라 다른 날의 값이었다
기획 문서의 수치를 코드로 옮기는데, 옮긴 값이 전부 문서에 실제로 있는 값이었고 그중 넷이 잘못돼 있었다. 스냅샷을 초기값으로 쓴 상수, 기댓값 환산치를 런타임 배수로 읽은 상수, 문서와 코드의 단위가 다른 임계값, 그리고 이 넷 때문에 옛 저장 파일을 이행하지 않고 거부하기로 한 판단.
기획 문서에 수치가 확정돼 있었다. 그 값을 코드에 넣는 작업이었다. 문서를 열고, 값을 찾고, 상수에 넣고, 옆에 문서의 절 번호를 주석으로 단다. 단순 작업처럼 보인다.
작업이 끝나고 잡힌 결함이 넷인데, 넷 다 문서에 실제로 있는 값을 정확히 옮긴 것이었다.
① 시작 예산 — 초기값 자리에 중간 스냅샷이 들어 있었다
시작 예산이 1,240,000 으로 박혀 있었다. 문서 어딘가에 그 값이 있다. 있긴 한데 그건 7일차 시점의 예시 상태였다.
초기값은 160,000 이다. 여덟 배 차이다.
여덟 배가 왜 문제냐 하면, 이 게임의 첫날 긴장이 예산이 모자란 것에서 오기 때문이다. 예산이 넉넉하면 이송 슬롯 한도라는 제약 자체가 작동하지 않는다. 버그로 보이지 않는다. 게임이 그냥 안 팽팽해진다. 「값이 틀렸다」가 아니라 「이 값이 원래 하려던 일을 안 한다」로 나타나니, 플레이해도 원인이 안 보인다.
문서의 숫자에는 시점이 붙어 있다. 그런데 코드로 옮기면 시점이 떨어져 나가고 숫자만 남는다. 이게 이번 건의 핵심이었다.
② 할인 계수 — 기댓값 환산치를 런타임 배수로 읽었다
어떤 선택을 미루면 비용이 0.8배가 된다고 코드에 적혀 있었다. 문서에도 0.8 이 있다.
그런데 문서의 0.8 은 밸런스를 검토하려고 계산한 기댓값 환산치였다. 「이 선택을 여러 번 반복하면 평균적으로 이 정도 이득」이라는 설계자의 계산 노트다. 런타임에 실제로 곱하라는 값이 아니다.
그대로 두면 치료비가 조용히 80%로 나온다. 그리고 아무도 안 본다 — 화면에 「할인되었습니다」가 뜨지 않기 때문이다. 그냥 값이 조금 싸고, 플레이는 멀쩡하게 굴러간다.
③ 임계값 — 문서와 코드의 단위가 달랐다
동공 반응을 재는 임계값이 있다. 문서는 밀리미터로 적어 뒀는데 코드는 초로 읽고 있었다.
여기에 눈금 문제가 겹쳤다. 화면의 표시 눈금이 0.01 단위였는데, 그러면 문턱을 넘기까지 세 칸이 아니라 열다섯 칸을 움직여야 한다. 플레이어는 「반응이 둔하다」고 느낀다. 이것도 버그로 신고되기 어려운 종류다.
④ 그리고 저장 파일을 이행하지 않기로 했다
위 셋을 고치면 저장 포맷이 바뀐다. 보통은 이행 코드를 써서 옛 파일을 읽어 준다. 이번에는 거부를 골랐다. 근거가 셋이다.
- 옛 포맷에 격리 상태라는 항목 자체가 없다. 이행하려면 없는 값을 지어내야 한다.
- 눈금이 다르다. 옛 파일의 체온 36 을 새 코드가 36.0℃ 로 읽으면, 0.5 를 기준으로 하는 판정에서 전부 정상으로 뒤집힌다.
- 되돌리기가 없다. 잘못 읽은 상태로 하루를 진행하면 그 판은 복구되지 않는다.
「안 열리는 저장」보다 「잘못 열린 저장」이 나쁘다. 안 열리면 사람이 안다. 잘못 열리면 사람이 모르고, 오판 한 번이 평판 수치로 남는다.
대신 거부할 때 사유를 문자열로 돌려주게 고쳤다. 「파일이 없다」와 「읽을 수 있는데 버렸다」는 전혀 다른 사건인데, 실패를 불리언 하나로 돌려주면 그 둘이 같아진다.
발견 경로 — 넷 다 값 대조로는 안 잡혔다
값 대조는 「코드의 숫자가 문서의 숫자와 같은가」를 본다. 넷 다 그 검사를 통과한다. 잡힌 경로는 각각 달랐다.
- 예산은 플레이해 보니 첫날 제약이 안 걸려서 이상했다.
- 할인 계수는 문서의 그 값 주변 문장을 읽다가 나왔다. 숫자만 보면 안 보이고 「이 값은 ~를 검토하기 위한 환산」이라는 서술을 읽어야 보인다.
- 단위는 화면에 표시된 값과 문서의 값이 자릿수가 달라서 걸렸다.
- 저장 포맷은 새 코드로 옛 파일을 열어 보다가 나왔다.
공통점은 전부 숫자 바깥을 봐야 보였다는 것이다.
지금 이 실수는 어떻게 잡히나
- 상수마다 문서의 절 번호를 주석으로 붙인다. 이게 있으면 「주변 문장」으로 돌아갈 수 있다. 이번 넷 중 셋이 이 주석 덕에 확인이 빨랐다.
- 문서와 코드의 값 대조를 자동화했다(현재 69건). 단위 불일치는 못 잡지만, 한쪽만 고치는 사고는 잡는다.
- 확정되지 않아 임시로 넣은 값은 한 배열에 모아 둔다. 흩어져 있으면 몇 개인지 아무도 모른다. 이번 판에서 8건에서 2건으로 줄었고, 남은 2건은 문서가 비어서가 아니라 그 기능이 아직 없어서 남은 것이다. 그 구별이 목록에 적혀 있다.
시점이 붙은 숫자를 자동으로 가려내는 방법은 아직 없다. 문서에 「초기값」과 「예시」를 표기로 구분하자는 안이 나왔는데, 표기 규칙은 지키지 않으면 없는 것과 같아서 그것만으로는 못 막는다.