블로그 #9: 마인크래프트 모드에 서버리스(Serverless) 두뇌를 부여했습니다 — 플레이어가 얼마나 위기에 처했는지에 따라 소환할 아군
요약
마인크래프트 모드에 AWS 서버리스 환경과 AI 에이전트를 결합하여, 플레이어의 전투 상황을 실시간으로 분석하고 적절한 아군 수를 결정하는 시스템을 구현했습니다. API 키와 클라우드 API 요청기 블록을 통해 게임 내 아이템을 클라우드 서비스와 연동하는 독특한 메커니즘을 소개합니다.
핵심 포인트
- AWS Lambda 기반의 서버리스 백엔드를 활용한 AI 에이전트 구현
- 플레이어의 체력, 주변 환경 등 전투 컨텍스트를 AI에 전달하여 의사결정 수행
- 게임 내 아이템과 클라우드 API를 연동하는 독창적인 CI/CD 개념 도입
- API 호출 제한(Rate Limit)을 게임 내 아이템 충전 횟수로 시뮬레이션
마인크래프트 모드에 서버리스(Serverless) 두뇌를 부여했습니다 — 플레이어가 얼마나 위기에 처했는지에 따라 소환할 아군 수를 결정합니다
Cloud Swords Mod — 블로그 9
저는 게임 플레이를 통해 클라우드 컴퓨팅 (Cloud Computing)을 가르치는 마인크래프트 (Minecraft) 모드를 만들고 있습니다. AWS 서비스의 이름을 딴 검들, 네트워크 인프라 (Network Infrastructure)처럼 작동하는 에너지 시스템, 클라우드 자격증을 거래하는 마을 주민들 같은 것들 말이죠.
하지만 버전 0.3.8부터 상황이 묘하게 변했습니다. 저는 이 모드를 클라우드에서 실행되는 실제 AI 에이전트 (AI Agent)에 연결했습니다. 이제 Lambda의 검 (Sword of Lambda)을 휘두르면, 정해진 수의 미니언을 생성하는 대신 AI가 당신의 전투 상황을 평가하여 얼마나 많은 아군이 필요한지 결정합니다.
게임은 절대 멈추지 않습니다. AI는 게임의 밸런스를 절대 깨뜨리지 않습니다. 그리고 이 모든 것은 비용이 거의 들지 않는 서버리스 (Serverless) 백엔드에서 실행됩니다.
제가 이것을 어떻게 만들었는지 소개합니다.
작동을 가능하게 하는 아이템들
API 키의 서 (Tome of API Key)
모든 클라우드 연결은 인증 (Authentication)에서 시작됩니다. 모드 내에서는 이것이 **API 키의 서 (Tome of API Key)**로 구현되어 있습니다. 이는 던전 상자에서 발견되는 희귀한 유물입니다 (요새(Bastion), 엔드 시티(End City), 네더 요새(Nether Fortress)에서 8% 확률로 드롭).
처음 아이템을 획득하면 고유한 API 키 (csk-XXXX 형식)를 생성하고 100회의 충전 횟수를 보여줍니다. 마법 부여의 반짝임과 함께 빛이 납니다. 이것은 클라우드로 향하는 당신의 여권입니다.
// 첫 인벤토리 틱(tick) 발생 시, 고유 키 생성
if (!stack.getNbt().contains("api_key")) {
String key = "csk-" + UUID.randomUUID().toString().substring(0, 8);
...
툴팁에는 키 미리보기, 남은 충전 횟수, 연결 상태가 표시됩니다. 충전 횟수가 0이 되면, 실제 API에서 속도 제한 (Rate Limit)에 걸리는 것처럼 클라우드가 당신의 호출을 거부합니다.
클라우드 API 요청기 (Cloud API Requester) (블록)
**클라우드 API 요청기 (Cloud API Requester)**는 마인크래프트와 AWS 사이의 가교 역할을 합니다. 이것은 제작 가능한 블록 (철 + 회로 기판 + 레드스톤 + 엔더 진주 + 데이터 코어)이며 두 개의 슬롯을 가지고 있습니다:
- 당신의 API 키의 서 (Tome of API Key)
- 클라우드 기능을 활성화하고 싶은 무기
두 가지를 모두 넣고 약 8초( "배포 타이머 (deployment timer)" ) 동안 기다리면, 무기의 NBT 데이터에 cloud_enabled=true가 표시됩니다. 이제 툴팁(tooltip)에 청록색으로 "☁ Cloud Enabled"라고 표시됩니다.
이것이 이 모드의 CI/CD 파이프라인입니다. 당신은 무기를 클라우드에 배포하고 있는 것입니다.
클라우드 활성화 무기 (Cloud-Enabled Weapons)
클라우드가 활성화되면, Sword of Lambda의 동작 방식이 완전히 바뀝니다. 하드코딩된 숫자의 미니언을 소환하는 대신, 다음과 같이 동작합니다:
- 당신의 전투 컨텍스트(combat context)를 백엔드(backend)로 전송합니다 (체력, 주변 몹, 바이옴, 차원 등)
- 액션바(actionbar)에 "☁ Cloud invocation sent..."를 표시합니다
- AI의 결정을 기다립니다
- 결정을 적용합니다: "☁ Cloud decided: 5 minions (Critical threat — max invocations)"
클라우드가 활성화되지 않은 상태라면, 검은 이전과 정확히 동일하게 작동합니다. 하위 호환성(Backward compatible)이 유지되므로 클라우드가 필요하지 않습니다.
아키텍처 (The Architecture)
┌─────────────────────────────────────────────────────────────┐
│ MINECRAFT CLIENT │
│ │
...
비동기 패턴: Fire-and-Forget + 폴링 (The Async Pattern: Fire-and-Forget + Polling)
게임은 네트워크 응답을 기다리느라 절대로 멈춰서는(freeze) 안 됩니다. 그래서 저는 실시간 애플리케이션에서 사용하는 것과 동일한 패턴을 사용했습니다:
- Fire (발사): 이벤트를 전송하고 즉시
request_id를 받습니다. - Forget (망각): 게임 플레이를 계속하며, 차단(block)하지 않습니다.
- Poll (폴링): 2초마다 (
ServerTickEvents를 통해) 결과가 준비되었는지 확인합니다. - Apply (적용): 준비되면 서버 스레드(server thread)를 위한 콜백(callback)을 큐(queue)에 넣습니다.
// CloudApiClient — non-blocking
public void sendEvent(JsonObject context) {
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString())
...
스레딩(threading) 수정이 매우 중요했습니다. Java의 HttpClient는 자체적인 비동기 스레드(async thread)에서 콜백을 실행하지만, Minecraft 엔티티 소환은 반드시 서버 스레드(server thread)에서 이루어져야 합니다. ConcurrentLinkedQueue 브릿지가 없었다면 버프(buffs)가 적용되지 않았을 것이고, 엔티티가 게임을 충돌(crash)시켰을 것입니다.
AI 에이전트: Strands + Ollama Cloud
두뇌는 Ollama Cloud(무료 티어 — 개발 시 Bedrock 비용 발생 없음)를 통해 gpt-oss:20b를 실행하는 Strands Agent입니다:
from strands import Agent
from strands.models.ollama import OllamaModel
...
에이전트는 다음과 같은 컨텍스트 (context)를 받습니다:
{
"player": "Carlos",
"weapon": "sword_of_lambda",
...
그리고 다음과 같이 응답합니다:
{"action": "summon", "count": 5, "duration": 10, "reason": "Critical threat"}
시스템 프롬프트 (system prompt)는 제한된 행동 (bounded actions)을 강제합니다. AI는 상한선이 정해진 값과 고정된 행동 세트 내에서만 선택할 수 있으므로 게임의 밸런스를 무너뜨릴 수 없습니다.
CDK 스택 (The CDK Stack)
프로덕션 백엔드는 단일 CDK 스택입니다:
class CloudSwordsStack(Stack):
def __init__(self, scope, id, **kwargs):
super().__init__(scope, id, **kwargs)
...
사용 계획 (usage plan)은 단순한 인프라가 아니라 게임 플레이 메커니즘입니다. 하루 100회의 요청 제한은 클라우드를 스팸처럼 사용할 수 없음을 의미합니다. 실제 API 예산 (API budgets)과 마찬가지로, 언제 호출할지 전략적으로 결정해야 합니다.
로컬 개발: 모의 서버 (The Mock Server)
개발을 위해 Strands Agent를 직접 통합하는 모의 서버 (mock server)를 실행합니다:
# mock_server.py — localhost:8777
agent = None
try:
...
모의 서버는 모든 상호작용을 interactions.json에 기록하며, 이는 블로그 #10을 위한 평가 데이터셋 (eval dataset)이 됩니다.
게임 플레이를 통해 배운 클라우드 개념
| 게임 메커니즘 | 클라우드 개념 |
|---|---|
| API 키의 서 (Tome of API Key) | API 키 + 인증 (authentication) |
| ... |
내가 배운 것
-
마인크래프트의 스레딩(Threading)은 가혹합니다 — 엔티티(entities)에 영향을 주는 모든 요소는 반드시 서버 스레드(server thread) 상에 있어야 합니다. 비동기 HTTP (Async HTTP) + 게임 로직의 조합은 세심한 큐 관리 (queue management)를 요구합니다.
-
게임플레이로서 작동하는 속도 제한 (Rate limiting) — 플레이어들은 제한된 클라우드 호출 (cloud invocations)을 중심으로 자연스럽게 전략을 세웁니다. 이는 강의 없이도 자원 관리 (resource management)를 가르쳐 줍니다.
-
시스템 프롬프트 (system prompts)를 통한 AI 가드레일 (guardrails) — 행동 범위 (action space)를 제한(예: 1~5명의 미니언, 특정 버프)하면 AI가 말 그대로 게임을 망가뜨릴 수 없게 됩니다. 최악의 경우에도 3명만 있으면 충분한 상황에서 5명의 미니언을 소환하는 정도에 그칩니다.
-
폴백 패턴 (Fallback patterns)의 중요성 — 클라우드가 다운되더라도 검은 로컬 로직 (local logic)을 통해 여전히 작동합니다. 비디오 게임을 통해 배우는 우아한 성능 저하 (Graceful degradation)입니다.
다음 단계
AI가 결정을 내립니다. 하지만 그 결정이 좋은 결정일까요? 블로그 10에서는 또 다른 AI를 심판으로 사용하여 에이전트의 전투 조언을 판정하는 평가 프레임워크 (evaluation framework)를 구축합니다. 메타(Meta)적이라고요? 물론입니다. 유용하냐고요? 놀랍게도 그렇습니다.
코드:
- 모드(Mod): cloud-swords-mod-1.20.1
- 백엔드(Backend): cloud-swords-backend-cdk
- 에이전트(Agent): cloud-swords-strands-agent
저는 Carlos Cortez입니다 — 클라우드 엔지니어이자 게이머이며, 재미 삼아 마인크래프트를 AI 에이전트에 연결하는 사람입니다. 이것은 Breaking the Cloud입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기