From b1babad05a122ab88e516bfeb62390d58d0e6512 Mon Sep 17 00:00:00 2001 From: "Claude (owner)" Date: Wed, 13 May 2026 15:22:55 +0900 Subject: [PATCH] =?UTF-8?q?music=5Fquiz:=2026.1.2=20=ED=98=B8=ED=99=98=20+?= =?UTF-8?q?=20=EC=A0=95=EB=A6=AC=20+=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - pack_format 69 → 75 (MC 26.1.2) - 사문화된 # say / # stopsound 디버그 주석 7곳 제거 - btn.mcfunction: 매 틱 모든 버튼마다 평가되던 디버그 매크로 라인 제거 - 데이터팩 분석·사용법·좌표 의존성을 README.md 에 정리 Co-Authored-By: Claude Opus 4.7 --- README.md | 200 ++++++++++++++++++ .../mq/function/commands/start.mcfunction | 2 - .../data/mq/function/commands/stop.mcfunction | 2 - music_quiz/data/mq/function/load.mcfunction | 1 - .../data/mq/function/players/login.mcfunction | 2 - .../data/mq/function/quiz/end.mcfunction | 4 - .../data/mq/function/quiz/start.mcfunction | 2 - .../mq/function/repeat/buttons/btn.mcfunction | 1 - music_quiz/pack.mcmeta | 2 +- 9 files changed, 201 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 57ff97a..c052491 100644 --- a/README.md +++ b/README.md @@ -1 +1,201 @@ # 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` diff --git a/music_quiz/data/mq/function/commands/start.mcfunction b/music_quiz/data/mq/function/commands/start.mcfunction index c450b43..1f7c470 100644 --- a/music_quiz/data/mq/function/commands/start.mcfunction +++ b/music_quiz/data/mq/function/commands/start.mcfunction @@ -7,6 +7,4 @@ stopsound @a weather $scoreboard players set max_index main $(max_index) scoreboard players set init main 1 -# say 게임시작 - dialog show @a mq:page1 diff --git a/music_quiz/data/mq/function/commands/stop.mcfunction b/music_quiz/data/mq/function/commands/stop.mcfunction index ce7b0a6..9699a6d 100644 --- a/music_quiz/data/mq/function/commands/stop.mcfunction +++ b/music_quiz/data/mq/function/commands/stop.mcfunction @@ -61,5 +61,3 @@ function mq:quiz/macro/summon with storage mq:main command_block stopsound @a weather function mq:images/image_delete with storage mq:main command_block - -# say "stop 실행" diff --git a/music_quiz/data/mq/function/load.mcfunction b/music_quiz/data/mq/function/load.mcfunction index 950f380..f0ba0d3 100644 --- a/music_quiz/data/mq/function/load.mcfunction +++ b/music_quiz/data/mq/function/load.mcfunction @@ -1,4 +1,3 @@ -# say "서버 리로드 성공" function mq:tellraw {"text":"서버 리로드 성공!","color":"white","msg":'""'} data merge storage mq:main { \ diff --git a/music_quiz/data/mq/function/players/login.mcfunction b/music_quiz/data/mq/function/players/login.mcfunction index abe7e9f..cde23bc 100644 --- a/music_quiz/data/mq/function/players/login.mcfunction +++ b/music_quiz/data/mq/function/players/login.mcfunction @@ -1,8 +1,6 @@ tag @s add player scoreboard players reset @s leave_game -# say "서버접속 확인" - title @s times 10t 80t 10t title @s subtitle "" title @s title "" diff --git a/music_quiz/data/mq/function/quiz/end.mcfunction b/music_quiz/data/mq/function/quiz/end.mcfunction index 8480d98..271354e 100644 --- a/music_quiz/data/mq/function/quiz/end.mcfunction +++ b/music_quiz/data/mq/function/quiz/end.mcfunction @@ -1,7 +1,3 @@ scoreboard players set init main 10 -# stopsound @a weather - -# say "엔딩" - scoreboard players set timer main 1 diff --git a/music_quiz/data/mq/function/quiz/start.mcfunction b/music_quiz/data/mq/function/quiz/start.mcfunction index 59b487e..f651eb1 100644 --- a/music_quiz/data/mq/function/quiz/start.mcfunction +++ b/music_quiz/data/mq/function/quiz/start.mcfunction @@ -1,7 +1,5 @@ scoreboard players set init main 2 -# say 퀴즈 시작! - scoreboard players set index main 0 bossbar set mq:process visible true diff --git a/music_quiz/data/mq/function/repeat/buttons/btn.mcfunction b/music_quiz/data/mq/function/repeat/buttons/btn.mcfunction index d605288..695e14b 100644 --- a/music_quiz/data/mq/function/repeat/buttons/btn.mcfunction +++ b/music_quiz/data/mq/function/repeat/buttons/btn.mcfunction @@ -20,7 +20,6 @@ $execute if block $(x) $(y) $(z) minecraft:stone_button[face=wall,facing=$(f),po if score $(n) buttons matches 1.. \ run scoreboard players set $(n) buttons 0 -# $execute as @e[type=minecraft:interaction,tag=mq,tag=$(n),limit=1] on target as @s positioned $(x) $(y) $(z) run say "$(n) 눌러짐" $execute as @e[type=minecraft:interaction,tag=mq,tag=$(n),limit=1] on target as @s positioned $(x) $(y) $(z) run playsound minecraft:block.stone_button.click_on block @s ~ ~ ~ 1 1 $execute as @e[type=minecraft:interaction,tag=mq,tag=$(n),limit=1] on target as @s positioned $(x) $(y) $(z) if score init main matches 0 run $(c) $execute as @e[type=minecraft:interaction,tag=mq,tag=$(n),limit=1] on target as @s positioned $(x) $(y) $(z) unless score init main matches 0 run trigger $(n) diff --git a/music_quiz/pack.mcmeta b/music_quiz/pack.mcmeta index 6c9fb06..cde6075 100644 --- a/music_quiz/pack.mcmeta +++ b/music_quiz/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { - "pack_format": 69, + "pack_format": 75, "description": "음악퀴즈용 데이터팩입니다." } } \ No newline at end of file