지난 일 년 사이, Claude Code나 Codex에게 게임 코드를 맡기는 일이 신기한 시도에서 일상적인 습관으로 바뀌었습니다. 리팩터링, 시스템 구현, 셰이더와 게임플레이 조정까지, 에이전트가 diff를 내놓는 속도는 사람이 따라올 수준이 아닙니다. 이제 문제는 그 diff가 동작하느냐가 아니라, 여전히 빠르냐입니다.
AI가 코드를 쓰는 시대의 병목
코드 쓰는 수고가 줄면, 병목은 ‘쓰기’에서 ‘확인하기’로 옮겨 갑니다. 기능이 동작하는지는 테스트가 알아서 답을 냅니다. 하지만 그 코드가 방금 실기기 프레임 타임을 몇 밀리초 밀어 올리지는 않았는지는, 초록색 테스트가 알려 주지 않습니다.
에이전트가 하루에 수십 건씩 diff를 올리기 시작하면, 그 하나하나를 사람이 손으로 프로파일링하는 것은 현실적이지 않습니다. 렌더 스레드에 무심코 할당이 늘고, 업데이트 루프의 계산량이 슬그머니 나빠지고, GC가 도는 빈도가 올라갑니다. 이런 것들은 모두 단위 테스트를 통과하고, 눈으로 하는 코드 리뷰도 빠져나가, 실기기에 올려서야 체감 저하로 드러납니다.
에이전트로 쓰는 속도가 빨라진 만큼, 확인하는 공정이 새로운 병목이 됩니다.
그러니 성능 확인을, 리뷰어의 알아챔이나 숙련자의 감에 기대는 공정으로 남겨 둘 수는 없습니다. 에이전트와 같은 속도로 도는, 기계 쪽의 판정으로 바꿔야 합니다.
회귀 게이트를 기계 쪽에 두기
할 일은 단순합니다. 빌드마다 성능 텔레메트리를 모으고, 직전의 알려진 정상 빌드와 비교해서, 임계값을 넘어 나빠졌으면 CI를 떨어뜨립니다. 사람이 숫자를 들여다보고 판단하는 대신, 회귀 여부를 기계가 판정해 파이프라인의 합격/불합격으로 돌려줍니다.
Framedash의 framedash perf-diff는 두 빌드의 프레임 타임, 메모리, GPU 시간에 대해 P50과 P95를 모두 내놓는 명령입니다. --fail-on-regression을 붙이면, 후보 빌드의 P50이 임계값을 넘어 나빠졌을 때 종료 코드 1로 떨어집니다(게이트 판정은 P50 비교로 하고, P95는 참고로 함께 표시됩니다).
framedash perf-diff --baseline "$BASE_SHA" --candidate "$GITHUB_SHA" \
--threshold 5 --fail-on-regression
비교 대상은 프레임 타임, 메모리, GPU 시간에 더해 맵 로드 시간(load_time_ms)과 디스크 IO(io.*)입니다. 모두 작을수록 좋은 지표로 다뤄집니다. --metric으로 특정 지표에만 게이트를 걸거나, --map과 --platform으로 비교 범위를 좁힐 수도 있습니다.
여기서 관건은 비교의 단위가 되는 build_id입니다. 어느 빌드의 숫자인지가 일의적으로 정해져 있지 않으면, 빌드끼리의 비교 자체가 성립하지 않습니다.
워크플로 전체 그림
에이전트가 쓴 코드가 이 회귀 게이트를 통과하기까지의 흐름을 따라가 봅시다.
게이트가 떨어지면, 에이전트가 직접 텔레메트리를 읽어 원인을 좁힙니다.
CI에서 이 흐름을 한꺼번에 도는 것이 framedash run-profile-test입니다. 이 명령은 자동 세션용 FRAMEDASH_* 환경 변수를 써내고, 지정한 프로파일링용 빌드를 띄운 뒤, 그 텔레메트리가 수집되기를 기다렸다가, 베이스라인에 대해 perf-diff 게이트를 겁니다.
framedash run-profile-test \
--command "./Build/Game.exe -nullrhi -ExecCmds='Automation RunTest Perf'" \
--scenario nightly --api-key-file ci-read.key \
--baseline "$BASE_SHA" --threshold 5 --fail-on-regression
띄워진 게임 쪽에서는, 자동 테스트 진입점에서 자동 세션 API를 한 번 호출합니다. SDK가 BeginAutomatedSessionFromEnvironment()를 부르면, run-profile-test가 써낸 FRAMEDASH_BUILD_ID / FRAMEDASH_GIT_BRANCH / FRAMEDASH_GIT_COMMIT / FRAMEDASH_TEST_SCENARIO를 읽어, 이후 모든 이벤트에 CI 빌드와 그 브랜치, 커밋, 시나리오가 자동으로 실립니다. 이벤트마다 태깅하는 코드는 필요 없습니다.
TelemetrySDK.Instance.BeginAutomatedSessionFromEnvironment();
// ... 프로파일링 시나리오 실행 ...
TelemetrySDK.Instance.EndAutomatedSession();
운영상 주의가 하나 있습니다. 짧은 빌드나 헤드리스 실행은 SDK의 정기 플러시보다 먼저 종료될 수 있습니다. 텔레메트리가 실제로 전송될 때까지 실행을 살려 두세요(각 SDK의 CI와 헤드리스 실행 안내에 방법이 있습니다). 그런 다음 run-profile-test가 수집을 기다렸다가 게이트를 겁니다.
build_id는 최상위 필드로 기록되고, 브랜치와 커밋과 시나리오는 ci.branch / ci.commit / ci.scenario 속성에 실립니다. 이로써 에이전트가 낸 커밋의 build_id가 그대로 회귀 비교의 후보가 됩니다.
키의 구분만 주의하면 됩니다. 게이트는 텔레메트리를 analytics:read 키로 읽고, 띄워진 게임은 별도의 events:write 수집용 키로 텔레메트리를 보냅니다. 이름 충돌을 피하려면, 게이트 쪽 키는 FRAMEDASH_API_KEY 환경 변수가 아니라 --api-key-file로 넘기고, FRAMEDASH_API_KEY는 게임의 수집용 키로 비워 둡니다.
게이트가 떨어지면, 어디를 볼까
perf-diff가 떨어졌을 때 알 수 있는 것은 어느 지표가 얼마나 나빠졌는지까지입니다. 어디서 나빠졌는지는 이 숫자만으로는 알 수 없습니다.
그럴 때 쓰는 것이 성능 히트맵입니다. FPS, 프레임 타임, GPU 시간, 메모리 사용량을 게임 맵 위에 셀 단위로 오버레이해 보여 줍니다. 디바이스나 빌드 프로파일로 좁힐 수 있어서, 회귀한 빌드의 어느 맵 어느 언저리가 무거워졌는지를 맵 위의 위치로 특정할 수 있습니다.
맵 위의 분포는 위치가 붙은 이벤트에서 그려집니다. 프로파일링 시나리오가 플레이어 위치를 등록된 맵 ID와 함께 보내면, SDK가 그 이벤트에 카메라 방향(요와 피치)을 자동으로 얹습니다. 이것만 갖춰지면, “build 1042의 desert_ruins, 북쪽을 본 한 구석에서 P95가 튄다”는 정도의 입도까지 쫓을 수 있습니다. 이로써 회귀는 재현 가능한 조사 대상이 됩니다.
에이전트 자신에게 텔레메트리를 읽히기
여기까지의 흐름에는 아직 사람이 한 군데 남아 있습니다. 히트맵을 열어 원인을 좁히고, 고칠 코드를 쓰는 공정입니다.
이 공정도 에이전트에게 넘길 수 있습니다. Framedash의 MCP 서버는 텔레메트리에 대한 읽기 전용 도구와 리소스를 LLM에 공개합니다. 히트맵 그리드 데이터, 대시보드 KPI, 심지어 생 SQL 쿼리까지, 에이전트가 자연어 지시로 직접 끌어올 수 있습니다.
claude mcp add framedash \
-e FRAMEDASH_API_KEY=fd_xxx \
-e FRAMEDASH_PROJECT_ID=your-project-uuid \
-- npx -y @framedash/mcp-server
이로써 회귀를 일으킨 에이전트 자신에게, 자기가 망친 곳을 읽어 고치게 하는 한 바퀴를 짤 수 있습니다. get_heatmap으로 맵 위의 무거운 곳을 훑고, query를 build_id로 좁혀 후보 빌드의 핫스팟을 뽑아내고, 원인의 짐작을 세워 코드를 고칩니다. 도구는 읽기 전용이라, 에이전트가 텔레메트리를 고쳐 쓰거나 지울 일은 없습니다. 고친 코드가 정말 회귀를 해소했는지는, 다음 빌드에서 같은 CI 게이트가 다시 한번 객관적으로 판정합니다.
판정은 기계에, 원인 읽기는 에이전트에게. 사람에게 남는 것은 임계값을 어디에 그을지와, 고친 방식이 타당한지를 마지막에 보는 자리입니다.
시작하기
필요한 것은 게임에 SDK를 넣고 build_id를 CI에서 넘기는 것과, CI에 게이트를 하나 더하는 것뿐입니다. SDK 통합은 몇 줄이면 되고, 지원 엔진은 Unity, UE5, Godot (C#)입니다.
- SDK와 CI의 구체적인 설정은 CI 연동 프로파일링에 정리되어 있습니다.
- 명령 목록은 CLI 레퍼런스를 참고하세요.
- 에이전트에게 쓰게 하려면, Claude Code 플러그인이 MCP 서버와 스킬을 한 번에 넣어 줍니다.
claude plugin marketplace add crane-valley/framedash-claude-plugin
claude plugin install framedash@framedash