이클립스 방어 횟수 즉시 표시·진동 · Music Shake 영상 재생 중 흔들기 판정 · 결과 공유
This commit is contained in:
@@ -105,6 +105,40 @@ export interface PolicyConfig {
|
||||
referralAttachDays: number;
|
||||
/** 긴급 돌발 타임어택 지속 시간 상한(분) — 원장 「최대 24시간」. 🟡 운영값. */
|
||||
timeAttackMaxMinutes: number;
|
||||
/** Music Shake 판정 · 성공 · 보상 운영값(원장 B-24). 아래 [MusicShakePolicy] 참고. */
|
||||
musicShake: MusicShakePolicy;
|
||||
}
|
||||
|
||||
/** Music Shake 판정 등급. 등급 체계 자체가 기준자료에 없다 — 아래 [MusicShakePolicy] 참고. */
|
||||
export type ShakeGrade = 'S' | 'A' | 'B' | 'C' | 'F';
|
||||
|
||||
/**
|
||||
* Music Shake 운영값 — `config/policy.musicShake`.
|
||||
*
|
||||
* **🟡 임시값 — 회신 대기. 근거 없음.** 원장 B-24 가 확정한 것은 「BPM 기반 Shake 판정이 성공 /
|
||||
* 보상 기준 · 완청 보상 아님 · 보상액은 운영값」뿐이다. 판정 창 · 성공 기준 · 등급(S/A/B/C) ·
|
||||
* 등급 배수는 PRD-04 · 상세정의 v1.6.1 §20 · 별첨 B 어디에도 수치가 없어 **저희가 임시로 둔
|
||||
* 값**이며, 해석 확인 요청 「2026-10-07 Music Shake」(Q-MS-04 · Q-MS-05) 회신으로 바꾼다.
|
||||
* 앱(`ShakeWindows`)도 같은 기본값을 쓴다.
|
||||
*/
|
||||
export interface MusicShakePolicy {
|
||||
/** 이 블록이 회신 전 임시값인가. 회신 반영 시 false 로 내린다. */
|
||||
provisional: boolean;
|
||||
/** perfect 판정 창 — 박과의 거리(박 길이 대비). 🟡 임시 0.2. */
|
||||
perfectWindow: number;
|
||||
/** good 판정 창(이 밖이면 miss). 🟡 임시 0.5. */
|
||||
goodWindow: number;
|
||||
/** 성공(보상) 문턱 — (perfect + good) / 구간 수. 🟡 임시 0.5(예전 코드의 「50%」를 옮긴 것). */
|
||||
passRate: number;
|
||||
/** 등급 문턱 — perfect / 구간 수. S 는 miss 0 도 요구. 🟡 임시(예전 코드 값을 옮긴 것). */
|
||||
gradeCuts: { S: number; A: number; B: number };
|
||||
/** 등급별 기본 보상 배수. 🟡 임시(예전 코드 값). 등급 보상 차등 자체가 회신 대기다. */
|
||||
gradeMultiplier: Record<ShakeGrade, number>;
|
||||
/**
|
||||
* 퀘스트 `rewardPop` 이 없을 때의 기본 보상(일반 POP). 🟡 Admin Figma 「Quest 유형별 검증」
|
||||
* (`2376:2189`) 의 BPM / Shake 「1 POP」 예시값 — 확정값이 아니다.
|
||||
*/
|
||||
pop: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,6 +207,16 @@ export const DEFAULT_POLICY: PolicyConfig = {
|
||||
referralDailyCapPerReferrer: 5,
|
||||
referralAttachDays: 7,
|
||||
timeAttackMaxMinutes: 1440,
|
||||
// 🟡 임시값 — 회신 대기 · 근거 없음(위 MusicShakePolicy 설명).
|
||||
musicShake: {
|
||||
provisional: true,
|
||||
perfectWindow: 0.2,
|
||||
goodWindow: 0.5,
|
||||
passRate: 0.5,
|
||||
gradeCuts: { S: 0.95, A: 0.8, B: 0.6 },
|
||||
gradeMultiplier: { S: 2, A: 1.5, B: 1.2, C: 1, F: 0 },
|
||||
pop: 1,
|
||||
},
|
||||
};
|
||||
|
||||
export async function loadPolicy(): Promise<PolicyConfig> {
|
||||
@@ -185,6 +229,8 @@ export async function loadPolicy(): Promise<PolicyConfig> {
|
||||
...raw,
|
||||
// 가중치는 부분 지정이 흔하므로 축별로 병합한다. 통째로 덮으면 축이 사라진다.
|
||||
fpiWeights: weights,
|
||||
// 판정 운영값은 키별로 병합한다 — 일부만 바꿔도 나머지 임시값이 남는다.
|
||||
musicShake: { ...DEFAULT_POLICY.musicShake, ...(raw.musicShake ?? {}) },
|
||||
// 구간표는 통째로 덮는다. 섞으면 운영에서 지운 구간이 되살아난다.
|
||||
stepTiers: normalizeTiers(raw.stepTiers) ?? DEFAULT_POLICY.stepTiers,
|
||||
} as PolicyConfig;
|
||||
|
||||
Reference in New Issue
Block a user