Claude (owner) 55ab7fc04b music_quiz: 버튼 interaction hitbox 를 3 타일 분할로 정확히 정합
단일 interaction 의 horizontal hitbox 는 width × width 정사각형 강제라
"가로 0.375 × 두께 0.125" 직사각형이 불가능 → 두께 방향만 잡으면
가로 방향이 짧아지고, 가로를 잡으면 두께가 0.375 가 되어 벽 안쪽으로
0.25 묻혀 F3+B 디버그에서 wireframe 이 벽 안과 머리 앞쪽으로 튀어나옴.

해결: width=0.125 interaction 3개를 가로축으로 타일링.
- 각 타일 깊이 0.125 = 버튼 머리 두께와 정확히 일치
- 3 × 0.125 = 0.375 = 버튼 머리 가로와 정확히 일치 (gap 없이 인접)
- facing 별 가로축이 다름: south/north 는 x, east/west 는 z

selector limit=1 제거 — 한 버튼에 interaction 이 3개라 limit=1 두면
MC 가 임의로 1개만 골라 잘못된 entity 만 검사할 수 있음. `on target`
은 클릭된 1개만 통과하므로 limit 없이도 단일 발화가 보장됨.
2026-05-17 04:05:01 +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의 부분집합).

100% 바닐라 — 의존 플러그인 없음

음원 재생과 정답 이미지 표시는 모두 바닐라 명령으로 처리한다. 음원과 페인팅 텍스처는 minecraft_launcher 가 만들어주는 리소스팩(musicquiz 네임스페이스)에서 가져온다.

  • 음원: /playsound musicquiz:track_NN <source> @s ~ ~ ~ <volume> <pitch> (예: musicquiz:track_01). 채널은 기본 weatherstopsound 와 함께 묶여 있다.
  • 정답 이미지: painting_variant musicquiz:cover_NN/summon painting 으로 벽에 띄우고, 다음 곡 직전 kill @e[type=painting,tag=mq_cover] 로 제거.

리소스팩 트랙 번호와 mq:init/songs 리스트의 순서가 1:1로 일치해야 한다. 1번째 곡 → track_01 / cover_01, … (2자리 zero-pad).

게임 흐름과 상태 (init 스코어보드)

게임 전체 상태는 main 스코어보드의 가상 플레이어 init 값으로 관리한다.

init 단계
0 정지/대기 (기본 상태)
1 게임 시작 — page1 대화창에서 ready 트리거 대기
2 카운트다운 (3·2·1)
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

버튼 본체는 보이는 stone_button 블록 + 그 좌표에 덮인 interaction 엔티티로 구성된다. 클릭 처리는 항상 interaction 경로로 흐르므로 on target as @s 로 누른 플레이어가 식별되고, 다수결(trigger $(n)) 투표가 성립한다.

interaction 은 데이터팩이 직접 소환·관리한다 — buttons 점수가 -1 (초기화) 일 때마다 같은 태그의 기존 entity 를 정리하고 정확히 1개를 (재)소환한다. /reloadcommands/stop 을 호출해 buttons 점수를 -1 로 재설정하므로, 리로드 시 자동 보장된다. /kill @e 로 지워졌어도 다음 /reload 한 번으로 복구. 월드 회로(커맨드블럭) 의존은 없다.

파일 구조

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    # 주제·스폰·오디오·페인팅·marker 설정
        │   │   ├── songs.mcfunction     # 곡 목록 + max_index 자동계산
        │   │   ├── buttons.mcfunction   # 버튼 좌표·실행 명령
        │   │   └── triggers.mcfunction  # 다수결 트리거 정의
        │   ├── commands/               # start·stop·skip·hint·replay·test
        │   ├── quiz/                   # 게임 진행 로직
        │   │   ├── start·select·setanswer·correct·end.mcfunction
        │   │   ├── play_sound·stop_sound.mcfunction  # /playsound · /stopsound 래퍼
        │   │   └── macro/              # 매크로 진입점
        │   │     ├── setanswer.mcfunction   # songs[$(idx)] → answer + track/cover id
        │   │     ├── play_sound.mcfunction  # $playsound 매크로
        │   │     ├── stop_sound.mcfunction  # $stopsound 매크로
        │   │     └── summon{,2}.mcfunction  # 정답 marker 엔티티 + alias 체인
        │   ├── images/                 # 정답 페인팅 표시·제거
        │   │   ├── show.mcfunction          # cover painting 소환
        │   │   ├── clear.mcfunction         # cover painting 일괄 제거
        │   │   └── macro/show.mcfunction    # $summon painting 매크로
        │   ├── repeat/                 # tick에서 호출되는 매 틱 처리
        │   │   ├── players·check_answer·timer.mcfunction
        │   │   ├── buttons/{handler,btn}.mcfunction
        │   │   └── triggers/{handler,trigger}.mcfunction
        │   └── players/login.mcfunction
        ├── dialog/page{1,2,3}.json
        └── advancement/player/login.json

사용 스코어보드 / 스토리지

스코어보드:

  • main — 게임 핵심 상태 (init, index, max_index, timer, score, song_idx)
  • 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 — 설정
    • audio = {namespace, source, volume, pitch}/playsound 파라미터
    • image = {namespace, x, y, z, facing} — 정답 페인팅 좌표
    • marker = {x, y, z} — 정답 입력 marker 엔티티 위치
    • answer = {title, author, alias, track, cover} — 현재 곡 정답
    • songs — 곡 목록 (mq:init/songs 가 채움)
    • button_defs / trigger_defs — 버튼·트리거 정의
  • mq:tmp — setanswer·play_sound·페인팅 호출용 임시 페이로드 (idx, pad, num, playsound, painting, marker_call)
  • func:tempfunc: 헬퍼 함수용 임시 NBT

설정 (한 곳에서 수정)

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

  • init/config.mcfunction — 주제, 스폰 위치, 오디오 설정(audio), 정답 페인팅 좌표(image), marker 엔티티 좌표. title[ … ] 채팅 접두사로도 사용된다.
  • init/songs.mcfunction — 곡 목록 (한 줄에 한 곡씩 append). alias 배열의 문자열은 정답 판정 시 동의어로 인정된다. 곡의 순서가 리소스팩 트랙 번호와 1:1 매칭 되므로 순서 변경 시 리소스팩도 함께 재생성해야 한다. max_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. minecraft_launcher 에서 생성한 musicquiz 리소스팩을 클라이언트에 적용 (런처가 자동 처리).
  3. 서버 /reload — 리로드 성공 메시지가 채팅에 표시되면 정상.
  4. 좌표 144, 62, -225 부근에 6개 버튼이 자동 배치된다.
  5. start 버튼을 눌러 게임 시작.

좌표 의존성 (주의)

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

  • 정답 입력 marker: 144 59 -219marker.{x,y,z}
  • 정답 페인팅: 144 84 -261 (facing south) — image.{x,y,z,facing}
  • 플레이어 스폰: 144 61 -219 (yaw 180) — spawn
  • 버튼 좌표: 140..148, 62, -225 / 144, 62, -213mq:init/buttons

변경 이력

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 — 무대 의존 제거 + 최적화 (2b61af2)

특정 맵 좌표에만 동작하던 장식 로직을 들어내고, 매 틱 부하와 정적 데이터 관리를 정비했다.

  • repeat/map/ (무대 트리/조명 애니메이션) 삭제
  • images/image_custom.mcfunction (호출자 없는 사문화 코드) 삭제
  • tick.mcfunction 디스패치를 init 상태로 게이팅 (idle 틱 함수 호출 8→4)
  • 곡 데이터를 mq:init/songsmq:main.songs 리스트로 한 번 적재. 매크로 룩업 한 줄로 50× → O(1) 복사
  • 버튼/트리거 정의를 mq:init/buttons / mq:init/triggers 의 storage 리스트로 분리. handler 는 인덱스로 매크로 호출만 한다.
  • 다수결 산술 dedup (트리거당 5 라인 절감 × 4 트리거)

2026-05-13 — 설정 통합 (b236118)

세계별 수정 포인트를 한 파일로 모았다.

  • init/config.mcfunction 신설 — 주제·곡 개수·스폰·명령 블록 좌표를 한곳에
  • mq:tellrawmq:main.title 을 읽도록 변경 ([ 주제 ] 접두사 동기화)

2026-05-13 — 바닐라 마이그레이션 (이번 커밋)

YP / TS Bukkit 플러그인 의존을 제거하고, 음원과 정답 이미지를 바닐라 명령으로 재구현했다. minecraft_launcher 가 생성하는 musicquiz 리소스팩과 한 쌍으로 동작한다.

삭제

  • mq:check/server + mq:repeat/check_server — 플러그인 설치 확인 로직
  • mq:quiz/macro/command_blockdata modify block … Command + auto 토글 패턴 (YP playall 호출용)
  • mq:quiz/play — 명령 블록 강제 재발화 함수
  • mq:images/image{,_set,_delete} — TS placeloc / removeall 호출
  • status 스코어보드 (yp, ts, skript, timer) — 플러그인 hello 패킷 대기에만 쓰이던 객체

신설

  • 음원mq:quiz/play_soundmq:quiz/macro/play_sound: $execute as @a at @s run playsound $(namespace):$(track) $(source) @s ~ ~ ~ $(volume) $(pitch)
  • 음원 정지mq:quiz/stop_soundmq:quiz/macro/stop_sound: $stopsound @a $(source) (모든 stopsound 호출 합쳐서 매크로화)
  • 정답 페인팅mq:images/showmq:images/macro/show: $summon minecraft:painting $(x) $(y) $(z) {variant:"$(namespace):$(cover)",facing:$(facing)b,Tags:["mq","mq_cover"]}
  • 정답 페인팅 제거mq:images/clear: kill @e[type=painting,tag=mq_cover]

스토리지 재구성

  • command_block 컴파운드(좌표·볼륨·이미지 영역·alias 사본을 한데 묶었던 것) 폐기
  • audio = {namespace, source, volume, pitch} 신설 — /playsound 인자
  • image = {namespace, x, y, z, facing} 신설 — /summon painting 좌표
  • marker = {x, y, z} 신설 — 정답 입력 marker 위치
  • answer.track / answer.cover 필드 추가 — 라운드별 리소스팩 ID (track_NN / cover_NN)
  • max_indexmq:init/songs 끝에서 songs 배열 길이로 자동 계산 (수동 동기화 필요 없음)

트랙 번호 padding

mcfunction 은 문자열 zero-pad 가 없으므로, quiz/select 에서 index ∈ 1..9 일 때만 mq:tmp.pad="0" 로 분기시키고, 매크로 안에서 "track_$(pad)$(num)" 로 조립한다.

기타

  • tick.mcfunction 에서 mq:repeat/check_server 제거 (매 틱 함수 호출 4→3 으로 추가 감소)
  • commands/start / commands/stop / commands/replay 의 하드코딩된 stopsound @a weather 를 모두 function mq:quiz/stop_sound 로 교체 — 채널 변경 시 audio.source 한 곳만 수정하면 됨
  • setanswer 호출 경로 단축: 기존 select → macro/command_block → play(auto-toggle) → setanswer → macro/setanswer + macro/summon → 현재 select → setanswer → macro/setanswer → macro/summon → play_sound

원격 저장소

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