Files
2nd/10_Wiki/Topics/Architecture/Machinations.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

230 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: wiki-2026-0508-machinations
title: Machinations
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Machinations Diagram, Game Economy Modeling]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [game-design, economy-modeling, simulation, balancing]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: machinations
---
# Machinations
## 매 한 줄
> **"매 game economy 의 visual flow simulation"**. Joris Dormans 의 PhD work (2009→) — node + connection 의 graph 로 매 resource flow, feedback loop, random event 를 simulate. 2026 의 Machinations.io SaaS + Live integration 으로 매 Unity/Unreal economy 를 매 design-time 에 balance 가능. F2P, gacha, idle 게임의 매 standard tool.
## 매 핵심
### 매 핵심 nodes
- **Pool**: resource 저장 (gold, energy, XP).
- **Source**: resource 생성.
- **Drain**: resource 소비.
- **Converter**: resource 변환 (예: 5 wood → 1 plank).
- **Trader**: bidirectional exchange.
- **Gate**: 매 conditional flow router.
- **End condition**: simulation 종료 trigger.
### 매 connection types
- **Resource connection**: rate (per tick) + label.
- **State connection**: source pool 의 value 가 매 다른 node 의 rate modifier.
- **Trigger**: event-based fire.
- **Activator**: enable/disable based on threshold.
### 매 simulation modes
- **Deterministic**: fixed rates → predictable.
- **Stochastic**: random with distribution → Monte Carlo.
- **Interactive**: player input 의 click on Source/Drain.
### 매 응용
1. F2P economy balancing (gacha rates, soft/hard currency).
2. Idle game progression curves.
3. RTS resource gathering loop.
4. Battle-pass / season pass tuning.
5. Player retention model (LTV simulation).
6. Educational economic modeling (supply/demand).
## 💻 패턴
### 1. Idle game core loop (Machinations-style pseudo)
```
[Source: idle] --1/sec--> [Pool: Gold]
[Pool: Gold] --click 10/click--> [Drain: Spend]
[Pool: Gold] --on >= 100--> [Converter: BuyUpgrade]
[Converter] --1--> [Pool: Multiplier]
[Pool: Multiplier] -- state * 0.5 --> [Source: idle].rate
# Feedback loop: more multiplier → faster gold → more upgrades
```
### 2. JS simulation harness (build your own)
```typescript
type Pool = { name: string; value: number };
type Edge = {
from: string;
to: string;
rate: (state: Record<string, number>) => number;
};
class Simulator {
pools: Pool[] = [];
edges: Edge[] = [];
tick = 0;
step() {
const state = Object.fromEntries(this.pools.map(p => [p.name, p.value]));
const deltas: Record<string, number> = {};
for (const e of this.edges) {
const r = e.rate(state);
deltas[e.from] = (deltas[e.from] ?? 0) - r;
deltas[e.to] = (deltas[e.to] ?? 0) + r;
}
for (const p of this.pools) p.value = Math.max(0, p.value + (deltas[p.name] ?? 0));
this.tick++;
}
}
const sim = new Simulator();
sim.pools = [{ name: "gold", value: 0 }, { name: "mult", value: 1 }];
sim.edges = [
{ from: "_source", to: "gold", rate: s => 1 * s.mult },
{ from: "gold", to: "mult", rate: s => s.gold >= 100 ? 100 : 0 }, // buy upgrade
];
```
### 3. Monte Carlo balance test
```typescript
function runMontecarlo(n = 1000) {
const completionTimes: number[] = [];
for (let i = 0; i < n; i++) {
const sim = buildEconomy({ seed: i });
while (!sim.done && sim.tick < 100_000) sim.step();
completionTimes.push(sim.tick);
}
completionTimes.sort((a, b) => a - b);
return {
p50: completionTimes[Math.floor(n * 0.5)],
p95: completionTimes[Math.floor(n * 0.95)],
p99: completionTimes[Math.floor(n * 0.99)],
};
}
// Use to validate "median player reaches L20 in ~2 hours".
```
### 4. Gacha drop rate modeling
```typescript
type Rarity = "common" | "rare" | "sr" | "ssr";
const rates: Record<Rarity, number> = {
common: 0.79,
rare: 0.17,
sr: 0.035,
ssr: 0.005, // 0.5%
};
function pull(): Rarity {
const r = Math.random();
let acc = 0;
for (const [k, p] of Object.entries(rates) as [Rarity, number][]) {
acc += p;
if (r < acc) return k;
}
return "common";
}
function pityCounter() {
let pulls = 0;
return () => {
pulls++;
if (pulls >= 90) { pulls = 0; return "ssr" as Rarity; }
return pull();
};
}
// Simulate 10k players → expected SSR per player + variance.
```
### 5. Feedback loop classification
```
Positive feedback: A → ... → A+ (rich-get-richer, snowball)
Negative feedback: A → ... → A- (rubber-banding, balance)
Multiplayer dynamics: Mario Kart blue shell (negative for leader)
```
```typescript
// Detect runaway: if d(pool)/dt grows super-linearly → rebalance
function detectRunaway(history: number[]): boolean {
const ratios = history.slice(1).map((v, i) => v / Math.max(history[i], 1));
return ratios.slice(-10).every(r => r > 1.1); // 10% growth/tick sustained
}
```
### 6. Progression pacing curve
```typescript
// Target: L = sqrt(XP / 50) → quadratic XP curve
function xpForLevel(L: number) { return 50 * L * L; }
// Sim: drop rate × kill rate × time = level after T
function levelAtTime(t: number, xpPerSec = 2) {
const totalXP = xpPerSec * t;
return Math.floor(Math.sqrt(totalXP / 50));
}
// Plot levelAtTime over 0..7200 (2h) and check pacing.
```
### 7. Machinations.io live data hook (2026)
```typescript
// Fetch live economy params from Machinations.io
// (designers tune in browser; game pulls latest)
async function fetchEconomyConfig(diagramId: string) {
const r = await fetch(`https://api.machinations.io/v2/diagrams/${diagramId}/config`, {
headers: { Authorization: `Bearer ${process.env.MACH_TOKEN}` },
});
return r.json(); // { goldPerSec, ssRate, levelCurve, ... }
}
// Update server tunables without redeploy.
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| F2P economy balance | Machinations.io diagram + Monte Carlo. |
| Idle / incremental | Custom JS simulator (lighter). |
| MMO economy stability | Agent-based simulation (more nodes). |
| Single-player RPG progression | Spreadsheet + simple sim. |
| Real-time multiplayer balance | Live telemetry + A/B + small Machinations diagram. |
| PVP balance (rock-paper-scissors) | Game theory tool, not Machinations. |
**기본값**: 매 currency-flow heavy game 의 design phase 에 매 Machinations diagram. Pure combat balance 는 매 다른 tool.
## 🔗 Graph
- 부모: [[Game Design]]
- Adjacent: [[Monte Carlo Simulation]] · [[Feedback Loops]]
## 🤖 LLM 활용
**언제**: economy diagram review, drop rate sanity check, progression curve drafting, feedback loop identification.
**언제 X**: 매 combat balance, 매 narrative pacing, 매 art/UX concerns.
## ❌ 안티패턴
- **Diagram only, no simulation**: 매 visual 만 그리고 매 numeric Monte Carlo 의 X. 매 deterministic only 는 stochastic player 의 outlier 을 miss.
- **Over-detailed model**: 매 50+ nodes — designer 가 매 mental model 잃음. 매 module 단위 분리.
- **Static rates in live game**: 매 Machinations 에서 balanced 후 hardcode. 매 LiveOps tunable 로 expose.
- **Ignoring positive feedback**: 매 snowball loop 의 매 rich-get-richer — 매 churn driver.
- **Single-seed simulation**: 매 1 run 으로 결정 — 매 N=1000+ Monte Carlo 필수.
## 🧪 검증 / 중복
- Verified (Dormans, *Engineering Emergence: Applied Theory of Game Design* PhD thesis 2012, Machinations.io docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Machinations primitives + Monte Carlo + gacha/idle pattern |