--- id: wiki-2026-0508-숨겨진-스탯-hidden-stats title: 숨겨진 스탯 (Hidden Stats) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Hidden Stats, Concealed Attributes, Internal Modifiers, Crit-Roll Stats] duplicate_of: none source_trust_level: A confidence_score: 0.85 verification_status: applied tags: [game-design, rpg, mechanics, balance, transparency] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: typescript framework: game-systems --- # 숨겨진 스탯 (Hidden Stats) ## 매 한 줄 > **"매 보이지 않는 number 가 매 visible 결과 의 형성"**. 매 hidden stats 는 player 에게 직접 노출 되지 않는 internal modifier — 매 luck floor, 매 individual values (Pokémon IV), 매 hidden affinity (Persona Social Link) 의 형태로 game depth 의 추가, but 매 transparency vs depth 의 균형 의 실패 시 매 player frustration 의 main source. ## 매 핵심 ### 매 정의 - **Hidden stat**: 매 game state 에 존재 but UI 에 직접 표시 되지 않는 numeric attribute. - **Visible stat**: ATK, HP, Speed 등 매 player 에 명시. - **Derived display**: damage = f(ATK, DEF, hidden_crit, RNG) — 매 player 가 결과 만 봄. ### 매 사용 사례 (전형) - **Pokémon**: IV (0–31), EV, Nature 의 hidden multiplier. - **Diablo / PoE**: monster pack-size variance, magic-find hidden roll. - **XCOM**: "scamming" 방지 의 RNG seed 의 hidden lock. - **Persona / Fire Emblem**: Social Link / Support 의 internal threshold. - **Souls 시리즈**: poise, hyperarmor frame-window 의 unlisted. - **Dwarf Fortress**: 매 모든 stat 의 hidden 의 default — 매 reputation 의 parametric. ### 매 design rationale 1. **Depth without overload**: UI 의 cluttering 회피. 2. **Replayability**: roll variance → 매 2번째 playthrough 의 다른 경험. 3. **Mystery as gameplay**: discovery 의 reward. 4. **Anti-min-max**: optimization 의 ceiling 의 unclear. ### 매 dark side 1. **Perceived unfairness**: "매 같은 stat 인데 왜 졌지?". 2. **Wiki dependency**: 매 datamining 의 force. 3. **Tutorial 의 confusion**: "매 왜 이번에는 효과 가 다르지?". ### 매 응용 (system 설계) 1. Pity timer (gacha) — hidden累積 카운터. 2. Difficulty rubber-banding — 매 hidden adaptive difficulty. 3. Drop rate boost — first-clear bonus. 4. Combo/streak modifier — recent-action window. ## 💻 패턴 ### Pattern 1 — IV system (Pokémon-like) ```typescript interface CreatureStats { baseHP: number; baseATK: number; baseDEF: number; iv: { hp: number; atk: number; def: number }; // 0–31, hidden ev: { hp: number; atk: number; def: number }; // 0–252, hidden until trained nature: Nature; // multiplier ±10% } function effectiveHP(c: CreatureStats, level: number): number { return Math.floor(((2 * c.baseHP + c.iv.hp + Math.floor(c.ev.hp / 4)) * level) / 100) + level + 10; } // Player sees only effectiveHP — IVs leaked via "Hyper Trainer" or judge-NPC. ``` ### Pattern 2 — Pity timer (gacha) ```typescript class PitySystem { private pulls = 0; // hidden private softPity = 75; private hardPity = 90; pull(baseRate = 0.006): boolean { this.pulls++; let rate = baseRate; if (this.pulls >= this.softPity) rate += 0.06 * (this.pulls - this.softPity); if (this.pulls >= this.hardPity) rate = 1; if (Math.random() < rate) { this.pulls = 0; return true; } return false; } } ``` ### Pattern 3 — Hidden affinity (Persona Social Link) ```typescript interface Bond { rank: number; // visible 1–10 exp: number; // hidden 0–999, threshold per rank affinity: number; // hidden multiplier 0.5..1.5 } function gainBond(b: Bond, action: ActionTag): void { const base = TABLE[action] ?? 1; // hidden table b.exp += Math.floor(base * b.affinity); if (b.exp >= NEXT_RANK[b.rank]) { b.rank++; b.exp = 0; } } ``` ### Pattern 4 — Crit-roll with hidden floor ```typescript function damageRoll(atk: number, def: number, hiddenLuck = 0): number { const base = Math.max(1, atk - def); const variance = 0.85 + Math.random() * 0.30; // 0.85..1.15 const luckyRoll = Math.random() < (0.05 + hiddenLuck); return Math.floor(base * variance * (luckyRoll ? 2 : 1)); } ``` ### Pattern 5 — Adaptive difficulty (DDA) ```typescript class HiddenDDA { private playerSkill = 0.5; // 0..1, hidden recordOutcome(playerWon: boolean) { this.playerSkill = this.playerSkill * 0.9 + (playerWon ? 1 : 0) * 0.1; } enemyHpScale(): number { return 0.7 + 0.6 * this.playerSkill; } } ``` ### Pattern 6 — Loot magic-find ```typescript function rollItem(baseTable: ItemDrop[], hiddenMF = 0): ItemDrop | null { const roll = Math.random() * (1 + hiddenMF); let acc = 0; for (const item of baseTable) { acc += item.chance; if (roll <= acc) return item; } return null; } // Player sees an item — never sees rolled value. ``` ### Pattern 7 — Telemetry (debugging hidden stats) ```typescript function logHidden(event: string, payload: Record) { if (DEBUG_HIDDEN) console.table(payload); // dev-only build flag analytics.send(event, payload); // server-side, never to client UI } ``` ## 매 결정 기준 | 상황 | Hidden? | Reason | |---|---|---| | Combat damage formula | Hidden | Mystery + variance | | Equipment ATK number | Visible | Optimization core | | Pity counter | Optional reveal (post-9.0) | 매 player goodwill | | Difficulty modifier | Hidden | Anti-gaming | | RNG seed | Hidden (often) | Anti-scumming | **기본값**: 매 visible if player decision-relevant; 매 hidden if narrative-immersion or replay variance. ## 🔗 Graph - 부모: [[게이미피케이션]] · [[게임 밸런싱|Game Balance]] - 변형: [[Adaptive Difficulty]] - Adjacent: [[데이터_기반_밸런싱(Data-Driven_Balancing)]] ## 🤖 LLM 활용 **언제**: 매 hidden-stat schema 의 design review, 매 telemetry event 의 schema generation. **언제 X**: 매 player-facing wiki 의 spoiler — 매 designer intent 의 위반. ## ❌ 안티패턴 - **Hidden + no telemetry**: 매 balance 의 검증 불가능. - **Total hidden**: 매 player agency 의 박탈. 매 2-3 visible "anchors" 의 필요. - **Late reveal as patch**: 매 hidden 의 UI 노출 의 sudden 변경 — 매 trust 의 destruction. - **Hidden + RNG-stack**: 매 chains 의 perceived unfair (e.g. hidden crit × hidden dodge × hidden block). ## 🧪 검증 / 중복 - Verified (Bulbapedia IV docs; Genshin Impact pity datamine; Persona 5 Royal social link tables). - 신뢰도 A−. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — IV/Pity/DDA pattern set |