본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 06. 07. 21:36

Slay the Spire 2의 게임 상태를 LLM에 전달하여 AI 군사를 만든 이야기

요약

Slay the Spire 2의 게임 상태를 구조화된 데이터로 변환하여 LLM에 전달하고, 최적의 플레이 전략을 조언받는 'AI 군사' 애플리케이션 구현 사례를 소개합니다. STS2MCP 모드를 활용해 게임 데이터를 취득하고 프롬프트에 따라 상황별 맞춤형 조언을 제공합니다.

핵심 포인트

  • STS2MCP를 통한 게임 상태의 구조화된 데이터 변환
  • 상황별(전투, 이벤트 등) 맞춤형 프롬프트 전환 메커니즘
  • MCP 서버 활용을 통한 Claude Desktop 등과의 연동 가능성
  • 방송 송출을 고려한 TTS 및 OBS 연동 기능 구현

Slay the Spire 2를 플레이하면서 문득 이런 생각이 들었습니다.

"이거, AI에게 손패나 적의 정보를 전달하면 어떤 판단을 내릴까?"

로그라이크 카드 게임(Roguelike Card Game)은 매 턴 상황이 변합니다.

손패, 에너기(Energy), 적의 행동, HP, 덱(Deck), 유물(Relic), 포션(Potion), 이벤트 선택지 등 판단 재료가 매우 많습니다.

그래서 이번에는 Slay the Spire 2의 플레이 상황을 AI에게 전달하여 다음 행동을 상담할 수 있는 애플리케이션을 만들어 보았습니다.

STS2MCP는 게임 내 상태를 로컬 API를 통해 취득하거나, 외부 도구로부터 게임에 대한 조작을 보낼 수 있는 Mod입니다.

나아가 MCP 서버로서도 이용할 수 있기 때문에, Claude Desktop이나 Claude Code와 같은 MCP 대응 클라이언트로부터 게임 상태를 다룰 수도 있습니다.

이번에 만든 앱에서는 STS2MCP를 "게임 상태를 취득하기 위한 기반"으로 사용하고, 그 위에 다음과 같은 메커니즘을 구현했습니다.

  • 현재의 게임 상태를 취득한다
  • 전투·이벤트·카드 선택·휴식처 등 장면마다 프롬프트(Prompt)를 전환한다
  • AI가 "다음에 무엇을 해야 하는지"를 방송용으로 알기 쉽게 반환한다
  • OBS의 텍스트 표시나 읽어주기(TTS)와 연동한다
  • 필요에 따라 핫키(Hotkey)로 재질의할 수 있다

이 기사에서는 STS2MCP를 사용하여 게임 상태를 취득하고, 이를 LLM에 전달하여 "AI 군사"로서 방송에 편입시키기까지의 흐름을 정리합니다.

만든 것은 Slay the Spire 2의 플레이를 서포트하는 "AI 군사" 앱입니다.

플레이어가 게임을 진행하면 앱 측에서 현재 상황을 취득하여 AI에게 질의합니다.

AI는 그 상황을 바탕으로 다음과 같은 조언을 반환합니다.

  • 이번 턴에 사용해야 할 카드
  • 공격과 방어의 우선순위
  • 이벤트 선택지의 추천
  • 획득해야 할 카드
  • 휴식처에서 회복할지, 강화할지
  • 향후 덱(Deck) 방침

게임 방송에서 사용하는 것도 상정하고 있기 때문에, 답변은 너무 길지 않게 시청자에게도 알기 쉬운 형태로 다듬고 있습니다.

예를 들면 다음과 같은 이미지입니다.

【군사】
작전: 우선은 피격 데미지를 억제하면서, 다음 턴 이후의 화력으로 연결한다.
대상: 방어 카드를 우선시하고, 남은 에너지로 공격.
...

이번 앱에서는 Slay the Spire 2의 게임 상태를 취득하기 위해 STS2MCP를 이용하고 있습니다.

STS2MCP는 Slay the Spire 2의 게임 내 상태를 외부 도구에서 다룰 수 있게 하는 Mod입니다.

주로 다음과 같은 정보를 취득할 수 있습니다.

  • 현재 상태
  • 전투 중인 플레이어 정보
  • 손패
  • 적의 정보
  • 이벤트 정보
  • 선택지
  • 유물(Relic)
  • 포션(Potion)
  • 덱(Deck) 정보

또한 외부 도구로부터 조작을 보낼 수도 있기 때문에, 단순한 상태 취득뿐만 아니라 AI 에이전트(AI Agent)에 의한 자동 플레이에도 응용할 수 있는 구성으로 되어 있습니다.

이번 앱에서는 갑자기 완전 자동 플레이를 목표로 하는 것이 아니라, 우선은 "AI가 판단하고 인간이 조작하는" 형태로 만들었습니다.

즉, STS2MCP를 사용하여 게임 상태를 취득하고, 그 상태를 AI에게 전달하여 AI로부터 조언을 받는 구성입니다.

Slay the Spire 2
↓
STS2MCP
...

개인적으로는 이 부분이 상당히 흥미로운 포인트였습니다.

STS2MCP를 통해 게임의 상태를 "인간이 화면을 보고 판단하는 정보"에서 "프로그램이 다룰 수 있는 구조화된 데이터(Structured Data)"로 변환할 수 있습니다.

그렇기 때문에 LLM에 대해서도,

"지금 이런 상황입니다. 다음에 무엇을 해야 합니까?"

라고 상당히 구체적으로 물어볼 수 있게 됩니다.

대략적인 구성은 다음과 같습니다.

Slay the Spire 2
↓
STS2MCP
...

앱 측에서는 현재의 상태를 다음과 같은 종류로 분류하고 있습니다.

  • 전투 중
  • 이벤트 중
  • 카드 선택
  • 휴식처
  • 보상 선택
  • 기타 상태

상태에 따라 AI에게 물어봐야 할 내용이 달라지기 때문에, 단일 프롬프트로 모든 것을 처리하는 것이 아니라 장면마다 프롬프트를 나누는 방침으로 정했습니다.

우선 STS2MCP가 공개하고 있는 로컬 API로부터 현재의 게임 상태를 취득합니다.

실제 엔드포인트(Endpoint) 명칭은 이용 중인 버전이나 구성에 따라 달라질 가능성이 있지만, 이미지는 다음과 같은 처리입니다.

import requests
STS2MCP_BASE_URL = "http://127.0.0.1:8080"

def fetch_game_state() -> dict:
    response = requests.get(
...

이 처리로 취득한 JSON을 이후 AI 판단의 입력으로 사용합니다.

포인트는 화면 캡처나 OCR이 아니라, 게임 상태를 구조화된 데이터 (Structured Data)로 취득할 수 있다는 점입니다.

화면을 이미지로서 AI에게 보여주는 방법도 있지만, 카드 이름, 적의 HP, 선택지, 이벤트 정보 등을 텍스트·JSON으로 다룰 수 있는 편이 프롬프트 (Prompt)에組み込み(組み込み, 포함시키기)하기 더 쉽습니다.

STS2MCP에서 취득한 게임 상태에는 현재의 상태를 나타내는 정보가 포함됩니다.

이 상태를 바탕으로 어떤 프롬프트를 사용할지 전환합니다.

def build_prompt(game_state: dict) -> str:
    state_type = game_state.get("state_type")
    if state_type == "combat":
...

전투 중이라면 "어떤 카드를 어떤 순서로 사용할 것인가"가 중요해집니다.

이벤트 중이라면 "어떤 선택지를 골라야 하는가"가 중요해집니다.

카드 보상이라면 "지금의 덱 방침에 맞는 카드는 무엇인가"가 중요해집니다.

단일 프롬프트로 모든 것을 처리하는 것보다, 상황에 따라 AI에게 전달하는 관점을 좁히는 편이 답변이 안정되기 쉬워졌습니다.

전투 중에는 패, 에너지, 적의 행동 예정, HP 등을 바탕으로 판단하도록 합니다.

def build_combat_prompt(game_state: dict) -> str:
    player = game_state.get("player", {})
    hand = game_state.get("hand", [])
...

AI에게 "자유롭게 생각해"라고 던지는 것이 아니라, 판단 방침과 출력 형식 (Output Format)을 지정하고 있는 점이 포인트입니다.

특히 방송에서 사용할 경우, AI의 답변이 너무 길면 템포가 나빠집니다.

그렇기 때문에 다음과 같이 출력 형식을 고정하고 있습니다.

작전:
카드 사용 순서:
이유:

이를 통해 OBS 표시도 쉬워졌고, 읽어주기(TTS)에도 사용하기 좋아졌습니다.

이벤트 중에는 전투와는 판단 기준이 달라집니다.

필요한 것은 카드의 사용 순서가 아니라, 선택지별 리스크와 리턴입니다.

def build_event_prompt(game_state: dict) -> str:
    event = game_state.get("event", {})
    player = game_state.get("player", {})
...

이벤트에서는 선택지 이름만 전달하면 AI가 판단하기 어려워하는 경우가 있었습니다.

예를 들어, 선택지의 타이틀만으로는 그것이 유물 (Relic) 획득인지, HP를 잃는 것인지, 카드를 추가하는 것인지 알 수 없습니다.

따라서 선택지별 설명이나 효과도 포함하여 전달하도록 했습니다.

def format_event_options(options: list[dict]) -> str:
    lines = []
    for option in options:
...

STS2MCP로부터 취득할 수 있는 구조화된 이벤트 정보가 있음으로써, 선택지의 비교를 AI에게 맡기기가 쉬워졌습니다.

STS2MCP를 사용함으로써 게임 화면을 인간이 육안으로 보고 판단하는 것뿐만 아니라, 게임 상태를 외부 애플리케이션에서 다룰 수 있게 됩니다.

이것은 상당히 큽니다.

예를 들어, 통상적으로 AI에게 게임 상황을 전달하려면 화면 캡처를 사용하거나 수동으로 상황을 적어야 할 필요가 있습니다.

하지만 STS2MCP를 사용하면 패, 적, 이벤트, 선택지 등을 구조화된 데이터로 취득할 수 있습니다.

그렇기 때문에 LLM에 대해서도 상당히 구체적으로 상황을 전달할 수 있습니다.

"지금 패는 이것입니다."
"적은 이 행동을 예정하고 있습니다."
"플레이어의 HP는 이 정도입니다."
"선택지는 이 세 가지입니다."
"이 상황에서 가장 좋은 행동을 판단해 주세요."

이런 형태로 만들 수 있으면 AI의 답변도 상당히 안정됩니다.

한편, STS2MCP가 취득해 주는 정보를 그대로 던지면 완벽하다는 뜻은 아니었습니다.

AI에게 전달하기 전에,

  • 어떤 정보가 판단에 필요한가
  • 어떤 정보는 생략해도 되는가
  • 지금이 전투인가 이벤트인가
  • 최종적으로 어떤 형식으로 답변해주길 원하는가

를 애플리케이션 측에서 정리할 필요가 있습니다.

즉, STS2MCP는 「게임 상태를 취득하는 계층 (Layer)」이며, 이번에 만든 앱은 「AI가 판단하게 하고, 방송에서 사용할 수 있는 형태로 변환하는 계층 (Layer)」이라는 위치에 있습니다.

이렇게 역할 분담을 하니 상당히 다루기 쉬워졌습니다.

AI의 답변은 OBS 상에 표시할 수 있도록 텍스트 파일로 출력하고 있습니다.

OBS 측에서는 해당 텍스트 파일을 읽어 들임으로써, 방송 화면 상에 AI의 조언을 표시할 수 있습니다.

또한, 읽어주기 용도로 VOICEVOX 등의 음성 합성 (Speech Synthesis)과 조합함으로써, AI가 실제로 말하고 있는 듯한 연출도 가능하게 했습니다.

다만, 읽어주기용 문장에는 약간의 정형화 (Formatting)가 필요했습니다.

예를 들어, 화면 표시용으로는 다음과 같은 헤더가 있으면 보기 좋습니다.

작전:
대상:
이유:

반면, 읽어줄 때는 그대로 두면 부자연스러워지는 경우가 있습니다.

그렇기 때문에, 읽어주기 전에는 다음과 같은 변환을 넣고 있습니다.

text = text.replace("작전:", "작전.")
text = text.replace("대상:", "대상.")
text = text.replace("이유:", "이유.")

세세한 부분이지만, 방송에서 사용할 경우에는 이러한 조정이 상당히 효과적입니다.

OBS의 텍스트가 업데이트되지 않는 것처럼 보이는 문제가 있었습니다.

조사해 보니, 핫키 (Hotkey)로 질의한 답변 자체는 생성되고 있지만, 그 직후에 다음 자동 처리가 실행되어 표시 내용이 덮어씌워지고 있었습니다.

따라서 수동 질의 중에는 자동 질의를 일시적으로 멈추거나, 수동 질의 결과를 우선 표시하는 등의 제어가 필요해졌습니다.

이벤트에서는 선택지의 효과를 AI가 올바르게 이해할 수 있는지가 중요했습니다.

선택지 이름만 전달하면, AI가 효과를 추측해 버리는 경우가 있습니다.

그렇기 때문에 다음과 같은 정보를 가급적 세트로 전달하도록 했습니다.

  • 선택지 이름
  • 설명
  • 효과
  • 선택 가능 여부
  • 획득할 수 있는 카드나 유물 (Relic)
  • HP 변동
  • 잠금 (Lock) 상태

AI에게 판단을 맡길 때도, 입력 데이터의 구조화 (Structuring)가 상당히 중요하다는 것을 느꼈습니다.

LLM은 유연하게 답변해 주지만, 게임 공략에서는 일관성 (Consistency)도 중요합니다.

따라서 다음과 같은 제약을 넣는 것이 안정적이었습니다.

  • 우선 현재의 생존을 우선할 것
  • 리스크가 높은 선택지는 이유를 명기할 것
  • 카드 선택 시에는 현재의 덱 (Deck) 방침에 맞는지 확인할 것
  • 불확실한 정보는 단정 짓지 말 것
  • 최종적인 권장 행동을 하나로 좁힐 것

AI에게 자유롭게 생각하게 하는 부분과, 앱 측에서 규칙화하는 부분의 균형이 중요했습니다.

게임과 AI의 궁합은 상당히 좋다고 느꼈습니다.

특히 Slay the Spire와 같은 카드 게임은 상황 판단의 연속입니다.

AI에게 현재 상태를 전달함으로써, "왜 그 카드를 사용하는지", "왜 그 선택지를 고르는지"를 언어화해 줍니다.

이는 공략 지원으로서도 재미있지만, 방송 콘텐츠로서도 상당히 궁합이 좋습니다.

플레이어가 AI와 상담하며 진행함으로써, 시청자도 "AI는 그렇게 생각하는구나", "아니, 그건 아니지"라며 딴지를 걸며 볼 수 있습니다.

단순한 자동 플레이가 아니라, 인간과 AI가 함께 고민하는 형태로 만들 수 있다는 점이 재미있는 포인트였습니다.

향후에는 다음과 같은 개선을 생각하고 있습니다.

  • 과거의 판단 이력을 AI에게 전달
  • 덱 방침을 장기 기억 (Long-term Memory)으로 갖게 함
  • 보스나 엘리트(Elite)를 향한 중장기 전략을 생각하게 함
  • AI의 판단과 실제 결과를 비교
  • 시청자 댓글을 AI의 판단 재료로 포함
  • AI의 인격(Persona)을 더욱 방송용으로 조정
  • 답변의 우선순위나 긴급도를 낼 수 있도록 함
  • STS2MCP의 조작 API도 활용하여, 장래에는 일부 조작의 자동화도 시도

특히 단발적인 판단뿐만 아니라 "이번 런 (Run)에서는 무엇을 목표로 하고 있는가"를 AI가 갖게 하면, 더욱 군사(Strategist)다워질 것 같습니다.

또한, 이번에는 "AI가 판단하고 인간이 조작하는" 형태였지만, STS2MCP는 외부 툴로부터 조작을 보낼 수도 있기 때문에, 장래에는 AI 에이전트 (AI Agent)에 의한 반자동 플레이나 검증으로도 확장할 수 있을 것 같습니다.

Slay the Spire 2의 게임 상태를 AI에게 전달하여, 공략 방침을 제안받는 앱을 만들었습니다.

구현해 보니 단순히 LLM API를 호출하는 것뿐만 아니라, 다음과 같은 점이 중요했습니다.

  • 게임 상태를 AI가 이해하기 쉬운 형태로 정리하기
  • 장면마다 프롬프트 (Prompt)를 전환하기
  • 방송에서 사용하기 쉬운 짧은 답변으로 다듬기
  • OBS 및 음성 읽어주기와 연동하기
  • 자동 질의와 수동 질의의 충돌을 제어하기

게임 AI라고 하면 자동 조작의 이미지가 있지만, 이번처럼 "함께 생각하는 AI"로서 구현하는 것만으로도 상당히 흥미로운 경험이 됩니다.

앞으로도 게임 방송과 AI를 결합한 실험을 계속 이어가고 싶습니다!

실제 동작을 확인하고 싶은 분들은 YouTube에 영상을 게시하고 있으니, 관심 있는 분들은 이쪽을 확인해 주세요!

AI 자동 생성 콘텐츠

본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0