Files
2nd/10_Wiki/Topics/Architecture/EVE_온라인(EVE_Online).md
T
2026-05-10 22:08:15 +09:00

7.7 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-eve-온라인-eve-online EVE 온라인(EVE Online) 10_Wiki/Topics verified self
EVE Online
EVE
CCP Games
none A 0.9 applied
game-design
mmo
sandbox
virtual-economy
distributed-systems
2026-05-10 pending
language framework
stackless-python tranquility

EVE 온라인(EVE Online)

매 한 줄

"매 single-shard MMO sandbox 의 player-driven economy 의 22-year proof". EVE Online (CCP Games, 2003-) 매 single persistent universe 매 모든 players 의 same world 의 share — 매 player-built corporations, wars, markets, espionage 의 ground truth. Architecture (Stackless Python + StacklessIO + cluster), economy, sandbox design 매 industry case study.

매 핵심

매 Architecture (Tranquility)

  • Single shard: 매 모든 players 매 one universe — 매 7,800+ star systems.
  • Per-system simulation node: 매 system 매 one node 의 simulate, 매 nodes 매 cluster 의 distribute.
  • Stackless Python: 매 lightweight tasklets 매 thousands 의 ships 의 concurrent simulation.
  • Time Dilation (TiDi): 매 fleet fight 의 thousands 의 ships 시 매 time slow-down (10%까지) — 매 graceful degradation.

매 Economy

  • Player-driven 99%: 매 모든 ships, modules, structures 매 player-mined / built.
  • PLEX: 매 real-money item 의 in-game ISK 의 trade — 매 secondary market.
  • Real economist: 매 CCP 매 in-house economist (Eyjólfur Guðmundsson) 매 quarterly reports 의 publish — 매 inflation, sink/faucet balance.

매 응용

  1. Sandbox MMO design reference.
  2. Distributed simulation scaling case.
  3. Virtual economy research (papers).
  4. Emergent player politics — Goonswarm, Test Alliance.

💻 패턴

TiDi-style adaptive tickrate

class AdaptiveSimulation:
    def __init__(self, target_fps=10):
        self.target_dt = 1.0 / target_fps
        self.tidi = 1.0  # 1.0 = real-time, 0.1 = 10% speed

    def step(self, entities):
        start = time.monotonic()
        for e in entities:
            e.update(self.target_dt * self.tidi)
        elapsed = time.monotonic() - start
        # If frame took longer than budget, dilate
        if elapsed > self.target_dt:
            self.tidi = max(0.1, self.target_dt / elapsed)
        else:
            self.tidi = min(1.0, self.tidi + 0.05)

Per-system node assignment

SYSTEM_NODES = {}  # system_id -> node_id

def route_player(player, system_id):
    node_id = SYSTEM_NODES.get(system_id)
    if node_id is None:
        node_id = pick_least_loaded_node()
        SYSTEM_NODES[system_id] = node_id
    forward_to_node(node_id, player)

def reinforce_system(system_id, expected_players):
    """
    Pre-fight reinforcement: 매 large fleet 의 expected 시
    매 system 의 dedicated high-spec node 의 move
    """
    if expected_players > 500:
        move_system_to_node(system_id, get_dedicated_node())

ISK economy faucet/sink tracking

@dataclass
class EconomicEvent:
    type: Literal['faucet', 'sink']
    source: str  # 'mission_reward', 'market_fee', 'jump_clone_cost'
    amount: int  # ISK
    actor_id: str
    ts: datetime

def monthly_economic_report(events: list[EconomicEvent]):
    by_source = defaultdict(lambda: {'in': 0, 'out': 0})
    for e in events:
        bucket = 'in' if e.type == 'faucet' else 'out'
        by_source[e.source][bucket] += e.amount
    total_in = sum(b['in'] for b in by_source.values())
    total_out = sum(b['out'] for b in by_source.values())
    return {
        'net': total_in - total_out,
        'inflation_signal': (total_in - total_out) / max(total_out, 1),
        'top_faucets': sorted(by_source.items(), key=lambda x: -x[1]['in'])[:5],
        'top_sinks': sorted(by_source.items(), key=lambda x: -x[1]['out'])[:5],
    }

Market order matching (regional)

class MarketEngine:
    def __init__(self):
        self.buy_orders = defaultdict(list)   # item_id -> [orders]
        self.sell_orders = defaultdict(list)

    def place_buy(self, order):
        sells = sorted(self.sell_orders[order.item_id], key=lambda o: o.price)
        remaining = order.quantity
        for s in sells:
            if s.price > order.max_price: break
            qty = min(remaining, s.quantity)
            self.execute_trade(order.buyer, s.seller, order.item_id, qty, s.price)
            s.quantity -= qty
            remaining -= qty
            if remaining == 0: break
        if remaining > 0:
            order.quantity = remaining
            heapq.heappush(self.buy_orders[order.item_id], order)

Killmail event sourcing

@dataclass
class Killmail:
    victim_id: str; attackers: list[str]
    ship_type: str; system_id: str
    isk_destroyed: int
    ts: datetime
    final_blow: str

# 매 immutable log — 매 zKillboard / EveWho 의 derive
def replay_corp_history(killmails: list[Killmail], corp_id: str):
    losses = sum(k.isk_destroyed for k in killmails if member_of(k.victim_id, corp_id))
    kills = sum(k.isk_destroyed for k in killmails
                if any(member_of(a, corp_id) for a in k.attackers))
    return {'isk_efficiency': kills / max(kills + losses, 1)}

Sovereignty / structure timer

class StructureTimer:
    """매 attacked structure 매 reinforce mode 의 enter — 매 24h timer."""
    def __init__(self, structure_id):
        self.id = structure_id
        self.state = 'anchored'
        self.timer_end = None

    def take_damage(self, dmg):
        if self.state == 'anchored' and self.hp_below(50):
            self.state = 'reinforced'
            self.timer_end = now() + timedelta(hours=24, minutes=randint(0, 360))
        elif self.state == 'reinforced' and now() >= self.timer_end:
            self.state = 'vulnerable'

매 결정 기준

상황 Approach
Massive single-world MMO 매 EVE 의 per-system node + TiDi
Sharded MMO (WoW-style) 매 EVE pattern 의 not-needed
Player economy 의 desire 매 explicit faucet/sink design + economist
Sandbox vs themepark 매 EVE-style emergent vs scripted quests
Anti-griefing 매 EVE 의 high/low/null-sec gradient

기본값: 매 single-shard 매 only 매 specific tradeoff 의 worth — 매 most MMOs 매 sharding 의 simpler. Economy 매 EVE pattern 의 broad applicability.

🔗 Graph

🤖 LLM 활용

언제: 매 player-economy game design reference. Distributed simulation 매 graceful degradation case. Virtual economy academic study. 언제 X: 매 non-MMO context. 매 small game 매 EVE complexity 의 over-apply.

안티패턴

  • No sinks: 매 only faucets — 매 hyperinflation. EVE 매 broker fees, jump clone, structure costs 의 sinks.
  • Hard server cap: 매 no TiDi 매 fleet fight 의 disconnect storm. Graceful slow-down 의 prefer.
  • Dev intervention 의 economy: 매 CCP 매 historically 의 hands-off — 매 player corp scams 매 allowed. 매 too much intervention 매 sandbox 의 break.
  • Single-shard 의 cargo-cult: 매 most games 매 single-shard 의 not-need — 매 sharding cost 의 cheaper.

🧪 검증 / 중복

  • Verified (CCP Games dev blogs; "EVE Online: How to Build a Single-Shard MMO" GDC; Eyjólfur Guðmundsson MER reports).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — EVE architecture + economy + 6 patterns