RTS 유닛 상성 설계 가이드: 가위바위보(RPS)를 넘는 다차원 복합 상성 매트릭스 구현
단순 가위바위보 구조의 한계를 극복하고 심도 있는 전술적 플레이를 유도하는 RTS 다차원 유닛 상성 시스템의 수학적 설계 공식과 데이터 주도 구현 기법을 상세히 다룹니다.

핵심 요약
단순 가위바위보(Rock-Paper-Scissors) 방식의 1차원 상성은 정답 빌드를 고착화하고 컨트롤의 개입 여지를 차단합니다. 현대 전략 시뮬레이션(RTS)은 ‘공격·방어 속성 매트릭스’, ‘기동성 및 교전 거리(사거리·탄도)’, ‘전장 지형 및 시야’, ‘전술 유틸리티(광역기, CC, 은폐)‘의 4가지 직교(Orthogonal) 차원을 결합한 복합 상성 시스템을 구축하여 하드 카운터(Hard Counter)를 소프트 카운터(Soft Counter)로 완화하고 전술적 유연성을 확보합니다.
단순 가위바위보(RPS) 상성은 왜 한계에 부딪히는가?
전통적인 RTS 게임에서 보병은 기병에 약하고 기병은 창병에 약하며 창병은 보병에 약하다는 식의 1차원 순환 상성(Rock-Paper-Scissors)은 직관적입니다. 플레이어가 시스템을 빠르게 학습할 수 있다는 장점이 있지만 게임이 고도화될수록 다음과 같은 구조적 한계가 발생합니다.
- 바이너리 전투 결과 (전투의 정답화): 상성 우위에 있는 유닛 조합을 마주했을 때 컨트롤이나 진형 배치로 극복할 수 없는 극단적인 결과가 발생합니다.
- 스노우볼링과 역전 불가능성: 테크 트리와 자원 우위를 선점한 플레이어가 상대의 유닛을 완벽히 카운터치는 단일 병종을 대량 생산(Deathball)하면 역전 기회가 소멸합니다.
- 마이크로 컨트롤의 무의미화: 사거리 우위, 카이팅, 지형 활용 등 플레이어의 조작 능력이 상성 배율 하나에 무력화되어 플레이 경험의 깊이가 얕아집니다.
따라서 현대 RTS 시스템 디자인의 핵심은 승패를 강제하는 하드 카운터(Hard Counter)를 줄이고 플레이어의 전술적 판단과 조작으로 극복 가능한 소프트 카운터(Soft Counter)의 비중을 높이는 다차원 상성 설계에 있습니다.

다차원 복합 상성을 구성하는 4대 설계 축
단일한 가위바위보 루프 대신 서로 간섭하지 않는 독립적인 게임플레이 변수들을 교차 배치함으로써 상성을 다차원화합니다.
flowchart TD
A[다차원 복합 상성 시스템] --> B[속성 레이어: 공격 / 방어 매트릭스]
A --> C[동역학 레이어: 사거리 / 기동성 / 투사체]
A --> D[공간 레이어: 지형 고저차 / 장애물 / 시야]
A --> E[유틸리티 레이어: 범위 피해 / CC / 상태이상]
B --> F[기본 대미지 교환 효율 결정]
C --> G[교전 개시 및 카이팅 성패 결정]
D --> H[명중률 및 대미지 보정]
E --> I[밀집 대형 붕괴 및 전황 역전]
1. 속성 레이어: 공격 타입과 방어 아머 매트릭스
대미지 유형(Damage Type)과 장갑 유형(Armor Type)을 분리하여 교차 행렬을 구성합니다. 《스타크래프트》의 소형/중형/대형 및 진동형/폭발형 시스템이나, 《워크래프트 3》의 일반/관통/공성/카오스 및 경장/헤비/미디엄/영웅 장갑 시스템이 대표적입니다.
| 공격 \ 방어 타입 | 경장갑(Light) | 중장갑(Armored) | 생체(Biological) | 기계(Mechanical) | 건물(Structure) |
|---|---|---|---|---|---|
| 일반(Normal) | 100% | 75% | 100% | 100% | 50% |
| 관통/저격(Piercing) | 150% | 50% | 125% | 75% | 35% |
| 폭발/충격(Concussive) | 50% | 150% | 75% | 125% | 150% |
| 공성(Siege) | 75% | 100% | 50% | 100% | 200% |
이 구조에서는 특정 유닛이 ‘기병’이라는 단일 태그로 정의되지 않고 [중장갑, 생체, 대형]과 같은 복합 태그를 가집니다. 따라서 상대는 단일 병종으로 완벽한 카운터를 칠 수 없으며 다채로운 공격 타입을 혼합해야 합니다.
2. 동역학 레이어: 사거리, 투사체 속도, 회전 속도
유닛의 물리적 기동 및 공격 메커니즘은 소프트 상성을 만드는 핵심 동력입니다.
- 사거리 및 이속 격차 (카이팅): 사거리가 길고 이동 속도가 빠른 경장거리 유닛은 근접 중장갑 유닛을 상대로 속성상 불리하더라도 거리 유지를 통해 승리할 수 있습니다.
- 즉발(Hitscan) vs 탄도(Ballistic) 투사체: 유도형 탄환인지 빗나갈 수 있는 비유도 포탄인지에 따라 유닛의 회피 기동 및 속도 상성이 결정됩니다.
- 터렛 회전 속도(Turn Rate)와 가속도: 거대 전차나 전함은 화력이 강력하지만 포탑 회전과 선회 속도가 느려 빠른 소형 유닛이 후방이나 측면을 파고드는 기동전에 취약합니다.
3. 공간 레이어: 지형 고저차와 전장의 안개
동일한 유닛 매치업이라도 전장의 위치에 따라 상성이 역전되도록 만듭니다.
- 고지대 페널티/보너스: 고지대 유닛은 시야 우위를 점하며 저지대에서 공격하는 유닛에게 빗맞힘(Miss Chance, 예: 25~30%)이나 대미지 경감 보너스를 받습니다.
- 초크포인트(Chokepoint)와 병목 현상: 좁은 길목에서는 수적 우위가 무력화되며 사거리가 긴 유닛과 광역 공격 유닛의 효율이 극대화됩니다.
4. 유틸리티 레이어: 범위 공격과 군중 제어(CC)
단일 DPS가 아무리 높은 유닛이라도 범위 공격(AoE, Splash Damage)과 CC기(감속, 기절, 무력화)의 존재로 인해 상성이 재정의됩니다. 소형 유닛 다수(Swarm)는 단일 타겟 극딜 유닛을 압도하지만 광역 포격 유닛에게는 순식간에 괴멸당합니다.

복합 상성 대미지 계산 공식 설계
다차원 상성을 수학적으로 정량화하기 위해 기본 공격력, 속성 보정치, 고정/비율 방어력, 거리 감쇠, 지형 가중치를 결합한 통합 계산식을 설계합니다.
수학적 모델링
단일 타격에 대한 유효 피해량 은 다음과 같이 정의할 수 있습니다.
여기서 각 변수의 역할은 다음과 같습니다.
- : 공격 유닛의 기본 공격력
- : 공격-방어 타입 상성 계수 (예: 0.5 ~ 2.0)
- : 사거리별 대미지 감쇠 계수 (일 때 감소)
- : 목표 유닛의 고정 방어력 (작은 피해를 다수 입히는 연타형 유닛 억제)
- : 목표 유닛의 비율 방어력 (, 대형 한 방 유닛의 과도한 피해 억제)
- : 지형 보정 계수 (고지대 공격 시 1.0, 저지대에서 고지대 공격 시 0.75 등)
- : 측후방 타격, 치명타 등 상황별 가중치
- : 최소 보장 피해량 (완전 면역 상태가 아닐 경우 통상 1)
데이터 주도(Data-Driven) 상성 시스템 구현 가이드
C# 및 유니티/언리얼 스타일의 데이터 구조를 활용하여 상성 테이블을 하드코딩하지 않고 확장성 있게 구현하는 3단계 절차입니다.
1단계: 속성 및 상성 매트릭스 데이터 정의
using System;
using UnityEngine;
public enum DamageType
{
Normal,
Piercing,
Concussive,
Siege,
Energy
}
public enum ArmorType
{
Light,
Armored,
Biological,
Mechanical,
Structure
}
[CreateAssetMenu(fileName = "DamageMatrix", menuName = "RTS/Combat/Damage Matrix")]
public class DamageMatrixSO : ScriptableObject
{
[System.Serializable]
public struct MultiplierEntry
{
public DamageType damageType;
public ArmorType armorType;
[Range(0f, 3f)] public float multiplier;
}
[SerializeField] private MultiplierEntry[] entries;
private float[,] table;
public void Initialize()
{
int damageTypesCount = Enum.GetValues(typeof(DamageType)).Length;
int armorTypesCount = Enum.GetValues(typeof(ArmorType)).Length;
table = new float[damageTypesCount, armorTypesCount];
// 기본값 1.0f 초기화
for (int i = 0; i < damageTypesCount; i++)
for (int j = 0; j < armorTypesCount; j++)
table[i, j] = 1.0f;
foreach (var entry in entries)
{
table[(int)entry.damageType, (int)entry.armorType] = entry.multiplier;
}
}
public float GetMultiplier(DamageType damageType, ArmorType armorType)
{
if (table == null) Initialize();
return table[(int)damageType, (int)armorType];
}
}
2단계: 전투 컨텍스트 기반 대미지 계산기 구현
public struct CombatContext
{
public float BaseDamage;
public DamageType DamageType;
public float AttackDistance;
public float OptimalRange;
public bool IsAttackerOnHighGround;
public bool IsDefenderOnHighGround;
public bool IsFlankingAttack;
}
public struct DefenderStats
{
public ArmorType ArmorType;
public float FlatArmor;
public float ArmorDamageReductionPercent; // 0.0 ~ 1.0
}
public static class DamageCalculator
{
public static float CalculateFinalDamage(
in CombatContext ctx,
in DefenderStats def,
DamageMatrixSO matrix)
{
// 1. 속성 상성 배율
float typeMultiplier = matrix.GetMultiplier(ctx.DamageType, def.ArmorType);
// 2. 거리 감쇠 (사거리 초과 시 감쇠)
float distMultiplier = 1.0f;
if (ctx.AttackDistance > ctx.OptimalRange && ctx.OptimalRange > 0f)
{
float overDistance = ctx.AttackDistance - ctx.OptimalRange;
distMultiplier = Mathf.Clamp01(1.0f - (overDistance * 0.1f));
}
// 3. 지형 보정
float terrainMultiplier = 1.0f;
if (!ctx.IsAttackerOnHighGround && ctx.IsDefenderOnHighGround)
{
terrainMultiplier = 0.75f; // 저지대 패널티
}
// 4. 측후방 기습 보정
float situationalMultiplier = ctx.IsFlankingAttack ? 1.25f : 1.0f;
// 5. 기본 대미지 계산 (고정 방어력 적용)
float rawDamage = (ctx.BaseDamage * typeMultiplier * distMultiplier) - def.FlatArmor;
rawDamage = Mathf.Max(1.0f, rawDamage);
// 6. 비율 방어력 적용
float mitigatedDamage = rawDamage * (1.0f - Mathf.Clamp01(def.ArmorDamageReductionPercent));
// 7. 최종 대미지 연산
float finalDamage = mitigatedDamage * terrainMultiplier * situationalMultiplier;
return Mathf.Max(1.0f, finalDamage);
}
}
3단계: 유닛 클래스 및 컴포넌트 연동
유닛이 단일 속성에 묶이지 않도록 데미지 수신 인터페이스를 분리하여 모듈화합니다. 이를 통해 버프, 디버프, 지형 판정이 실시간으로 반영됩니다.
밸런스 검증을 위한 테스팅 프레임워크 구축
다차원 상성은 복잡성이 높기 때문에 디자이너의 직관만으로는 특정 유닛의 OP(Overpowered) 현상을 예측하기 어렵습니다. 따라서 다음과 같은 자동화 검증 환경이 필수적입니다.
- 비용 대비 교전 효율(Cost Efficiency) 시뮬레이터: 동일 자원 가치(예: 광물 1,000 기준)를 가진 두 부대를 1:1 대치시켜 잔존 체력 비율을 자동 기록하는 몬테카를로(Monte Carlo) 시뮬레이션을 실행합니다.
- 상성 엔트로피(Counter Entropy) 분석: 단일 유닛이 전체 병종의 70% 이상을 상대로 승률 60% 이상을 기록하는 경우(God Tier 유닛), 해당 유닛의 다차원 속성 중 하나(기동성, 사거리, 회전 속도 등)를 깎아 소프트 카운터 약점을 부여합니다.
자주 묻는 질문 (FAQ)
Q1. 하드 상성과 소프트 상성의 적절한 배분 비율은 어떻게 설정해야 하나요?
전체 유닛 상성 관계의 70~80%는 소프트 상성(상성 계수 1.2~1.5배, 컨트롤/지형으로 극복 가능)으로 구성하고 특수 목적 유닛(예: 대공 전용 포탑 vs 공중 폭격기, 공성 병기 vs 방어 타워)의 20~30%만 하드 상성(상성 계수 2.0배 이상 또는 공격 불가 제약)으로 배치하는 것이 가장 이상적인 전술적 긴장감을 형성합니다.
Q2. 복합 상성을 도입하면 캐주얼 유저의 진입 장벽이 너무 높아지지 않나요?
시각적/청각적 피드백(VFX/SFX)을 명확히 제공하여 해결합니다. 상성 우위 공격 시 타격 이펙트 크기와 타격음을 증폭시키고 빗맞힘이나 장갑 튕겨냄(Deflect) 연출을 명확히 주면 유저가 수식을 외우지 않아도 직관적으로 유불리를 체감할 수 있습니다.
Q3. 실시간 대규모 전투에서 다차원 상성 연산의 CPU 오버헤드는 어떻게 최적화하나요?
속성 상성 매트릭스는 2D 플랫 배열(float[,] 또는 1D 배열 매핑)로 캐싱하여 O(1) 조회를 보장하고 지형 고저차 판정은 레이캐스트 대신 격자형 지형 데이터(Grid Height Map)를 통해 비트 연산으로 판정하여 프레임 드랍을 방지합니다.
요약 및 결론
성공적인 RTS 전투 시스템은 ‘정답이 정해진 가위바위보’가 아니라 ‘상황에 따라 결과가 유동적으로 변하는 복합 생태계’여야 합니다.
- 공격/방어 속성 매트릭스로 기본적인 대미지 교환율을 설계하십시오.
- 사거리, 투사체 속도, 회전 속도를 통해 마이크로 컨트롤의 역전 여지를 제공하십시오.
- 지형, 시야, 광역 유틸리티를 결합하여 맵 리딩과 전술 배치의 가치를 극대화하십시오.
이러한 다차원 상성 구조가 확립될 때 유저는 단순 암기형 빌드 오더를 넘어 매 순간 창의적인 전술을 만들어내는 깊이 있는 재미를 경험하게 됩니다.



