출사표: 북벌
2026제갈량의 북벌을 다룬 삼국지 전략 시뮬레이션입니다. 제갈량이 되어 북벌이 왜 그렇게 어려웠는지 겪어 볼 수 있습니다.

제갈량의 북벌을 다룬 삼국지 전략 시뮬레이션입니다. 플레이어는 제갈량이 되어 한중에서 내정을 다스리는 한편, 기회를 보아 군을 일으켜 북벌을 시도합니다. 장안을 함락시키면 승리하고, 한중이 함락되거나 제갈량이 사망하면 패배합니다. 퇴근 후 틈틈이 만들다 보니 5월 말에 시작한 것을 8월이 되어서야 마무리했습니다.
왜 삼국지 게임을 만들었나
돌이켜 보면 어린 시절부터 언젠가는 게임을 만들고 싶어서 프로그래밍을 손에서 놓지 않았던 것 같습니다. 옛날 PC 통신에 GW-BASIC으로 만든 간단한 삼국지 게임을 업로드했던 기억도 아직 나고요. 물론 그동안은 역량도 부족했고 여유도 없었기에 게임 만들기는 버킷 리스트에만 넣어 두고 있었는데, 2026년 들어서는 드디어 웹 인터페이스로 전략 게임을 만들어 볼 만하지 않을까 하는 생각이 들었습니다.
우선 추억의 90년대 KOEI 삼국지나 대항해시대 같은 것부터 생각이 났지만, 게임 속 수많은 요소를 구현할 걸 생각하면 일이 너무 커질 것 같고, 그렇다고 단순한 게임을 만들기는 싫고… 그러다 문득 예전에 2차 세계대전 전략 게임인 Hearts of Iron을 독일로 플레이했던 기억이 났습니다. 모스크바를 공략하려다 석유가 부족해지자, 딱히 역사를 따라 할 생각은 없었는데도 결국 카프카스의 유전을 확보하기 위해 군대를 움직이게 되었는데요. 그런 느낌이 나도록 어떤 역사적 인물이 처한 전략적 상황에 집중해서 게임으로 만들어 보면 어떨까 싶었습니다.
게임은 일단 재미가 있어야 하니, 역사 속에서 최종적으로 승리한 경우보다는 패배했지만 잘 싸운 것으로 유명한 경우들을 떠올려 보았습니다. 제갈량, 한니발, 롬멜 같은 이름이 생각났는데, 저는 가급적 고증을 지키는 걸 좋아하는 성향이라 역사적 사실이나 당시의 전략적 상황에서 크게 벗어나고 싶지는 않았습니다. 물론 고증을 너무 지켜 버리면 재미가 없겠죠. 북아프리카 전역과 제2차 포에니 전쟁을 다룬 게임을 프로토타입으로 간단히 만들어 보았는데, 롬멜은 어떤 수를 써도 알렉산드리아로 갈 수가 없었고, 한니발은 승리 조건을 로마와 평화 협정을 맺는 것으로 두어야 했습니다. 그런데 플레이어가 원하는 것은 그런 것이 아니겠죠.
그런 점에서 제갈량의 북벌은 꽤 괜찮아 보였습니다. 특히 1차 북벌은 성공 가능성이 없지 않았던 것 같고, 삼국지나 출사표라는 서사도 워낙 잘 알려져 있으니까요.
북벌은 어려워야 했습니다
삼국지를 다룬 게임은 정말 많습니다. 그런데 북벌이 어려웠던 게임은 별로 없었던 것 같습니다. 장수 놀음인 삼국지 게임에서 촉한은 플레이어가 잡으면 결코 약한 세력이 아니니까요. 그래서 위연의 자오곡 계책을 받아들이지 않을 만큼 신중했던 제갈량의 사정을 게임에서 느끼기는 쉽지 않습니다. 촉과 위의 국력 차이, 한중에서 관중으로 이어지는 긴 보급로, 그리고 제갈량에게 남은 수명 같은 것들 말이죠.

그래서 이 세 가지를 게임의 가장 큰 제약으로 삼았습니다. 그렇다고 이길 수 없는 게임을 만들 생각은 없었습니다. 잘 준비하고 기회를 잡으면 장안을 함락시킬 수 있지만, 이 문제들을 가볍게 보면 실패할 수밖에 없는 정도를 생각했습니다. 그중 제갈량의 수명은 보이지 않는 값으로 만들었습니다. 식소사번(食少事煩)이라는 말이 있을 만큼 제갈량은 매사를 직접 처리하며 격무에 시달렸습니다. 이를 반영해 제갈량이 이것저것 직접 일을 맡으면 위와의 국력 차이를 어느 정도 메울 만큼 성과가 나오지만, 그만큼 수명도 닳아서 실제로 제갈량이 죽은 234년 가을쯤에는 《삼국지연의》에서 따온, 북두칠성에 수명을 비는 이벤트가 나타나도록 했습니다.

고증을 반영한 게임을 만들었습니다
가장 먼저 눈에 들어오는 게임 맵 이미지는 실제 지형을 그대로 옮겨 그린 것이 아닙니다. 한중 분지와 관중 평야 일대의 지형도를 ChatGPT에 주고, 진령산맥을 넘어가야 하는 촉군의 상황이 느껴지는 게임 지도로 바꿔 달라고 해서 만든 것입니다. 전체 모양은 다소 닮았지만 이미지 생성의 특성상 어느 정도 차이는 감수해야 했습니다. 실제 지형 정보로 3D 렌더링을 해서 게임 지도로 써 보기도 했는데, 별로 예쁘지가 않았습니다. 그래서 일단 생성된 이미지 위에 눈대중으로 거점을 직접 배치했습니다.
대신 화면에서 가까워 보인다고 실제로도 가까운 곳으로 처리하지는 않았습니다. 거점들의 실제 추정 위치를 바탕으로 거리를 계산해 게임 속 이동 경로에 반영했고, 진령산맥을 넘는 길은 바이두 백과의 촉도(蜀道) 항목까지 찾아보며 경로를 잡았습니다. 그래서 지도만 보면 금성과 무위가 아주 가까워 보이지만, 실제로는 꽤 멀고 게임 안에서도 열흘 이상이 걸립니다. 이미지에 위치를 맞추다 보니 실제 추정 위치나 지형과 다른 곳에 놓인 거점도 있습니다. 거점 간 이동 경로도 편의상 직선에 가깝게 단순화했습니다. 그래도 화면에 보이는 것과는 별개로, 예를 들면 가정(街亭)이 전략적 요충지라는 점 같은 것들은 플레이하면서 자연스럽게 느껴지도록 만들어 보려고 했습니다.
그리고 AI에게 잔도에서는 부대가 느리게 움직이게 해 달라고 하면 일단 그럴듯한 숫자를 넣어 줍니다. 처음에는 그것으로 충분할 줄 알았는데, 결국 이것도 고대 군대의 대략적인 이동 속도를 조사해 지형에 따라 달라지게 했습니다. 전투 결과는 단순하게 계산되지만, 고대 전투에서 패한 쪽은 추격당하며 사망자가 많이 나고 승리한 쪽은 부상병을 수습할 여지가 크다는 점을 반영했습니다. 패주 중 추격으로 입은 피해는 영구 손실로 잡고, 승리한 쪽은 부상병 일부를 회복하도록 한 것입니다.

또, 공성전에서는 수비 측이 훨씬 유리하게 했습니다. 그렇다고 위군이 장안에만 틀어박혀 있게 하지는 않았습니다. 거점을 계속 잃으면 공격성이 높아지고 장안에 필요한 병력만 남긴 채 촉군을 요격하거나 빼앗긴 거점을 되찾고 보급선을 끊으러 나옵니다. 게임의 승리 조건만 보면 위나라는 장안만 지키면 되는 것 아니냐고 생각할 수 있겠지만, 현실에서는 그런 장수라면 군주의 의심을 사거나 부하들의 불평을 잔뜩 듣겠죠.
아울러 《한진춘추》에 전하는 노성 전투를 바탕으로 사마의의 호전성은 처음에 높게 두되, 본대가 제갈량의 본대에 한 번 패하면 공격성을 낮추고 견벽거수(堅壁拒守), 즉 지구전으로 돌아서게 했습니다. 이런 류의 게임이 흔히 그렇듯 내정 기반이 갖춰지면 후반에 할 일이 없어지기 쉬워서, 지속적인 랜덤 이벤트와 후반 전용 명령도 만들어 두었고요.
그 밖에도 손권의 칭제를 두고 제갈량이 쓴 절맹호의(絶盟好議)의 일부를 이벤트 텍스트에 옮기는 등, 실제 역사에 남은 제갈량의 글을 게임 속 스크립트에 담아 보기도 했습니다.

개인적으로 특히 넣고 싶었던 것은 직백오수(直百五銖)였습니다. 유비가 촉을 얻은 뒤 오수전의 100배 가치를 매긴 동전을 발행해 짧은 시간에 국고를 채웠다는 기록이 있습니다. 출토된 직백오수 가운데에는 촉한 후기로 갈수록 훨씬 작고 가볍게 만든 것들도 있습니다. 요컨대 유비 정권은 경제학 용어로 말하면 주조차익(seigniorage)을 챙긴 것입니다. 그래서 이걸 게임에서 돈만 늘어나는 좋은 정책으로 만들 수는 없었습니다. 그렇다고 촉의 내정을 북벌만을 위한 수탈적인 전쟁 기계로 그리는 것도 제갈량의 정치를 설명하기에는 맞지 않아 보였고요. 결국 제갈량에게 남은 시간은 한정되어 있으니 민심을 희생해서라도 국고를 확보할지를 저울질하는 전략적 선택으로 그려 보았습니다.
바이브 코딩으로 게임을 만드니
바이브 코딩으로 만든 만큼 직접 작성한 코드는 없습니다. 5월 말에 GPT-5.5로 첫 프로토타입을 만들었고, 본격적인 작업은 거의 Claude Opus 4.8로 진행했습니다. 작업이 길어지는 사이 Claude Fable 5가 나와서 기능 추가와 밸런스 검토는 Fable 5로 했고, GPT-5.6 Sol로 코드 리뷰를 더했습니다. 이미지는 ChatGPT Image 2.0, 배경음악은 Suno로 만들었고, 효과음은 무료 에셋 사이트에서 적당한 것을 골랐습니다.
처음 프로젝트를 시작할 때에는 막연한 아이디어만 있다 보니, 한 번에 게임을 다 만들려 하기보다 메인 화면과 핵심 개념 구현만 목표로 프롬프트를 쓰는 편이 나았습니다. 이 게임도 “지도 위에 거점이 있고, 거점 사이 경로를 따라 부대가 이동하고, 상대의 거점이나 부대와 만나면 전투가 벌어지는 웹 전략 게임”을 만들어 보자는 것에서 시작했습니다.
그런데도 완성하기까지 여름이 다 갔습니다. 틈틈이 작업한 것이라지만, 군대 유닛이 잔도에서 하루에 얼마나 움직일지, 위군 AI는 촉군의 움직임을 어느 시점에 알아차릴지, 패주한 부대는 어디까지 물러나야 할지… 이런 것들은 결국 제가 정해야 했습니다. 처음에는 기획 문서까지는 아니더라도 만들고 싶은 내용을 다 써 줘야 했고요. 더 큰 문제는 제가 말하지 않은 부분이었습니다. Claude는 제가 언급하지 않은 것이 있어도 그걸 비워 두지 않고 대체로 그럴듯하게 채워서 결과를 만들어 줍니다. 앞서 말한 잔도의 이동 속도가 그랬고, 전투 결과 계산 같은 것들도 처음에는 다 그럴듯했습니다. 그런데 그럴듯한 것과 제가 만들고 싶은 것은 사실 다른 것이었고, 그 차이는 플레이해 보기 전에는 잘 보이지 않았습니다. 그러다 보니 실제로 가장 오래 한 일은 플레이하면서 그런 부분을 찾아내어 왜 이렇게 되어 있는지 묻고, 제 생각과 다르면 Claude Code에 그걸 설명하는 글을 입력하는 일이었습니다. 그럴 때면 Claude는 제가 결정한 내용을 주석으로 남겼는데, 나중에 코드를 열어 보니 이런 주석이 꽤 많았습니다.
기능 외에도 등장인물 간 대화나 명령 설명 같은 텍스트를 Claude에게 써 보라고 했더니 거의 다 마음에 들지 않아 결국 전부 직접 검수했습니다. AI 특유의 문체도 거슬렸지만, 등장인물끼리 대화할 때 고증대로라면 아랫사람이나 적대적인 관계가 아닌 한 이름을 함부로 부르지 않고 벼슬이나 자(字)를 불러야 할 텐데 그냥 이름을 불렀습니다. 또, 제갈량과 대화하는 부하들이 황제에게 하듯 무조건 자신을 신(臣)이라 칭하고 있었는데 그것도 좀 어색하게 느껴졌고요. 그러니까 얼핏 보면 틀린 문장은 아니지만 잘 뜯어보면 어색한 대사들이었습니다. 그래서 코드 리뷰는 Fable 5와 GPT-5.6 Sol에게 맡겼지만 텍스트 검수만큼은 직접 했습니다. 물론 코드 리뷰도 코드만 직접 안 봤을 뿐이지, 결국 직접 플레이하면서 의도하지 않게 만들어진 부분이나 오류를 찾아내야 했고요.

작업이 길어지다 보니 AI에게 내용을 처음부터 다시 설명해야 하는 일도 종종 있었는데, 이때는 소스 코드에 남은 주석과 테스트 코드가 생각보다 큰 도움이 되었습니다. 의도대로 기능이 작동하는지, 게임 내 밸런스가 적절한지를 평가하는 테스트가 꽤 만들어져 있었고, AI도 이런 테스트를 읽어 맥락을 파악하는 모습을 볼 수 있었습니다. 처음부터 설계 문서를 따로 만든 것은 아니지만, 지나고 보니 왜 그렇게 만들었는지에 관한 기록은 대부분 코드 안에 남아 있었습니다.
그래서 바이브 코딩이면 정말 게임도 바로 뚝딱 만들 수 있느냐고 묻는다면, 엄청나게 편해진 것은 맞지만 그렇지는 않다고 답하겠습니다. 코드를 쓰지 않아도 되니 예전 같으면 엄두도 못 냈을 일을 퇴근 후 여유 시간만으로 혼자 해낼 수 있었습니다. 하지만 어떤 게임을 만들고 싶은지, 무엇을 살리고 무엇을 버릴지는 여전히 제가 정해야 했습니다. 오히려 AI는 묻지 않으면 그럴듯하게 알아서 만들어 버리는 편이라서, 제가 정하지 않은 것이 무엇인지 찾아내는 일까지 제 몫이 되었습니다. 즉, 바이브 코딩이라고 하면 마치 AI에게 모든 걸 맡기고 결과만 받아 보는 일 같지만, 정말 제가 만들었다고 할 만한 게임을 완성하기까지는 결국 제갈량처럼 모든 일을 직접 챙겨야 했습니다.
한 번 해 보신다면
이 게임은 데스크톱 전용입니다. 지도가 커서 좁은 화면에는 아무래도 맞지 않아 모바일 대응은 생각하지 않았습니다. 역사대로 마속과 왕평에게 가정을 맡겼다가 패하는 경우가 아니라면, 첫 북벌은 아마 군량이 떨어져 한중으로 물러나게 될 것이고, 그 뒤로도 계속 군량이 북벌의 발목을 잡을 겁니다.
그럼, 이제 플레이하시면서 왜 제갈량의 북벌이 어려웠는지 조금 느껴 보시면 좋겠습니다. 혹시 장안에 한나라의 깃발을 다시 꽂으신다면… 그건 제갈량도 못 한 일이죠! 그리고 삼국지에 관심이 있는 분이라면 게임에 넣어 둔 수십 개의 역사 이벤트를 하나씩 수집해 보시는 것도 재미가 되겠네요. 이 게임은 kongming.jwlee.kr에서 바로 플레이할 수 있습니다.