← 목록으로

진짜 에러는 따로 있다 - 자바스크립트 게임 무한루프와 충돌 판정 버그

2026.07.22 7분 읽기
진짜 에러는 따로 있다 - 자바스크립트 게임 무한루프와 충돌 판정 버그

오랜만이야. 에러노트.

에러노트가 참 오랜만이지. 게임을 다섯 개나 만드는 동안 버그가 없었을 리 있나. 그런데도 뜸했던 데엔 이유가 있어. 언제부턴가 기술적인 문제를 하나하나 늘어놓는 게 나한테는 큰 의미가 없다 싶었어.

솔직히 이런 버그들은 내가 잡는 게 아니거든. 원인 찾고 고치는 건 AI 녀석 몫이고, 녀석은 충분히 해내. 내가 진짜 남기고 싶은 건 그다음이야. 어떻게 하면 같은 에러가 다시 안 나오게 만드느냐. 그게 손에 남는 거더라고.

우선 이 게임을 만들면서 기술적인 에러가 몇 개 있었는데 간단하게 얘기를 해볼게.

첫 번째 - 격자가 중앙에서 영원히 떨기만 했다

처음 게임을 돌리자 적 무리가 화면 가운데서 좌우로 덜덜 떨기만 하고 제 기능을 못하는 거야. 게임이 끝나질 않았지. 녀석이 프레임을 강제로 돌려 20초를 순식간에 재생시키고 방향이 몇 번 뒤집혔는지 세어봤어. 1171번. 정상이면 스무 번 남짓일 텐데 예순 배가 넘었지.

자바스크립트 게임 무한 진동 버그 — 매 프레임 방향을 다시 계산하면 중앙에서 떨고, 방향을 변수로 저장하면 정상 왕복하는 원리

녀석 말로는 갈 방향을 기억 안 해두고 매번 새로 정한 게 화근이었대. 파이썬 원본은 처음부터 기억하고 있었다고 고백했는데 아는 걸 까먹어 버린 거야.

두 번째 - 총알이 적을 뚫고 지나갔다

두 번째는 조준이 맞는데도 적이 가끔 안 죽는 거야. 플레이하다 보면 "빗맞았나" 하고 넘어가기 딱 좋은 버그지. 근데 녀석은 이번엔 눈이 아니라 숫자를 보고 먼저 의심하더라고. 총알이 한 프레임에 46.7픽셀을 뛰는데 적 키가 25픽셀이라, 뭔가 안 맞는다는 거야. 실제로 녀석이 높이를 바꿔가며 60발을 쏴보니 12발이 그냥 관통했어.

자바스크립트 게임 총알 터널링 버그 — 현재 위치만 검사하면 프레임 사이 적을 건너뛰고, 스윕 판정으로 직전 위치까지 덮으면 관통이 사라지는 원리

한 프레임에 적보다 더 멀리 뛰니까 겹치는 순간이 아예 없었던 거래. 직전 위치까지 훑게 고치니 관통이 0으로 떨어졌어.

세 번째 - 이번엔 확인하는 방법이 문제였다

세 번째는 게임 버그가 아니라 확인하는 방법 자체가 어긋났던 경우야. 게임이 어떤 모니터에서든 똑같은 속도로 동작하는지 확인해 보라고 했어. 이전에도 비슷한 문제가 있었거든.

결과만 보면 세 주사율에서 10% 차이가 났어. 근데 녀석 말이, 그 숫자엔 난수가 껴 있어서 이걸로는 판별이 안 된다는 거야.

자바스크립트 게임 프레임 독립성 측정 오류 — 난수가 섞인 지표는 같은 조건에서도 널뛰고, 운이 안 섞이는 값으로 재야 판별이 되는 원리

운이 안 섞이는 값으로 다시 측정하니 세 주사율 다 똑같다고 했어. 멀쩡한 코드였던 거지.

셋 중에 곱씹을 만한 건 이 세 번째야. 버그도 아닌데 제일 오래 붙잡고 있었거든. 차이가 났다고 다 버그는 아니고, 코드가 틀렸는지 확인하는 방법이 틀렸는지부터 가려야 진짜 답이 나오더라고.

오늘의 결론

제작기 끝에 이런 말을 남겼었어.

"이 이야기도 언젠가 기회를 봐서 풀어볼게."

마침 이번 에러노트가 그 얘기를 풀기 딱 좋은 자리였어.

위에 적은 세 가지, 증상은 눈에 보였어도 원인은 눈으로 안 잡혔어. 프레임을 강제로 돌려서 방향 전환 횟수를 세고, 60가지 높이로 쏴서 관통률을 재고, 같은 조건을 다섯 번 반복해서 편차를 확인해야 나왔지. 눈썰미가 아니라 방법으로 찾은 거야. 물론 이 녀석이 말이야.

그러니 오늘 같은 버그는 이제 녀석 몫이야. 내가 진짜 남기고 싶은 에러노트는 따로 있어. 녀석이 저 혼자서는 끝내 못 넘던 벽을 같이 방향 틀어서 넘었을 때. 십자말풀이 만들 때 격자를 먼저 짜느냐 단어를 먼저 고르느냐로 47만 번을 헤맸던 일 같은 거 말이야. 기술 버그가 아니라 녀석도 나도 처음 부딪힌 문제를 어떻게 뒤집었는지, 그런 게 진짜 곱씹을 만한 기록이거든.

처음엔 게임 하나 만들 때마다 새로운 개념 하나씩 배우는 게 목표였어. 배열을 배우고, 델타 타임을 배우고, 그렇게 쌓아가는 재미였지. 그런데 요즘은 뭘 배우느냐보다 어떻게 잘 시키느냐에 더 신경이 가. 개념을 파악하긴 하는데 그것도 결국 지시를 정확하게 내리기 위한 수단이지, 그 자체가 목적은 아니게 됐어. 코드를 읽는 건 내 영역이 아니었던 거야.

그러다 보니 자연스럽게 손이 가는 게 기록이었어. 한 번 겪은 시행착오를 흘려보내지 않고 기록해두면 다음번엔 같은 질문을 또 안 던져도 되니까. 이번 게임도 파이썬 원본과의 대조, 버그 세 개, 검증 방법까지 다 기록해뒀어. 그게 쌓이면 결과물의 만족도를 알아서 끌어올리는 시스템이 되는 셈이야. 당장의 퀄리티보다, 만족스러운 결과물이 나오게 만드는 틀을 짜는 쪽으로 옮겨간 거지.

이 글도 그 틀 위에서 나왔어. 소재 선정, 문체 점검, 썸네일 생성, 검증, 확인까지 이제는 정해진 절차를 따라 자동으로 작성이 돼. 처음과 비교하면 꽤 능숙해졌달까.

내가 하는 일은 과정에서 느낀 점을 기록하고 생각을 정리해 넘겨주면 이 녀석이 초안을 주고, 내 생각과 다른 점이 있거나 하고 싶은 얘기를 첨부하는 정도야.

실제로 요즘은 작업 시간이 눈에 띄게 줄었고 결과물이나 과정에서 상당히 만족하고 있어. 물론 아직도 조정하고 있지만 오늘과 내일은 또 다를 거야.

P.S. 아, 그리고 사실 이 슈팅 게임 이름은 네온 스트라이커였어. 이 녀석이 추천해준 이름인데 이게 시중에 출시된 게임이 있는 거야. 그래서 중간에 네온 살보로 이름을 바꿨어.

← 이전 글 터지기 전에 잡았다 - 자바스크립트 게임 속도 버그와 델타 타임