185 lines
6.8 KiB
Markdown
185 lines
6.8 KiB
Markdown
---
|
||
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<string, unknown>) {
|
||
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]]
|
||
- 변형: [[Pity System]] · [[Adaptive Difficulty]] · [[IV System]]
|
||
- 응용: [[Gacha Mechanics]] · [[Persona Social Link]]
|
||
- Adjacent: [[데이터_기반_밸런싱(Data-Driven_Balancing)]] · [[RNG Design]]
|
||
|
||
## 🤖 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 |
|