FFT 바다 엔진에서 갈라져 나와 낚시 게임을 만들고 있습니다. 첫 관문은 캐스팅이었습니다. 조준하고, 힘을 모으고, 날아가고, 물에 떨어지고, 감아 들이는 한 바퀴입니다.

줄은 늘어나지 않습니다

낚싯줄을 스프링으로 만들면 안 됩니다. 늘어나지 않는 줄은 곧 아주 뻣뻣한 스프링인데, 그건 명시적 적분기가 발산하는 바로 그 조건입니다.

속도 대신 위치를 들고 다니면서 "길이"를 제약으로 푸는 방식(베를레 체인)을 썼습니다. 뻣뻣할수록 어려워지는 문제를 뻣뻣할수록 쉬워지는 문제로 바꾼 셈입니다.

제약은 당기기만 하고 밀지 않습니다. 줄이 짧아지면 끌어당기지만, 길이가 남으면 아무것도 하지 않고 늘어집니다. 낚싯줄은 루어를 받쳐 올리지 않으니까요.

조준을 조타에서 떼어 낸 건 편의가 아닙니다

처음엔 배가 보는 방향으로 던지게 하려 했습니다. 안 됩니다.

배의 방향타는 전진 속도가 있어야 듣습니다. 물이 흘러야 힘을 받으니까요. 그런데 캐스팅은 배를 세워 놓고 하는 일입니다. 캐스팅이 가능할 만큼 세운 배는 돌릴 수가 없습니다. 조타로 조준하게 두면 조준이 필요한 바로 그 순간에 조준이 불가능해집니다.

그래서 조준 방향을 배의 방향과 완전히 분리했습니다. 편의 기능처럼 보이지만 없으면 게임이 성립하지 않습니다.

루어가 물속에서 사라졌습니다

여기가 이번 작업에서 가장 재미있었던 부분입니다.

물 아래를 보이게 하는 굴절 패스는 화면 좌표를 파면 기울기로 꺾은 뒤 그 자리를 읽습니다. 그런데 꺾은 자리가 물체를 빗나가면 물체는 없는 것이 됩니다. 가늘수록 잘 빗나갑니다.

크기를 바꿔 가며 쟀습니다. 9.3m 거리, 수심 0.5m, 배경 물 대비 밝기입니다.

물체 크기보이는 정도
0.23m (실제 루어 크기)4 / 255
0.92m242 / 255
2.76m250 / 255

물고기가 잘 보였던 이유가 여기서 밝혀졌습니다. 물고기는 0.32~0.92m라 우연히 임계값 위에 있었던 것입니다.

10cm짜리 루어를 1m로 키우면 그림은 고쳐집니다. 대신 게임이 망가집니다. 팔뚝만 한 루어를 던지는 낚시가 되니까요.

실제 낚시가 쓰는 답을 그대로 썼습니다. 수면에 찌를 띄우고, 루어는 그 아래 안 보이는 채로 둡니다. 찌는 수면 위에 있으니 굴절 패스가 아니라 일반 렌더에 그려져서 또렷합니다. 플레이어가 보는 것도 원래 찌입니다. 낚시가 원래 그렇습니다.

렌더링 한계를 우회한 게 아니라, 그 한계가 현실의 어떤 사정과 같은 모양이라는 걸 알아본 경우였습니다.

줄도 같은 이유로 수면에 얹었습니다

줄에도 같은 문제가 있었습니다. 물에 잠긴 구간이 3분의 1쯤 통째로 사라져 있었습니다. 줄은 루어보다 더 가늘어서 당연했습니다.

줄을 수면에 뜨게 했습니다. 이것도 물리적으로 맞습니다 — 모노필라멘트 줄은 거의 중성부력이라 실제로도 수면 근처에 뜹니다.

실측

항목
만충 캐스팅2.75초 · 45.3m
67% 캐스팅2.17초 · 28.5m
착수 후 정착2.6m
릴링2.4m/s (45m 회수 18.4초)

두 번 데인 것

낚싯대가 안 보인다고 한참 헤맸는데, 원인이 렌더링이 아니었습니다.

카메라를 어딘가 보게 만든 뒤 행렬을 갱신하지 않으면 이전 자세로 투영됩니다. 그러면 있는 물체가 화면 밖으로 나가고, 증상은 정확히 "안 보인다"입니다. 없는 걸 찾느라 있는 걸 못 봤습니다.

또 하나는 곡선의 길이를 캐시해 둔 것이었습니다. 낚싯대가 휘면 길이가 달라지는데 캐시된 값을 계속 써서 대가 사라졌습니다.

둘 다 인수인계 문서에 적어 뒀습니다. "안 보인다"는 증상은 원인 후보가 너무 넓어서, 겪은 사람이 적어 두지 않으면 다음 사람이 처음부터 다시 좁혀야 합니다.