난이도를 감으로 맞추다 봇에게 시켰더니, 봇을 두 마리 만들어야 했습니다


100층까지 내려가는 3D 로그라이크를 만들면서 제일 답이 안 나오던 게 난이도였습니다.

제가 만든 게임이라 이미 다 알고 있어서, 제가 플레이해서 잰 숫자는 못 믿을 게 되더라고요.

그래서 봇에게 시켰습니다. 1층부터 실제 게임을 그대로 플레이하는 봇(src/dev/simBot.ts, 1,002줄)을 붙여서 N판 돌리면 사망 층 분포가 나오게요.

여기까지는 순조로웠는데, 봇을 똑똑하게 만들수록 측정이 망가지기 시작했습니다.

1. 봇을 개선하면 기준선이 죽습니다

처음엔 봇 하나였습니다. 상자도 열고 드래프트도 잘 고르게 계속 개선했어요. 그러다 사망 분포가 바뀌었는데, 그때 손이 멈췄습니다.

이게 게임이 쉬워져서인지, 봇이 잘해져서인지 구분이 안 되더라고요. 회귀를 재는 자(尺) 자체가 매주 늘었다 줄었다 하고 있었던 겁니다.

그래서 프로파일을 둘로 쪼갰습니다.

  • hard기준선 전용. 출구로 직행, 상자 안 열고, 이벤트 전부 거절. 기준선을 뜬 뒤로는 행동 동결
  • human — 체감 난이도용. 상자 들르고, 드래프트를 화면 정보로 점수화해 고르고, 방 이벤트를 상황 보고 판단

사람형 봇에는 원칙을 하나 걸었습니다. “사람이 화면에서 못 읽는 정보는 주지 않는다.” HUD 체력 텍스트, 카드 희귀도 테두리처럼 플레이어가 실제로 보는 것만 파싱합니다. 대신 길찾기(BFS)는 허용했어요. 사람도 미니맵을 보니까요.

2. 기준선은 체감 난이도가 아니었습니다

둘로 나누고 나서 바로 확인된 게 이겁니다. 같은 게임인데 기준선 봇은 6층·9층에서 죽는데, 사람형 봇은 12층 캡까지 3판 전부 무사통과(평균 아이템 46.7개)했습니다.

만약 기준선 숫자만 보고 “평균 8층에서 죽네, 너무 어렵다”고 판단해 난이도를 낮췄다면, 실제 플레이어에겐 맹탕이 됐을 겁니다. 기준선은 회귀 탐지용 자일 뿐이고, “이 게임 어렵나?“에는 사람형 수치로 답해야 합니다.

3. 성장은 복리인데 위협은 선형이었습니다

가장 크게 뒤집힌 건 반대쪽이었습니다. 파밍런(2층마다 전설 보상)을 돌렸더니 160아이템으로 61층까지 무저항 순항했어요.

원인은 단순했습니다. 적 스탯은 15~21층에서 상한에 걸리는데 아이템은 계속 복리로 쌓입니다. 그 뒤로는 게임이 아니라 산책이었던 거죠.

고칠 때 적 HP를 부풀리고 싶은 유혹이 있었는데, 그러면 초반까지 같이 딱딱해집니다. 그래서 30층부터 받는 피해만 가속하는 램프와 스폰 상한 상향으로 갔어요.

결과는 사망 10·10·15·30층입니다. 최상급 파밍을 가정해도 가끔만 뚫리는 분포로 정착했고, 하드런(평균 8.3층)은 15층 미만이라 영향 없다는 것까지 같이 확인했습니다.

💡 팁 / 주의할 점

  • 팁: 자동 측정 장치는 “재는 놈”과 “느끼는 놈”을 분리하세요. 하나로 겸하면 반드시 둘 다 못 하게 됩니다. 기준선 쪽은 성능이 나빠도 상관없습니다. 안 변하는 게 미덕이에요.
  • 주의할 점: CI에는 GPU가 없어서 봇 1판에 30분씩 걸렸습니다. 뷰포트를 640×360으로 줄이고 저품질 모드를 강제하니 5판이 16분으로 줄었어요. 다만 줄여도 되는 건 픽셀뿐입니다. 게임 로직 쪽 상수를 건드려 시간을 줄이면 그건 다른 게임을 측정하는 겁니다.

정리

매일 새벽 하드런 5판을 돌려 기준선(중앙값 5~13층)을 벗어나면 이슈가 자동으로 열립니다.

그런데 이걸 그냥 “실패”로 묶지는 않았어요. 종료 코드를 나눠서 크래시는 job 실패로, 기준선 이탈은 이슈로 갑니다.

진짜 고장과 튜닝 신호가 같은 색 알림으로 오면, 저부터 둘 다 무시하게 되더라고요.


태그: #게임개발, #로그라이크, #밸런싱, #자동검증, #Playwright, #클로드코드, #AI개발, #threejs, #CI, #인디게임