같은 부품으로 만든 네 번째 게임 — 낚시
조이스틱 슈팅 게임은 6부에서 꽂아 만들었습니다. 게임이 셋이 됐고, 다음은 캐비닛 정리라고 썼는데 — 그 전에 하나만 더 만들기로 했습니다.
이번엔 새 부품이 없습니다. 1부부터 있던 맥주 레버와 2부에서 붙인 진동 모터를 그대로 씁니다. 레버를 낚싯대로 보고, 진동을 입질과 장력으로 쓰면 낚시가 됩니다.
처음 설계 — 장력과 진행도 두 수식
장력과 진행도, 두 개의 힘이 반대로 작용하는 구조를 잡았습니다.
장력 = (물고기 힘 + 레버) ÷ 2 → 둘 다 세면 줄이 끊어진다
진행도 = (레버 − 물고기 힘) ÷ 50 → 레버가 이겨야 끌려온다
같은 레버 하나가 한쪽으로는 저를 돕고 다른 쪽으로는 저를 위협합니다. 문서로 보면 꽤 우아합니다. 캐스팅 세기로 거리를 정하고, 멀리 던질수록 큰 물고기가 걸리지만 입질을 오래 기다린다는 도박도 얹었습니다.
만들었습니다. 돌려봤습니다. 재미가 없었습니다.
여기서부터가 이 글의 본론입니다. 네 번의 “이거 이상한데”가 있었고, 그때마다 막연한 감상 뒤에 정확한 숫자가 하나씩 숨어 있었습니다.
첫 번째 — 캐스팅 4단계, “감도 안 잡힌다”
캐스팅이 문제였습니다. 레버를 당겼다 놓아 던지고, 입질을 기다리고, 다시 당겨 후킹하고, 그 다음에 힘겨루기. 단계가 넷입니다. 손에는 레버 하나뿐인데 그 하나로 서로 다른 네 가지 동작을 해야 하니 뭘 하고 있는지 알 수가 없습니다.
정리는 단순했습니다. 캐스팅을 통째로 없앴습니다. 찌가 저절로 물에 내려가 있고, 입질이 오면 채고, 그 다음은 버티기. 플레이어가 하는 일이 둘로 줄었습니다.
승리 조건도 바꿨습니다. “진행도를 채운다”는 추상적인 게이지 대신 “물고기 체력을 0까지 깎는다” 로. 세게 당길수록 물고기가 빨리 지치지만 그만큼 줄이 위험해집니다 — 맞바꿈은 그대로 살아 있고 설명은 한 문장으로 줍니다.
두 번째 — 장력 평균 수식, “줄이 안 달아”
장력 수식이 이 글에서 제일 재미있는 지점입니다.
장력이 (물고기 힘 + 레버) ÷ 2 라는 평균이었습니다. 평균이라는 건 레버가
기여할 수 있는 몫이 아무리 세게 당겨도 절반뿐이라는 뜻입니다. 레버를 물리적
끝까지 밀어도 피라미 상대로는 575, 붕어 상대로는 650. 위험선은 800이었습니다.
넷 중 어느 것도 위험선에 닿지 못했습니다. 맞바꿈이 성립한 적이 아예 없었던 것입니다.

왼쪽이 이전입니다. 레버를 끝까지 당겨도 네 막대 모두 붉은 위험선 아래에 머뭅니다. 오른쪽이 이후입니다. 가중치 합이 1을 넘어(0.7 + 0.5) 세게 당기면 게이지가 실제로 찹니다.
레버가 지배적이고 물고기 힘이 그 위에 얹히는 구조로 바꿨습니다. 물고기 힘이 0이어도 레버만 최대면 693 — 아무 것도 안 걸린 채로 세게 당기는 것조차 위험합니다. 게이지가 절반에서 멈추는 게임과 끝까지 차오르는 게임은 손맛이 다릅니다.
한 가지 더 배웠습니다. 사용자는 “장력이 끝까지 안 올라간다”고 했는데, 저는 처음에 레버 하드웨어를 의심했습니다. 실제로는 레버가 990까지 멀쩡히 올라가고 있었고 문제는 그 값을 절반으로 나누고 있던 제 수식이었습니다. 입력을 의심하기 전에 자기 수식을 먼저 봐야 합니다.
세 번째 — 발작 주기, “물고기가 너무 잘 잡혀”
난이도는 줄이 깎이기 시작했는데도 여전히 낮았습니다. 원인이 둘이었습니다.
발작이 예고편처럼 올라왔습니다. 물고기가 갑자기 힘을 쓰는 구간을 넣었는데, 힘이 한 틱에 40씩만 움직이도록 해뒀습니다. 평소 420에서 발작 950까지 가려면 13틱, 1.3초가 걸립니다. 게이지가 슬금슬금 올라가는 걸 보면서 여유롭게 레버를 내리면 그만입니다. 위협이 아니라 안내 방송이었습니다.
한 틱에 250씩 채가도록 바꿨습니다. 0.3초 만에 최대로 갑니다. 대신 가라앉을 때는 그대로 느리게 둬서, 한 번 물면 한동안 버텨야 합니다.
작은 물고기는 발작을 한 번도 겪지 않았습니다. 첫 발작이 정상 주기(2.64.4초) 뒤에
오는데 피라미 승부는 2.1초, 붕어는 3.5초에 끝납니다. 산술적으로 발작이 올 수가 없습니다.
그냥 당기면 잡히는 물고기였습니다. 첫 발작을 0.51.2초로 앞당기니 모든 물고기가
최소 한 번은 위기를 줍니다.
그리고 사용자가 정확히 요구한 것 — “고기들이 움직일 때 줄 강도가 빨리 달도록”. 발작 중에는 줄이 두 배로 깎이게 했습니다. 꾸준한 장력보다 갑작스러운 충격이 줄을 끊는다는 쪽이 낚시답기도 합니다.
| 물고기 | 붙잡고 버티기 | 발작 대비하며 조절 |
|---|---|---|
| 피라미 | 랜딩 2.1초 (줄 243까지) | 랜딩 2.7초 |
| 붕어 | 줄끊김 1.8초 | 랜딩 5.0초 |
| 잉어 | 줄끊김 1.7초 | 랜딩 8.6초 |
| 월척 | 줄끊김 1.7초 | 랜딩 13.5초 |
작은 물고기는 힘으로 밀어붙여도 되고, 큰 물고기는 반드시 조절해야 합니다. 그제서야 “실력”이라는 게 생겼습니다.
네 번째 — 후킹 판정, “진동이 아예 안 와”
입질 진동은 울리게 해뒀는데 체감이 없다고 했습니다. 래더를 봐도 조건이 맞고, 아침에 맥주 게임 진동은 실측으로 정상이었습니다. 모터도 배선도 멀쩡했습니다.
범인은 후킹 판정이었습니다.
if (레버 위치 >= 450) 후킹 성공
레버를 당긴 채로 입질을 기다리면 어떻게 되나요. 입질하는 순간 이 조건이 이미 참입니다. 후킹이 1스캔 만에 성립하고, 입질 창이 몇 밀리초 만에 닫히고, 진동은 울릴 시간이 없습니다. “손을 떼고 기다리다가 채는” 제 머릿속 그림에서만 동작하는 코드였습니다.
절대 위치가 아니라 얼마나 올렸는지로 바꿨습니다. 창이 열린 뒤 관측한 최저 레버에서 350만큼 채야 걸립니다. 어디서 시작하든 진짜로 채는 동작을 해야 하고, 부수 효과로 입질 진동이 당길 때까지 계속 울립니다. 원래 의도했던 “지금이야”라는 신호가 그제야 신호 노릇을 합니다.
물고기 정체를 그림자로 숨겼다
물고기 숨기기는 고친 이야기가 아니라 더한 이야기입니다.
걸리는 순간 화면에 물고기가 그대로 보였습니다. 월척이 보이면 “아 조심해야지”, 피라미면 “그냥 당기지 뭐”. 결과를 미리 아니까 긴장이 없습니다.
힘겨루기 중에는 물속 그림자만 보이게 했습니다. 뭔가 묵직한 게 걸린 건 알겠는데 그게 뭔지는 모릅니다. 잡아 올려야 비로소 “월척이다!!”가 뜹니다. 놓치면 영영 모릅니다 — “줄이 끊어졌다, 뭐였을까”.

피라미부터 월척까지 네 종류를 같은 상태로 그린 것입니다. 체력 게이지 최대치만 다르고 그림자는 완전히 같습니다.
여기서 함정이 하나 있었습니다. 그림자 크기를 물고기에 맞춰 그리면 크기로 정체가 새어나갑니다. 움직이는 세기도 마찬가지입니다 — 피라미는 힘이 150, 월척은 420이니 그 값으로 흔들림을 정하면 진폭만 봐도 압니다.
그래서 크기와 모양은 전부 상수로 박고, 흔들림은 절대값이 아니라 이번 물고기의 평소와 발작 사이를 0~1로 정규화한 값으로 정했습니다. 어떤 종류든 평소는 0, 발작은 1이라 진폭이 같아집니다. 그리고 눈으로 “비슷해 보이네” 하고 넘기지 않도록, 네 종류를 같은 상태로 렌더해 픽셀 해시를 비교했습니다. 해시가 일치해야 진짜로 같은 것입니다.
이제 크기를 짐작할 단서는 손에 오는 진동과 장력 게이지뿐입니다. 그림을 보는 게임에서 감각을 읽는 게임이 됐습니다.
물고기 그림은 이번에도 생성 AI에게
물고기 그림은 4부와 6부에서처럼 제미나이에 맡겼습니다. 한 줄 프롬프트로 네 종류가 크기 순서대로 나란히 나왔습니다.

왼쪽부터 피라미, 붕어, 잉어, 월척입니다.
다만 이번엔 잔재주가 필요했습니다. 그림 오른쪽 아래에 AI 생성 표식인 별 모양이 박혀 있었는데 배경 제거로는 안 지워졌습니다. 배경과 떨어진 섬이라서입니다. 연결 요소를 분석해 큰 덩어리 넷(물고기)만 남기고 나머지를 지웠더니 깨끗해졌습니다.
부수 효과가 재미있었습니다. 그 별이 월척 조각의 경계 상자를 부풀리고 있어서, 제거하고 나니 월척 크기가 300×287에서 300×201로 정정됐습니다. 화면에서 이상하게 뚱뚱하던 이유가 그거였습니다.
낚시 게임 밸런싱에서 얻은 교훈
- “재미없다”는 감상은 반드시 숫자 하나를 가리킵니다. 번거롭다 → 단계가 넷, 안 끊어진다 → 평균이라 절반만 기여, 너무 쉽다 → 발작이 1.3초에 걸쳐 예고, 진동이 없다 → 판정이 1스캔에 끝남. 네 번 다 그랬습니다.
- 입력을 의심하기 전에 자기 수식을 보십시오. 레버가 끝까지 안 올라간다는 말에 하드웨어부터 뒤졌는데, 레버는 990까지 멀쩡히 갔고 문제는 그걸 2로 나누던 제 식이었습니다.
- 평균은 기여도를 반으로 깎습니다. 두 값을 합쳐 하나를 만들 때 습관적으로 평균을 쓰는데, 그러면 어느 쪽도 혼자서는 최대치에 못 갑니다. 그게 의도인지 한 번은 물어봐야 합니다.
- “안 보이게 했다”는 눈이 아니라 해시로 확인하십시오. 비슷해 보이는 것과 같은 것은 다릅니다. 크기·모양·움직임 어느 하나만 새어도 숨긴 의미가 없습니다.
게임이 넷이 됐습니다. 맥주, 블랙잭, 슈팅, 낚시. 부품은 레버 하나, 버튼 넷, 조이스틱 하나, 진동 모터 하나가 전부입니다. 같은 손잡이를 다르게 읽으면 다른 게임이 된다는 걸 네 번에 걸쳐 확인한 셈입니다.
이제 진짜로 캐비닛을 정리할 차례입니다.
“재미없다”는 감상은 언제나 고칠 숫자 하나를 가리킵니다.
문의
- Email : [email protected]
- Insta : https://www.instagram.com/going.sen/
- Website : https://intosen.com/kr/consult/
댓글
닉네임만 입력하면 바로 댓글을 남길 수 있어요. Google/GitHub 로그인도 가능합니다.