
게임 밸런스 고려 누락이 발생해도 1분 만에 모든 스테이지 재조정 완료: AI와 시뮬레이터로 실현하는 재작업 제로의 레벨 디자인
요약
C++ Axmol 엔진 기반 액션 RPG 개발 중, AI와 Python 시뮬레이터를 활용해 게임 밸런스를 자동 조정하는 파이프라인을 구축했습니다. 수작업 대신 고수준의 의도만 입력하면 1분 만에 모든 스테이지의 수치를 재조정하고 검증할 수 있습니다.
핵심 포인트
- AI와 시뮬레이터를 활용한 레벨 디자인 자동화 구현
- 수작업 파라미터 입력 배제로 사양 변경 시 대응력 극대화
- 권장 레벨에 비례한 동적 난이도 게이트(gap) 계산 로직 적용
- 시뮬레이터와 게임 엔진 간의 계산식 일치로 검증 신뢰도 확보
※ 본 기사는 필자(roripika)의 실제 게임 개발(C++ / Axmol Engine 『losthistoria』)에서의 실체험·개발 로그를 바탕으로, 페어 프로그래밍(Pair Programming) AI 에이전트(Antigravity)가 구성·집필을 지원하여 전달합니다.
개인 개발이나 소규모 팀의 게임 개발에서 가장 머리를 싸매게 되는 작업 중 하나가 **「레벨 디자인 (Level Design, 게임 밸런스 조정)」**입니다.
- 「적의 HP나 공격력을 감으로 설정했다가, 클리어 불가능한 스테이지나 너무 쉬운 스테이지가 양산되었다」
- 「개발이 진행된 후에 『데미지 계산식의 고려 누락』이나 『신규 스킬의 사양 추가』가 발생하여, 수백 개의 스테이지 파라미터를 수작업으로 수정해야 하는 절망을 맛보았다」
이러한 경험은 없으신가요?
본 기사에서는 현재 C++ / Axmol 엔진으로 개발 중인 본격 액션 RPG 『losthistoria』에서, **「수치를 직접 입력하는 것을 일절 그만두고, AI와 Python 시뮬레이터에 의해 『적정 클리어』와 『저레벨 전멸』을 자동 결정·증명하는 메커니즘」**을 구축한 노하우를 공유합니다.
이 메커니즘을 도입함으로써, 나중에 레벨 디자인의 큰 고려 누락이나 사양 변경이 발생하더라도, 1개 커맨드(약 1분)로 모든 스테이지의 밸런스 재조정과 자동 검증이 완결되게 되었습니다.
기존의 게임 개발에서는 다음과 같은 흐름으로 레벨 디자인이 이루어지곤 합니다.
[플래너] 감으로 적 HP/ATK를 JSON에 수작업 입력
➔ [테스트 플레이] 개발자 스스로 플레이하며 "조금 강할지도"라며 미세 조정
➔ [스테이지 증가] 스테이지 수가 50, 100으로 늘어나며 관리 불능 상태가 됨
...
개발자 스스로 테스트 플레이를 반복하면 조작에 숙련되어 버려, 「딱 적당한 난이도」의 감각이 마비되는 문제도 있습니다.
그래서 본 프로젝트에서는 **「인간은 고수준(High-level)의 의도만을 작성하고, 구체적인 수치와 검증은 AI/시뮬레이터에 맡긴다」**는 원칙으로 전면 전환했습니다.
레벨 디자인 파이프라인을 다음과 같이 분리했습니다.
【인간의 역할】 설계 시트에 「고수준의 의도」만을 작성
└ 지역명 / 권장 레벨 / 등장하는 적의 종류 / WAVE 수
│
...
인간이 다루는 영역을 「의도의 설정」으로만 한정함으로써, 파라미터의 수작업 입력을 완전히 배제했습니다.
단순히 「클리어할 수 있다」뿐만 아니라, **「적정한 난이도 게이트 (저레벨에서는 클리어할 수 없는 것)」**를 자동 탐색·증명하기 위해 다음과 같은 기준을 시뮬레이터에 포함했습니다.
상정 파티가 권장 레벨로 도전했을 경우, **「남은 HP 약 20%65%」, 「소요 시간 약 25초45초/스테이지」**로 클리어할 수 있는 수치를 타겟으로 합니다.
권장 레벨보다 일정 레벨(gap) 낮은 파티로 도전했을 경우, 반드시 전멸(클리어 불가)함을 증명합니다.
시뮬레이터 개발 중 매우 중요한 지견을 얻었습니다.
「권장 레벨보다 3레벨 낮으면 전멸」이라는 고정값 규칙(gap = 3)을 만들면, 고레벨 대역에서 파탄이 납니다.
스테이터스의 성장 곡선에서 고레벨 대역이 될수록 「1레벨당 스테이터스 상승률 (전투력 비)」은 작아집니다. 그렇기 때문에 Lv70 스테이지에서 고정적으로 「3레벨 차이 (Lv67)」로 설정해도, 전력 차이가 몇 %밖에 나지 않아 난이도 게이트로서 기능하지 못하고 클리어되어 버리는 것입니다.
이 문제를 해결하기 위해, 게이트 폭 gap을 권장 레벨에 비례한 동적 계산으로 변경했습니다.
$$\text{gap} = \max(2, \text{round}(\text{권장Lv} \times 0.12))$$
이를 통해 초반에는 23레벨 차이, 종반에는 78레벨 차이라는, 게임 전체를 통해 적정한 난이도 허들이 자동으로 유지되게 되었습니다.
시뮬레이터(tools/battle_sim.py)는 C++ 게임 본편의 계산식과 엄격하게 일치시켰습니다.
# C++ (UnitData::calculateStats, DamageCalculator::calcDamage)와 완전히 일치하는 Python 구현 예시
def calc_damage(atk, target_def, elem_bonus=1.0):
# 방어구 DEF에 의한 감쇄식: ATK * (1 - DEF / (DEF + 100))
...
시뮬레이터 측은 '장비 없음(DEF=0)', '필살 스킬은 일정 주기로 발동'이라는 **플레이어를 다소 과소평가하는 전제(안전 마진)**로 계산을 진행합니다. 실제 전투에서는 플레이어의 퍼즐 정확도나 장비에 의해 약간 유리해지기 때문에, 절묘한 손맛이 느껴질 수 있도록 조정되어 있습니다.
이 시스템의 진가는 '개발 후반부에 큰 고려 누락이나 사양 변경이 발생했을 때' 발휘됩니다.
개발 도중, '오라클(사제 직업)의 스킬을 '전체 회복(全体リジェネ)'에서 '사망한 아군을 부활시키는 리저렉션(Resurrection)'으로 교체한다'는 큰 사양 변경이 발생했습니다.
게다가, '시뮬레이터 측에서 특정 직업의 패시브 스킬에 의한 속성 버프 계산이 누락되었다'는 고려 누락도 밝혀졌습니다.
-
아군의 회복량 및 내구 성능의 전제가 완전히 바뀌었기 때문에, 모든 스테이지의 적 ATK/HP를 재조정해야 했습니다.
-
100개 이상의 스테이지를 수작업으로 수정하고 플레이 테스트하는 데 며칠에서 몇 주가 소요될 상황이었습니다.
AI(Antigravity)에게 지시: '오라클의 신규 스킬 '리저렉션'의 HP 회복률과, 버프 계산 수정을 battle_sim.py에 반영하여, 모든 스테이지의 wave_table.json을 재피팅(re-fitting)해 줘.'
실행: AI가 몇 초 만에 시뮬레이터 코드를 수정하고, python3 tools/battle_sim.py --fit을 자동 실행했습니다.
결과: 약 1분 만에 모든 스테이지의 적 스탯 배율이 일괄적으로 재계산되었고, 모든 스테이지에서 '권장 레벨 클리어 ∧ 저레벨 전멸' 검증(E2E PASS)이 완료되었습니다!
// 자동 업데이트된 Content/data/wave_table.json
{
"stage_ruins_03": {
...
수작업에 의한 수정 비용 및 확인 비용이 완전히 제로가 되었습니다.
게임 개발에서의 레벨 디자인 자동화를 통해 배운 가장 중요한 결론은, 다음 한마디로 요약됩니다.
'처음부터 완벽한 밸런스를 노리지 마라. 몇 번이고 1초 만에 모든 수정을 할 수 있는 시스템(파이프라인)을 먼저 만들어라.'
의도와 수치의 분리: 인간은 '어떻게 즐겁게 만들고 싶은가(의도)'만 정의하고, 수치는 시뮬레이터가 계산하게 한다. -
증명 가능한 난이도 게이트: '클리어할 수 있다'뿐만 아니라 '저레벨에서는 이길 수 없다(동적인 gap)'를 수치적으로 자동 증명한다. -
AI와의 협업: 고려 누락이나 사양 변경이 일어나더라도, AI에게 시뮬레이터의 전제식을 고치게 하면 순식간에 모든 데이터의 재피팅 및 검증이 완료된다.
레벨 디자인의 수치 조정으로 바쁜 개인 개발자나 기획자분들은 '시뮬레이터 + AI를 통한 자동 재피팅' 시스템을 꼭 도입해 보시기 바랍니다!
*필자 주: 본 기사에서 소개된 게임 『losthistoria』는 C++ / Axmol Engine으로 개발 중인 다크 판타지 RPG입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기