33 KiB
MagnetismHeroes 첫 체험판 기획서
2026-10-06 사용자 결정: 첫 버전은 효과음·배경음악 없이 진행한다. 한국어 숫자·안내 음성 44개와 시각 연출은 유지한다. 아래 효과음·음악 제작·포함·반복·믹싱 기준은 첫 버전의 필수 인수 범위에서 제외하며, 무음 효과음·음악을 미완료로 취급하지 않는다. 이후 추가는 별도 요청으로 진행한다. 음성 순서·오프라인 재생·전환 정리 및 출처·고지 기준은 계속 적용한다.
이 문서는 구현할 게임의 동작과 완료 기준을 정의한다. 대상은 한국어를 사용하는 5~7세이며, 첫 제작 대상은 안드로이드 스마트폰·태블릿이다. 숫자를 이루는 자석을 직접 찾고, 세고, 붙이고, 떼면서 수량과 숫자 기호를 연결한다.
R01. 제작 범위와 학습 목표
- Unity 6 기반의 가로 화면 3D 카툰 게임을 만든다. 설치된 에디터 버전은
6000.6.3f1이다. - 첫 체험판에는 아래에 정의한 30개 스테이지, 순차 해금, 재플레이, 도움, 성공 후 자유 놀이, 기기 내 저장을 포함한다.
- 학습 범위는 1~10 수 세기, 합치기, 분리하기, 두 행동을 함께 쓰기다. 분리는 한 수를 두 수로 구성하는 경험이며, 이번에는 나눗셈·곱셈 교육으로 확장하지 않는다.
- 혼자 오프라인으로 플레이한다. 계정, 서버, 광고, 결제, 사용자 추적을 추가하지 않는다.
- 아이폰·아이패드 지원은 후속 범위다. 이번에 iOS 빌드나 검증을 완료했다고 주장하지 않는다. 앱 스토어 배포도 이번 작업에 포함하지 않는다.
- Numberblocks는 수량을 캐릭터와 연결하는 표현의 참고다. 게임의 캐릭터·배경·자석 표현은 이 프로젝트에 맞게 만든다.
R02. 자석과 친구의 규칙
- 구 형태의 자석 한 개는 항상 1이다. 묶음의 값은 소속 구의 개수와 같다.
- 자석을 합쳐도 각각의 구가 보인다. 큰 구 하나로 대체하거나 구의 크기로 수량을 표현하지 않는다.
- 묶음마다 대표 얼굴 하나와 숫자 표시 하나가 있다. 서로 떨어진 1 두 개에는 각각 얼굴과 숫자 1이 있고, 붙이면 하나의 얼굴과 숫자 2를 가진 친구가 된다.
- 숫자는 묶음 위에 표시하며 카메라를 돌려도 읽을 수 있게 한다. 자석 배열로 숫자 글자의 모양을 만드는 기능은 포함하지 않는다.
- 같은 개수는 어떤 모양에서도 같은 수다. 직선·평면·입체 배열에 따라 정답 여부가 달라지지 않는다.
- 아이가 붙인 모양이 합체 영웅의 몸이 된다. 변신 연출 때문에 정해진 캐릭터 형태로 재배열하지 않는다. 분리 시 두 친구로 모이는 배치 조정은 R04를 따른다.
- 자석은 중력 없이 놓은 위치에 뜬다. 다른 묶음 가까이에 가져가 놓으면 접촉하는 위치에 붙고 하나의 묶음이 된다. 합체 직전에는 붙을 대상을 알아볼 수 있게 한다.
- 합체는 두 묶음의 구를 모두 보존한다. 분리는 기존 구를 두 묶음으로 나누며 구를 생성하거나 없애지 않는다. 한 구는 정확히 한 묶음에 속한다.
- 위치·모양 변경은 구의 정체성을 바꾸지 않는다. 이 원칙으로 중복 계수를 방지하고 저장 후 같은 놀이 상태를 복원한다.
R03. 입체 공간과 터치 조작
| 상황 | 입력 | 결과 |
|---|---|---|
| 일반 상태 | 친구를 한 손가락으로 끌기 | 그 묶음 전체 이동 |
| 나누기 상태 | 구를 짧게 누르기 | 해당 구 선택 또는 선택 해제 |
| 나누기 상태 | 선택한 구를 끌어내기 | R04에 따라 분리 |
| 빈 공간 | 한 손가락으로 쓸기 | 놀이터를 보는 시점 회전 |
| 놀이터 | 두 손가락으로 오므리거나 벌리기 | 확대·축소 |
| 수 세기 상태 | 구를 짧게 누르기 | R05에 따라 한 번 세기 |
- 앞뒤 위치는 시점을 옆으로 돌린 후 끌어 옮기는 방식으로 조절한다. 평면에만 놓거나 정해진 방향으로만 붙도록 제한하지 않는다.
- 놀이터는 한 화면에서 둘러보는 작은 입체 공간이다. 플레이어 캐릭터를 걸어 다니게 하는 넓은 탐험 월드는 만들지 않는다.
- 회전하여 사물 뒤·위·아래를 확인할 수 있고, 각 수집 자석에는 발견하고 잡을 수 있는 시점이 존재해야 한다. 장식물 내부에 완전히 갇힌 자석을 배치하지 않는다.
- 구를 눌렀다가 끄는 동작은 탭과 구분한다. 끌기를 계수나 선택 탭으로 중복 처리하지 않는다.
- 화면 버튼 위에서 시작한 입력은 친구나 카메라를 움직이지 않는다. 두 손가락 조작을 친구 이동·분리로 동시에 처리하지 않는다.
- 화면을 벗어나 놓거나 조작이 취소되면 자석을 잃지 않도록 마지막 유효 위치를 유지한다. 카메라에는 놀이 대상이 복구 불가능하게 사라지지 않는 거리 경계를 둔다.
- 터치 판정 여유, 흡착 거리, 회전·확대 속도, 애니메이션 시간은 실제 조작으로 조정할 값이다. 수량·정답 규칙을 바꾸는 수단으로 사용하지 않는다.
R04. 나누기
- 아이가 친구를 선택하고 ‘나누기’를 누른다.
- 같은 친구에 속한 구들을 눌러 선택한다. 선택된 구를 빛으로 구분하고 선택 개수를 표시한다.
- 선택한 구를 끌어내면 선택한 쪽과 남은 쪽이 각각 하나의 친구로 자연스럽게 모인다.
- 서로 떨어진 구도 함께 선택할 수 있다. 선택 구끼리 물리적으로 붙어 있을 필요는 없다.
- 두 결과 묶음은 각각 숫자와 대표 얼굴을 가진다. 기존 모양은 분리 과정에서 일부 달라질 수 있다.
- N개 친구에서 유효한 선택 수는 1~N-1이다. 0개·전체 선택은 분리를 실행하지 않으며 구를 소실시키지 않는다. 1인 친구는 나눌 수 없다.
- 선택 중에는 한 묶음만 다룬다. 다른 묶음으로 대상을 바꾸거나 나누기를 취소하면 확정하지 않은 선택을 해제한다.
- 분리 후 선택 상태를 종료한다. 떨어진 두 친구는 아이가 다시 가까이 가져오기 전까지 즉시 재합체하지 않는다.
- 예: 5에서 양 끝의 두 개를 선택하면 결과는 항상 2와 3이다. 중간 연결이 끊겼다는 이유로 세 개 이상의 친구가 생기지 않는다.
R05. 탐험하며 수 세기
- 해당 스테이지의 목표 N과 정확히 N개의 자석을 제공한다. 각 자석은 처음에는 분리된 1인 친구로 놀이터 곳곳에 있다.
- 아이는 시점을 돌려 발견한 자석을 직접 끌어와 다른 자석에 붙인다. 누르기만 해도 자동 수집되는 방식은 사용하지 않는다.
- 모든 자석을 하나의 N인 친구로 모은 뒤 하나씩 눌러 센다. 1 스테이지에서도 직접 자석을 끌어 모으는 행동과 한 번 세는 행동이 필요하다. 처음부터 놓여 있다는 이유만으로 수집 완료 또는 성공으로 처리하지 않는다.
- 직접 끌어 놓은 구와 그 조작으로 합쳐진 묶음의 구들을 수집한 것으로 기록한다. 카메라를 돌리거나 자석을 보기만 한 것은 수집이 아니다.
- 세기 입력은 모든 구를 수집하여 하나로 모은 뒤 활성화된다. 처음 누른 구에만 계수 표시를 남기고, 이번에 센 개수에 맞춰 ‘하나, 둘, …, 열’을 들려준다. 이미 센 구를 다시 눌러도 수가 늘지 않는다.
- 뒤쪽 구는 시점을 돌려 찾는다. 위치·모양 변경이나 합체·분리는 이미 센 구의 기록을 지우지 않는다. 분리하여 모으기 조건을 잃으면 다시 하나로 모은 후 세기를 계속한다.
- 성공 조건은 전체 N개 수집 + N개의 단일 묶음 + N개 모두 계수 완료다. 숫자 표시를 읽거나 묶음을 만들기만 해서는 성공하지 않는다.
- 완료 전에는 자석을 추가하거나 반납할 수 없다. 총 N개를 유지한다.
R06. 합치기·분리하기 퍼즐
- 탐험 없이 표에 지정된 묶음들이 준비된 상태로 시작한다. 목표는 만들 친구들의 숫자로 보여준다.
- 놀이 공간에 있는 모든 묶음의 개수를 목표 구성과 비교한다. 순서와 위치는 무관하지만 묶음 수와 각 개수는 같아야 한다.
- 예: 목표가 2와 2이면 4 하나 또는 2·1·1은 오답이다. 2인 친구 두 개를 만들면 성공이다.
- ‘하나 옮기기’ 등 스테이지의 설명은 풀이를 돕는 표현이다. 최종 구성에 도달하면 모두 합친 뒤 다시 나누는 풀이도 인정한다. 특정 제스처 이력이나 최소 횟수를 성공 조건에 넣지 않는다.
- 조작을 확정한 후 정답을 판정한다. 합체·분리 애니메이션의 중간 모양으로 정답을 판정하지 않는다.
- 목표와 다르면 친구가 부담 없는 표정으로 반응하며 계속 조작할 수 있다. 시간제한, 목숨, 실패 점수, 오답에 따른 초기화는 없다.
- 완료 전 자석 공급·반납은 불가능하다. 모든 계산 퍼즐은 자석 총량을 보존한다.
R07. 30개 스테이지
표의 수집은 처음에 흩어진 1인 친구들이다. 구성은 준비된 묶음을 조작하는 퍼즐이다. 같은 숫자가 반복되면 서로 다른 묶음이다.
| 번호 | 종류 | 처음의 구 수 또는 묶음 | 목표 | 경험 |
|---|---|---|---|---|
| 1 | 수집 | 1개 | 1개 모아 세기 | 하나 |
| 2 | 수집 | 2개 | 2개 모아 세기 | 둘 |
| 3 | 수집 | 3개 | 3개 모아 세기 | 셋 |
| 4 | 수집 | 4개 | 4개 모아 세기 | 넷 |
| 5 | 수집 | 5개 | 5개 모아 세기 | 다섯 |
| 6 | 구성 | 1, 1 | 2 | 처음 합치기 |
| 7 | 구성 | 2, 1 | 3 | 하나 더 붙이기 |
| 8 | 구성 | 3, 1 | 4 | 하나 더 붙이기 반복 |
| 9 | 구성 | 2, 3 | 5 | 두 묶음 합치기 |
| 10 | 구성 | 2 | 1, 1 | 처음 나누기 |
| 11 | 구성 | 3 | 2, 1 | 하나 떼기 |
| 12 | 구성 | 4 | 2, 2 | 두 개 함께 떼기 |
| 13 | 구성 | 5 | 3, 2 | 다른 크기로 나누기 |
| 14 | 구성 | 3, 1 | 2, 2 | 나누고 다시 합치기 |
| 15 | 구성 | 4, 1 | 3, 2 | 두 행동 함께 쓰기 |
| 16 | 수집 | 6개 | 6개 모아 세기 | 여섯 |
| 17 | 수집 | 7개 | 7개 모아 세기 | 일곱 |
| 18 | 수집 | 8개 | 8개 모아 세기 | 여덟 |
| 19 | 수집 | 9개 | 9개 모아 세기 | 아홉 |
| 20 | 수집 | 10개 | 10개 모아 세기 | 열 |
| 21 | 구성 | 5, 1 | 6 | 큰 수에 하나 붙이기 |
| 22 | 구성 | 3, 4 | 7 | 다른 두 묶음 합치기 |
| 23 | 구성 | 4, 4 | 8 | 같은 크기 합치기 |
| 24 | 구성 | 5, 5 | 10 | 열 만들기 |
| 25 | 구성 | 6 | 5, 1 | 큰 수에서 하나 떼기 |
| 26 | 구성 | 7 | 4, 3 | 여러 개 골라 떼기 |
| 27 | 구성 | 9 | 5, 4 | 아홉 나누기 |
| 28 | 구성 | 10 | 5, 5 | 열을 같은 크기로 |
| 29 | 구성 | 5, 3 | 4, 4 | 두 친구의 크기 바꾸기 |
| 30 | 구성 | 6, 4 | 5, 5 | 종합 놀이 |
앞의 구성 스테이지는 총량 5 이하, 뒤의 구성 스테이지는 총량 610이다. 뒤 구간에서도 15인 친구를 재료나 결과로 사용한다.
R08. 진행·도움·학습 안내
- 새 저장에서는 1번만 열린다. 스테이지를 성공하면 완료 기록을 남기고 다음 번호를 연다. 완료한 스테이지는 다시 플레이할 수 있다.
- 재플레이에서 풀다가 나와도 이전 완료 기록과 뒤 스테이지의 해금은 유지한다.
- 성공하면 같은 공간과 자석 배치를 유지한 채 축하하고 자유 놀이로 전환한다. 자동으로 다음 스테이지에 이동하지 않는다.
- 자유 놀이에서 ‘다음’을 누르면 다음 스테이지의 저장 상태가 있을 경우 이어 하고, 없으면 처음 상태로 시작한다. 30번에는 존재하지 않는 31번으로 가는 버튼을 제공하지 않는다. 자유 놀이와 스테이지 선택은 계속 사용할 수 있다.
- 6번 첫 진입에서 합치기, 10번 첫 진입에서 ‘나누기 → 선택 → 끌어내기’를 짧게 시범으로 안내한다. 시범은 퍼즐의 실제 구를 조작하거나 완료 기록을 만들지 않는다. 이미 본 시범은 자동 반복하지 않는다.
- 도움 버튼은 현재 상태에 맞는 한 행동을 제안한다. 수집 중에는 아직 모으지 않은 자석 하나, 세는 중에는 아직 세지 않은 구 하나를 알려준다.
- 수집한 구들을 다시 분리하여 여러 친구가 된 경우에는 먼저 합칠 두 묶음을 알려준다. 수집 기록이 모두 있다는 이유로 세기 조건이 아직 안 되는 상태에서 계수 힌트만 제시하지 않는다.
- 구성 퍼즐의 도움은 현재 묶음에서 목표에 접근할 수 있는 첫 행동을 제안한다. 이전 배치에만 유효했던 고정 힌트를 반복하지 않는다. 예를 들어 적절한 묶음을 가리키며 ‘4에서 하나를 떼어 볼까?’라고 안내한다.
- 도움은 자석을 대신 움직이거나 정답을 자동 실행하지 않는다. 도움 사용 횟수로 보상을 깎거나 진행을 막지 않는다.
R09. 성공 후 자유 놀이
- 스테이지를 성공한 자리에서 같은 친구들로 자유롭게 합체·분리·이동·입체 배열을 만들 수 있다.
- 자석을 하나씩 꺼낼 수 있고, 친구를 반납할 수 있다. 묶음에서 일부만 반납하려면 먼저 나누기로 분리한다.
- 화면에 존재하는 구의 합계는 최대 10이다. 10개이면 추가를 실행하지 않고 구를 중복 생성하지 않는다. 반납하면 그 수만큼 다시 꺼낼 수 있다.
- 전부 반납한 빈 공간도 허용한다. 이는 0을 가르치는 별도 스테이지가 아니며, 자석을 다시 꺼낼 수 있다.
- 자유 놀이에는 정답·실패가 없고 완료 기록을 취소하지 않는다.
- 최근 자유 놀이 상태 하나만 보존한다. 다른 스테이지에서 자유 놀이를 시작하면 이 저장은 새 놀이 상태로 교체된다. 스테이지별 미완료 퍼즐 저장과는 별개다.
R10. 시작 화면과 저장·이어하기
- 시작 화면에서 스테이지 선택과, 저장이 있을 때 최근 자유 놀이 이어 하기를 제공한다.
- 스테이지별 미완료 퍼즐 상태를 각각 하나씩 저장한다. 다른 스테이지로 이동해도 이전 스테이지의 배치를 덮어쓰지 않는다.
- 저장이 있는 스테이지를 선택하면 해당 퍼즐을 이어 한다. 저장이 없는 완료 스테이지를 선택하면 처음 배치로 재플레이한다.
- 성공한 퍼즐의 미완료 저장은 제거하고, 완료 기록과 최근 자유 놀이 상태를 함께 갱신한다. 재플레이 중 미완료 저장과 과거 완료 기록은 동시에 존재할 수 있다.
- 복원 대상은 구의 위치, 묶음 소속, 수집·계수 여부, 바라보던 방향과 확대 정도다. 튜토리얼을 본 기록도 유지한다.
- 자석을 놓거나 합체·분리·계수·추가·반납을 확정했을 때, 카메라 조작을 마쳤을 때, 화면 전환·앱 일시 정지 시 저장한다. 손가락을 대고 있는 중간 위치, 미확정 분리 선택, 애니메이션 중간 프레임은 저장 대상이 아니다.
- 중단 시에는 마지막으로 확정한 조작 상태로 돌아온다. 앱이 중간에 종료되어도 반쪽 합체, 구의 복제·소실, 완료만 기록되고 자유 놀이가 비는 상태가 생기지 않도록 저장을 한 단위로 교체한다.
- 기기 내 앱 전용 공간에 저장한다. 기기 간 동기화·여러 사용자 프로필·계정 복구는 범위 밖이다.
R11. 화면·캐릭터·한국어 소리
- 둥근 자석, 표정이 있는 대표 얼굴, 친근한 작은 입체 놀이터로 구성한다. 합체·분리 때 표정과 움직임으로 친구가 바뀌었음을 보여준다.
- 장식은 구·숫자·목표·선택 표시를 가리지 않는다. 탐험용 가림은 시점을 돌리면 해결할 수 있어야 한다.
- 숫자, 목표, 현재 선택 개수, 주요 버튼은 가로 스마트폰·태블릿 화면과 화면 가장자리 안전 영역에 맞춰 배치한다. 실제 기기의 가독성 합격은 후속 검증으로 구분한다.
- 한국어 화면, 하나~열 숫자 읽기와 짧은 안내 음성을 앱에 포함한다. 효과음·배경음악은 첫 버전에 포함하지 않는다. 음성은 네트워크 생성이나 다운로드가 없어도 재생되어야 한다.
- 소리만으로 조작·정답·힌트를 전달하지 않는다. 대응하는 숫자·강조·표정을 함께 보여준다.
- 원본 애니메이션의 캐릭터·음원을 제품 자산으로 가져오지 않는다. 사용할 자산의 출처와 사용 가능 범위를 기록한다.
합체 영웅의 외형
시각적 정체성은 살아 있는 자석 구 + 빛나는 연결부 + 자력 망토다. 붙으면 하나의 영웅 팀이 되고, 나뉘면 함께 돕는 두 팀이 된다는 느낌을 표정과 움직임으로 전달한다.
- 모든 구의 기본 크기는 같다. 매끈하고 둥근 장난감 질감으로 표현하며 각 구의 경계를 구분할 수 있어야 한다. 갑옷이나 몸체 장식으로 구를 덮거나 별도의 머리 구를 추가하지 않는다.
- 대표 얼굴은 기존 구 하나의 표면에 큰 눈·입과 얇은 영웅 마스크로 표현한다. 묶음 위 숫자와 함께 합체·분리 결과에 맞춰 갱신한다.
- 구가 접촉한 부분에는 부드러운 빛의 고리를 표현한다. 연결이 확정되면 붙은 자리에서 묶음 안으로 빛이 퍼져 자력으로 한 팀이 되었음을 보여준다.
- 자력 망토는 묶음 뒤에서 흐르는 얇은 빛의 리본이다. 안정된 상태에서 묶음마다 하나이며 이동·합체·분리에 반응한다. 얼굴·마스크·연결부·망토는 수량에 포함되지 않는 장식이며 독립적인 입력 대상이 아니다.
- 장식은 숫자와 구별 선택·계수 표시를 가리지 않는다. 입체 배치로 가려진 구는 카메라를 돌려 확인할 수 있어야 한다. 선택과 이미 센 구의 표시는 연결부의 장식 빛과 구분한다.
- 같은 수의 다른 배열은 동등한 수량 조건을 만족한다. 모양에 따른 자세·망토 움직임의 차이는 개성 표현이며 능력 등급이나 새로운 정답 조건이 아니다. 1~10 전체에 같은 외형 원칙을 적용한다.
- 시안의 색 조합·마스크 윤곽은 탐색안이다. 최종 색·빛의 강도·망토 길이·동작 시간은 모바일 가독성과 조작감을 보고 조정한다.
합체·분리의 변신 연출
| 단계 | 표현 | 동작과의 관계 |
|---|---|---|
| 합체 후보에 접근 | 두 친구가 서로를 바라보고 구와 망토 끝이 살짝 끌리는 모습 | 붙을 대상을 알리는 미리보기; 구 소속은 아직 바꾸지 않음 |
| 합체 확정 | 접촉부에 빛의 고리, 연결된 구를 따라 빛이 퍼짐 | 확정된 합체 결과를 표현 |
| 한 팀 완성 | 대표 얼굴·숫자·망토가 각각 하나가 되고 짧게 떠오르며 웃음 | 아이가 만든 배치를 유지하고 새 수량 표시 |
| 분리 선택 | 선택 구의 테두리와 선택 개수 표시, 망토 일부가 선택한 쪽으로 흐름 | 선택만으로 두 친구를 만들지 않음 |
| 분리 확정 | ‘톡’ 효과와 함께 연결이 풀리고 양쪽에 얼굴·숫자·망토가 각각 하나씩 생김 | R04에 따른 두 결과 묶음을 표현 |
| 두 팀 완성 | 두 친구가 짧게 서로를 바라보고 고개를 끄덕이는 모습 | 같은 구들이 나뉘어 함께 일한다는 인상 |
연출은 짧게 하고 반복 조작을 방해하는 긴 변신 장면을 넣지 않는다. 흔들림·살짝 떠오르기는 시각 표현이며 확정된 구 ID·수량·기본 배치·계수 기록을 바꾸지 않는다. 취소·다음 조작·화면 전환·앱 복원 시에는 현재 확정 상태에 맞춰 표현을 정리하고 이전 연출이 뒤늦게 얼굴·숫자를 덮어쓰지 않게 한다. 얼굴·연결부·망토는 복원 상태에서 다시 만들며 연출 중간 프레임은 저장하지 않는다.
R12. 구성과 데이터 계약
외부 API는 없다. 게임 규칙, 터치·공간 조작, 화면·소리 표현, 저장을 작은 책임으로 나눈다. 단일 플레이 세션에서 조작을 순서대로 확정하므로 여러 사용자의 동시 쓰기 조정은 필요하지 않다. 물리 연출의 흔들림이나 렌더링 프레임이 수학 상태를 결정하지 않는다.
- 수량·구 소속·합체·분리·계수·목표 판정과 진행 제어는 Unity 객체에 의존하지 않는 순수 C#으로 구현한다. Unity 입력과 화면은 이 규칙을 호출하고 결과를 표현한다. 화면 객체의 직접 변경으로 수학 상태를 바꾸지 않는다.
- 렌더링은 URP, 입력은 Input System, 게임 UI는 uGUI와 TextMeshPro를 사용한다. 묶음의 숫자와 얼굴은 확정 상태에서 계산한다.
- 진행은 명시적인 상태 머신으로 제어하고, Presenter가 상태를 화면에 전달한다. 저장 인터페이스로 파일 접근을 분리하며 시작 코드에서 의존성을 직접 연결한다. 이 범위를 위해 범용 DI·이벤트·MVVM 프레임워크를 추가하지 않는다.
- 고정 스테이지는 ScriptableObject 자산으로 제작하고 실행 시 순수 C# 정의로 변환한다. 실행 중 원본 자산을 수정하지 않는다. 미완료 배치와 완료 기록은 별도의 로컬 JSON 버전 1에 저장한다.
- 개발은 작은 퍼즐의 입력·규칙·화면·저장을 함께 연결한 뒤 확장한다. 최초 수 세기 퍼즐부터 Android APK 설치·실행·이어하기를 검증하고, 전체 기능 완성 후 최종 Android 검증을 다시 수행한다.
스테이지 정의
| 필드 | 의미와 제약 |
|---|---|
id |
1~30의 고유 정수 |
kind |
counting 또는 composition |
initialGroups |
처음 묶음별 양의 정수 배열. 수집형은 N개의 1 |
targetGroups |
목표 묶음별 양의 정수 배열. 수집형은 [N] |
layout |
구와 장식의 초기 배치. 모든 구를 발견·조작할 수 있어야 함 |
초기 총량과 목표 총량은 같고 1~10이다. 표 R07이 정의의 기준이며 데이터 파일에서 임의로 숫자나 스테이지 수를 바꾸지 않는다. 목표 배열은 정렬하여 중복까지 포함해 비교한다.
저장 계약
저장 형식은 로컬 JSON이며 다음 의미와 필드 경계를 보존한다. 직렬화 라이브러리의 내부 선택으로 게임 동작이나 저장 계약을 변경하지 않는다.
| 필드 | 의미와 제약 |
|---|---|
schemaVersion |
최초 버전 1 |
completedStageIds |
중복 없는 완료 번호 목록. 정상 플레이에서 감소하지 않음 |
seenTutorialIds |
merge, split 중 이미 본 안내 목록 |
puzzleStates |
스테이지별 미완료 상태 배열. 동일 번호 최대 하나, 총 최대 30개 |
latestFreePlay |
없음 또는 최근 자유 놀이 상태 하나 |
퍼즐 상태는 stageId, balls, groups, collectedBallIds, countedBallIds, camera를 가진다. 자유 놀이 상태는 sourceStageId, balls, groups, camera를 가진다. sourceStageId는 완료한 스테이지여야 한다.
balls: 상태 안에서 고유한id와 3차원position. 분리·합체·복원 후에도 구 ID는 유지한다. 자유 놀이에서 새로 꺼낸 구는 현재 상태와 충돌하지 않는 ID를 가진다.groups: 고유id와 비어 있지 않은ballIds. 모든 구는 하나의 묶음에 정확히 한 번 속하며, 존재하지 않는 구를 참조하지 않는다.collectedBallIds,countedBallIds: 존재하는 구 ID의 중복 없는 부분집합. 센 구는 수집한 구다. 구성 퍼즐에서는 두 목록이 비어 있다.camera: 유효한 시점 기준점target, 회전rotation, 양수 거리distance. 값을 복원하여 같은 방향·확대 정도로 이어 한다.- 얼굴·숫자는 묶음 소속에서 다시 계산한다. 중복 저장한 숫자 때문에 실제 개수와 표시가 달라지면 안 된다.
- 미완료 퍼즐에는 해당 스테이지 초기 총량과 동일한 구가 있어야 한다. 자유 놀이는 0~10개이며, 빈 상태이면 묶음도 비어 있다.
- 입력 선택과 진행 중 애니메이션은 저장하지 않는다. 수집·계수 단계는 복원된 상태에서 판정한다.
- 손상·불완전 저장은 구를 일부만 불러오지 않고 유효한 마지막 저장으로 복원한다. 유효본을 확인할 수 없으면 읽기 실패를 기록하고 정상 초기 상태로 진입하며, 손상 파일을 무조건 덮어써 원인을 없애지 않는다.
상태 전이
- 화면은 시작 화면, 스테이지 선택, 퍼즐, 자유 놀이로 구분한다.
- 퍼즐 안에서는 일반 조작과 나누기 선택을 구분한다. 수집형의 세기 가능 여부는 R05 조건으로 결정한다.
- 성공 전이는 한 번만 확정한다. 성공 시 완료 기록·미완료 저장 제거·자유 놀이 생성은 같은 상태 변경이다.
- 다시 실행하면 시작 화면으로 들어가 아이가 스테이지 또는 최근 자유 놀이를 선택한다. 저장을 불러온 것 자체로 성공 연출을 반복하지 않는다.
R13. 필요한 검증과 결과물
현재 저장소에는 게임 코드와 기존 검증 명령이 없다. 개발 과정에서 자동 검증 진입점을 만들고 아래 증거를 남긴다. 이 기획 단계에서 게임 테스트나 빌드를 실행했다고 기록하지 않는다.
| 검증 | 합격 기준 |
|---|---|
| 스테이지 자료 | 고유 번호 1~30, R07과 전부 일치, 총량 보존, 목표 구성 유효 |
| 수학 규칙 | 합체·분리 후 구 ID 보존, 모든 유효 분할, 0개·전체 선택 거부, 목표 다중집합 판정 |
| 수 세기 | 1번의 수집 생략 불가, 미수집 상태 계수 불가, 중복 탭 불가, N개 수집·단일 묶음·계수 모두 필요 |
| 조작·진행 | 이동/탭/회전/핀치 충돌 없음, 순차 해금·재플레이·도움·성공 후 자유 놀이, 30번 이후 경계 |
| 자유 놀이 | 10개 제한, 반납 후 추가, 빈 놀이판 복구, 완료 기록 불변 |
| 저장 | 최소 두 스테이지의 서로 다른 미완료 상태와 자유 놀이를 함께 저장·복원; 구·묶음·계수·카메라 일치; 성공 상태 변경의 일관성 |
| 전체 과정 | 새 저장에서 30개를 모두 해결할 수 있고 마지막까지 해금됨. 자동화 가능한 규칙은 자동 검사하고 화면 연결은 플레이 검사 |
| 구조와 데이터 경계 | 순수 C# 규칙에서 Unity 객체 참조 없음; 화면·저장 결과와 규칙 상태 일치; 플레이 전후 고정 스테이지 자산 불변 |
| 합체 영웅 표현 | 1~10에서 구 개수·기본 크기·배치 유지; 안정 상태의 묶음마다 얼굴·숫자·망토 각각 하나; 2+3→5와 5→2+3 표현 일치; 선택·계수 가독성; 취소·연속 조작·복원 후 오래된 연출 잔존 없음 |
| 자산과 소리 | 서로 다른 배경 테마 3개; 최종 모델·2D·시각 효과·TTS 음성 실제 포함; 출처·사용 조건 기록; 빠른 계수 입력의 순차 발화·마지막 숫자 보존; 화면 전환 후 음성 정리 확인; 효과음·배경음악 제외 |
| 조기 Android 검사 | 첫 수 세기 퍼즐의 APK 설치·실행, 수집·계수, 성공 전 배치의 종료·재실행 복원. 전체 30개 완료 검증으로 대신 기록하지 않음 |
| Android 빌드 | 설치 가능한 APK 생성, 빌드 로그와 사용한 에디터·도구·대상 설정 기록 |
| Android 가상 기기 | APK 설치·실행, 가로 화면, 오프라인 동작, 수집/합체/분리, 스테이지 진행, 앱 종료·재실행 후 개별 퍼즐과 자유 놀이 복원 확인 |
- 결과물은 Unity 프로젝트, 안드로이드 APK, 자동 검사 결과, 가상 기기 검증 기록이다.
- 기능 구현 전에 해당 요구사항의 정상 동작·무효 동작·경계 조건을 합격 사례로 정한다. 필수 사례가 누락되거나 실패하면 그 기능을 완료로 표시하지 않는다. 필요한 검사 미실행은 통과와 구분하며, 실행한 소스 상태와 빌드에 검증 증거를 연결한다.
- 작업 환경의 Unity
6000.6.3f1에는 Android Build Support와 Unity 제공 SDK·NDK·OpenJDK가 설치되어 있다. 설치 확인은 APK 빌드 성공과 별개이며, 빌드 결과로 개발 환경을 검증한다. - 가상 기기 실행이 환경 문제로 불가능하면 실패 원인과 미검증 항목을 명시한다. APK가 생성되었다는 이유만으로 검증 전체를 완료 처리하지 않는다.
- 실제 손가락 조작, 스마트폰·태블릿별 가독성, 실제 기기의 성능·발열·배터리 확인은 기기 준비 후 수행한다. 가상 기기 결과로 이 항목들이 검증되었다고 주장하지 않는다.
R14. 자산 제작 범위와 인수
- 자석 친구·얼굴·마스크, 배경, 화면 그림, 연결 빛·자력 망토 등 특수 효과와 한국어 음성을 제작·확보하여 앱에 포함한다. 효과음·배경음악은 첫 버전에서 제외한다. 기존 수량·배치·조작·성공 규칙은 유지한다.
- 자석 표현과 프리팹·효과는 Unity에서 만들고, 입체 배경 소품은 Blender로 제작한다. AI 이미지는 실제 얼굴·UI 그림·텍스처에도 활용하며 스타일·투명 가장자리·사용 조건을 검수한다. 동적으로 바뀌는 숫자와 한국어 문구는 실제 텍스트로 표시한다.
- 배경은 서로 다른 테마 3개로 구성한다. 공통 소품을 재사용할 수 있지만 주요 소품·색·배경 표현으로 테마를 구별한다. 같은 테마의 배치를 여러 스테이지에서 사용하며 30개의 별도 배경 씬을 요구하지 않는다. 테마 이름·소품·색·스테이지별 테마 배정은 미술 조정 대상이고 R07의 순서·목표는 고정이다.
- 테마는 고정 스테이지 정의에서 가져온다. 성공 후 같은 공간을 유지하고 퍼즐·자유 놀이를 복원할 때 원래 스테이지의 테마를 사용한다. 배경 변경이 새로운 성공 조건이 되지 않는다.
- 효과음·배경음악은 사용자의 2026-10-06 결정으로 첫 버전에서 제외한다. 후속 요청 전에는 제작·선정·구매를 진행하지 않는다. 기존 무음 연결은 정상 범위이며 반복·믹싱 청취 인수는 이번 필수 검사가 아니다.
- 한국어 음성은 로컬 Qwen3-TTS로 미리 파일을 제작한다. 기존 conda 환경
qwen3-tts를 재사용하고, GPU에서Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice의 한국어Sohee목소리를 사용한다. 실행 담당자가 숫자·안내·실제 도움 문구의 대본과 생성 절차를 준비해 이 환경에서 파일을 생성·검수한다. 게임과 빌드는 Qwen3-TTS·모델·conda 환경에 의존하지 않으며 완성된 음성 파일만 사용한다. CPU·다른 모델/목소리·클라우드 TTS로 제작 방향을 자동 변경하지 않는다. - 제작 환경의 패키지 설치, 모델 가중치 확보, 모델 로딩, GPU 추론, 파일 생성, 발음·품질 검수는 별도 확인 단계다. 현재 패키지 설치와 클래스 import는 확인했지만 PyTorch는 CPU 구성이다. GPU 실행과 모델·음성 생성은 검증하지 않았다. 개발 실행에서 필요한 GPU 환경을 정비하고 실제 한국어 샘플로 확인하며, 설치나 import만으로 제작 준비 완료를 선언하지 않는다.
- 음성은 고유 ID와 한국어 전체 대본, 고정 모델·목소리·언어 및 생성 설정을 연결하여 제작한다. 문구나 설정이 바뀌면 해당 음성을 새 후보로 생성하고 채택한 원본·Unity용 파일·생성 이력의 대응을 유지한다. 생성 성공과 청각 검수 통과를 구분하며 같은 seed를 기록했다고 동일 파일이 재현된다고 주장하지 않는다.
- 숫자 읽기는 하나~열의 발음과 계수 순서를 보존한다. 빠르게 눌러도 입력과 계수 표시는 즉시 처리하고 발화는 겹치지 않게 순서대로 재생한다. 중복 탭은 발화를 추가하지 않는다. 성공 후 같은 보드에서 자유 놀이로 바뀌어도 대기 중인 숫자 읽기를 끝내며, 축하 소리로 마지막 숫자를 가리지 않는다. 소리 때문에 조작이나 성공 판정을 지연하지 않는다.
- 화면·스테이지 전환과 앱 일시 정지에는 이전 음성 큐를 정리한다. 복원으로 지난 계수·성공 음성을 반복하지 않는다. 상태가 바뀌면 오래된 대기 안내를 취소하며 안내가 계수 순서를 끊지 않는다.
- 제작 원본과 Unity에 넣는 파일을 구별하고, 실제 최종 파일별 출처·사용 조건·생성 도구/모델·대본/프롬프트·수정·검수 기록을 남긴다. 필요한 사용 고지를 결과물에 포함한다. TTS 모델·개발 도구·제작 캐시는 앱에 포함하지 않는다.
- 임시·사용 조건 미확인 자산으로 최종 자산 완료를 선언하지 않는다. 필수 로컬 TTS 출력이 없거나 청각 검수가 끝나지 않았으면 해당 완료 항목은 미완료다. 효과음·배경음악 제외는 미완료가 아니다. 파일 존재만으로 발음·가독성을 통과 처리하지 않는다.