13 Commits

Author SHA1 Message Date
Claude (owner)
cce5469dc2 music_quiz: answer 정규화 도입 (대소문자/공백 무시)
- mq:answer/normalize: storage 의 norm.in 을 한 글자씩 떼어내
  소문자화 + 공백 제거 후 norm.acc 에 누적. char 단위 반복은
  'data modify ... set string from ... <start> <end>' (1.20+) 로,
  결합은 매크로 ($(acc)$(c)) 로 수행하는 pure-datapack 구현.

- process: 큐의 text 를 정규화한 결과를 judge.input 으로 사용
- judge: answer.title 정규화 후 judge.answer 로 사용
- iter_aliases: alias 각 항목 정규화 후 비교

원본 songs.mcfunction 의 title/alias 표기는 그대로 유지 (display
및 정규화 입력으로 모두 사용됨). 입력이 'Lose My Mind' / 'lose my mind'
/ 'LOSEMYMIND' / 'losemymind' 어떤 형태든 동일한 정규형으로 떨어져 매치.
2026-05-15 00:23:42 +09:00
Claude (owner)
8c30f4de5e temp: 애니메이션 painting 텍스처 검증용 sample 파일 추가
리소스팩 1번 방식 (.png 세로 스트립 + .png.mcmeta) 이
painting_variant 에서 동작하는지 검증하기 위한 샘플.

사용 위치: musicquiz 리소스팩의
  assets/musicquiz/textures/painting/gif.png
  assets/musicquiz/textures/painting/gif.png.mcmeta

데이터팩 v1.0.6 의 mq:gif painting_variant 와 짝.
2026-05-14 23:58:07 +09:00
Claude (owner)
ae434c3a07 music_quiz: answer/macro/match — NBT path compound matcher 공백 제거
execute if data <source> <path> 의 path 토큰은 공백을 허용하지 않음.
'judge {input:...}' → 'judge{input:...}' 로 붙여써야 compound predicate 가
정상 적용됨.
2026-05-14 23:50:28 +09:00
Claude (owner)
663891c966 music_quiz: 애니메이션 텍스처 테스트용 painting_variant gif 추가
리소스팩 musicquiz:gif 텍스처가 .png.mcmeta 애니메이션을 따르는지
검증하기 위한 1×1 painting_variant. 텍스처 자체는 리소스팩에 별도 배치.
2026-05-14 23:39:20 +09:00
Claude (owner)
c2dcf0c44f music_quiz: painting_variant 를 mq 네임스페이스로 통합
- data/musicquiz/painting_variant/* → data/mq/painting_variant/* 로 이동
  변종 ID = mq:cover_NN, 텍스처 asset_id = musicquiz:cover_NN (리소스팩)
- title/author 필드 제거 (기본값 사용)
- init/config.mcfunction 의 image.namespace 기본값을 "mq" 로 변경
2026-05-14 23:23:29 +09:00
Claude (owner)
f71bd95de5 music_quiz: pack.mcmeta 에 min_format / max_format 명시 (26.1.2 = format 75)
25w31a 이후 pack metadata 에서 min_format / max_format 가 권장 필드로
추가됨. 없으면 게임 시작 시 PackRepository.reload 단계에서
"missing mandatory fields min_format and max_format" WARN 로그가
fallback 으로 처리되며, 향후 버전에서 hard fail 로 바뀔 가능성이
있어 명시. 단일 버전(26.1.2) 만 지원하므로 75/75 로 고정.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 23:04:43 +09:00
Claude (owner)
b19f37969a music_quiz: add painting_variant definitions (cover_01 ~ cover_50)
리소스팩의 assets/musicquiz/textures/painting/cover_NN.png 를 게임에서
painting entity 로 띄우려면 데이터팩 쪽에 painting_variant 정의가
있어야 한다. 곡 수(50)에 맞춰 data/musicquiz/painting_variant/cover_NN.json
50개를 추가. asset_id 의 musicquiz:cover_NN 이 자동으로
assets/musicquiz/textures/painting/cover_NN.png 를 가져다 쓴다.
width/height = 1×1 (정사각 한 블록).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 22:57:49 +09:00
Claude (owner)
416eaee14a music_quiz: chat_answer 모드 활성 알림 — race-free 함수 호출 방식으로 전환
기존: storage chat_answer:status active 1b/0b 플래그를 모드가 set,
데이터팩이 mq:load 에서 0b 로 reset 하는 구조였는데,
통합 서버에서 mq:load 가 player join 이후에 도는 케이스가 발견되어
모드가 써놓은 1b 를 데이터팩이 직후에 0b 로 덮어쓰는 race 발생.

수정: storage 플래그를 완전히 제거. 모드가 직접 PlayerLoggedInEvent
핸들러에서 mq:players/mod_active_notice 함수를 해당 플레이어로 호출.
데이터팩이 없으면 함수가 없어 silent fail → race 없음.

- mq:load: chat_answer:status 0b 초기화 라인 삭제
- mq:players/login: 조건부 tellraw 제거 (모드가 직접 호출하므로)
- mq:players/mod_active_notice: 새 함수, 그냥 tellraw 만 수행
2026-05-14 03:14:55 +09:00
Claude (owner)
de6e040623 music_quiz: add pack.png icon 2026-05-14 02:28:52 +09:00
Claude (owner)
141bc5eaa5 music_quiz: fix invalid dialog type — simple_input_form → notice
mq/dialog/answer.json 이 'minecraft:simple_input_form' 타입을 쓰는데
1.21.6 dialog registry 에 그 타입이 없어서 데이터팩 로드 자체가 실패
"세계를 불러올 수 없습니다" 오류. 유효한 타입 중 단일 버튼 + inputs 를
지원하는 minecraft:notice 로 교체, action 을 button(label+inner action)
구조로 감싼다. dynamic/run_command 템플릿은 그대로 — $(text) 매크로 치환.
2026-05-13 23:36:29 +09:00
Claude (owner)
083297bf50 music_quiz: songs 의 volume 을 필수 기본 정보로 승격 (전 곡 기본 1.0)
기존엔 volume 이 선택 필드여서 미지정 시 config.audio.volume 으로 fallback 되었는데,
곡마다 음량 조절을 자주 하기 위해 모든 곡 엔트리에 volume 을 명시 (모두 1.0). 런타임
quiz/play_sound 흐름은 그대로 — songs[i].volume 을 그대로 사용.
2026-05-13 22:27:17 +09:00
Claude (owner)
cfe6a41888 music_quiz: chat_answer 모드 활성화 시 로그인 메세지 표시
mq:load 가 storage chat_answer:status active 를 0b 로 초기화. chat_answer 모드의
PlayerLoggedInEvent / ServerPlayConnectionEvents.JOIN 핸들러가 첫 로그인 직후
1b 로 set 하므로, mq:players/login 에서 1b 인 경우 "[채팅정답] 모드가 활성화되어
있습니다. 정답 입력 시 채팅으로 바로 제출할 수 있습니다." tellraw.
2026-05-13 22:21:17 +09:00
Claude (owner)
7adcda68de music_quiz: dialog 기반 정답 입력 + 큐 기반 first-submit-wins 추가
정답 입력 UI 를 dialog 로 제공 (mq:dialog/answer), #minecraft:quick_actions 태그
등록으로 빠른행동키에서 바로 열 수 있게 함. 동시 제출 시 먼저 제출한 사람이 정답으로
인정되도록 mq:answer/ 에 submit_seq 기반 FIFO 큐 + 매크로 기반 제출자 lookup 으로
처리. tick/stop/setanswer 도 새 큐 흐름에 맞춰 업데이트.
2026-05-13 22:20:58 +09:00
74 changed files with 526 additions and 57 deletions

View File

@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"mq:answer"
]
}

View File

@@ -0,0 +1,32 @@
{
"type": "minecraft:notice",
"title": {
"text": "정답 입력",
"bold": true
},
"body": [],
"inputs": [
{
"type": "minecraft:text",
"key": "text",
"label": {
"text": "정답"
},
"width": 300,
"max_length": 64,
"initial": ""
}
],
"can_close_with_escape": true,
"pause": false,
"after_action": "close",
"action": {
"label": {
"text": "제출"
},
"action": {
"type": "minecraft:dynamic/run_command",
"template": "function mq:answer/submit {text:'$(text)'}"
}
}
}

View File

@@ -0,0 +1,12 @@
# aliases 배열 첫 원소와 비교 → 매치 시 즉시 종료, 아니면 pop 후 재귀
execute store result score alen func.temp run data get storage mq:tmp aliases
execute if score alen func.temp matches 0 run return 0
data modify storage mq:tmp norm.in set from storage mq:tmp aliases[0]
function mq:answer/normalize
data modify storage mq:tmp judge.answer set from storage mq:tmp norm.acc
function mq:answer/macro/match with storage mq:tmp judge
data remove storage mq:tmp aliases[0]
execute if score @s answer matches 1 run return 0
function mq:answer/iter_aliases

View File

@@ -0,0 +1,19 @@
# 제출자(@s) 로 실행됨 — answer.title 및 alias 들과 비교
# 매치되면 @s answer = 1 → check_answer 가 정답처리 흐름으로 진입
# 매치 안되면 @s answer = 2 → check_answer 가 reset 처리 (1회 비교 후 초기화)
# 1) 제목과 비교 (정규화 후)
data modify storage mq:tmp norm.in set from storage mq:main answer.title
function mq:answer/normalize
data modify storage mq:tmp judge.answer set from storage mq:tmp norm.acc
function mq:answer/macro/match with storage mq:tmp judge
# 2) 제목 매치 실패 시 alias 들과 순차 비교 (조기 종료)
execute unless score @s answer matches 1 run data modify storage mq:tmp aliases set from storage mq:main answer.alias
execute unless score @s answer matches 1 run function mq:answer/iter_aliases
# 3) 끝까지 매치 실패면 오답 처리 (check_answer 가 reset)
execute unless score @s answer matches 1 run scoreboard players set @s answer 2
# 4) 처리 완료 — 이 제출자의 submit_seq 정리 (다음 큐 항목과 혼동 방지)
scoreboard players reset @s submit_seq

View File

@@ -0,0 +1,2 @@
# queue entry 의 seq 점수를 가진 플레이어(@s) 컨텍스트로 judge 실행
$execute as @a[scores={submit_seq=$(seq)},limit=1] run function mq:answer/judge

View File

@@ -0,0 +1,3 @@
# judge.input 과 judge.answer 가 같으면 @s answer = 1
# 매크로 치환으로 answer 필드를 NBT predicate 의 리터럴로 박아넣음
$execute if data storage mq:tmp judge{input:"$(answer)"} run scoreboard players set @s answer 1

View File

@@ -0,0 +1,13 @@
# 입력 문자열 정규화 — 소문자 변환 + 공백 제거 (대소문자/공백 무시 비교용)
#
# 입력 : storage mq:tmp norm.in (원본 문자열)
# 출력 : storage mq:tmp norm.acc (정규화 결과)
#
# 호출 예:
# data modify storage mq:tmp norm.in set from storage mq:main answer.title
# function mq:answer/normalize
# # 이후 storage mq:tmp norm.acc 에 결과
#
# 동작: norm.in 을 한 글자씩 떼어내며 normalize/step 으로 재귀
data modify storage mq:tmp norm.acc set value ""
function mq:answer/normalize/step

View File

@@ -0,0 +1,3 @@
# acc 끝에 c 를 매크로로 concat
# 매크로 인자: storage mq:tmp norm → $(acc), $(c)
$data modify storage mq:tmp norm.acc set value "$(acc)$(c)"

View File

@@ -0,0 +1,47 @@
# normalize 의 1-문자 처리 + 재귀 스텝
# 사전조건: storage mq:tmp norm.in 비어있지 않을 수 있음 / norm.acc 누적값
execute store result score n.len func.temp run data get storage mq:tmp norm.in
execute if score n.len func.temp matches 0 run return 0
# 머리글자 추출 → norm.c
data modify storage mq:tmp norm.c set string from storage mq:tmp norm.in 0 1
# 공백 제거 (스킵)
execute if data storage mq:tmp norm{c:" "} run data modify storage mq:tmp norm.c set value ""
# 대문자 A-Z → 소문자 a-z
execute if data storage mq:tmp norm{c:"A"} run data modify storage mq:tmp norm.c set value "a"
execute if data storage mq:tmp norm{c:"B"} run data modify storage mq:tmp norm.c set value "b"
execute if data storage mq:tmp norm{c:"C"} run data modify storage mq:tmp norm.c set value "c"
execute if data storage mq:tmp norm{c:"D"} run data modify storage mq:tmp norm.c set value "d"
execute if data storage mq:tmp norm{c:"E"} run data modify storage mq:tmp norm.c set value "e"
execute if data storage mq:tmp norm{c:"F"} run data modify storage mq:tmp norm.c set value "f"
execute if data storage mq:tmp norm{c:"G"} run data modify storage mq:tmp norm.c set value "g"
execute if data storage mq:tmp norm{c:"H"} run data modify storage mq:tmp norm.c set value "h"
execute if data storage mq:tmp norm{c:"I"} run data modify storage mq:tmp norm.c set value "i"
execute if data storage mq:tmp norm{c:"J"} run data modify storage mq:tmp norm.c set value "j"
execute if data storage mq:tmp norm{c:"K"} run data modify storage mq:tmp norm.c set value "k"
execute if data storage mq:tmp norm{c:"L"} run data modify storage mq:tmp norm.c set value "l"
execute if data storage mq:tmp norm{c:"M"} run data modify storage mq:tmp norm.c set value "m"
execute if data storage mq:tmp norm{c:"N"} run data modify storage mq:tmp norm.c set value "n"
execute if data storage mq:tmp norm{c:"O"} run data modify storage mq:tmp norm.c set value "o"
execute if data storage mq:tmp norm{c:"P"} run data modify storage mq:tmp norm.c set value "p"
execute if data storage mq:tmp norm{c:"Q"} run data modify storage mq:tmp norm.c set value "q"
execute if data storage mq:tmp norm{c:"R"} run data modify storage mq:tmp norm.c set value "r"
execute if data storage mq:tmp norm{c:"S"} run data modify storage mq:tmp norm.c set value "s"
execute if data storage mq:tmp norm{c:"T"} run data modify storage mq:tmp norm.c set value "t"
execute if data storage mq:tmp norm{c:"U"} run data modify storage mq:tmp norm.c set value "u"
execute if data storage mq:tmp norm{c:"V"} run data modify storage mq:tmp norm.c set value "v"
execute if data storage mq:tmp norm{c:"W"} run data modify storage mq:tmp norm.c set value "w"
execute if data storage mq:tmp norm{c:"X"} run data modify storage mq:tmp norm.c set value "x"
execute if data storage mq:tmp norm{c:"Y"} run data modify storage mq:tmp norm.c set value "y"
execute if data storage mq:tmp norm{c:"Z"} run data modify storage mq:tmp norm.c set value "z"
# acc = acc + c (매크로 결합)
function mq:answer/normalize/append with storage mq:tmp norm
# 나머지로 진행
data modify storage mq:tmp norm.in set string from storage mq:tmp norm.in 1
function mq:answer/normalize/step

View File

@@ -0,0 +1,4 @@
# trigger input 으로 호출됨 — 다음 trigger 사용을 위해 즉시 재활성화 후 dialog 표시
scoreboard players reset @s input
scoreboard players enable @s input
dialog show @s mq:answer

View File

@@ -0,0 +1,21 @@
# tick 에서 매 tick 호출됨 — 큐의 가장 먼저 제출된 항목 1개를 처리
# 1 tick 당 1건 처리 — 동시 다발 제출은 FIFO 순서로 자동 직렬화됨
execute store result score qlen func.temp run data get storage mq:input queue
execute if score qlen func.temp matches 0 run return 0
# 첫번째 항목 = 가장 먼저 제출된 것
data modify storage mq:tmp judge set value {input:"", answer:""}
# 입력 정규화 (소문자 + 공백제거) — 정답과 비교는 둘 다 정규화된 형태로
data modify storage mq:tmp norm.in set from storage mq:input queue[0].text
function mq:answer/normalize
data modify storage mq:tmp judge.input set from storage mq:tmp norm.acc
# 매크로로 해당 seq 를 가진 플레이어 찾아서 judge 실행
data modify storage mq:tmp _find set value {seq:0}
data modify storage mq:tmp _find.seq set from storage mq:input queue[0].seq
# 항목 제거 (한 번 비교했으면 큐에서 빼기)
data remove storage mq:input queue[0]
function mq:answer/macro/find_submitter with storage mq:tmp _find

View File

@@ -0,0 +1,14 @@
# 정답 dialog 제출 핸들러 — 매크로 인자 {text:"..."} 받음
# 퀴즈 진행 중(init=5) 이 아니면 제출 무시
execute unless score init main matches 5 run return 0
# 제출 순번 부여 — seq 는 setanswer 에서 0 으로 초기화됨
# 동일 tick 내 동시 제출도 명령 실행 순서대로 1씩 증가하여 고유한 seq 가 부여됨
scoreboard players add seq func.temp 1
scoreboard players operation @s submit_seq = seq func.temp
# 큐에 {text, seq} append — process 는 queue[0] (가장 먼저 제출된 것) 부터 처리
data modify storage mq:tmp new_entry set value {text:"", seq:0}
execute store result storage mq:tmp new_entry.seq int 1 run scoreboard players get @s submit_seq
$data modify storage mq:tmp new_entry.text set value "$(text)"
data modify storage mq:input queue append from storage mq:tmp new_entry

View File

@@ -13,6 +13,11 @@ scoreboard players set test buttons -1
scoreboard players reset @a answer scoreboard players reset @a answer
# 정답 입력 큐 / 제출 순번 초기화
data remove storage mq:input queue
scoreboard players reset @a submit_seq
scoreboard players set seq func.temp 0
# 트리거 시작 # 트리거 시작
scoreboard objectives remove ready scoreboard objectives remove ready
scoreboard objectives add ready trigger scoreboard objectives add ready trigger
@@ -31,8 +36,15 @@ scoreboard objectives add hint trigger
scoreboard objectives remove replay scoreboard objectives remove replay
scoreboard objectives add replay trigger scoreboard objectives add replay trigger
scoreboard objectives remove input
scoreboard objectives add input trigger
# 트리거 끝 # 트리거 끝
# 제출자 식별용 순번 점수 (queue entry 의 seq 와 매칭)
scoreboard objectives remove submit_seq
scoreboard objectives add submit_seq dummy
scoreboard objectives setdisplay sidebar scoreboard objectives setdisplay sidebar
scoreboard objectives remove score scoreboard objectives remove score
scoreboard objectives add score dummy {"text":"점수","bold":true} scoreboard objectives add score dummy {"text":"점수","bold":true}

View File

@@ -11,11 +11,11 @@ data modify storage mq:main spawn set value {x: 144, y: 61, z: -219, r: 180, f:
# pitch — 1.0 = 원본 속도 # pitch — 1.0 = 원본 속도
data modify storage mq:main audio set value {namespace: "musicquiz", source: "weather", volume: 1.0, pitch: 1.0} data modify storage mq:main audio set value {namespace: "musicquiz", source: "weather", volume: 1.0, pitch: 1.0}
# 정답 페인팅 — minecraft_launcher 리소스팩 musicquiz:cover_NN painting_variant # 정답 페인팅 — 데이터팩의 mq:cover_NN painting_variant (텍스처는 리소스팩 musicquiz:cover_NN)
# namespace — painting_variant 네임스페이스 (기본 "musicquiz") # namespace — painting_variant 네임스페이스 (기본 "mq")
# x,y,z — 페인팅 entity 좌표 (벽면 앞쪽 블록 위치) # x,y,z — 페인팅 entity 좌표 (벽면 앞쪽 블록 위치)
# facing — 페인팅이 바라보는 방향: south=0 / west=1 / north=2 / east=3 # facing — 페인팅이 바라보는 방향: south=0 / west=1 / north=2 / east=3
data modify storage mq:main image set value {namespace: "musicquiz", x: 144, y: 84, z: -261, facing: 0b} data modify storage mq:main image set value {namespace: "mq", x: 144, y: 84, z: -261, facing: 0b}
# 정답 입력용 marker entity 소환 좌표 # 정답 입력용 marker entity 소환 좌표
data modify storage mq:main marker set value {x: 144, y: 59, z: -219} data modify storage mq:main marker set value {x: 144, y: 59, z: -219}

View File

@@ -1,60 +1,59 @@
# 곡 한 개 = 한 줄. # 곡 한 개 = 한 줄.
# 필수 — title, author, alias # 필수 — title, author, alias, volume
# 선택 — volume (이 곡만의 /playsound 음량. 미지정시 init/config.mcfunction # volume: /playsound 음량. 1.0 = 기본. 곡마다 음량 조절 가능.
# 의 audio.volume 사용)
# 곡 순서가 리소스팩의 track_NN / cover_NN 인덱스와 1:1 매칭된다. # 곡 순서가 리소스팩의 track_NN / cover_NN 인덱스와 1:1 매칭된다.
# 예) {title:"Quiet Song", author:"...", alias:[...], volume:2.0} # 예) {title:"Quiet Song", author:"...", alias:[...], volume:2.0}
data modify storage mq:main songs set value [] data modify storage mq:main songs set value []
data modify storage mq:main songs append value {title:"Lose My Mind", author:"Don Toliver", alias:[" "," "," "]} data modify storage mq:main songs append value {title:"Lose My Mind", author:"Don Toliver", alias:[" "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"The Chase", author:"Hearts2Hearts", alias:[" "," "," "]} data modify storage mq:main songs append value {title:"The Chase", author:"Hearts2Hearts", alias:[" "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"HOT SAUCE", author:"BABYMONSTER", alias:[" "," "]} data modify storage mq:main songs append value {title:"HOT SAUCE", author:"BABYMONSTER", alias:[" "," "], volume:1.0}
data modify storage mq:main songs append value {title:"Golden", author:"HUNTR/X", alias:[""," "]} data modify storage mq:main songs append value {title:"Golden", author:"HUNTR/X", alias:[""," "], volume:1.0}
data modify storage mq:main songs append value {title:"돌림판", author:"머쉬베놈", alias:["Spin the wheel"]} data modify storage mq:main songs append value {title:"돌림판", author:"머쉬베놈", alias:["Spin the wheel"], volume:1.0}
data modify storage mq:main songs append value {title:"OVERDRIVE", author:"TWS", alias:["",""]} data modify storage mq:main songs append value {title:"OVERDRIVE", author:"TWS", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"눈물참기", author:"QWER", alias:[]} data modify storage mq:main songs append value {title:"눈물참기", author:"QWER", alias:[], volume:1.0}
data modify storage mq:main songs append value {title:"깨어", author:"tripleS", alias:[]} data modify storage mq:main songs append value {title:"깨어", author:"tripleS", alias:[], volume:1.0}
data modify storage mq:main songs append value {title:"like JENNIE", author:"제니", alias:[" "," "," "," "]} data modify storage mq:main songs append value {title:"like JENNIE", author:"제니", alias:[" "," "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"Rich Man", author:"aespa", alias:[" "," "]} data modify storage mq:main songs append value {title:"Rich Man", author:"aespa", alias:[" "," "], volume:1.0}
data modify storage mq:main songs append value {title:"I DO ME", author:"KiiiKiii", alias:[" "," "," "]} data modify storage mq:main songs append value {title:"I DO ME", author:"KiiiKiii", alias:[" "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"SIGN", author:"izna", alias:["",""]} data modify storage mq:main songs append value {title:"SIGN", author:"izna", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"WICKED", author:"ALLDAY PROJECT", alias:["",""]} data modify storage mq:main songs append value {title:"WICKED", author:"ALLDAY PROJECT", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"Good Thing", author:"i-dle", alias:["굿 "," "," "]} data modify storage mq:main songs append value {title:"Good Thing", author:"i-dle", alias:["굿 "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"0+0", author:"한로로", alias:[]} data modify storage mq:main songs append value {title:"0+0", author:"한로로", alias:[], volume:1.0}
data modify storage mq:main songs append value {title:"HANDS UP", author:"MEOVV", alias:[" "," "," "]} data modify storage mq:main songs append value {title:"HANDS UP", author:"MEOVV", alias:[" "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"Blue Valentine", author:"NMIXX", alias:[" "," "]} data modify storage mq:main songs append value {title:"Blue Valentine", author:"NMIXX", alias:[" "," "], volume:1.0}
data modify storage mq:main songs append value {title:"Flower", author:"오반", alias:["",""]} data modify storage mq:main songs append value {title:"Flower", author:"오반", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"Soda Pop", author:"Saja Boys", alias:[" "," "]} data modify storage mq:main songs append value {title:"Soda Pop", author:"Saja Boys", alias:[" "," "], volume:1.0}
data modify storage mq:main songs append value {title:"REBEL HEART", author:"IVE", alias:[" "," "]} data modify storage mq:main songs append value {title:"REBEL HEART", author:"IVE", alias:[" "," "], volume:1.0}
data modify storage mq:main songs append value {title:"GO!", author:"CORTIS", alias:["","!","GO","","!"]} data modify storage mq:main songs append value {title:"GO!", author:"CORTIS", alias:["","!","GO","","!"], volume:1.0}
data modify storage mq:main songs append value {title:"BEEP", author:"izna", alias:["","",""]} data modify storage mq:main songs append value {title:"BEEP", author:"izna", alias:["","",""], volume:1.0}
data modify storage mq:main songs append value {title:"Pookie", author:"FIFTY FIFTY", alias:["",""]} data modify storage mq:main songs append value {title:"Pookie", author:"FIFTY FIFTY", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"DAISIES", author:"Justin Bieber", alias:["","",""]} data modify storage mq:main songs append value {title:"DAISIES", author:"Justin Bieber", alias:["","",""], volume:1.0}
data modify storage mq:main songs append value {title:"빌려온 고양이", author:"ILLIT", alias:[]} data modify storage mq:main songs append value {title:"빌려온 고양이", author:"ILLIT", alias:[], volume:1.0}
data modify storage mq:main songs append value {title:"TOO BAD", author:"OfficialGDRAGON", alias:[" "," "," "]} data modify storage mq:main songs append value {title:"TOO BAD", author:"OfficialGDRAGON", alias:[" "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"시작의 아이", author:"마크툽", alias:[]} data modify storage mq:main songs append value {title:"시작의 아이", author:"마크툽", alias:[], volume:1.0}
data modify storage mq:main songs append value {title:"STYLE", author:"Hearts2Hearts", alias:["",""]} data modify storage mq:main songs append value {title:"STYLE", author:"Hearts2Hearts", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"Good Goodbye", author:"화사", alias:["굿 굿"," "," "]} data modify storage mq:main songs append value {title:"Good Goodbye", author:"화사", alias:["굿 굿"," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"너에게 닿기를", author:"10CM", alias:[]} data modify storage mq:main songs append value {title:"너에게 닿기를", author:"10CM", alias:[], volume:1.0}
data modify storage mq:main songs append value {title:"IRIS OUT", author:"Kenshi Yonezu", alias:[" "," "," "]} data modify storage mq:main songs append value {title:"IRIS OUT", author:"Kenshi Yonezu", alias:[" "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"Sugar On My Tongue", author:"Tyler, The Creator", alias:[" "," "," "]} data modify storage mq:main songs append value {title:"Sugar On My Tongue", author:"Tyler, The Creator", alias:[" "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"Hollywood Action", author:"BOYNEXTDOOR", alias:[" "," "]} data modify storage mq:main songs append value {title:"Hollywood Action", author:"BOYNEXTDOOR", alias:[" "," "], volume:1.0}
data modify storage mq:main songs append value {title:"SPAGHETTI", author:"LE SSERAFIM", alias:["",""]} data modify storage mq:main songs append value {title:"SPAGHETTI", author:"LE SSERAFIM", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"Gabriela", author:"KATSEYE", alias:["",""]} data modify storage mq:main songs append value {title:"Gabriela", author:"KATSEYE", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"LIKE YOU BETTER", author:"프로미스나인", alias:[" "," "," "," "," "]} data modify storage mq:main songs append value {title:"LIKE YOU BETTER", author:"프로미스나인", alias:[" "," "," "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"뛰어", author:"BLACKPINK", alias:["jump"]} data modify storage mq:main songs append value {title:"뛰어", author:"BLACKPINK", alias:["jump"], volume:1.0}
data modify storage mq:main songs append value {title:"CHANEL", author:"Tyla", alias:["",""]} data modify storage mq:main songs append value {title:"CHANEL", author:"Tyla", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"오늘만 I LOVE YOU", author:"BOYNEXTDOOR", alias:[" "," "]} data modify storage mq:main songs append value {title:"오늘만 I LOVE YOU", author:"BOYNEXTDOOR", alias:[" "," "], volume:1.0}
data modify storage mq:main songs append value {title:"earthquake", author:"지수", alias:["","",""," "]} data modify storage mq:main songs append value {title:"earthquake", author:"지수", alias:["","",""," "], volume:1.0}
data modify storage mq:main songs append value {title:"윽!", author:"염따", alias:[""]} data modify storage mq:main songs append value {title:"윽!", author:"염따", alias:[""], volume:1.0}
data modify storage mq:main songs append value {title:"Abracadabra", author:"Lady Gaga", alias:["",""]} data modify storage mq:main songs append value {title:"Abracadabra", author:"Lady Gaga", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"멸종위기사랑", author:"이찬혁", alias:[]} data modify storage mq:main songs append value {title:"멸종위기사랑", author:"이찬혁", alias:[], volume:1.0}
data modify storage mq:main songs append value {title:"Dirty Work", author:"aespa", alias:[" "," "," "," "," "]} data modify storage mq:main songs append value {title:"Dirty Work", author:"aespa", alias:[" "," "," "," "," "], volume:1.0}
data modify storage mq:main songs append value {title:"HOT", author:"LE SSERAFIM", alias:["",""]} data modify storage mq:main songs append value {title:"HOT", author:"LE SSERAFIM", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"FAMOUS", author:"ALLDAY PROJECT", alias:["",""]} data modify storage mq:main songs append value {title:"FAMOUS", author:"ALLDAY PROJECT", alias:["",""], volume:1.0}
data modify storage mq:main songs append value {title:"XOXZ", author:"IVE", alias:[" "," ",""]} data modify storage mq:main songs append value {title:"XOXZ", author:"IVE", alias:[" "," ",""], volume:1.0}
data modify storage mq:main songs append value {title:"여름이었다", author:"H1-KEY", alias:[]} data modify storage mq:main songs append value {title:"여름이었다", author:"H1-KEY", alias:[], volume:1.0}
data modify storage mq:main songs append value {title:"LOV3", author:"식케이", alias:["3","3"]} data modify storage mq:main songs append value {title:"LOV3", author:"식케이", alias:["3","3"], volume:1.0}
data modify storage mq:main songs append value {title:"Drive", author:"Ed Sheeran", alias:["",""]} data modify storage mq:main songs append value {title:"Drive", author:"Ed Sheeran", alias:["",""], volume:1.0}
# 곡 개수는 songs 배열 길이에서 자동 계산됨 # 곡 개수는 songs 배열 길이에서 자동 계산됨
execute store result storage mq:main max_index int 1 run data get storage mq:main songs execute store result storage mq:main max_index int 1 run data get storage mq:main songs

View File

@@ -8,3 +8,6 @@ title @s title ""
$setworldspawn $(x) $(y) $(z) $(r) $(f) $setworldspawn $(x) $(y) $(z) $(r) $(f)
$tp @s $(x) $(y) $(z) $(r) $(f) $tp @s $(x) $(y) $(z) $(r) $(f)
gamemode adventure @s gamemode adventure @s
# 채팅정답 모드 활성 알림은 모드가 직접 PlayerLoggedInEvent 핸들러에서
# mq:players/mod_active_notice 를 호출해서 표시한다 (race-free).

View File

@@ -0,0 +1,3 @@
# chat_answer 모드의 PlayerLoggedInEvent 핸들러가 직접 호출.
# 모드가 없으면 이 함수가 호출될 일이 없으므로 메세지가 안 뜬다.
tellraw @s ["",{"text":"[채팅정답] ","color":"green","bold":true},{"text":"모드가 활성화되어 있습니다.","color":"gray"},{"text":" 정답 입력 시 ","color":"gray"},{"text":"채팅","color":"yellow","bold":true},{"text":"으로 바로 제출할 수 있습니다.","color":"gray"}]

View File

@@ -12,6 +12,15 @@ scoreboard players set skip buttons -1
scoreboard players set hint buttons -1 scoreboard players set hint buttons -1
scoreboard players set replay buttons -1 scoreboard players set replay buttons -1
# 이전 문제의 미처리 정답 입력 정리 + 새 문제의 input trigger 활성화
data remove storage mq:input queue
scoreboard players reset @a submit_seq
scoreboard players set seq func.temp 0
scoreboard players enable @a input
# 정답 입력 안내 (클릭 시 trigger input → tick 에서 dialog 오픈)
function mq:tellraw {"text":"","color":"black",msg:[{"text":"[ 정답 입력 ]","color":"green","bold":true,"click_event":{"action":"run_command","command":"/trigger input set 1"},"hover_event":{"action":"show_text","value":{"text":"클릭하여 정답 입력창 열기","color":"gray"}}}]}
scoreboard players set init main 5 scoreboard players set init main 5
function mq:quiz/play_sound function mq:quiz/play_sound

View File

@@ -4,3 +4,7 @@ function mq:repeat/triggers/handler
execute if score init main matches 2.. run function mq:repeat/timer execute if score init main matches 2.. run function mq:repeat/timer
execute if score init main matches 5..6 run function mq:repeat/check_answer execute if score init main matches 5..6 run function mq:repeat/check_answer
# 정답 입력 다이얼로그: init=5 (곡 재생 중) 일 때만 열림 / 제출 처리
execute if score init main matches 5 as @a[scores={input=1..}] run function mq:answer/open
execute if score init main matches 5 run function mq:answer/process

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_01",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_02",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_03",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_04",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_05",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_06",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_07",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_08",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_09",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_10",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_11",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_12",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_13",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_14",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_15",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_16",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_17",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_18",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_19",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_20",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_21",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_22",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_23",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_24",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_25",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_26",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_27",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_28",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_29",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_30",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_31",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_32",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_33",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_34",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_35",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_36",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_37",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_38",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_39",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_40",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_41",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_42",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_43",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_44",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_45",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_46",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_47",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_48",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_49",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:cover_50",
"width": 1,
"height": 1
}

View File

@@ -0,0 +1,5 @@
{
"asset_id": "musicquiz:gif",
"width": 1,
"height": 1
}

View File

@@ -1,6 +1,8 @@
{ {
"pack": { "pack": {
"pack_format": 75, "pack_format": 75,
"min_format": 75,
"max_format": 75,
"description": "음악퀴즈용 데이터팩입니다." "description": "음악퀴즈용 데이터팩입니다."
} }
} }

BIN
music_quiz/pack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
temp/gif.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

6
temp/gif.png.mcmeta Normal file
View File

@@ -0,0 +1,6 @@
{
"animation": {
"frametime": 1,
"interpolate": false
}
}