AI 게임 엔진의 해부: 프롬프트 안에 실제로 들어 있는 것
글 Mariana Muntean, Cinevva CEO
낯선 사람들이 Cinevva에 대해 가장 흔히 하는 말은 그냥 AI 래퍼라는 것입니다. 홈페이지에 들어와서 "Describe your game"이라고 적힌 입력 상자 하나를 보고는 제품을 다 이해했다고 결론 내립니다. 그들이 이해한 건 정문입니다. 제품은 그 문장을 입력할 때 보이지 않는 모든 것이고, 이번 주부터는 거기에 더해 플레이어들이 당신의 게임을 찾으러 걸어 들어오는 오픈 월드까지입니다.
그 입력 뒤에는 완전한 게임 엔진이 있습니다. 타입이 정의된 26개의 도구를 가진 오케스트레이터, 생성 모델 한 무리, 11개 제공처에 걸친 통합 에셋 검색, 에이전트가 읽고 쓸 수 있는 실시간 게임 iframe, 그리고 같은 에이전트가 완성된 당신의 게임을 넘겨볼 수 있는 게임플레이 릴로 출시해 주는 스토어프런트가 있죠. 이 중 별난 건 하나도 없습니다. 전부 배관 작업입니다. 흥미로운 일은 무엇을 무엇에 연결할지 정하는 것이었습니다.
이 글은 그 기계를 위에서 아래로 훑습니다. 기술 투자자에게 들려주는 설명이자, 기여를 고민하는 개발자에게 들려주는 설명이기도 합니다. 둘 다 같은 답을 원합니다.
1. 프롬프트는 표면이지 시스템이 아니다

첫 번째 설계 결정은 사용자가 직접 발을 들이기 전까지 모든 걸 숨기는 것이었습니다. 홈페이지의 일은 하나뿐입니다. 문장 하나를 프로젝트로 바꾸는 것이죠. 우리는 경험을 공개되는 쪽(프롬프트, 쇼케이스, 스토어프런트 피드)과 창작자 쪽(IDE, 에셋 도구, 게시 흐름)으로 나눴습니다. 그냥 놀고 싶은 사람들은 조종석을 들여다볼 필요가 없도록요.
그래서 플레이스홀더가 "Make a snake game with neon graphics"나 "Top-down zombie shooter" 같은 문구로 돌아가는 것입니다. 이건 튜토리얼이 아닙니다. 허가증입니다. 사용자는 "이상한 아케이드 아이디어"도 합법적인 입력이라는 걸 알게 됩니다.
제출하는 순간 세 가지 일이 일어납니다. 시스템이 안정적인 ID를 가진 새 게임 프로젝트를 만듭니다. 빈 파일 트리(index.html, game.js, style.css, assets/, GDD.md)를 심습니다. 그리고 당신의 문장을, 그 빈 파일들을 가리키는 프로젝트 컨텍스트 창과 함께 오케스트레이터로 보냅니다. 이 순간부터 당신은 손을 가진 에이전트와 대화하게 됩니다.
2. 입력 뒤에는 완전한 브라우저 IDE

창작자 작업 공간은 전적으로 브라우저 안에서 돌아가는 3분할 IDE입니다. 왼쪽에 파일 트리, 가운데에 코드 편집기, 오른쪽에 실시간 게임 iframe, 아래쪽을 가로지르는 채팅 입력. 이 배치는 일부러 고른 것입니다. 이미 코드를 쓰는 사람은 한눈에 알아봅니다. 코드를 쓰지 않는 사람은 가운데 패널을 무시하고 채팅하고만 대화하면 됩니다.
파일 트리는 비유가 아닙니다. 모든 프로젝트는 실제로 HTML, JS, CSS, 생성된 이미지, GLB 모델, 오디오 파일로 이루어진 작은 정적 사이트이고, R2에서 Cloudflare Worker를 거쳐 바로 서빙됩니다. 빌드 단계가 없습니다. 이 점이 중요합니다. 에이전트가 당신이 실제로 출시할 파일들을 읽고 쓸 수 있다는 뜻이고, 같은 산출물이 iframe 안에서도, Capacitor로 감싼 휴대폰에서도, Tauri로 감싼 Steam에서도, Discord 안에서 Embedded Activity로도 돌아간다는 뜻입니다. 하나의 파일 시스템, 여섯 개의 배포 대상입니다.
우리가 생성하는 모든 게임은 window에 두 개의 함수를 노출해야 합니다. getGameState()는 실행 중인 게임을 설명하는 평범한 객체(플레이어 위치, 점수, 생명, 적, 타이머)를 반환합니다. setGameState(patch)는 부분 업데이트를 실시간 게임에 다시 적용합니다. 이 작은 API가 바로 에이전트가 다시 로드하지 않고도 실행 중인 게임을 들여다보고 수정하게 해 주는 계약입니다. 왜 그런지는 6절에서 다시 다룹니다.
3. 오케스트레이터, 진짜 엔진이 사는 곳

이걸 "AI 래퍼"라고 부르는 사람들이 놓치는 부분은, AI가 코드를 쓴다기보다는 작은 오케스트라를 지휘한다는 점입니다. 오케스트레이터는 프런티어 모델을 상대로 도는 tool-calling 루프로, 약 천 줄짜리 시스템 프롬프트와 26개 함수로 이루어진 타입 정의 도구 표면을 갖추고 있습니다. 그 도구 정의가 엔진입니다. 모델은 지휘자입니다.
26개의 도구는 다섯 가지 계열로 나뉩니다. 파일 시스템 도구(list_game_files, read_files, search_game_file, edit_files, write_files, delete_files, rename_files)는 에이전트가 당신의 게임을 다른 코드베이스처럼 다루게 해 줍니다. 프로젝트 도구(create_new_game, list_games, open_game, ask_user, game_ready)는 프로젝트의 수명 주기와 사람에게 다시 넘기는 단계를 처리합니다. 생성 도구(generate_image, generate_skybox, generate_music, generate_sfx, rig_model, apply_animation, list_animations, list_skybox_styles)는 다음 절에서 다룰 전용 모델들을 호출합니다. 지식 도구(search_fonts, list_library_docs, search_library_docs, list_generations)는 에이전트에게 환각이 아닌, 믿을 수 있고 색인된 사실의 출처를 줍니다. 그리고 런타임 도구(read_console_logs, execute_js)는 에이전트가 실시간 게임을 보고 만지게 해 줍니다.
전형적인 첫 턴은 대략 이렇습니다. 사용자가 "Make a neon space shooter"를 입력합니다. 모델은 설계를 설명하는 GDD.md와 함께 write_files 호출을 내보내고, 그다음 다시 write_files로 index.html, game.js, style.css를 내보냅니다. prompt="synthwave space shooter, 120 BPM, driving bassline"으로 generate_music을 호출하면 ElevenLabs Music에 대한 작업이 시작되고 R2 안의 MP3 URL이 돌아옵니다. 별이 빛나는 배경을 위해 Blockade Labs의 model 3 스타일로 generate_skybox를 호출합니다. game_ready(title, message)를 호출해 iframe을 새 빌드로 전환하고, 마지막으로 read_console_logs를 호출해 게임이 오류 없이 부팅됐는지 확인합니다. 스택 트레이스가 보이면, 사용자가 무언가를 보고하기 전에 edit_files로 돌아가 고칩니다.
이 설계의 흥미로운 속성은, 시스템 프롬프트와 도구 스키마만이 제품에 특화된 유일한 부분이라는 점입니다. 모델을 바꿔도 전부 그대로 작동합니다. 우리는 지난 한 해 동안 표면을 바꾸지 않고 세 개의 프런티어 모델 사이를 옮겨 다녔습니다. 그 표면이 우리 것이기 때문입니다.
4. 에셋 쪽: 모델 팬아웃

에이전트는 이미지, 음악, 사운드, 3D를 직접 생성하지 않습니다. 전문가들을 호출합니다. Cinevva의 에셋 쪽은 분야별 최고 모델들로 팬아웃한 다음, 하나의 출력이 다음 것의 유효한 입력이 되도록 붙여 놓은 구조입니다.
이미지와 스프라이트의 경우 generate_image가 Flux Pro 1.1을 호출하는데, 너비와 높이는 항상 32의 배수이고, 프롬프트가 투명도를 요구하면 출력 형식이 PNG로 전환됩니다. 곡 전체는 에이전트가 스타일 프롬프트와 초 단위 길이로 ElevenLabs Music을 호출합니다. 일회성 효과음은 ElevenLabs SFX가 "laser gun firing, sci-fi blaster" 같은 텍스트에서 5초에서 15초 사이의 클립을 만들어 냅니다. 360도 환경은 generate_skybox가 약 90가지 스타일 중 하나로 Blockade Labs를 호출하며, 기본값은 model 3 Digital Painting입니다. 3D 캐릭터의 경우 rig_model이 GLB를 Tripo로 보내 이족, 사족, 육족, 팔족, 뱀형, 또는 수생 생물로 스키닝하고 리깅하며, 그다음 apply_animation이 15개 프리셋(idle, walk, run, jump, climb, dive, slash, shoot, hurt, fall, turn, 그리고 비이족용 행진 동작) 중 아무거나 재생합니다.
이것들은 하나하나가 동기 호출이 아니라 작업입니다. 짧으면 몇 초, 길면 몇 분이 걸립니다. 오케스트레이터는 이들을 띄우고 곧바로 jobId와 함께 반환하며, 별도의 채널이 에셋이 준비되면 결과를 대화로 다시 흘려보냅니다. 이게 느낌을 완전히 바꿉니다. 3D 모델이 백그라운드에서 리깅을 끝내는 동안 에이전트는 계속 게임 로직을 만들 수 있습니다. 사용자는 단일 임계 경로에서 기다릴 일이 없습니다.
산출물은 모두 같은 곳에 떨어집니다. cdn.cinevva.com 뒤의 R2이고, 평범한 URL로 주소를 지정할 수 있습니다. 이 말은 에이전트의 다음 write_files 호출이 그냥 <audio src="https://cdn.cinevva.com/audio/abc.mp3">를 임베드하면 게임이 바로 작동한다는 뜻입니다. SDK도, asset bundler도, manifest도 없습니다.
5. 11개 제공처에 걸친 에셋 검색

생성은 특정한 무언가가 필요할 때 훌륭합니다. 검색은 이미 존재하는 무언가가 있을 때 더 빠릅니다. 에셋 라이브러리는 무료 및 라이선스 제공처 11곳에 걸친 연합 검색으로, 하나의 순위가 매겨진 피드로 반환됩니다.
제공처 레지스트리는 worker 안에 있으며, 각 쿼리를 PolyHaven, Sketchfab, Freesound, Kenney, AmbientCG, Quaternius, OpenGameArt, Smithsonian 3D 컬렉션, TurboSquid, Synty, Jamendo에 병렬로 던집니다. 각 제공처는 공통 인터페이스(search, getMetadata, isBrowsable, getSupportedTypes)를 구현하므로, 새 제공처를 추가하는 일은 TypeScript 파일 하나입니다. 집계 계층은 제공처마다 다른 페이지네이션 방식을 커서 기반으로 처리하고, 라이선스를 중복 제거하며, 에셋 타입을 공통 분류 체계(model, texture, audio, hdri, sprite)로 정규화하고, 각 에셋에 라이선스를 태그로 붙입니다. 그래서 에이전트는 재배포할 수 없는 것을 절대 고르지 않습니다.
지난 분기에 ChatGPT가 이 도구를 게임 개발자를 위한 최고의 무료 에셋 검색 도구 중 하나로 추천했을 때, 우리는 그 추천을 직접 읽어 봤습니다. 핵심에 대해서는 옳았습니다. 요점은 우리가 단일 라이브러리 위에 검색창을 얹었다는 게 아닙니다. 요점은 "stone wall texture"를 검색하는 인디 개발자가 PolyHaven과 AmbientCG의 결과를 나란히 받고, 그 옆에 Kenney의 양식화된 버전과 Smithsonian의 사진 측량 옵션까지 받는다는 것입니다. 쿼리 한 번에, 일관된 라이선스 메타데이터와 함께요. 에이전트도 같은 엔드포인트를 호출해서 사람과 똑같은 방식으로 에셋을 고를 수 있습니다.
엔진에서 자주 과소평가되는 부분이 바로 여기입니다. 대부분의 게임 AI 데모는 모든 걸 처음부터 생성해서, 결국 균일하고 번들거리며 살짝 기이한 룩으로 끝납니다. Cinevva에서 흥미로운 게임들은 생성된 에셋을 Smithsonian의 진짜 CC0 사진 측량물, 그리고 Quaternius의 손으로 만든 로우폴리 나무와 섞습니다. 오케스트레이터는 그걸 한 턴에 해낼 수 있습니다.
6. 에이전트가 게임을 플레이한다

우리가 보여 줄 때 대부분의 엔지니어를 놀라게 하는 부분이 바로 이것입니다. 에이전트는 단지 코드를 파일에 쓰는 데 그치지 않습니다. 샌드박스 iframe에서 게임을 실행하고, 콘솔을 읽고, UI와 3D 장면을 층으로 나눠 스크린샷을 찍고, 실시간 런타임 안에서 JavaScript를 실행해 상태를 검사하거나 바꿉니다.
read_console_logs는 iframe에서 나온 console.log, console.warn, console.error 그리고 잡히지 않은 예외의 마지막 50줄을 반환합니다. 모든 game_ready 호출 후에, 에이전트는 시스템 프롬프트에 의해 read_console_logs를 호출하고 사용자에게 다시 넘기기 전에 모든 오류를 고치도록 요구받습니다. 이 규칙 하나가 다른 도구들에 있는 "AI는 다 됐다고 했는데 화면이 까맣다" 류의 실패 대부분을 없앱니다.
execute_js는 더 강력한 쪽입니다. 게임의 전역 스코프 안에서 임의의 JavaScript를 실행합니다. 모든 게임이 getGameState와 setGameState를 구현하도록 요구받기 때문에, 에이전트는 JSON.stringify(getGameState())를 실행해 실행 중인 게임의 전체 상태를 읽고, setGameState({player: {x: 500, y: 100}})로 플레이어를 순간 이동시키거나, setGameState({lives: 99})로 무적을 부여하거나, setGameState({level: 3})로 앞으로 건너뛸 수 있습니다. 더 낮은 수준도 찔러 볼 수 있는데, scene.children.map(c => c.type)로 Three.js 장면 그래프를 검사하거나 document.querySelectorAll('canvas').length로 렌더러가 마운트됐는지 확인하는 식입니다.
이게 왜 중요한지 보일 겁니다. 사용자가 "2단계에서 플레이어가 벽에 끼인다"고 말하면, 에이전트는 추측할 필요가 없습니다. 2단계를 열고, getGameState()를 실행하고, 충돌 데이터를 살펴보고, execute_js 패치를 돌려 수정안을 테스트한 다음, 그제야 수정안을 디스크에 씁니다. 당신이 디버그하는 방식 그대로 디버그합니다. 우리는 iframe을 대상이 아니라 동료로 다룹니다.
7. 라이브러리 문서, 지루한 사실의 출처
우리는 게임이 실제로 쓰는 라이브러리(Three.js, Tone.js, Cannon, 그리고 늘어나는 중)의 공식 문서를 구조화되고 검색 가능한 JSON 저장소로 색인합니다. 에이전트는 열린 웹에 손을 뻗기 전에 search_library_docs("threejs", "Mesh")에 손을 뻗습니다. 더 빠르고, 버전이 관리되며, 두 마이너 릴리스 전에 이름이 바뀐 메서드를 절대 환각하지 않습니다.
이건 화려한 일이 아닙니다. 하지만 작동하는 코드를 만드는 AI와, 그럴듯해 보이지만 40번째 줄에서 죽는 코드를 만드는 AI의 차이입니다. Cinevva로 만든 게임의 눈에 보이는 품질 대부분이 이 한 가지 결정에서 나옵니다.
8. 플레이 가능에서 발견 가능으로: 릴과 스토어프런트

아무도 플레이하지 않는 게임은 개인 취미입니다. 인디 개발에서 풀리지 않은 가장 어려운 문제는 이제 게임을 만드는 게 아닙니다. 배포입니다. 그래서 엔진은 "플레이 가능"에서 멈추지 않습니다. "플레이어 앞에 있음"에서 멈춥니다.
Cinevva의 모든 프로젝트는 play.cinevva.com/{game-id} 같은 안정적인 공유 URL을 가지며, 이 URL은 게임의 최신 빌드를 전체 페이지 iframe으로 열고 좋아요와 공유를 위한 작은 오버레이를 띄웁니다. 에이전트가 game_ready를 호출하면, IDE 안의 미리보기만 전환하는 게 아닙니다. 15초짜리 게임플레이 릴을 Cinevva 스토어프런트에 게시하겠다고 제안하기도 합니다. 릴은 게임이 플레이되는 실제 녹화로, iframe에서 직접 캡처됩니다(우리는 에이전트가 게임 런타임에 주입하는 작은 레코더 스크립트를 함께 보냅니다). 그래서 시청자가 스크롤로 지나치는 것은 마케팅 편집물이 아니라 진짜 게임플레이입니다.
이게 개발자가 사는 루프를 바꿉니다. 옛 루프는 코드 작성, 빌드, 패키징, 업로드, Steam 페이지 작성, 알고리즘과 싸우기, 위시리스트 카운터 지켜보기였습니다. 새 루프는 문장 하나 입력, 에이전트가 만드는 걸 지켜보기, 게시 누르기, 당신의 게임이 다른 모든 것과 함께 같은 스와이프 피드에 나타나는 걸 지켜보기입니다. 발견은 창작이 일어나는 같은 제품 안에서, 같은 URL에서, 같은 로그인으로 일어납니다.
개발자 커뮤니티 독자라면 이 부분을 살펴보세요. 배포는 언제나 게임 엔진이 함께 출시하지 않는 해자였습니다. Unity는 에디터를 출시하고, 당신은 게임을 Steam에 출시합니다. Unreal은 에디터를 출시하고, 당신은 Epic Store에 출시합니다. Cinevva는 양쪽 다 출시합니다. 엔진과 스토어프런트는 게임을 만든 바로 그 오케스트레이터를 통해 서로 대화합니다.
9. Top Performers: 발견의 플라이휠

릴 피드는 플라이휠의 절반입니다. Top Performers 차트가 나머지 절반입니다. 이 차트는 게임을 trending, recent, all-time top으로 순위 매기는데, 가중치는 원시 클릭이 아니라 완주율(플레이어가 한 세션을 끝냈는가)로 둡니다. 완주율은 설치 수보다 조작하기 어렵습니다. 60초 동안 주의를 붙드는 게임이 열었다 닫히는 게임을 이깁니다.
모든 신호는 오케스트레이터의 다음 턴으로 되먹임됩니다. 에이전트가 "파워업을 추가하자"고 말할 때, 고정된 패턴 라이브러리에서 끌어오는 게 아닙니다. 이번 달 Cinevva에서 어떤 메커니즘이 실제로 플레이어를 붙잡는지 지켜본 모델에서 끌어옵니다. 플라이휠은 페이지 하단의 차트가 아닙니다. 엔진 전체의 학습 신호입니다.
투자자라면, 이것이 데이터 해자입니다. 우리는 단지 생성된 게임만 가진 게 아닙니다. 실제 세션 수준 참여 지표가 붙은 생성 게임을 가졌고, 그것을 만들어 낸 프롬프트에 붙어 있고, 에이전트가 내린 에셋 선택에 붙어 있고, 그걸 좋아한 플레이어에게 붙어 있습니다. 한 바퀴를 돌 때마다 다음 바퀴가 더 단단해집니다.
10. 엔진이 게임이 되다
여기가 제가 몇 달째 소셜에서 흘려 온 부분입니다. 1절부터 9절까지는 게임을 만드는 시스템을 설명합니다. 직접 보기 전까지 설명하기 더 어려운 것은, 그 시스템 자체가 하나의 장소가 될 때 무슨 일이 일어나는가입니다.
게임을 만드는 일은, 우리가 지금까지 출시한 모든 것을 가지고도 고된 작업입니다. 한 번도 게임을 만들어 본 적이 없다면, 당신은 갑자기 줄거리, 캐릭터, 세계, 메커니즘, 누가 무엇을 언제 하는지, 빛이 어떻게 움직이는지, 특수 효과가 어떻게 층층이 쌓이는지, 음악, 음향 효과, 카메라 움직임을 책임지게 됩니다. 양이 많습니다. 게다가 그 모든 것 위에, 결과물이 누군가 다른 사람의 도구가 뱉어낸 템플릿이 아니라 당신 것처럼 느껴지길 원하죠. 프롬프트와 오케스트레이터는 기계적인 작업 대부분을 당신 대신 해 줍니다. 그것들이 혼자서 못 하는 건, 완성된 당신의 것에 다른 사람들이 지켜보는 무대를 마련해 주는 일입니다.
그래서 우리는 무대를 지었습니다. 올해 대부분 동안 Oleg와 엔진 팀은 오픈 월드를 브라우저에 넣는 일에 대한 14부작 시리즈를 발행해 왔습니다. 실시간으로 깎을 수 있는 조각된 지형. 경사와 고도에 따라 스스로를 바위나 풀로 칠하는 바이옴. 컴퓨트로 생성된 지형 위에서 바람에 휘는 8만 개의 풀잎. 하이트맵 지형과 볼류메트릭 지형을 같은 발걸음으로 걷고, 질주하고, 점프하고, 활공하는 캐릭터. 그 무엇도 그 자체를 위한 기술 데모가 아니었습니다. 이것을 위한 기반이었습니다.
오늘 오픈 월드가 초기 형태로 라이브 상태입니다. 아바타를 입고 걸어 들어갑니다. 당신이 게시한 게임들이 당신 주변에 방문 가능한 공간으로 나타납니다. 스토어프런트 릴과 Top Performers 차트가 지금 그것들을 보여 주는 방식과 같지만, 이번엔 스와이프가 아니라 두 발로 도착합니다. 세계를 떠나지 않고도 낯선 사람의 게임 안으로 들어갈 수 있습니다. 방금 플레이한 것을 만든 사람 옆에 서서 다음에 무엇을 더하면 좋을지 말해 줄 수 있습니다. 방금 만난 사람과 함께 지형 한 조각을 깎아 새 프로젝트의 씨앗으로 만들 수 있습니다. 발견은 더 이상 피드가 아닙니다. 산책이 됩니다.
우리 엔진은 언제나 기술적 의미에서 게임 엔진이었습니다. 오늘은 문자 그대로의 의미에서도 게임 엔진이 됩니다. 당신의 게임을 만드는 그것이 이제 그 자체로 하나의 게임이고, 3절의 같은 오케스트레이터, 4절의 같은 에셋 레일, 6절의 같은 getGameState 계약, 8절의 같은 릴, 9절의 같은 차트가 모두 당신의 플레이어들이 걸어 다니는 하나의 장소로 합쳐집니다. 만드는 것과 노는 것 사이의 경계는 언제나 인위적이었습니다. 이제 그 경계는 사라졌습니다.
우리가 잘했다고 생각하는 것
첫 번째로 잘한 것은 프롬프트를 제품이 아니라 UI 어포던스로 다룬 것입니다. 제품은 오케스트레이터, 도구 표면, 에셋 레일, 그리고 스토어프런트입니다. 프롬프트는 사용자를 시스템 안으로 들이는 가장 값싼 방법입니다.
두 번째는 빌드 단계가 없는 평평한 브라우저 네이티브 파일 시스템을 고집한 것입니다. Cinevva 게임이 하나의 사실 출처에서 모바일, 데스크톱, Steam, Discord로 출시되는 이유가 이것입니다. 에이전트가 자기가 쓴 것을 읽을 수 있는 이유도 이것입니다.
세 번째는 모든 생성 게임이 getGameState와 setGameState를 구현한다는 계약입니다. 시스템 프롬프트의 그 한 줄이 에이전트를 코드 생성기가 아니라 협력자처럼 느껴지게 만드는 것입니다. 에이전트는 플레이할 수 있고, 플레이할 수 있는 시스템은 디버그할 수 있습니다.
네 번째는 스토어프런트를 엔진과 같은 루프에 연결한 것입니다. 우리는 원시 모델 품질로는 이기지 않을 겁니다. 오픈 웨이트 생성기보다 두 달 앞선다는 데에는 지킬 만한 우위가 없습니다. 우리는 당신의 게임을 만드는 바로 그 에이전트가 그것을 게시하고, 측정하고, 낯선 사람들이 어떻게 플레이했는지에서 배울 때 이깁니다.
기계 전체가 돌아가는 모습을 보고 싶다면, 홈페이지 프롬프트가 여전히 정문입니다. 문장 하나를 입력하세요. 그 뒤에서 무슨 일이 일어나는지 지켜보세요. 그런 다음 여기로 돌아와서 엔진의 어느 부분을 다음에 써 주면 좋을지 알려 주세요.