프로젝트·학습
포메이션 대신 한 장면을 지휘하게 했다: 전술 웹게임 ‘다음 수’ 제작기
AI가 자료 정리와 초안 편집을 보조했고, 핵심 주장과 공개 여부는 작성자가 검토했습니다.
DAKER의 월드컵 전술 웹서비스 챌린지를 보고 처음 떠올리기 쉬운 형태는 포메이션 보드였다. 선수를 끌어다 놓아 4-3-3이나 3-4-3을 만들고, 완성된 대형을 보여 주는 서비스다. 그런데 배치가 끝난 뒤 무엇이 달라지는지 보여 주지 못하면 조작은 있어도 결정의 무게는 남지 않았다.
반대로 축구 경기 전체를 시뮬레이션하려고 하면 선수 능력치, 공의 움직임, 압박과 커버, 체격과 공중볼, 팀 전체의 연쇄 이동까지 다뤄야 한다. 짧은 웹 프로젝트가 축구 매니지먼트 게임의 축소판이 되기 시작하면 사용자는 읽어야 할 것이 많아지고, 나는 검증할 수 없는 숫자를 계속 만들어야 했다.
그래서 범위를 경기 전체가 아니라 결정이 필요한 한 장면으로 줄였다. 상대가 무엇을 할지도 숨기지 않았다. 모든 수를 본 상태에서도 무엇을 지키고 무엇을 포기할지 골라야 하는 전술 게임, 다음 수는 그렇게 만들었다.

정답을 맞히는 대신 우선순위를 정하게 했다
이 프로젝트의 핵심 질문은 “상대 전술을 맞힐 수 있는가?”가 아니다. 상대의 주 경로와 대안 경로를 실행 전에 모두 보여 준다. 정보가 부족해서 틀리는 게임이 아니라, 모든 위험을 동시에 막을 수 없을 때 우선순위를 정하는 게임이다.
사용자는 같은 경기 84분에 벌어질 수 있는 세 가지 재구성 상황을 차례로 다룬다.
- 코너킥에서 첫 공, 파포스트 대안, 세컨드볼과 역습 출구를 나눈다.
- 빌드업 압박에서 중앙 차단과 측면 덫을 어떻게 벗어날지 정한다.
- 막판 롱볼에서 첫 경합, 뒷공간, 낙하 지점과 전진 출구를 배분한다.
각 문제에는 네 명의 선수와 다섯 개의 공간이 있다. 사용자는 선수를 직접
이동해 네 공간만 채운다. 한 공간은 남을 수밖에 없다. 여기에 팀 전체가
어떻게 움직일지 컴팩트, 전진, 출구 중 하나를 고르고, 이번 선택을
무엇으로 평가할지도 보호, 통제, 역습 중 하나로 정한다.

처음에는 선수 한 명만 체스말처럼 움직이는 방식을 생각했다. 하지만 축구에서 한 선수의 전진은 주변 선수의 간격과 커버를 바꾼다. 그렇다고 열한 명을 모두 조정하게 하면 한 문제를 풀기 전에 지친다. 네 선수의 공간 배치와 팀 원칙을 분리한 것은 이 두 문제 사이에서 택한 절충이었다. 사용자는 몇 번의 선택만 하지만 결과 재생에서는 팀 원칙에 따라 실제 출발점과 도착점이 함께 달라진다.
AI 해설보다 판정 규칙을 먼저 만들었다
“오른쪽에서 수적 우위를 만들었지만 왼쪽 풀백 뒤 공간이 열렸다” 같은 문장을 만들려면 처음에는 AI API가 필요하다고 생각하기 쉽다. 그러나 AI가 그럴듯한 해설을 붙여도 화면의 선수 이동과 같은 원인에서 나온 설명인지 보장하기 어렵다.
다음 수는 런타임 AI와 숨은 확률을 사용하지 않는다. 각 CASE가 다음 네 연결고리를 순서대로 검사하도록 직접 규칙을 작성했다.
- 상대의 첫 위험을 막았는가
- 공개된 대안까지 대응했는가
- 다음 공을 통제할 준비가 됐는가
- 공을 되찾은 뒤 전진 출구가 남았는가
가장 먼저 실패한 연결고리가 대표 장면을 정하지만, 뒤의 준비 상태도 계속
판정한다. 그래서 첫 공을 막았어도 세컨드볼을 잃을 수 있고, 수비 숫자를
늘렸어도 역습 출구는 사라질 수 있다. 결과는 즉시 위험 보호, 다음 국면
통제, 전환 위협을 낮음·보통·높음으로 따로 보여 준다.
여기에는 모든 지표가 동시에 최고인 보편적 정답을 넣지 않았다. 동일한 선택은 항상 동일한 6단계 재생과 결과를 만들지만, 무엇을 성공으로 볼지는 사용자가 고른 기준에 따라 달라진다. 축구를 정확하게 예측한다는 주장이 아니라, 전술 선택에는 서로 교환되는 이득과 대가가 있다는 점을 조작으로 보여 주려는 모델이다.
탑뷰에서 이해하고 선수 시야에서 체감한다
위에서 내려다보는 전술판은 공간을 이해하기 좋지만, 선수가 왜 뒤의 침투를 놓쳤는지는 잘 느껴지지 않았다. 그래서 최초 실패 순간을 관련 선수 뒤에서 다시 보는 2.5D 선수 시야를 추가했다.

이 화면은 진짜 3D 경기도, 실제 선수의 생체 시야도 아니다. 판정 엔진에서 사용한 같은 평면 좌표를 카메라 방향에 맞춰 SVG 원근으로 다시 투영한다. 골대, 공과 주변 선수의 크기·가림 순서를 함께 바꾸고 방향 버튼으로 카메라를 돌릴 수 있게 했다.
탑뷰는 전술의 전체 구조를 설명하고, 선수 시야는 실패 순간을 체감하게 하며, 결과 체크는 어떤 연결고리에서 무너졌는지 확인한다. 서로 다른 세 화면이 같은 판정 프레임을 사용해야 해설과 연출이 따로 놀지 않는다.
축구를 모르는 사람을 위한 페이지는 별도로 뒀다
전술 게임의 선택지는 축구가 익숙하지 않은 사람에게 오프사이드부터 장벽이 될 수 있다. 압박, 커버, 균형, 세컨드볼과 역습 같은 단어도 설명 없이 선택지에 넣으면 초심자에게는 또 다른 능력치 표가 된다.
그렇다고 본 게임을 긴 튜토리얼로 막고 싶지는 않았다. 그래서 전술 캠페인과 별개의 전술 아카데미 페이지를 만들었다. 핵심 개념은 짧은 장면과 함께 설명하고, 오프사이드는 네 가지 상황을 직접 판정하는 퀴즈로 구성했다.

처음 만든 퀴즈는 선수 위치와 패스 선만 보여 줬다. 축구를 아는 사람은 그 선으로 다음 전개를 상상할 수 있지만 초심자는 공이 언제 출발하고 공격수가 언제 움직이는지 알기 어려웠다. 이후 공과 선수의 움직임을 함께 재생하고, 다시 보기로 시작 순간부터 확인할 수 있게 바꿨다. 일반적인 전진 패스와 컷백 상황도 따로 나눴다.
아카데미는 게임의 필수 관문이 아니다. 축구를 아는 사람은 바로 CASE를 풀고, 낯선 사람만 필요한 개념을 확인할 수 있다. 입문자 설명을 핵심 경험에 억지로 섞기보다 접근성을 보완하는 독립 기능으로 둔 것이다.
실제 기록과 만든 상황을 화면에서도 분리했다
대회 주제에는 실제 월드컵 데이터 활용이 포함되어 있지만, 이 게임의 세 전술 장면을 실제 경기 장면처럼 보이게 만들고 싶지는 않았다. 데이터는 다음 세 층으로 나눴다.
| 구분 | 사용 범위 |
|---|---|
| 실제 기록 | 경기 번호·대진·날짜·개최지·스코어, 선수 이름과 기본 포지션 |
| 재구성 상황 | 코너킥·압박·롱볼 국면, 상대 경로, 선수 시작·도착 좌표 |
| 전술 모델 | 배치 적합성, 연결고리 판정, 정성 지표, 결말과 선수 시야 |
실제 사실은 CC0로 공개된 OpenFootball과 Wikidata 자료에서 필요한 필드만 선별했다. 원본 전체 데이터셋을 저장소에 복사하지 않았고, 선수 사진과 팀 로고도 사용하지 않았다. 오프사이드 설명은 IFAB 경기 규칙을 기준으로 직접 작성했다.
외부 축구 API를 붙이지 않은 것도 이 경계와 관련 있다. 심사자가 별도 키 없이 전체 흐름을 실행해야 했고, 무료 API라고 해서 데이터의 상업적 재사용 권리까지 자동으로 생기는 것은 아니었다. 앱의 핵심 기능은 로컬 TypeScript 데이터와 판정 규칙만으로 작동한다.
공개 링크와 검증 범위
공개 저장소의 현재 main은 2026년 7월 26일 22시 19분(KST)의
e19af631 커밋에 머물러 있다. 이 공개 버전에서 기록한 npm test는
TypeScript 검사와 프로덕션 build, 33개 테스트를 모두 통과했다. 테스트에는
세 CASE의 결정론적 판정, 복수 해법, 비지배 결과, 6단계 재생, 2.5D 투영과
카메라 회전, 오프사이드 퀴즈, 서버 렌더링이 포함된다.
공개 상태는 다음 링크에서 확인할 수 있다.
2026년 8월 3일 다시 확인했을 때 웹앱은 익명 요청에 HTTP 200을 반환했고, GitHub 저장소는 공개 상태였으며, YouTube 시연 영상도 공개 메타데이터를 읽을 수 있었다. 다만 테스트 통과가 실제 축구 분석의 정확성을 뜻하지는 않는다. 세 CASE는 교육과 게임을 위해 만든 대체 상황이고, 전술 판정은 공식 선수 능력치나 승률이 아니다. 2.5D 화면도 실제 트래킹 데이터로 복원한 선수 시야가 아니다.
세 링크가 공개돼 있다는 사실과 DAKER 계정에 최종 접수가 끝났다는 사실도 같지 않다. 로컬 기록에는 최종 접수증이나 제출값이 없어 대회 제출 완료 여부를 확정하지 못했다. 따라서 이 글은 “DAKER 챌린지를 계기로 만들고 공개했다”까지만 말한다. 최종 제출, 순위, 방문자 수, 영상 조회수와 상금은 확인된 결과가 생기기 전에는 성과로 쓰지 않는다.
작게 만든다는 것은 선택을 없애는 일이 아니었다
처음에는 기능을 늘릴수록 축구 게임에 가까워질 것이라고 생각했다. 하지만 열한 명의 능력치와 90분의 움직임을 조금씩 흉내 내는 것보다, 한 장면에서 사용자가 책임질 선택을 분명하게 만드는 편이 이 프로젝트에는 맞았다.
범위를 줄일 때 남겨야 할 것은 메뉴의 개수가 아니라 다음 세 가지였다.
- 사용자가 직접 바꾸는 것이 있어야 한다.
- 그 선택 때문에 얻는 것과 잃는 것이 화면에서 함께 보여야 한다.
- 결과를 되감아 한 수를 바꾸고 차이를 비교할 수 있어야 한다.
다음 수가 실제 축구를 대신하지는 않는다. 대신 짧은 웹 인터랙션 안에서 “왜 이 선수를 여기로 옮겼고, 그 대가로 어느 공간을 내줬는가”를 한 번 더 생각하게 하는 것이 이 프로젝트가 책임질 수 있는 범위다.