문서 가이드

디버깅과 성능

틱이 왜 느린지, 명령이 왜 먹히지 않는지, 게임이 왜 멈춰 있는지. 증상별로 점검하고 내장된 실게임 검증 스크립트로 확인합니다.

회신 확인하기

모든 명령의 회신이 가장 직접적인 단서입니다.

r = g.cast(hero, "blizzard", x=tx, y=ty)
if not r:
    print(r.reason, r.verdict)     # rejected(…)와 사유 코드
print(r.exec_us, r.engine_us)      # 이 명령이 게임 스레드에서 실행된 마이크로초 / 그중 엔진의 명령 함수 자체가 쓴 시간

정상이라면 명령 하나가 게임 스레드에서 몇 마이크로초에서 수백 마이크로초가 걸립니다. 배치 블록이 끝나면 g.last_receipts에 이번 배치의 명령별 회신이 들어 있습니다.

게임 안에서 보기

g.say(unit, "후퇴")              # 유닛 머리 위에 채팅 말풍선 표시(게임에 영향 없음)
g.message("크립 사냥 시작")      # 왼쪽 아래 메시지 영역에 한 줄 출력(로컬에서만 보임)

print한 내용은 Bot을 실행하는 터미널에 출력됩니다. 매 틱의 핵심 결정을 출력하고 머리 위 말풍선과 함께 보면 코드를 읽는 것보다 훨씬 빠릅니다.

틱이 느릴 때

먼저 다음 경우에 해당하는지 확인하세요.

원인해결 방법
명령을 하나씩 보내 매번 한 프레임씩 기다림with g.batch():로 감싸면 수십 개도 한 번만 기다림
g.visible() / g.can_do()를 하나씩 호출(매번 고속 레인으로 한 프레임 대기)가시성은 스냅샷의 u.visible_to()로, 실행 가능성은 g.can_do_many([...])로 한꺼번에 질의
on_tick 안에서 sleep하거나 대기게임 시간을 기록해 두고 다음 틱에 다시 판단
비싼 계산(경로 탐색, 전체 맵 스캔)을 매 틱 다시 수행결과를 캐시하고 몇 틱마다 다시 계산. g.grid()는 자체 2초 캐시가 있고, g.stats()의 기술 레벨은 5초에 한 번 캐시

게임이 멈춤 / Bot이 게임 진입을 기다리기만 함

증상대개 원인
계속 “게임 진입 대기”인스턴스 번호가 틀림. 또는 게임 창이 최소화됨 — 최소화하면 게임 시뮬레이션이 멈춤(시계가 흐르지 않음)
게임은 돌아가는데 Bot 명령에 반응이 없음다른 플레이어의 유닛에 명령 중(회신 not_owner). 또는 Bot이 observer 역할로 연결됨(forbidden)
명령이 held됨더 높은 우선순위의 레이어(레퍼런스 브레인의 반사 레이어, 콘솔의 수동 명령)가 이 유닛을 점유하고 있어 전송되지 않음
일시 정지 후에도 명령이 내려짐정상: 일시 정지 중에는 엔진 시계가 멈추지만, 이벤트 디스패치는 계속 돌고 명령도 그대로 실행됨

연결해서 상태 보기

python -m openwar3 status --inst 5

연결 상태를 출력합니다. 게임 pid, 월드 발행 주기와 수집 1회당 소요 시간, 고속 레인 카운터, 게임 중인지 여부, 유닛 수, 게임 시계.

실게임 검증 스크립트

테스트 인스턴스를 하나 띄우고, SDK 기능이 여러분의 컴퓨터에서 정상 동작하는지 항목별로 확인합니다.

python tools/sdk_live_check.py --inst 20                 # 전체
python tools/sdk_live_check.py --inst 20 --only prod     # 한 섹션만 검증

섹션은 배치, 시간, 생산, 대기열 명령, 전투 속성, 경로 탐색, 공정 모드입니다. 각 섹션은 실제 대전에서 명령을 내리고 효과를 다시 읽어 통과 개수를 출력합니다.

오프라인 테스트는 게임을 띄울 필요가 없습니다.

python tools/run_tests.py

흔한 “버그처럼 보이는 것”

  • 건설 회신은 수락됐는데 건설 부지가 끝내 생기지 않음: 숲속 지점도 엔진은 그 자리에서 수락하고, 일꾼이 도착해서야 실패합니다. build_near를 쓰세요. 실패한 지점을 추적해 한동안 블랙리스트에 올립니다.
  • 스킬 회신은 수락됐는데 시전되지 않음: 끊겼거나 마나가 부족합니다. 시전 후 다음 틱에 g.cooldown()이 쿨다운에 들어갔는지 확인하세요.
  • 공격 명령이 수락됐는데 병력이 다른 적을 공격함: 특정 대상을 공격하려면 g.attack(병력, 적)(우클릭과 같은 의미)을 써야 합니다. 원시 공격 오더는 대상에 대해 오더만 바꾸고 대상을 기록하지 않아서, 근처의 다른 적을 공격합니다.
  • 일꾼 수가 맞지 않음: 금광에 들어간 일꾼은 스냅샷에 없습니다.
  • 죽은 영웅을 훈련할 수 없음: 영웅은 유일하므로 g.revive(제단)을 써야 합니다. 부활에는 식량이 필요하고, 사망 후 약 3게임초가 지나야 부활할 수 있습니다.