생각은 여러분의 모델이, 실행은 War3AI가
Agent가 실제 환경에서 스스로 일을 해내려면 세 가지가 필요합니다. 명확하게 표현할 수 있는 행동, 읽을 수 있는 피드백, 실수해도 괜찮은 환경. 우리는 워크래프트 III를 바로 그런 환경으로 바꿨습니다.
Agent가 여기서 스스로 해낼 수 있는 이유
AI에게 게임을 시키는 흔한 방법은 마우스와 키보드를 흉내 내고 화면을 인식하는 것이라, 제대로 됐는지는 추측할 수밖에 없습니다. 우리는 반대로 “모델이 스스로 오류를 고치려면 무엇이 필요한가”에서 출발해 모든 인터페이스를 설계했습니다.
“무엇을 할지”만 말하기
이동, 공격, 건설, 시전…… 시맨틱 명령은 플레이어의 조작에 그대로 대응합니다. 유닛은 4자리 코드, 스킬은 오더 이름으로, 게임 속 명칭과 같습니다. 모델에게 저수준 지식은 필요 없습니다.
모든 행동에 구조화된 피드백
회신은 같은 프레임에 읽어 옵니다. 수락 여부, 사유 코드, 명령 전후의 오더, 실행 시간. “왜 안 됐는가”는 추측이 아니라 숫자 하나입니다.
결과는 화면 없이
스냅샷은 지금 어떤 상태인지, 이벤트 스트림은 무슨 일이 있었는지 알려 줍니다. 모든 피해, 모든 처치, 모든 생산 완료. Agent는 자신의 판단을 검증할 수 있습니다.
문서가 곧 인터페이스
api.json은 코드에서 생성되며, 메서드 103개 각각에 실측 상태와 내부 메커니즘이 표시되어 있습니다. llms.txt로 사이트 전체를 한 번에 읽습니다. 모델이 메서드를 지어낼 이유가 없습니다.
실패해도 안전
Bot이 예외를 던져도 다음 틱은 계속됩니다. 마감 시간이 지난 명령은 다시 실행되지 않습니다. Bot 프로세스가 죽어도 게임은 그대로 돌아갑니다. Agent는 마음 놓고 시도할 수 있습니다.
첫날부터 공정하게
공정 모드는 시야 안의 것만 제공하며, 아레나 규칙과 같습니다. Agent가 로컬에서 익힌 능력은 나중에 아레나에 올라가도 한 줄도 고칠 필요가 없습니다.
Agent가 Bot 작성
가장 빠른 입문 방법이며 프로그래밍을 몰라도 됩니다. 매뉴얼, api.json, 예제 하나를 Claude Code, Cursor, Codex 또는 어떤 대화형 모델에든 건네고, 쉬운 말로 전략을 설명하세요. openwar3.Bot을 상속한 Python 파일을 작성해 주며, 명령 한 줄로 대전에 나갑니다.
- 프롬프트 템플릿에 “실게임에서 부딪히며 얻은 규칙” 15가지가 들어 있음
- api.json의 메서드만 쓰게 해서 지어내기를 차단
- 오류는 그대로 붙여 넣고, 본 현상을 설명해 고치게 함
좋습니다. rush_bot.py의 구조를 따라 api.json의 메서드만 사용해 작성하겠습니다:
- 채집에는
idle_workers()만 보내고, 금광 하나에 5명 - 병영 대기열은 1개만, 식량 막힘은
production().blocked로 확인 - 출격은
path_distance로 멀티를 고르고attack_move로 이동 - 영웅 체력이 30% 미만이면
move로 귀환, 죽으면revive
Agent가 스스로 반복 개선하게
명령을 실행할 수 있는 Coding Agent라면 “한 판 돌리고 결과 보기”까지 맡길 수 있습니다. 무인 실행 명령 하나, 구조화된 대전 보고서 하나, 명확한 목표 하나를 주면 한 라운드씩 고쳐 나갑니다.
- 실행
play.py --speed 200 --minutes 10 --fair - 읽기 대전 보고서: 생산 타임라인, 손실, 가장 많이 거부된 이유
- 수정 결과에 가장 큰 영향을 주는 한 곳, 주석에 근거를 기록
- 재실행 몇 판 연속으로 나아지지 않으면 멈추고 보고
{
"reason": "到时间了",
"clock": 612.4,
"timeline": [
[15, "training", "hpea"],
[118, "construction", "hbar"],
[161, "training", "Hamg"],
[402, "upgrade", "hkee"]
],
"lost": {"hfoo": 7, "Hamg": 1},
"killed": {"ogru": 4, "ngno": 6},
"rejects": [
["train hfoo: rejected(人口不够)", 41],
["attack ogru: rejected(目标看不见…)", 9]
]
}가장 많이 거부된 이유는 “식량 부족” 41회로, 병영이 계속 식량을 기다렸습니다. 규칙 12에 따라 production().blocked가 보이면 식량이 거의 찰 때까지 기다리지 말고 즉시 농장을 짓습니다. 이번 라운드에서는 이 한 곳만 고칩니다.
LLM 운영 코치
“무엇을 모을지, 어디에 인력을 투입할지, 이번 1분은 싸울지 버틸지” — 이렇게 전체를 보고 우선순위를 정하는 판단은 if / else로 쓰면 서로 충돌하지만, LLM은 바로 이런 일을 잘합니다. 레퍼런스 브레인은 20게임초마다 로컬 모델에 묻고, 엄격한 JSON 하나를 받습니다.
{
"diagnosis": "금 820 목재 60, 목재가 병목이라 병영이 목재 부족으로 생산 중단",
"workers": {"gold": 10, "lumber": 7},
"priority": ["hpea", "hhou", "hfoo"],
"posture": "hold",
"avoid": ["목재가 부족할 때 방어구 업그레이드를 먼저 연구하지 말 것"]
}일꾼 배분 10 / 7 · 훈련 우선순위 hpea → hhou → hfoo · 방침 hold
명령, 회신 읽기, 컨트롤
유닛이 말하게 하기
어떤 유닛이든, 어떤 신분으로든 머리 위에 말풍선을 띄우고, 여러 유닛이 동시에 말하며, 말풍선마다 스타일을 따로 설정할 수 있습니다. 로컬 LLM을 연결하면 한 마디가 들어가고 답변 한 마디가 유닛 머리 위에 스트리밍으로 나타납니다. 일꾼 수다 모임, 영웅 대화, 전황 해설이 모두 준비되어 있습니다.
POST http://127.0.0.1:8872/api/chat
{
"inst": 16, "unit": "0x14A12614", "name": "마운틴 킹",
"persona": "너는 마운틴 킹을 연기한다. 호탕하고 술을 좋아하며, 구어체로 한두 문장",
"message": "앞에 오우거 무리가 있는데, 돌격할까?",
"stream": true
}
→ {"reply": "돌격! 이 한 잔만 비우고 돌격이다!",
"first_token_ms": 283, "total_ms": 342}AI 동료
RPG나 커스텀 맵에서 나만의 AI 동료를 곁에 두세요. 여러분을 따라다니며 사냥을 돕고, 체력이 낮으면 치유해 주고, 한가할 때는 말을 걸어 줍니다. 대사는 로컬 LLM에 연결할 수 있습니다. 클래스 하나를 상속하고 속성 몇 개만 바꾸면 여러분만의 동료가 됩니다.
매 틱 위에서부터 차례로 확인해, 조건이 맞는 항목을 실행
- 후퇴 자기 체력이 낮고 근처에 적이 있으면 여러분 뒤로 물러남
- 치유 여러분의 체력이 낮고 스킬이 준비되면 한 번 치유
- 지원 여러분을 공격하는 적부터, 그다음 여러분이 공격하는 적을 공격
- 따라가기 너무 멀어지면 따라오고, 일정 거리 이상 벌어지면 곧장 달려서 돌아옴
- 잡담 싸울 일이 없을 때 1~2분마다 한마디
채팅창에 -follow / -stay / -heal / -hi를 입력하거나 동료를 우클릭하세요
LLM이 도구를 직접 호출
MCP를 지원하는 클라이언트 — Claude Code, Claude Desktop, 로컬 모델의 Agent 프레임워크 — 에 war3_mcp.py를 연결하면, LLM이 직접 게임 상황을 보고, 명령을 내리고, 화면에서 플레이어에게 말하고, 카드를 띄워 플레이어에게 묻고, 스크린숏으로 화면을 봅니다. 코드를 먼저 쓸 필요 없이, 떠오르는 대로 시키면 됩니다.
- 도구 10개: 게임 상황 한 페이지, 유닛, 이벤트, 아무 공개 API 호출, API 조회, 화면 알림, 머리 위 말하기, 플레이어에게 묻기, 스크린숏, JASS
- 세 가지 역할: 개발, 선수(플레이어 하나만 지휘하고 그 시야만 봄), 관전자(읽기 전용)
- 처음 도구를 호출할 때 게임에 연결하므로, 게임은 나중에 켜도 됨
도구 2개를 호출했습니다:
war3_overview→ 금 500 · 식량 10/12 · 타운 홀 1 · 일꾼 5 · 팔라딘 1war3_ask_player→ 화면 가운데에 카드 세 장, 고르는 동안 게임 일시 정지- “멀티”를 클릭하셨네요. 결과가 그대로 대화로 돌아왔으니, 이어서 일꾼을 배치하겠습니다
Agent가 직접 출전
아레나는 WebSocket / JSON을 사용합니다. 심판이 매 틱 시야 기준으로 필터링한 관찰을 보내면 Bot이 행동 목록을 돌려줍니다. 어떤 언어든, 어떤 모델이든 — 코드 없이 LLM이 틱마다 JSON을 직접 출력하게 해도 — 연결할 수 있습니다. 로컬 버전은 지금 바로 쓸 수 있습니다. 게이트웨이의 선수 역할은 플레이어 하나만 지휘하고 그 시야만 볼 수 있게 합니다. 아레나에 더해야 할 것은 모두가 신뢰하는 심판입니다.
- 게임 시간에 맞춰 틱을 진행하므로, 느린 쪽이 손해를 볼 뿐 남을 붙잡지 않음
- 모든 행동은 먼저 유닛 소유권을 검증하고, 기록해 두어 리플레이 가능
- SDK로 작성한 Bot은
Game을ArenaGame으로 바꾸기만 하면 출전 가능
{"t": "obs", "tick": 57, "gameMs": 11400, "me": 1,
"res": {"gold": 320, "lumber": 150, "food": [18, 30]},
"units": [
{"id": 101, "type": "hfoo", "owner": 1,
"x": -4500, "y": 2200, "hp": 380, "hpMax": 420}],
"visibleEnemies": [
{"id": 733, "type": "ogru", "owner": 2,
"x": -3900, "y": 2500, "hp": 700}],
"deadlineMs": 180} id는 심판이 부여하는 고정 번호로, 게임 내내 바뀌지 않습니다. {"t": "act", "tick": 57, "actions": [
{"do": "attack", "unit": 101, "target": 733},
{"do": "train", "unit": 5, "code": "hfoo"},
{"do": "cast", "unit": 7, "spell": "thunderbolt", "target": 733},
{"do": "move", "unit": 102, "x": -5000, "y": 2000}]} category == "command"인 것들이며, 파라미터 이름도 같습니다. 늦게 도착한 act는 패스로 처리합니다. 이것들을 여러분의 Agent에게 건네세요
모두 일반 텍스트나 JSON이며, 로그인도 렌더링도 없습니다. Agent가 바로 가져가면 됩니다.
| 사용 중인 도구 | 연결 방법 | 적합한 용도 |
|---|---|---|
| Claude Code / Cursor / Codex 등 Coding Agent | 저장소 디렉터리에서 열고 매뉴얼, api.json, 예제를 읽게 합니다. 직접 게임을 돌리고, 보고서를 읽고, 반복 개선할 수 있습니다 | Bot 작성, 자율 반복 |
| 인터넷에 접속할 수 있는 대화형 모델 | 먼저 war3ai.com/ko/llms-full.txt 파일을 읽게 합니다 | Bot 작성 |
| 인터넷에 접속할 수 없는 대화형 모델 | 매뉴얼, api.json, 예제 하나를 프롬프트에 붙여 넣습니다 | Bot 작성 |
| 로컬 모델(LM Studio / Ollama) | OpenAI 호환 API. MoE 모델을 권장하며 사고 단계는 끕니다 | 참모, 대사(지연에 민감) |
| 클라우드 API(Claude / GPT / Gemini / DeepSeek…) | OpenAI 호환 API 또는 각 사 SDK. 참모 레이어는 비동기이므로 몇 초 지연은 괜찮습니다 | 참모, 향후 직접 대전 |
| MCP를 지원하는 클라이언트(Claude Code / Claude Desktop…) | tools/war3_mcp.py 연결: 도구 10개로 게임 상황 보기, 명령, 플레이어에게 묻기, 스크린숏 | 플레이하면서 지휘, 같이 플레이, 해설 |
| 모든 언어 / 브라우저 / 다른 컴퓨터 | WebSocket / JSON 게이트웨이: Python SDK와 이름도 인자도 같음. JS 클라이언트와 데모 페이지 포함 | 나만의 도구와 UI, 원격 Bot |