알고리즘에서 모험으로
Source: Dev.to

이전 글(From Ruby to Swift: Building a Maze Generation Framework)에서 나는 미로 알고리즘에 빠진 이야기를 공유했습니다. Jamis Buck의 Ruby 코드를 Swift로 포팅하고, 시각화 엔진을 만들며, “완벽한” 미로를 이해하는 지적 즐거움에 대해 썼었죠.
그 프로젝트를 MazeGenerator 프레임워크와 기술 데모로 마무리했습니다. 작업의 90%가 끝난 느낌이었고, UI만 감싸고 “시작” 버튼만 추가하면 게임이 될 거라 생각했습니다.
그것은 착각이었습니다. 나는 시뮬레이션을 만들었을 뿐, 게임은 아니었습니다. 시뮬레이션을 게임으로 바꾸는 과정에서 나는 안 좋은 설계 선택, 혹독한 피드백, 그리고 “재미”에 대한 완전한 전환을 겪게 되었습니다.
The “Nerd” Trap (v1.0)
게임을 만들기 전에 게임 엔진을 먼저 만들면 잘못된 것에 가치를 두게 됩니다. 나는 알고리즘에 집착했습니다. 플레이어가 Recursive Backtracker(길고 구불구불한 강)와 Prim’s Algorithm(짧고 유기적인 가지)의 차이를 느끼길 원했죠.
게임의 첫 번째 버전은 기본적으로 기술 데모에 컨트롤만 추가한 것이었습니다.
핵심 루프: 알고리즘을 선택하고, 미로를 생성하고, 풀고, 벽에 닿지 않으면서 점수를 깎이는 것을 피합니다.
“멋진” 기능: 손가락으로 모양을 스케치하면 프레임워크가 그 주위에 미로를 생성하는 “Draw Mode”.
교육적 요소: “Diagonal Bias”와 “Spanning Trees”를 설명하는 정보 화면.
나는 이것이 훌륭하다고 생각했지만, 실제로는 지루했습니다.
The Reality Check
자신이 직접 사용해 보지 않으면 사람들을 설득할 수 없습니다. 나는 게임을 폰에 설치하고 Balatro나 Mini Motorways 대신 플레이해 보았습니다. 한 시간도 버티지 못했죠. 즐거움을 주거나 더 많은 점수를 얻고 싶게 만드는 요소가 없었습니다. 나는 지루했습니다.
게다가 “Draw Mode”? 손가락이 두꺼운 상태로 화면에 마스크를 그리면 블록처럼 못생긴 형태가 됩니다. 기술적으로는 멋졌지만 사용자 경험은 최악이었습니다.
Finding the Fun
세 달째였습니다. 코드베이스는 아무도 신경 쓰지 않는 기능들(알고리즘 선택기, 학습 탭, 맵 에디터)로 뒤죽박죽이었습니다. 선택의 기로에 섰습니다: 아무도 하지 않을 기술 데모를 출시할까, 아니면 nerdy한 기능을 없애고 게임을 재미있게 만들까.
나는 후자를 선택했습니다.
알고리즘 선택기를 제거했습니다. 교육 콘텐츠를 숨겼습니다. Draw 화면을 없앴습니다.
The Move Limit
플레이어가 벽에 부딪히면 벌점을 주는 방식을 멈추고 Move-Based 시스템을 도입했을 때 돌파구가 열렸습니다.
새 버전에서는 미로를 풀기 위해 제한된 이동 수를 부여받습니다.
- 효율성 중요: 그냥 떠돌아다닐 수 없습니다; 계획이 필요합니다.
- 공정성 보장: 특정 미로 시드에 대해 최적 경로는 고정된 스텝 수입니다. 나는 Dijkstra 알고리즘을 이용해 “Perfect Score”를 수학적으로 계산할 수 있었습니다.
- 긴장감: 이동 수가 다 떨어지는 것은 타이머가 올라가는 것보다 훨씬 스트레스를 줍니다(좋은 의미에서).
갑자기 레이싱 게임이 아니라 전략 게임이 되었습니다.
Building the “Game” Part
핵심 메커니즘을 잡은 뒤에는 이를 진행 시스템에 얹어야 했습니다. 게임은 루프가 아니라 여정처럼 느껴져야 합니다.
다음 요소들을 도입했습니다:
- 파워업: 이동이 핵심이므로 파워업은 경제와 관련되었습니다. “Demolish Wall”은 코인을 사용해 구매하지만, 남은 이동 수가 소진되기 전에 숨겨진 상자를 얻고 돌아올 수 있게 해줍니다. “Jump”는 긴 복도를 건너뛰고 남은 이동을 현금처럼 사용할 수 있게 합니다.
- 지형: 얼음(미끄러져 이동 수를 절약하지만 제어력 상실)과 진흙(이동 수가 두 배) 을 추가했습니다.
- 진행: 점점 어려워지는 레벨을 도입했습니다 – 미로가 커지고, 상자가 최적 경로에서 멀어지며, 지형이 험해집니다. 10레벨마다 보상이 주어지고, 가끔은 희귀 아바타를 잠금 해제하거나 숨겨진 보석을 발견합니다.
The Tech Stack: SwiftUI
전체 게임을 SwiftUI 로 만들었습니다.
많은 개발자들이 SpriteKit이나 Unity 를 권했지만, 격자 기반 퍼즐 게임이라면 SwiftUI 가 놀라울 정도로 충분했습니다.
- State Management: 격자는
VStack과HStack으로 구성되고, 게임 상태에 따라 렌더링됩니다. - Animations: SwiftUI 의 암시적 애니메이션 덕분에 플레이어 이동(타일 간 슬라이드)이 부드럽게 구현되었습니다.
- Iterative Speed: “Mud” 타일 뷰를 한 파일에서 바꾸면 Preview 에서 전체 게임에 즉시 반영됩니다.
가장 어려웠던 부분은 “아이템”과 플레이어 레이어를 미로 레이어 위에 배치하는 것이었습니다. 복잡한 ZStack 레이어링을 사용했는데, 심장이 약한 사람에게는 권하지 않지만 결과는 좋았습니다.
Launching
게임 MZ: Maze Adventures 가 완성되었습니다.
게임 안의 귀여운 아바타는 아내가 디자인했고, 덜 귀여운 것은 제가 만들었습니다. 음악은 아들이 작곡했으며(그도 게임을 플레이하기 위해 다운로드했죠), 알고리즘 선택기, “Draw Mode”, 교육 강의는 전혀 없습니다.
오직 미로만 있습니다. 완벽하고, 답답하고, 아름다운 미로.
지금 바로 App Store 에서 다운로드할 수 있습니다.
