AI 보조 게임 개발

Claude Code로 Unity 게임플레이 로직을 '테스트부터' 짜는 실전 워크플로우

kr-gamedev 2026. 5. 27. 09:01

AI 코딩 도구를 게임 개발에 붙여보면 한 가지 벽에 부딪힌다. 웹 백엔드 코드는 AI가 기가 막히게 짜주는데, 게임플레이 로직은 자꾸 미묘하게 틀린다. 데미지 계산식이 한 끗 어긋나고, 쿨다운이 프레임 단위로 새고, 상태 전이가 엣지 케이스에서 무너진다. 그럴듯해 보이지만 돌려보면 다른 코드. 이게 게임 개발자가 AI 도구에 정을 못 붙이는 가장 큰 이유다.

원인은 명확하다. 게임플레이 로직은 "맞는지"를 눈으로 확인하기 어렵다. 웹은 응답 JSON만 보면 되지만, 게임은 플레이 모드 들어가서 직접 때려봐야 안다. AI가 짠 코드가 맞는지 검증하는 비용이 너무 비싸니, 결국 사람이 다시 다 읽게 되고 생산성 이득이 증발한다.

해결책은 의외로 고전적이다. 검증을 사람 눈이 아니라 테스트 코드에 맡기는 것. Claude Code 같은 에이전트형 도구는 테스트를 직접 실행하고 결과를 보고 스스로 고칠 수 있다. 그래서 "테스트부터 정의하고 구현은 AI에게" 패턴이 게임 로직에서 특히 강력하다. 오늘은 Unity EditMode 테스트와 Claude Code를 묶어 게임플레이 로직을 안전하게 자동 구현하는 워크플로우를 정리한다.

1. 왜 EditMode 테스트가 AI와 궁합이 좋은가

Unity 테스트는 크게 PlayMode와 EditMode로 나뉜다. PlayMode는 실제 씬을 띄우고 프레임을 돌리니 느리고 환경 의존적이다. 반면 EditMode 테스트는 에디터 컴파일 직후 도메인에서 바로 도는, 사실상 순수 NUnit 테스트다.

핵심은 게임플레이 로직의 상당수가 MonoBehaviour 없이도 검증 가능하다는 점이다. 데미지 공식, 인벤토리 누적, 스킬 쿨다운, 경험치 곡선 같은 것들은 순수 C# 클래스로 분리하면 EditMode에서 밀리초 단위로 수백 개를 돌릴 수 있다. AI 에이전트가 빠른 피드백 루프를 돌리기에 이상적인 환경이다.

먼저 검증하고 싶은 로직을 MonoBehaviour에서 떼어낸다. 예를 들어 데미지 계산은 이렇게 순수 함수로 만든다.

// Assets/Scripts/Combat/DamageCalculator.cs
public readonly record struct CombatStats(float Attack, float Defense, float CritRate, float CritMultiplier);

public static class DamageCalculator
{
    // C# 12 패턴: 입력은 record struct, 출력은 결정적
    public static int Compute(CombatStats attacker, CombatStats defender, float roll)
    {
        float baseDmg = attacker.Attack * attacker.Attack / (attacker.Attack + defender.Defense);
        bool isCrit = roll < attacker.CritRate;
        float final = isCrit ? baseDmg * attacker.CritMultiplier : baseDmg;
        return Mathf.Max(1, Mathf.RoundToInt(final));
    }
}

roll을 인자로 받는 게 포인트다. 내부에서 Random.value를 부르면 테스트가 비결정적이 되어 AI가 검증할 수 없다. 난수를 바깥으로 밀어내면 모든 분기를 정확히 찍어 테스트할 수 있다.

2. 사람이 테스트를 쓰고, AI에게 구현을 맡긴다

이 워크플로우의 핵심은 역할 분담이다. 게임 디자인 의도를 가장 잘 아는 건 사람이다. 그래서 사람은 "무엇이 맞는가"를 테스트로 박는다. 구현 디테일은 AI에게 넘긴다.

먼저 사람이 명세를 테스트로 작성한다.

// Assets/Tests/EditMode/DamageCalculatorTests.cs
using NUnit.Framework;

public class DamageCalculatorTests
{
    static readonly CombatStats Hero = new(Attack: 100, Defense: 0, CritRate: 0.25f, CritMultiplier: 2.0f);
    static readonly CombatStats Dummy = new(Attack: 0, Defense: 100, CritRate: 0, CritMultiplier: 1);

    [Test]
    public void Defense_HalvesDamage_WhenEqualToAttack()
    {
        // 공격 100, 방어 100 이면 100*100/200 = 50
        Assert.AreEqual(50, DamageCalculator.Compute(Hero, Dummy, roll: 0.99f));
    }

    [Test]
    public void Crit_AppliesMultiplier_WhenRollUnderRate()
    {
        // roll 0.1 < 0.25 → 크리. 50 * 2.0 = 100
        Assert.AreEqual(100, DamageCalculator.Compute(Hero, Dummy, roll: 0.1f));
    }

    [Test]
    public void Damage_NeverDropsBelowOne()
    {
        var glassCannon = new CombatStats(1, 9999, 0, 1);
        Assert.AreEqual(1, DamageCalculator.Compute(glassCannon, Dummy, roll: 0.99f));
    }
}

이제 Claude Code에게 던지는 프롬프트는 단순하다. "DamageCalculatorTests가 전부 통과하도록 DamageCalculator를 구현하고, 통과할 때까지 테스트를 돌려라." 에이전트는 구현, 테스트 실행, 실패 로그 확인, 수정을 사람 개입 없이 반복한다.

3. AI가 직접 테스트를 돌리게 만드는 한 줄

여기서 결정적인 디테일. Unity 테스트는 보통 에디터 UI에서 돌리지만, AI 에이전트는 GUI를 못 쓴다. 그래서 커맨드라인 배치 모드로 테스트를 돌릴 수 있게 길을 터줘야 한다.

# CI나 AI 에이전트가 호출하는 EditMode 테스트 실행
"/Applications/Unity/Hub/Editor/6000.0.30f1/Unity.app/Contents/MacOS/Unity" \
  -batchmode -runTests -projectPath . \
  -testPlatform EditMode \
  -testResults ./TestResults.xml \
  -logFile -

이 명령을 프로젝트 루트의 스크립트나 CLAUDE.md에 박아두면, 에이전트가 "테스트는 이렇게 돌리면 된다"는 걸 알게 된다. 결과 XML과 콘솔 로그를 읽고 실패한 케이스를 정확히 짚어 다음 수정에 반영한다. 사람은 빨간불이 초록불로 바뀌는 것만 지켜보면 된다.

주의할 점은 배치 모드 한 번 실행에 에디터 부팅 시간이 끼어 수십 초가 든다는 것이다. 그래서 로직을 어셈블리 단위로 잘게 쪼개고, EditMode 어셈블리에서 엔진 의존성을 최대한 걷어내면 루프가 훨씬 빨라진다. asmdef로 테스트 어셈블리를 분리해 두는 건 이 워크플로우에서 선택이 아니라 필수다.

4. 잘 되는 것과 안 되는 것을 구분하라

이 방식이 만능은 아니다. 경계를 알아야 한다.

잘 되는 영역: 수치 계산, 상태 머신 전이, 인벤토리/경제 시스템, 세이브 데이터 직렬화, 절차적 생성의 결정적 부분. 입력과 기대 출력을 명확히 쓸 수 있는 모든 곳.

안 되는 영역: "손맛", 카메라 흔들림 강도, 점프 곡선의 기분, 파티클 타이밍. 이런 건 테스트로 못 박으니 여전히 사람이 플레이 모드에서 감으로 튜닝해야 한다. AI에게 맡기지 말고 직접 만져야 하는 영역이다.

그래서 실전 전략은 분리다. 게임 코드를 "검증 가능한 결정적 로직"과 "감으로 튜닝하는 연출"로 갈라놓는다. 전자는 테스트로 박고 AI에게 위임해 생산성을 끌어올리고, 후자는 사람이 손으로 다듬는다. 이 분리 자체가 코드 품질을 끌어올리는 부수 효과까지 준다.

마무리

게임플레이 로직에서 AI 도구가 헛도는 이유는 검증 비용이 비싸기 때문이다. 해법은 사람이 의도를 EditMode 테스트로 명세하고, 구현과 검증 루프를 Claude Code 같은 에이전트에게 통째로 넘기는 것이다. 핵심은 세 가지로 압축된다. 로직을 MonoBehaviour에서 떼어 순수 함수로 만들 것, 난수 같은 비결정성을 인자로 밀어낼 것, 배치 모드 실행 경로를 에이전트에게 알려줄 것. 검증 가능한 영역과 손맛으로 튜닝할 영역을 명확히 가르는 순간, AI는 게임 개발에서도 진짜 일꾼이 된다.