지난번에는 Claude가 새 네이티브 MCP를 통해 언리얼 엔진 5.8 안에서 세계를 지었습니다. 그리고 그 영상 아래 압도적인 베스트 댓글은 이것이었습니다: “좋아요, 그런데 로컬의 무료 오픈소스 AI로도 이게 되나요?” 타당한 질문입니다. Claude는 훌륭하죠——청구서를 보기 전까지는.
그래서 이번에는 클라우드 없음, API 키 없음, 구독 없음. Qwen3.6-27B——270억 파라미터, 약 17기가바이트가 소비자용 GPU 한 장에 올라가는 모델——를 같은 네이티브 MCP를 통해 라이브 언리얼 에디터에 직결했습니다. 프롬프트는 17개, 그리고 하나하나가 모두 새 채팅입니다: 모델은 단계 사이에 아무것도 기억하지 못합니다. 씽킹 모드는 꺼져 있습니다. 그리고 Cline 히스토리의 모든 작업이 구석에 같은 숫자로 끝납니다: $0.00.

진짜 질문은 “에디터를 열 수 있는가”가 아니었습니다. 로컬 모델이 실제 프로젝트에서 살아남을 수 있는가였습니다: 블루프린트를 작성하고, 28개 위젯의 HUD를 짓고, 입력 시스템을 연결하고, 엔진 내부에서 자신의 버그를 추적하는가——아니면 첫 도구 호출에서 무너지는가. 우리가 아는 한, 이 사례 이전에 UE의 네이티브 MCP를 통한 로컬 LLM 빌드 성공을 공개한 사람은 없었습니다; 우리가 찾은 유일한 공개 시도는 출시 당일 실패로 끝났습니다. 여기 정확한 셋업과 무엇을 지었는지, 그리고 솔직한 결론이 있습니다.
1. 모델: Qwen3.6-27B, 그리고 실제로 필요한 하드웨어
선택은 Qwen3.6-27B입니다——오픈 모델 중 에이전틱 코딩 벤치마크 상위권에 있는 밀집(dense) 오픈 가중치 모델로, 이번 세대에 도구 호출 개선이 내장되어 있습니다. 여기서 사용한 정확한 빌드는 unsloth GGUF 리포지토리의 UD-Q4_K_XL 퀀트 (UD = Unsloth Dynamic)——가중치 약 17 GB입니다.

2. llama.cpp로 로컬 서빙(플래그가 승부의 전부)
llama.cpp는 명령 하나로 설치합니다——Windows에서는 winget install llama.cpp——그리고 서버를 띄웁니다. -hf 플래그가 첫 실행 시 Hugging Face에서 정확한 퀀트를 바로 가져오므로, 별도의 다운로드 단계가 없습니다:
winget install llama.cpp # macOS/Linux: curl -LsSf https://llama.app/install.sh | sh
llama serve -hf unsloth/Qwen3.6-27B-GGUF:UD-Q4_K_XL -a Qwen3.6-27B \
--host 127.0.0.1 --port 1235 \
-ngl 99 -fa on -c 40960 \
--cache-type-k q8_0 --cache-type-v q8_0 \
--jinja --reasoning off \
--temp 0.7 --top-p 0.80 --top-k 20 --min-p 0.0 \
--presence-penalty 1.5 --repeat-penalty 1.0각 블록이 하는 일——하나하나 제자리를 얻어낸 것들이니까요:
-ngl 99는 모든 레이어를 GPU에 올립니다(99는 그냥 “전부”라는 뜻). -fa on은 플래시 어텐션을 활성화. -c 40960은 Qwen3의 네이티브 컨텍스트 최대치——VRAM이 빠듯하면 낮추세요. q8_0 K/V 캐시 플래그는 어텐션 캐시를 8비트로 압축: 메모리는 거의 절반, 품질은 거의 그대로.-a Qwen3.6-27B는 API에서의 모델 이름——나중에 Cline에 정확히 그대로 입력할 문자열입니다. --reasoning off는 씽킹 모드를 비활성화: 에이전트 루프에는 턴당 빠른 도구 호출 하나가 필요하지, 독백이 아닙니다——지연 시간은 낮아지고, 낭비되는 토큰도 없습니다.--repeat-penalty 1.0, 즉 끔. llama.cpp의 기본값은 1.1이고, 그 구식 페널티는 Qwen에 실제로 해를 끼칩니다.--jinja는 llama.cpp가 모델의 네이티브 채팅 템플릿을 쓰도록 강제합니다. 이것이 없으면 서버는 Qwen이 도구 호출을 포맷하는 태그를 파싱하지 못하고——Cline은 단 하나의 도구 호출도 보지 못합니다. 모델은 살아 있는 것처럼 보이고, 즐겁게 대화하지만, 에디터에는 아무것도 하지 않습니다. 로컬 에이전트가 “말은 하는데 행동은 안 한다”면, 가장 먼저 확인할 것이 이 플래그입니다.
3. Cline을 자신의 서버로 향하게 하기
Cline이 에이전트 하니스입니다——무료 오픈소스 VS Code 확장. llama-server가 OpenAI 호환 엔드포인트를 노출하므로, Cline은 마치 클라우드 API인 것처럼 여러분의 GPU와 대화합니다:
API Configuration
Provider는 OpenAI Compatible; Base URL은 http://127.0.0.1:1235/v1( /v1 경로는 필수); Model은 Qwen3.6-27B—— -a 플래그와 정확히 일치해야 합니다; API Key는 비어 있지 않은 아무 문자열(서버는 확인하지 않지만 Cline이 필드를 요구합니다). Context Window는 40960, 서버와 동기화. Reasoning Effort는 None, --reasoning off와 맞춥니다.
언리얼 에이전트에 중요한 기능들
Native Tool Call ON——프롬프트 꼼수 대신 모델의 진짜 도구 호출 포맷을 사용. Parallel Tool Calling OFF——어차피 언리얼 에디터는 병렬로 작업할 수 없습니다; 한 번에 한 작업입니다. Auto Compact OFF——여기서는 채팅 하나가 작업 하나이므로, 압축할 긴 히스토리가 아예 생기지 않습니다.
Yolo Mode ON(선택이지만, 이게 핵심)
Yolo Mode는 모든 도구 호출을 자동 승인합니다——bypass-permissions의 로컬 버전입니다. 클라우드 에이전트에서는 모든 “진행할까요?”가 여러분의 주의력과 돈을 잡아먹지만, 여기서는 모델이 여러분의 것이니 그냥 달리게 두세요.

4. 언리얼 엔진 5.8로 브리지하기
언리얼 쪽은 이전 장에서 다룬 것과 같은 네이티브 MCP 서버입니다——플러그인을 활성화하고 Auto Start Server를 켜면 에디터가 http://127.0.0.1:8000/mcp에서 수신합니다. (MCP 플러그인은 아직 Experimental로 표시되어 있고, 가끔 티가 납니다—— 아래에서 더 다룹니다.) 새로운 것은 Cline에 이를 알려주는 부분뿐입니다, cline_mcp_settings.json에서:
{
"mcpServers": {
"unreal-mcp": {
"type": "streamableHttp",
"url": "http://127.0.0.1:8000/mcp"
}
}
}첫 작업, 새 채팅에서: “check mcp connection to unreal engine.” 맨 처음의 execute_python_code 호출은 AttributeError로 실패했습니다——잘못된 Python API 호출. 그리고 이것이 처음으로 진짜 고무적인 순간이었습니다: 모델이 트레이스백을 읽고, 연결은 멀쩡하며 자신의 코드만 틀렸다고 스스로 결론 내린 뒤, 수정한 코드로 재시도했습니다. 8밀리초 뒤: “MCP connection to Unreal Engine: SUCCESSFUL.”

작업 사이에 기억이 없는 로컬 모델은 룰 파일에 살고 죽습니다. 이 파일—— BurgerTower_SystemPrompt.md——은 프로젝트 컨벤션, 에디터 API 노트, 컴파일 규율, 그리고 그냥 두면 각각 프롬프트를 하나씩 잡아먹었을 엔진 함정들을 담고 있습니다(float는 real 타입으로 선언해야 하며 그러지 않으면 조용히 int가 된다; 도구 호출당 시스템 하나; 기본값 경고를 없애려면 두 번 컴파일). 프로젝트에 넣고 상황에 맞게 고치세요.
5. 스트레스 테스트: 프롬프트 17개로 완전한 게임
프로젝트는 BurgerTower——원버튼 아케이드 스태커입니다. 음식 조각이 점점 높아지는 타워 위에서 흔들리고, 탭해서 떨어뜨립니다. 깔끔한 착지는 보너스 점수와 고기 육즙 스플래시; 기울어진 타워는 무너지며 런이 끝납니다. 층이 오를 때마다 카메라가 높이 올라갑니다——도시, 구름, 성층권, 우주. 프로젝트에 들어 있는 것은 아트뿐: 음식 메시 8개, 파노라마 텍스처 하나, 빈 스튜디오 맵 하나. 모든 블루프린트, 그래프, 위젯, 입력 에셋, 머티리얼, 이펙트를 모델이 에디터 안에서 라이브로, Python을 통해 작성해야 합니다.

그리고 이것을 데모가 아닌 진짜 벤치마크로 만드는 규칙 하나: 모든 프롬프트는 깨끗한 컨텍스트의 완전히 새로운 Cline 작업입니다. 모델은 단계 사이에 아무것도 기억하지 못합니다——연속성은 프롬프트 자체가 운반합니다. 매일 아침 기억상실로 깨어나는 시공업자에게 건네는 의뢰서처럼요. 총 17건의 의뢰입니다.
프롬프트 1-6: Play를 한 번도 누르지 않고 뼈대 전체를
첫 여섯 프롬프트는 모든 부품을 따로 짓고 컴파일만으로 검증합니다: 물리 프로파일과 메시 풀을 갖춘 낙하 조각 액터(메시가 루트 컴포넌트 자체여야 합니다——물리는 루트를 시뮬레이션하므로, 빈 루트 아래 매달린 메시는 물리가 깨어나는 순간 뜯겨 나갑니다); 삼중 필터링된 Hit 이벤트가 물리 접촉을 정확히 한 번의 “착지했다” 신호로 바꾸는 이벤트 그래프; 엔진 템플릿에서 복제한 Niagara 버스트; 상태 변수 19개의 카메라 폰; 그리고 HUD.

HUD는 문장 하나를 따로 받을 자격이 있습니다: 위젯 28개——점수 카드, 골드 BEST 알약, PERFECT!/COMBO 콜아웃, CITY/CLOUDS/STRATOSPHERE/SPACE 눈금이 있는 고도 게이지, RETRY 버튼이 달린 완전한 사망 화면——이 UMG 디자이너에서 클릭 한 번 없이, 도구 호출 두 번으로, 전부 코드로 배치되고 앵커링되고 채색되고 스타일링됐습니다. 두 번째 호출은 로컬 모델이 약 2분 30초 동안 스트리밍한 하나의 연속된 코드 블록이었습니다. 깔끔하게 컴파일됐습니다.
프롬프트 7-13: 연결, 첫 Play, 첫 게임 오버
2막은 부품들을 의존성 순서로 연결합니다: 먼저 폰의 착지 수신부, 다음은 Tick 심장박동(스윙 사인 곡선, 부드러운 카메라 상승, 프레임별 HUD 업데이트, 물리 기반 실패 체크), Enhanced Input 에셋, BeginPlay 부트스트랩, 그리고 게임 모드——기본 폰을 설정한 뒤에는 게임 모드를 다시 컴파일해야 하며, 그러지 않으면 Play가 계속 엔진의 기본 폰을 스폰한다는 미묘한 함정까지 포함해서. 모델은 다시 컴파일하고 값을 다시 읽어 검증했습니다. 시리즈 전체의 첫 Play는 프롬프트 11이 지나서야 옵니다: 폰이 스폰되고, HUD가 0으로 올라오고, 조각 하나가 베이스 번 위에서 흔들립니다.

프롬프트 12는 드롭 버튼입니다——누르는 순간에 퍼펙트를 판정하고, 조각의 물리를 깨우고, 카메라를 한 단계 올리고, 다음 조각을 스폰——그리고 시리즈 최대의 코드 블록: 약 3분의 스트리밍, 이어서 엔진이 그래프를 컴파일하는 3분 30초. 작업 도중 MCP 엔드포인트가 세션을 떨어뜨렸습니다; Cline이 스스로 정확히 같은 호출을 재전송했고 빌드는 계속됐습니다. 이런 전달 실패는 프로젝트 전체에서 세 번 일어났고, 에이전트는 매번 카메라 앞에서 스스로 복구했습니다. 그리고: Play, 첫 드롭, “PERFECT! x4” 연속, 기울어지는 타워, 5,316미터에서의 붕괴, GAME OVER, RETRY——게임 루프 전체가 작동합니다. 프롬프트 13은 고전적인 손맛 패스: 스윙을 넓히고, 속도를 올리고, FOV를 70에서 80으로 엽니다.

프롬프트 14-15: 수식으로 지은 셰이더, 그리고 릴리스 패스
프롬프트 14는 과시 구간입니다: 배경 머티리얼을 코드로 짓기—— MaterialEditingLibrary로 머티리얼 노드 약 18개——세로로 긴 파노라마 텍스처를 스크린 스페이스에 매핑하고, 보이는 창이 카메라 상승에 맞춰 위로 미끄러지게. 순수 셰이더 수학이, 프롬프트에 수식으로 받아쓰여, 모델에 의해 노드 배선으로 옮겨졌습니다. 이 작업은 시리즈의 유일한 진짜 걸림돌도 낳았습니다: 응답 하나가 전송 중 유실됐고, 재시도가 첫 호출이 이미 만들어 둔 에셋과 충돌해 언리얼이 덮어쓰기 대화상자를 띄웠습니다. 모델은 루프에 빠지지 않았습니다——머티리얼이 존재한다고 결론 내리고 2부로 넘어갔습니다. 프롬프트 15는 릴리스 패스: 프롬프트 7부터 의도적으로 연결하지 않고 둔 exec 와이어 하나(게이트 뒤에 대기시킨 퍼펙트 히트 버스트)를 연결하고, 이펙트를 고기 육즙 갈색으로 다시 칠하고, 점호를 돌립니다——에셋 8개, 전부 깔끔하게 컴파일.

프롬프트 16: 진짜 버그——그리고 제목에 답하는 순간
릴리스 패스 후에도 퍼펙트 스플래시는 게임에서 여전히 흰색으로 렌더링됐습니다——도구 리포트는 초록불이었고 색상 값이 에셋 안에 검증 가능하게 들어 있었는데도요. 프롬프트 16은 모델에게 수수께끼를 건넵니다: 왜 색이 화면에 도달하지 못했는지 알아내라. 모델이 내놓은 진단은 프로젝트 전체에서 가장 영리한 순간입니다: Niagara는 시스템을 백그라운드에서 컴파일하며, 게임은 내내 이펙트의 낡은 컴파일 사본을 재생하고 있었다. 해법: 세 이미터 모두에서 색을 다시 설정하고, 저장하고, 에디터에서 시스템을 열어 리빌드를 강제한다. 다음 Play: 퍼펙트 두 번, 불꽃이 튀는 진갈색 스플래시. 이것은 튜토리얼 패턴 매칭이 아닙니다——엔진의 에셋 파이프라인에 대한 추론입니다.
프롬프트 17은 디저트입니다: 새 파노라마——버거 도시 위에서 우적거리는 거대한 머리——를 임포트하고 머티리얼의 샘플러를 그쪽으로 다시 향하게 합니다. 임포트 한 번, 리포인트 한 번; 팬 수식은 텍스처를 건드리지 않는 스칼라 파라미터에 살고 있으므로, 배경은 세션 중에 뷰포트에서 라이브로 교체됐습니다.

6. 솔직한 결론
- 실제 프로젝트에서 살아남았습니다. 새 컨텍스트 프롬프트 17개, 모든 시스템이 깔끔하게 컴파일, 진짜 엔진 수준 버그 하나를 진단하고 수정. 게임의 뼈대는 Play를 한 번도 누르지 않고 지어졌습니다.
- 클라우드 프론티어 모델보다 느립니다. 큰 코드 블록은 소비자용 GPU 한 장에서 2~3분씩 스트리밍되고, 가장 무거운 그래프는 엔진 컴파일에만 약 3.4분이 더 걸렸습니다. 점심시간이 아니라 여유로운 저녁을 잡으세요.
- 하니스가 실질적인 일을 합니다. Cline은 끊긴 MCP 호출을 세 번 재전송했고, 모델은 자신의 잘못된 API 호출과 에셋 충돌 재시도에서 복구했습니다. Experimental 등급의 MCP 엔드포인트는 딸꾹질을 할 것이고——루프가 그것을 흡수할 것도 기대하세요.
- 여러분이 돈 내지 않는 지능은 프롬프트가 운반합니다. 정밀하고 한 번에 시스템 하나씩인 브리프와 룰 파일이, 기억 없는 로컬 모델을 시니어처럼 행동하게 만듭니다. 모호한 프롬프트는 접촉을 견디지 못합니다.
- Claude를 대체하나요? 이런 구조화된 빌드에서는——정말로, API 비용 $0.00으로, 일을 해냈습니다. 지저분하고 열린 결말의 작업에서는 프론티어 모델이 여전히 27B 로컬 모델에는 없는 여유를 사 줍니다. 이념이 아니라 프로젝트별로 고르세요.

그리고 네, 숫자점도 맞아떨어집니다: 프롬프트 17개, 약 17 GB의 모델, 그리고 17.7킬로미터 높이의 최종 타워——우주의 가장자리를 지나, 거인의 벌린 입 속으로, 제대로 된 게임 오버 화면과 함께. 그 모든 단계의 청구액은 $0.00.
실제로 손에 들어오는 것
이것이 전체 파이프라인입니다: llama.cpp 명령 하나, Cline 설정 페이지 하나, MCP 항목 하나——그리고 클라우드 에이전트들이 움직이는 것과 같은 에디터를 움직이는 로컬 모델. 이런 프로젝트를 먹여 살리는 생성 도구는 계속 바뀝니다; 새 도구가 나오면 바로 아레나로 들어가, 커밋 전에 블라인드로 비교할 수 있습니다. 이 이야기의 이전 장은 언리얼 엔진 5.8 네이티브 MCP + Claude와 Claude Code + 언리얼 엔진 5에서.
전체 빌드 보기
전체 셋업과 17개 프롬프트 전부를, 처음부터 끝까지 YouTube에서.
Stefan Vaskevich