- 무대 한정 코드 제거: repeat/map/ (트리/조명), images/image_custom (파이브가이즈),
load.mcfunction의 map 스코어보드·fill·counter 초기화
- 매 틱 디스패치를 init 상태로 게이팅:
· timer는 init>=2, check_answer는 init in {5,6}에서만 호출
· idle(init=0) 틱의 함수 호출 8개 → 4개
- 곡 50개를 매크로 체인(250+ 명령/회) → 스토리지 리스트 O(1) 룩업으로 전환
mq:init/songs가 mq:main.songs를 적재, setanswer는 index-1로 인덱스 룩업
- 버튼/트리거 정의를 mq:init/buttons / mq:init/triggers로 분리해
mq:main.button_defs · trigger_defs 스토리지 리스트로 관리
- repeat/triggers/trigger.mcfunction: 투표 후처리 산술 블록 중 변하지 않는
max_player·rest_player 재계산 제거, $(n)_player 갱신만 1라인
- 작가용 메모 수정.txt 제거
- README.md: 변경 사항·새 구조·스토리지 스키마 반영
566 lines -, 154 lines +.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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) |
4 |
곡 셋업 (한 틱 사이) |
5 |
곡 재생 + 정답 입력 단계 |
6 |
정답 공개·점수 부여 |
10 |
엔딩 시퀀스 |
main 스코어보드의 timer는 활성 상태에서만 증가하는 카운터로,
mq:repeat/timer가 이를 보고 상태 전이를 처리한다. 매 틱 디스패치는
init 값에 따라 게이팅된다.
트리거 명령
다음 명령은 trigger 타입 스코어보드로 등록돼 있어 어드벤처 모드의
일반 플레이어도 사용할 수 있다.
trigger ready— 시작 안내 대화창에서 시작 확정trigger cancel— 시작 취소trigger stop— 다수결 종료trigger skip— 다수결 스킵 (현재 곡 패스)trigger hint— 다수결 힌트 요청 (자음 절반 가리기 —func:hint)trigger replay— 다수결 다시 듣기
스킵/힌트/리플레이는 mq:repeat/triggers/trigger 매크로 안에서
max_player = ceil(전체/2) 다수결 계산을 거친 뒤 실행된다. 트리거
정의 자체는 mq:init/triggers에서 storage 리스트로 관리된다.
입력 버튼
관리자가 사용하는 6개의 물리 스톤 버튼. 좌표·표면 방향·실행 명령은
mq:init/buttons에서 storage 리스트(mq:main button_defs)로 관리되며,
mq:repeat/buttons/handler가 매 틱 storage 인덱스로 btn 매크로를 호출한다.
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/ # 공용 헬퍼 (length/half/shuffle/text_list/join…)
│ ─ mq:commands/hint에서 사용
└── mq/
├── function/
│ ├── load.mcfunction # 스코어보드·storage 초기화, init/* 호출
│ ├── tick.mcfunction # 매 틱 서브함수 디스패치 (init 게이팅)
│ ├── tellraw.mcfunction # 매크로 prefix 메시지 헬퍼
│ ├── init/ # 정적 데이터를 storage 로 적재
│ │ ├── songs.mcfunction # mq:main songs 리스트
│ │ ├── buttons.mcfunction # mq:main button_defs 리스트
│ │ └── triggers.mcfunction # mq:main trigger_defs 리스트
│ ├── check/server.mcfunction # YP / TS 설치 확인
│ ├── commands/ # start·stop·skip·hint·replay·test
│ ├── quiz/ # 게임 진행 로직
│ │ ├── start·select·play·correct·end·setanswer.mcfunction
│ │ └── macro/ # 매크로 진입점 (summon·setanswer·command_block)
│ ├── repeat/ # tick에서 호출되는 매 틱 처리
│ │ ├── players·check_answer·timer·check_server.mcfunction
│ │ ├── buttons/{handler,btn}.mcfunction
│ │ └── triggers/{handler,trigger}.mcfunction
│ ├── players/login.mcfunction
│ └── images/{image,image_set,image_delete}.mcfunction
├── dialog/page{1,2,3}.json
└── advancement/player/login.json
사용 스코어보드 / 스토리지
스코어보드:
main— 게임 핵심 상태 (init,index,max_index,timer,score,song_idx)status— 외부 의존(YP·TS·Skript) 및 글로벌 타이머buttons— 물리 버튼 상태 머신answer— 플레이어별 정답 입력값 (1=정답,2=오답)func.temp— 산술용 임시 상수 (two=2등)leave_game—custom:leave_game통계 (재접속 감지)score— 사이드바 표시용 점수ready/cancel/stop/skip/hint/replay— 플레이어 트리거
스토리지:
mq:main— 게임 전역 데이터title,max_index,spawn— 설정answer={title, author, alias}— 현재 곡 정답command_block— 명령 블록 좌표/볼륨, 이미지 표시 영역, 작업용 alias 사본songs— 곡 목록 (mq:init/songs가 채움)button_defs— 버튼 정의 (mq:init/buttons가 채움)trigger_defs— 트리거 정의 (mq:init/triggers가 채움)
mq:tmp— setanswer 룩업용 임시 인덱스func:temp—func:헬퍼 함수용 임시 NBT
곡 목록 수정
곡은 data/mq/function/init/songs.mcfunction 한 파일에 정의된다.
한 줄에 한 곡씩, 리스트로 append 한다:
data modify storage mq:main songs append value {title:"...", author:"...", alias:["...","..."]}
곡 순서가 게임 내 순서이며, alias 배열에 적은 문자열은 정답 판정에서
동의어로 인식된다. 곡 수를 늘리거나 줄이면 mq:function/load.mcfunction의
max_index 기본값(50)도 함께 맞추는 것이 좋다.
설치
- 서버 월드 폴더
datapacks/에music_quiz/디렉터리째 복사. - YP, TS 플러그인 설치 확인.
- 서버
/reload— 리로드 성공 메시지가 채팅에 표시되면 정상. - 좌표
144, 62, -225부근에 6개 버튼이 자동 배치된다. start버튼을 눌러 게임 시작.
좌표 의존성 (주의)
다음 좌표가 데이터팩 안에 박혀 있어, 다른 월드에서 그대로 사용하려면 값을 바꿔야 한다:
- 명령 블록:
144 59 -219—mq:load의command_block초기값 - 플레이어 스폰:
144 61 -219(yaw 180) —mq:load의spawn초기값 - 버튼 좌표:
140..148, 62, -225/144, 62, -213—mq:init/buttons - 이미지 표시 영역:
131 77 -262~157 91 -262—mq:load의command_block.x1..z2
변경 이력
2026-05-13 — 26.1.2 호환 + 1차 정리 (b1babad)
이전 푸시본(6841b7a 이전퀴즈 데이터팩)을 26.1.2 기준으로 정비.
pack_format69 → 75 (MC 26.1.2 / 1.21.11)mq:load,mq:players/login,mq:commands/start,mq:commands/stop,mq:quiz/start,mq:quiz/end,mq:repeat/buttons/btn등에 남아 있던# say .../# stopsound사문화 디버그 주석 제거
2026-05-13 — 무대 의존 제거 + 최적화 (이번 커밋)
특정 맵 좌표에만 동작하던 장식 로직을 들어내고, 매 틱 부하와 정적 데이터 관리를 정비했다.
삭제 (특정 맵 한정)
repeat/map/디렉터리 통째 — 무대 트리/조명 애니메이션 (tree,lamp1)images/image_custom.mcfunction— 파이브가이즈 간판 (호출자 없음)data/mq/수정.txt— 작가용 TODO 메모load.mcfunction의map스코어보드 초기화,tree map -1,lamp1 map -1,fill 94 78 -279 194 78 -279 minecraft:red_wooltick.mcfunction의function mq:repeat/map/tree,function mq:repeat/map/lamp1
매 틱 부하 감소
tick.mcfunction디스패치를init상태로 게이팅:repeat/timer는init >= 2일 때만repeat/check_answer는init in {5, 6}일 때만check_server/players/buttons/handler/triggers/handler는 항상 호출 (게임 비활성 상태에서도 시작 버튼·로그인 처리 필요)
- idle 틱(
init=0)에서 함수 호출 8개 → 4개. 정답 스캔과 카운트다운 reset 로직이 빠진다.
곡 관리 단순화
기존: quiz/setanswer.mcfunction 안에 50곡의 function mq:quiz/macro/setanswer { index:N, title:..., author:..., alias:... } 가
나열돼 있어, 매번 50개 매크로 호출 × 5라인 (if score index matches N
가드 포함) = 약 250 명령이 평가됐다.
변경:
- 곡 데이터를
mq:init/songs에서mq:main.songs리스트로 한 번 적재 quiz/setanswer.mcfunction은index - 1을 계산해mq:tmp.idx에 저장quiz/macro/setanswer.mcfunction은 매크로 한 줄로 룩업:data modify storage mq:main answer set from storage mq:main songs[$(idx)]- 호출당 3 라인의 storage 복사로 끝남 (50× → O(1))
버튼/트리거 정의 분리
- 버튼 6개의 좌표·실행 명령을
mq:init/buttons에서mq:main.button_defs리스트로 적재.repeat/buttons/handler는 인덱스로 매크로 호출만 한다. - 트리거 4개(stop/skip/hint/replay)도 동일하게
mq:init/triggers→mq:main.trigger_defs로 분리. - 버튼/트리거를 추가·제거할 때
repeat/*/handler가 아닌init/*만 편집하면 된다.
다수결 산술 dedup
repeat/triggers/trigger.mcfunction 에서 투표 갱신 전후로 real_max_player,
rest_player, max_player 를 두 번 계산했다. 이 값들은 (참가자 수에만
의존하므로) 한 틱 안에서 바뀌지 않는다. 갱신되는 것은 $(n)_player
(투표 수)뿐이라 — 후처리 블록은 $(n)_player 재계산 한 줄로 축약.
트리거당 5 라인 절감 × 4 트리거.
다듬지 않은 부분 (의도된 동작)
mq:commands/test및mq:repeat/timer의 3중playsound— 음량 강조용 스택 호출.mq:quiz/play의auto 1b→0b토글 두 줄 — 명령 블록 강제 재발화 패턴.mq:repeat/buttons/btn내부 상태머신 — 상태 -2/-1/0/1/2 전이 의미가 엮여 있어 라인 단축 시 디바운스가 깨질 위험이 있어 유지.func:헬퍼는mq:commands/hint가 사용 중이므로 유지.
원격 저장소
https://git.tkrmagid.kr/tkrmagid/mc_datapack.git