f8b21af4be
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>
6.5 KiB
6.5 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-alliance-동맹 | Alliance (동맹) | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
Alliance (동맹)
매 한 줄
"매 player-formed group — shared goals, shared resources, shared identity". 매 MMO/SLG 의 retention 핵심 system. 매 EverQuest guild (1999) → World of Warcraft guild (2004) → Lords Mobile/Rise of Kingdoms 동맹 (2017+). 매 2026 modern SLG (4X/RTS hybrid) 의 core loop driver — solo player retention < 7 days, alliance member retention > 90 days 의 typical metric.
매 핵심
매 구조
- Membership tier: Leader / Officers (R4/R5) / Members / Recruits.
- State: roster, treasury, buff inventory, war declarations, territory.
- Permissions: hierarchical RBAC — invite/kick/promote/demote/disband.
- Lifecycle: create → recruit → grow → war → decline → disband.
매 server-authoritative invariants
- 매 single alliance per player 의 enforcement (atomic).
- Member cap (typical 50–100) — atomic check-and-insert.
- Treasury balance — race-free debit/credit (transactional).
- War state machine — pending/active/peace transitions.
매 응용
- SLG 4X game (Lords Mobile pattern) — alliance buffs, rallies, KvK.
- MMO guild (WoW pattern) — guild bank, calendar, perk levels.
- Mobile RPG clan (Clash of Clans pattern) — clan wars, donations.
- Social fitness app (Strava clubs) — challenges, leaderboards.
💻 패턴
Schema (Postgres)
CREATE TABLE alliances (
id BIGSERIAL PRIMARY KEY,
tag VARCHAR(5) UNIQUE NOT NULL,
name VARCHAR(40) NOT NULL,
leader_id BIGINT NOT NULL REFERENCES players(id),
member_cap SMALLINT NOT NULL DEFAULT 50,
treasury_gold BIGINT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE alliance_members (
player_id BIGINT PRIMARY KEY REFERENCES players(id),
alliance_id BIGINT NOT NULL REFERENCES alliances(id) ON DELETE CASCADE,
rank SMALLINT NOT NULL, -- 1=member..5=leader
joined_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX ON alliance_members (alliance_id);
Atomic join (server)
async function joinAlliance(playerId: bigint, allianceId: bigint) {
return await db.tx(async (t) => {
// 1. Player must not be in any alliance
const existing = await t.oneOrNone(
"SELECT 1 FROM alliance_members WHERE player_id=$1 FOR UPDATE", [playerId]);
if (existing) throw new Error("ALREADY_IN_ALLIANCE");
// 2. Member cap check (lock alliance row)
const a = await t.one(
"SELECT member_cap, (SELECT COUNT(*) FROM alliance_members WHERE alliance_id=$1)::int AS n " +
"FROM alliances WHERE id=$1 FOR UPDATE", [allianceId]);
if (a.n >= a.member_cap) throw new Error("ALLIANCE_FULL");
await t.none(
"INSERT INTO alliance_members(player_id, alliance_id, rank) VALUES($1,$2,1)",
[playerId, allianceId]);
});
}
Permission check
const PERMS = {
invite: 2, // R2+
kick: 3, // R3+
promote:4, // R4+
disband:5, // leader only
} as const;
function can(memberRank: number, action: keyof typeof PERMS): boolean {
return memberRank >= PERMS[action];
}
Alliance chat (Redis pub/sub)
// Publish
await redis.publish(`alliance:${allianceId}:chat`,
JSON.stringify({ from: playerId, msg, ts: Date.now() }));
// Subscribe (per connected client)
const sub = redis.duplicate();
await sub.subscribe(`alliance:${allianceId}:chat`, (raw) => {
ws.send(raw);
});
War declaration state machine
type WarState = "PEACE" | "PENDING" | "ACTIVE" | "COOLDOWN";
const transitions: Record<WarState, WarState[]> = {
PEACE: ["PENDING"],
PENDING: ["ACTIVE", "PEACE"],
ACTIVE: ["COOLDOWN"],
COOLDOWN: ["PEACE"],
};
function transition(from: WarState, to: WarState) {
if (!transitions[from].includes(to))
throw new Error(`INVALID_TRANSITION ${from}->${to}`);
}
Treasury (idempotent donation)
async function donate(playerId: bigint, amt: bigint, idemKey: string) {
await db.tx(async (t) => {
const dup = await t.oneOrNone(
"SELECT 1 FROM idempotency WHERE key=$1", [idemKey]);
if (dup) return;
await t.none("INSERT INTO idempotency(key) VALUES($1)", [idemKey]);
await t.none("UPDATE players SET gold = gold - $2 WHERE id=$1 AND gold >= $2", [playerId, amt]);
await t.none("UPDATE alliances SET treasury_gold = treasury_gold + $2 WHERE id=$1", [allianceId, amt]);
});
}
Member roster cache invalidation
async function onMembershipChange(allianceId: bigint) {
await redis.del(`alliance:${allianceId}:roster`);
await redis.publish(`alliance:${allianceId}:events`, JSON.stringify({type:"ROSTER_CHANGED"}));
}
매 결정 기준
| 상황 | Approach |
|---|---|
| Casual mobile, < 30 members | Single-shard SQL, simple roster |
| MMO, 100+ members, real-time chat | Sharded SQL + Redis pub/sub |
| Cross-server alliance war (KvK) | Event-sourced log + global service |
| Persistent territory control | Server-authoritative grid + alliance ownership |
기본값: 매 Postgres alliance/member tables + Redis pub/sub for chat/presence + idempotent treasury operations.
🔗 Graph
- 변형: Guild · Clan · Faction
- Adjacent: Leaderboard
🤖 LLM 활용
언제: 매 long-session retention 의 game (MMO, SLG, persistent world), 매 social cooperation 의 core mechanic. 언제 X: 매 short-session arcade, 매 strict-PvP only without cooperation, 매 < 1k DAU 의 single-player feel.
❌ 안티패턴
- Client-authoritative membership: 매 cheat 의 trivial (forge join). 매 server-authoritative 만.
- No member cap: 매 mega-alliance dominance — 매 game balance 의 destruction.
- Synchronous broadcast: 매 large alliance (500+) 의 chat fan-out blocks. 매 async pub/sub 의 사용.
- Disband without grace period: 매 leader 의 grief vector. 매 24h cooldown.
🧪 검증 / 중복
- Verified (Lords Mobile design, EVE Online corporation system, WoW guild system, Clash of Clans clan system).
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content (game alliance system architecture) |