Claude (owner) b2361187b9 music_quiz: 설정을 init/config.mcfunction 한 곳으로 모음
- 주제(title), 곡 개수(max_index), 스폰 위치, 음원 명령 블록 좌표/볼륨,
  이미지 표시 영역 좌표를 모두 init/config.mcfunction 에서 관리
- tellraw 접두사([ … ])가 storage 의 title 을 참조하도록 변경 — 주제
  변경 시 config 한 줄만 고치면 채팅 접두사까지 일관 적용
- load.mcfunction 의 인라인 data merge 블록을 제거하고 init/config 호출로
  대체 (스코어보드/보스바 같은 런타임 인프라는 load 본문에 유지)
- README 의 "곡 목록 수정" 절을 "설정 (한 곳에서 수정)" 으로 재작성

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 16:02:27 +09:00

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/                  # 사용자 설정·정적 데이터 (수정 포인트)
        │   │   ├── config.mcfunction    # 주제·곡 개수·스폰·명령 블록 좌표
        │   │   ├── songs.mcfunction     # 곡 목록
        │   │   ├── buttons.mcfunction   # 버튼 좌표·실행 명령
        │   │   └── triggers.mcfunction  # 다수결 트리거 정의
        │   ├── 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_gamecustom: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:tempfunc: 헬퍼 함수용 임시 NBT

설정 (한 곳에서 수정)

세계마다 다른 값은 모두 data/mq/function/init/ 폴더에서 편집한다. /reload 후 반영된다.

  • init/config.mcfunction — 주제, 곡 개수, 스폰 위치, 음원 명령 블록 좌표, 정답 이미지 표시 영역. title[ … ] 채팅 접두사로도 사용된다.
  • init/songs.mcfunction — 곡 목록 (한 줄에 한 곡씩 append). alias 배열의 문자열은 정답 판정 시 동의어로 인정된다. 곡 수를 바꾸면 init/config.mcfunctionmax_index 도 함께 맞춰야 한다.
  • init/buttons.mcfunction — 6개 물리 버튼의 좌표·표면 방향·실행 명령.
  • init/triggers.mcfunction — 다수결 트리거(stop/skip/hint/replay) 표시 이름·실행 명령.

load.mcfunction 은 위 4개를 호출해 mq:main 스토리지를 적재한다. 스코어보드·보스바 같은 런타임 인프라는 load.mcfunction 본문에 남아 있다.

다이얼로그 페이지(data/mq/dialog/page{1,2,3}.json) 의 타이틀과 설명문구는 JSON 텍스트 컴포넌트가 storage 참조를 일관되게 지원하지 않으므로 직접 편집해야 한다.

설치

  1. 서버 월드 폴더 datapacks/music_quiz/ 디렉터리째 복사.
  2. YP, TS 플러그인 설치 확인.
  3. 서버 /reload — 리로드 성공 메시지가 채팅에 표시되면 정상.
  4. 좌표 144, 62, -225 부근에 6개 버튼이 자동 배치된다.
  5. start 버튼을 눌러 게임 시작.

좌표 의존성 (주의)

다음 좌표가 데이터팩 안에 박혀 있어, 다른 월드에서 그대로 사용하려면 값을 바꿔야 한다:

  • 명령 블록: 144 59 -219mq:loadcommand_block 초기값
  • 플레이어 스폰: 144 61 -219 (yaw 180) — mq:loadspawn 초기값
  • 버튼 좌표: 140..148, 62, -225 / 144, 62, -213mq:init/buttons
  • 이미지 표시 영역: 131 77 -262 ~ 157 91 -262mq:loadcommand_block.x1..z2

변경 이력

2026-05-13 — 26.1.2 호환 + 1차 정리 (b1babad)

이전 푸시본(6841b7a 이전퀴즈 데이터팩)을 26.1.2 기준으로 정비.

  • pack_format 69 → 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.mcfunctionmap 스코어보드 초기화, tree map -1, lamp1 map -1, fill 94 78 -279 194 78 -279 minecraft:red_wool
  • tick.mcfunctionfunction mq:repeat/map/tree, function mq:repeat/map/lamp1

매 틱 부하 감소

  • tick.mcfunction 디스패치를 init 상태로 게이팅:
    • repeat/timerinit >= 2 일 때만
    • repeat/check_answerinit 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.mcfunctionindex - 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/triggersmq: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/testmq:repeat/timer 의 3중 playsound — 음량 강조용 스택 호출.
  • mq:quiz/playauto 1b0b 토글 두 줄 — 명령 블록 강제 재발화 패턴.
  • mq:repeat/buttons/btn 내부 상태머신 — 상태 -2/-1/0/1/2 전이 의미가 엮여 있어 라인 단축 시 디바운스가 깨질 위험이 있어 유지.
  • func: 헬퍼는 mq:commands/hint 가 사용 중이므로 유지.

원격 저장소

  • https://git.tkrmagid.kr/tkrmagid/mc_datapack.git
Description
No description provided
Readme 303 KiB
Languages
mcfunction 100%