Files
mc_datapack/README.md
Claude (owner) b1babad05a music_quiz: 26.1.2 호환 + 정리 + README
- pack_format 69 → 75 (MC 26.1.2)
- 사문화된 # say / # stopsound 디버그 주석 7곳 제거
- btn.mcfunction: 매 틱 모든 버튼마다 평가되던 디버그 매크로 라인 제거
- 데이터팩 분석·사용법·좌표 의존성을 README.md 에 정리

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 15:22:55 +09:00

202 lines
8.8 KiB
Markdown

# 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<n>`) — 음원 재생용. 명령 블록을 통해 호출된다.
- **TS** (`ts placeloc <image>.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: <N>, 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<n>` 호출 및 `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`