# mc_datapack 마인크래프트 자작 데이터팩 모음 저장소. 현재 포함된 데이터팩: - `music_quiz/` — 음악퀴즈 데이터팩 --- ## music_quiz — 음악퀴즈 데이터팩 플레이어가 노래를 듣고 정답을 맞히는 멀티플레이 음악 퀴즈. 관리자가 버튼/대화창으로 라운드를 진행하고, 참가자는 트리거 명령으로 정답·스킵·힌트·다시듣기 투표에 참여한다. ### 호환 버전 - **Minecraft 26.1.2** (pack_format `75`) 기준으로 작성되어 있다. - 1.21.6에서 도입된 `dialog` 시스템, 1.21+의 단수형 `function/` 태그 폴더, 매크로 함수(`function ... with storage`) 기능을 사용한다. - 텍스트 컴포넌트는 JSON 표기로 작성돼 있으며, 1.21.5 이후의 SNBT 파서와도 호환된다 (JSON은 SNBT의 부분집합). ### 의존 Bukkit 플러그인 데이터팩 자체만으로는 동작하지 않고, 다음 Bukkit 플러그인이 서버에 설치돼 있어야 한다: - **YP** (`yp playall song`) — 음원 재생용. 명령 블록을 통해 호출된다. - **TS** (`ts placeloc .jpg ...`) — 정답 이미지 표시용. 서버 측 상태는 `status` 스코어보드의 `yp`, `ts`, `skript` 값으로 추적하며, 플러그인 미설치 시 `mq:check/server`가 안내 타이틀을 띄운다. ### 게임 흐름과 상태 (`init` 스코어보드) 게임 전체 상태는 `main` 스코어보드의 가상 플레이어 `init` 값으로 관리한다. | `init` | 단계 | |--------|------| | `0` | 정지/대기 (기본 상태) | | `1` | 게임 시작 — page1 대화창에서 `ready` 트리거 대기 | | `2` | 카운트다운 (3·2·1) | | `5` | 곡 재생 + 정답 입력 단계 | | `6` | 정답 공개·점수 부여 | | `10` | 엔딩 시퀀스 | `status` 스코어보드의 `timer`는 매 틱 증가하는 카운터로, `mq:repeat/timer`가 이를 보고 상태 전이를 처리한다. ### 트리거 명령 다음 명령은 `trigger` 타입 스코어보드로 등록돼 있어 어드벤처 모드의 일반 플레이어도 사용할 수 있다. - `trigger ready` — 시작 안내 대화창에서 시작 확정 - `trigger cancel` — 시작 취소 - `trigger stop` — 다수결 종료 - `trigger skip` — 다수결 스킵 (현재 곡 패스) - `trigger hint` — 다수결 힌트 요청 - `trigger replay` — 다수결 다시 듣기 스킵/힌트/리플레이는 `mq:repeat/triggers/trigger` 매크로 안에서 `max_player = ceil(전체/2)` 다수결 계산을 거친 뒤 실행된다. ### 입력 버튼 관리자가 사용하는 6개의 물리 스톤 버튼이 좌표 `144 62 -225` 근처 오크 통나무 위에 배치된다. `mq:repeat/buttons/handler`가 매 틱 상태를 점검하고, 각 버튼에 대응하는 `mq:commands/*`를 호출한다. - `start` / `stop` / `skip` / `hint` / `replay` / `test` 버튼 본체는 `interaction` 엔티티 + `redstone_block`-`red_wool` 토글 패턴으로 디바운스를 처리한다. ### 파일 구조 ``` music_quiz/ ├── pack.mcmeta # pack_format 75 └── data/ ├── minecraft/tags/function/ │ ├── load.json # → mq:load │ └── tick.json # → mq:tick ├── func/function/ # 공용 유틸 (text_list / half / shuffle 등) └── mq/ ├── function/ │ ├── load.mcfunction # 스코어보드·storage 초기화 │ ├── tick.mcfunction # 매 틱 서브함수 디스패치 │ ├── tellraw.mcfunction # 매크로 prefix 메시지 헬퍼 │ ├── check/server.mcfunction # YP / TS 설치 확인 │ ├── commands/ # start·stop·skip·hint·replay·test │ ├── quiz/ # 게임 진행 로직 (start·select·play·correct·end·setanswer) │ │ └── macro/ # 매크로 진입점 (summon·setanswer·command_block …) │ ├── repeat/ # tick에서 호출되는 매 틱 처리 │ │ ├── players.mcfunction │ │ ├── check_answer.mcfunction │ │ ├── timer.mcfunction │ │ ├── check_server.mcfunction │ │ ├── buttons/{handler,btn}.mcfunction │ │ ├── triggers/{handler,trigger}.mcfunction │ │ └── map/{tree,lamp1,…} # 무대 조명 애니메이션 │ ├── players/login.mcfunction # 접속 처리 (어드밴스먼트 보상으로 호출) │ └── images/ # 이미지 표시 (TS 플러그인 호출) ├── dialog/page{1,2,3}.json # confirmation 다이얼로그 └── advancement/player/login.json # 접속 트리거 ``` ### 사용 스코어보드 / 스토리지 - `main` — 게임 핵심 상태 (`init`, `index`, `max_index`, `timer`, `score`) - `status` — 외부 의존(YP·TS·Skript) 및 글로벌 타이머 - `buttons` — 물리 버튼 상태 머신 - `answer` — 플레이어별 정답 입력값 (`1`=정답, `2`=오답) - `map` — 무대 조명/장식 애니메이션 카운터 - `func.temp` — 산술용 임시 상수(`two=2` 등) - `leave_game` — `custom:leave_game` 통계 (재접속 감지) - `score` — 사이드바 표시용 점수 - `ready` / `cancel` / `stop` / `skip` / `hint` / `replay` — 플레이어 트리거 스토리지: - `mq:main` — 게임 전역 설정 (`title`, `max_index`, `answer`, `command_block`(좌표·볼륨), `spawn`) - `func:temp` — 유틸 함수용 임시 NBT ### 곡 목록 수정 곡은 `data/mq/function/quiz/setanswer.mcfunction`에 50곡이 하드코딩돼 있다. 형식: ``` function mq:quiz/macro/setanswer { index: , title: "<제목>", author: "<가수>", alias: ["<별칭1>","<별칭2>"] } ``` `alias` 배열에 적은 문자열은 정답 판정에서 동의어로 인식된다. 곡을 늘리거나 줄이면 `mq:function/load.mcfunction`의 `max_index` 기본값(50)도 함께 맞추는 것이 좋다. ### 설치 1. 서버 월드 폴더 `datapacks/`에 `music_quiz/` 디렉터리째 복사. 2. YP, TS 플러그인 설치 확인. 3. 서버 `/reload` — 리로드 성공 메시지가 채팅에 표시되면 정상. 4. 좌표 `144, 62, -225` 부근에 6개 버튼 영역과 무대 구조물(트리 램프 등)이 자동 생성된다. 5. `start` 버튼을 눌러 게임 시작. ### 좌표 의존성 (주의) 다음 좌표가 데이터팩 안에 직접 박혀 있어, 다른 월드에서 그대로 사용하려면 코드를 수정해야 한다: - 명령 블록: `144 59 -219` - 플레이어 스폰: `144 61 -219` (`yaw 180`) - 무대 조명 (`map/tree`): `142, 66/70/74/78/81`, z `-186..-196` - 무대 조명 (`map/lamp1`): y `78`, z `-279`, x `94..194` - 이미지 표시 영역: `131 77 -262` ~ `157 91 -262` - 버튼/장식 영역: `144 62 -225` 부근 --- ## 26.1.2 호환을 위해 적용한 변경 이전 푸시본(`6841b7a 이전퀴즈 데이터팩`)을 26.1.2 기준으로 정비하면서 다음을 적용했다: 1. **`pack_format` 69 → 75** `music_quiz/pack.mcmeta`를 26.1.2(=1.21.11 계열)에 맞게 갱신했다. 2. **사문화된 디버그 출력 제거** - `mq:load`, `mq:players/login`, `mq:commands/start`, `mq:commands/stop`, `mq:quiz/start`, `mq:quiz/end`에 남아 있던 `# say ...` 주석 라인 제거. - `mq:repeat/buttons/btn`에서 매 틱 모든 버튼마다 평가되던 `# $execute ... say "$(n) 눌러짐"` 주석 라인 제거. - `mq:quiz/end`의 `# stopsound @a weather` 주석 라인 제거. 3. **호환성 점검 — 코드 변경 없이 26.1.2에서도 동작하는 항목** - `dialog show @a mq:page` 호출 및 `dialog clear @a` (1.21.6+) - `function ... with storage` 매크로 (1.20.2+, 26.1.x에서도 그대로 동작) - `function/` 단수형 태그 디렉터리 (1.21+ 표준) - `tellraw`/`title`/`bossbar`/`scoreboard` JSON 텍스트 컴포넌트 (1.21.5의 SNBT 전환에서 JSON 문법이 SNBT의 부분집합이므로 그대로 유효) - `minecraft:interaction` 엔티티의 `attack`/`response` 데이터 접근 - `custom:leave_game` 통계 — 명칭/네임스페이스 변경 없음 ### 다듬지 않고 남겨둔 부분 리뷰 중 다음 항목은 **의도된 동작**으로 판단해 손대지 않았다. - `mq:repeat/triggers/trigger`의 산술 블록이 두 번 등장하는 구조 — 중간에 투표 점수가 갱신되므로 재계산이 필요하며, 묶어버리면 `max_player = ceil(N/2)` 다수결 판정이 한 틱 뒤로 밀린다. - `mq:commands/test`의 3중 `playsound` 호출 — 음량 강조를 위한 의도. - `mq:quiz/play`의 `auto 1b` → `0b` 토글 두 줄 — 명령 블록 강제 재발화 패턴. --- ## 원격 저장소 - `https://git.tkrmagid.kr/tkrmagid/mc_datapack.git`