API 카탈로그

API 103개, 모두
“검증 여부, 속도, 내부 동작 방식”을 명시

python -m openwar3 catalog --write가 코드에서 생성하며 SDK와 함께 갱신됩니다. 모델은 어떤 메서드가 존재하는지, 어떤 것이 실제로 동작하는지 추측할 필요가 없습니다. 같은 데이터를 JSON으로도 제공하므로 Agent에게 바로 건넬 수 있습니다.

58 관찰
28 명령
9 게임 제어
6 샌드박스
2 연결과 도구
98 실게임 검증
0 실험
5 추정 / 실측 미완
103개

관찰 58

상태를 읽기만 하며 게임을 바꾸지 않습니다. 대부분 푸시 스냅샷을 바로 읽으므로 대기가 없습니다.

맵 전체의 완전한 상태(WorldState): .units .players .items .clock .me. max_age초 안에 다시 호출하면 같은 스냅샷을 반환합니다. ⚠ 금광에 들어간 일꾼은 목록에 없습니다. 기본값은 맵 전체가 보이는 상태입니다(락스텝 모델이라 로컬에 모든 정보가 있음). Game(fair=True)일 때만 시야로 필터링합니다.

내부 메커니즘 W3P 월드 블록 Local\War3World_<pid>(런타임이 50 ms마다 푸시, seqlock)

실게임 검증 푸시 스냅샷

마지막으로 본 적(또는 'creep' 크립, 또는 특정 플레이어 번호) 유닛: [(그때의 유닛 상태, 그때의 게임 시계, 지난 초)], 최신순. 죽는 것을 보면 목록에서 지웁니다. 공정 모드와 일반 모드 모두 "지금 아군이 볼 수 있는가"를 기준으로 기록합니다 — 플레이어 머릿속에 있는 바로 그 지도입니다: 정찰한 병력, 상대 영웅을 마지막으로 본 위치, 상대가 확장 기지를 언제 가져갔는지. max_age를 주면 그 게임 초 이내의 기록만 반환합니다.

내부 메커니즘 푸시 스냅샷의 visibleTo (스냅샷을 갱신할 때마다 보이는 적/크립 유닛을 기록)

실게임 검증 푸시 스냅샷

이번 게임의 지형 테이블 MapInfo: .walkable(x,y) .buildable(x,y) .at(x,y) .bounds (플레이 가능 영역) .starts (시작 지점) .cells (bit0 이동 불가, bit1 건설 불가). 게임 시작 후 계산이 끝나기까지 몇 초 걸리며, 그 전에는 None을 반환합니다. 나무는 포함되지 않습니다(trees() 사용).

내부 메커니즘 W3P 맵 블록 Local\War3Map_<pid>(게임 시작 후 런타임이 나눠서 계산, IsTerrainPathable 이동/건설)

실게임 검증 푸시 스냅샷

내가 몇 번 플레이어인지(0~11).

내부 메커니즘 월드 블록 헤더

실게임 검증 푸시 스냅샷

{'gold','lumber','food_used','food_cap','gold_gathered','lumber_gathered'}. player 기본값은 아군이며, 모든 플레이어를 읽을 수 있습니다. 읽지 못하면 None을 반환합니다. 0으로 취급하지 마세요.

내부 메커니즘 월드 블록 players[16]

실게임 검증 푸시 스냅샷

16개 플레이어 슬롯 전체: Player(id, gold, lumber, food_used, food_cap, gold_gathered, lumber_gathered, race, known).

내부 메커니즘 월드 블록 players[16]

실게임 검증 푸시 스냅샷

핸들 쌍 (lo, hi)로 유닛을 찾습니다(오더 대상, 작업 대상, 이벤트가 주는 값은 모두 핸들 쌍).

내부 메커니즘 월드 블록 by_handle

실게임 검증 푸시 스냅샷

건물인지 여부(타워 포함). 유닛 테이블의 이동 속도가 0인지로 판정합니다. 언데드 본진 건물은 점유 면적이 0이므로 점유 면적으로 판정하지 마세요.

내부 메커니즘 스냅샷 + units.json (spd==0 = 건물)

실게임 검증 푸시 스냅샷

아군 일꾼(농부 / Peon / 시종 / 위습).

내부 메커니즘 푸시 스냅샷

실게임 검증 푸시 스냅샷

할 일이 없는 일꾼: 오더도 없고 작업도 없는 일꾼(이번 틱에 방금 일을 맡긴 일꾼은 제외). ⚠ 작업 중인 일꾼에게 채집 명령을 다시 내리면 채집 주기가 끊깁니다(수입이 0이 됨).

내부 메커니즘 푸시 스냅샷(오더 슬롯 + 작업 슬롯)

실게임 검증 푸시 스냅샷

살아 있는 아군 영웅(죽은 영웅은 제단의 부활 목록에 있음, revive 참고).

내부 메커니즘 푸시 스냅샷

실게임 검증 푸시 스냅샷

아군 전투 유닛: 일꾼도 건물도 아닌 유닛.

내부 메커니즘 푸시 스냅샷 + units.json

실게임 검증 푸시 스냅샷

아군 건물(타워, 건설 중인 기초 포함). types로 특정 종류만 고를 수 있습니다. 예: {'hbar'}.

내부 메커니즘 푸시 스냅샷

실게임 검증 푸시 스냅샷

이 일꾼이 건물을 짓고 있는지(지으러 가는 중 / 수리를 돕는 중 포함, 이번 틱에 방금 맡긴 것도 포함). 건설 일꾼을 고를 때 이 일꾼은 건너뛰어야 합니다. 그렇지 않으면 이전 기초 공사가 멈춥니다.

내부 메커니즘 푸시 스냅샷(오더 = 건물 4자 코드, 또는 건설/수리 오더)

실게임 검증 푸시 스냅샷

이 건물이 아직 완성되지 않았는지(체력이 가득 차지 않음). ⚠ 공격받아 손상된 건물도 체력이 가득 차 있지 않습니다 — 초반 판단에는 충분하지만, 교전이 시작된 뒤에는 시간과 함께 판단하세요.

내부 메커니즘 푸시 스냅샷(기초의 체력이 아주 낮은 값에서 최대치까지 오름)

실게임 검증 푸시 스냅샷

맵 위의 금광. ⚠ 나이트 엘프가 휘감은(Entangle) 금광과 중립 금광은 같은 좌표에 유닛이 하나씩 있습니다. 채집은 자기 쪽 금광으로 보내야 합니다.

내부 메커니즘 푸시 스냅샷(ngol/egol/ugol)

실게임 검증 푸시 스냅샷

크립(중립 적대). ⚠ 밤에는 시야가 짧아져, 먼 캠프가 안개 속으로 들어가면 그 대상에게 내리는 명령이 거부됩니다(원인 코드 1001).

내부 메커니즘 푸시 스냅샷(owner 12 = 중립 적대)

실게임 검증 푸시 스냅샷

{'hp','hp_max','mana','mana_max'}(부동소수점, 엔진 원값). u는 스냅샷에서 얻은 유닛이면 됩니다(최신 값으로 바꿔 읽음).

내부 메커니즘 월드 블록 유닛 hp/hpMax/mana/manaMax

실게임 검증 푸시 스냅샷

{'level','xp','skill_points'}.

내부 메커니즘 월드 블록 유닛 level/xp/skillPoints

실게임 검증 푸시 스냅샷

[{code, level, cooldown, flags}]. 버프는 buffs(u)에 있습니다. "상세 정보"가 있는 유닛에만 있습니다(영웅 > 플레이어 유닛 > 크립, 최대 256개).

내부 메커니즘 월드 블록 상세: 스킬(코드 / 레벨 / 플래그 / 남은 쿨다운)

실게임 검증 푸시 스냅샷

유닛에 걸린 버프 코드(예: 'BHds' Divine Shield, 'Bslo' 감속). 코드별 효과는 data/game/buffs.json 참고.

내부 메커니즘 월드 블록 상세: B로 시작하는 스킬 객체

실게임 검증 푸시 스냅샷

이 스킬의 남은 쿨다운(게임 초). 0 = 사용 가능. 이 스킬이 없으면(또는 이 유닛에 상세 정보가 없으면) None을 반환합니다.

내부 메커니즘 월드 블록 상세: 스킬 남은 쿨다운(스킬 타이머)

실게임 검증 푸시 스냅샷

6칸 아이템의 4자 코드(빈칸은 None). 인벤토리가 없으면 None을 반환합니다.

내부 메커니즘 월드 블록 상세: 인벤토리 6칸

실게임 검증 푸시 스냅샷

{'order','target','x','y'}: 유닛이 지금 수행 중인 오더(order는 0x000D00xx 또는 건물 4자 코드, 0 = 대기). target은 핸들 쌍이며, g.unit(target)으로 유닛으로 바꿉니다.

내부 메커니즘 월드 블록 유닛 오더 / 오더 대상 / 오더 대상 지점

실게임 검증 푸시 스냅샷

유닛이 **실제로 공격하거나 쫓고 있는** 유닛(없으면 None). ⚠ 공격 명령을 내리면 오더 슬롯은 금방 비고 공격은 작업(task)에 걸립니다 — "누구를 공격 중인지"는 current_order가 아니라 이것으로 판단하세요.

내부 메커니즘 월드 블록 유닛 작업 대상

실게임 검증 푸시 스냅샷

엔진 게임 시계(게임 초, 로딩 중에는 0). 배속에서는 실제 시간보다 빠르게 흐릅니다.

내부 메커니즘 월드 블록 헤더 clockMs (엔진 게임 시계)

실게임 검증 푸시 스냅샷

이 건물이 지금 무엇을 만들고 있는지: Production(kind, queue, duration, elapsed, blocked, progress, remaining…). 아무것도 안 하면 None을 반환합니다. kind 'queue'(훈련/연구/영웅, queue는 최대 7칸, [0]이 진행 중) / 'construction'(건설 중) / 'upgrade'(본진 건물/타워 업그레이드); blocked = 대기열은 있지만 시작하지 못함(대개 인구 부족 — 농장을 지을 때입니다); progress 0..1. 상대 건물도 볼 수 있습니다(공정 모드에서는 보이는 건물만).

내부 메커니즘 월드 블록 생산 테이블(Aque/ABnP/AUnP 스킬 객체 + 런타임이 추적한 경과 시간, 실측 오차 < 0.2 게임 초)

실게임 검증 푸시 스냅샷

훈련/연구 대기열의 4자 코드([0]이 진행 중). 대기 중이거나 생산 건물이 아니면 [].

내부 메커니즘 월드 블록 생산 테이블

실게임 검증 푸시 스냅샷

진행 중인 모든 생산 [(건물, Production)]. owner는 units()와 같습니다: 'me' / 'enemy' / 플레이어 번호 / 'all'. 프로의 활용법: 상대가 어떤 유닛을 뽑는지, 어떤 기술을 연구하는지, 언제 테크 업을 하는지 봅니다(건물을 정찰했을 때).

내부 메커니즘 월드 블록 생산 테이블

실게임 검증 푸시 스냅샷

지상 유닛이 a에서 b까지 걸어가는 거리(a, b는 유닛 또는 (x,y)). 갈 수 없으면 None. 섬 맵에서 "이 크립 캠프/확장 기지에 지상으로 갈 수 있는가"를 판단할 때 쓰세요. 직선 거리보다 믿을 만합니다(숲, 절벽, 건물을 돌아감). 정밀도는 한 칸 128이며, 한 칸보다 좁은 틈은 막힌 것으로 판정합니다.

내부 메커니즘 맵 블록(엔진 IsTerrainPathable) + 트리 블록 + 건물 점유 면적, SDK 측 A*(128당 한 칸)

실게임 검증 푸시 스냅샷 + 로컬 계산

지상으로 갈 수 있는지 여부(맵 블록 계산 전 = None).

내부 메커니즘 위와 같음

실게임 검증 푸시 스냅샷 + 로컬 계산

경로의 꺾이는 지점 [(x,y)...](마지막 점이 b). path(units, 지점 목록)와 함께 쓰면 부대가 이 경로를 따라 이동합니다(타워를 피하고 샛길로).

내부 메커니즘 위와 같음

실게임 검증 푸시 스냅샷 + 로컬 계산

유지비 단계: {'level': 'none'/'low'/'high', 'income': 1.0/0.7/0.4, 'next_at': 다음 단계의 인구(없으면 None)}. 프로의 상식: 3티어 테크 업이나 공격/방어 업그레이드 중에는 인구 50에서 멈추고, 결전 직전에야 80까지 늘립니다.

내부 메커니즘 1.27 고정 규칙: 인구 0~50은 유지비 없음, 51~80은 수입 ×0.7, 81~100은 ×0.4

추정 푸시 스냅샷

영웅이 다음 레벨까지 필요한 경험치(10레벨 = 0).

내부 메커니즘 월드 블록 level/xp + MiscGame NeedHeroXP 공식

실게임 검증 푸시 스냅샷

필드의 (보이는) 크립을 캠프로 묶습니다: [{'x','y','units','level','hp','max_level'}], 아군 본진에서 가까운 순. level = 캠프 총 레벨(사냥 난이도를 흔히 재는 기준), hp = 총 체력. time_to_kill / path_distance와 함께 사냥할 곳을 고르세요.

내부 메커니즘 푸시 스냅샷(크립을 600 거리 기준으로 한 무리로 묶음) + units.json 레벨

실게임 검증 푸시 스냅샷

버프 코드가 무엇인지: {'ability','effect','dur','hero_dur','targets'}(예: 'Bslo' -> 감속). 한 코드에 여러 행이 있으면 첫 행을 반환합니다.

내부 메커니즘 data/game/buffs.json (AbilityData.slk의 BuffID -> 스킬/효과/지속 시간)

실게임 검증 로컬 데이터

유닛의 전투 속성 combat.UnitStats: 체력/마나 최대치, 방어력(공격/방어 업그레이드, 영웅 민첩 포함), 방어 타입, 이동 속도, 낮/밤 시야, 무기(공격 가능 대상, 사거리, 공격 간격, 피해량 범위, 공격 타입, 스플래시). u는 유닛(소유자의 기술과 영웅 레벨을 자동 적용) 또는 4자 코드(player 기본값은 아군). .dps_vs(상대) / .hits_to_kill(상대) / combat.time_to_kill(무리, 상대)와 함께 쓰세요. ⚠ 아이템, 오라, 버프는 반영하지 않습니다.

내부 메커니즘 데이터 테이블(UnitBalance/UnitWeapons/UpgradeData/MiscGame) + 실시간 기술 레벨 + 영웅 레벨

실게임 검증 푸시 스냅샷 + 고속 레인(5초마다 한 배치)

이 유닛 무리가 함께 target을 공격해 죽이는 데 걸리는 게임 초(target의 현재 체력 기준. 상성, 방어력, 공격/방어 업그레이드는 반영하고 무빙, 스플래시, 치유는 반영하지 않음). 프로의 활용법: 점사는 가장 가까운 적이 아니라 "가장 빨리 죽일 수 있는" 적(time_to_kill이 가장 작은 적)부터. 공격할 수 없으면 None.

내부 메커니즘 stats() + 실시간 체력

실게임 검증 푸시 스냅샷

게임 내 시각(시, 0~24). 시작은 오전 8시이며, 하루 = 480 게임 초(낮과 밤 각 240초, 낮밤 진행 속도에 따라 조정). 읽지 못하면(구버전 런타임 / 게임 중이 아님) None을 반환합니다.

내부 메커니즘 월드 블록 확장 영역: GetFloatGameState(GAME_STATE_TIME_OF_DAY)

실게임 검증 푸시 스냅샷

지금이 밤인지(18:00~6:00). 프로의 운영: 밤에는 크립이 잠들고(먼저 공격해도 포위당하지 않음), 모든 유닛의 시야가 짧아지며(기습하기 좋은 때), 나이트 엘프의 보초와 유닛은 밤에 나무 곁에서 은신합니다. 읽지 못하면 None.

내부 메커니즘 월드 블록 확장 영역(6~18시가 낮)

실게임 검증 푸시 스냅샷

게임 내 시각 hour시까지 남은 게임 초(예: seconds_until(18) = 해가 지기까지 남은 시간, 밤 사냥을 계획할 때 사용).

내부 메커니즘 월드 블록 확장 영역 + 하루 480초(실측 1시간 = 20 게임 초)

실게임 검증 푸시 스냅샷

바닥에 있는 아이템 [Item(addr, handle_lo, handle_hi, type, x, y, life)]. 주워 가거나 사용되면 item.removed 이벤트가 발생합니다.

내부 메커니즘 월드 블록 items[] (바닥에 있는 것만: 소지자 핸들이 모두 FF)

실게임 검증 푸시 스냅샷

살아 있는 나무(DestructableData에서 targType에 tree가 포함된 것). (x,y)를 주면 가까운 순으로, 최대 limit그루. 각각은 Tree(addr, handle_lo, handle_hi, type, x, y, life)이며, 그대로 gather에 넘겨 벌목할 수 있습니다.

내부 메커니즘 트리 블록 Local\War3Trees_<pid>(2초마다 갱신)

실게임 검증 푸시 스냅샷

마지막 호출 이후에 일어난 일: unit.appeared / unit.died / unit.removed / unit.damaged / order.changed / hero.levelup / owner.changed / item.appeared / item.removed / game.started (발행 간 비교로 얻음, 정밀도 = 발행 주기 50 ms), 그리고 엔진 수준의 damage / killed (런타임이 게임 스레드에서 발생 즉시 기록, **타격마다** 발생): damage: handle = 맞은 유닛, .source_addr = 때린 유닛(snapshot().unit_by_addr로 유닛으로 변환), .value = 실제로 깎인 체력, .raw_damage = 방어력 적용 전 피해, .attack_type(normal/pierce/siege/magic/chaos/hero/spell), .damage_type killed: 이 타격으로 죽음, .source_addr = 처치한 유닛 그리고 런타임이 생산 테이블을 추적해 얻는 production.done (정밀도 = 발행 주기): 유닛 = 건물, .done_code = 완료된 4자 코드, .done_kind = 'training'(유닛/영웅/부활) / 'research' / 'construction'(건물 완공) / 'upgrade'(테크 업/타워 업그레이드), .value = 걸린 게임 초 09-25 보강: spell.cast: 유닛 = 시전자, .spell 스킬 4자 코드, b 레벨, value 쿨다운 초, x,y 시전 지점(스킬 쿨다운이 시작될 때 인식, 정밀도 = 발행 주기) player.left: .player 나가거나 패배 판정으로 제거된 플레이어 번호; game.ended: 게임에서 나감 selection.changed: 로컬 플레이어의 선택이 바뀜(g.selection()으로 유닛을 가져옴) message: 화면 메시지 영역의 한 줄(게임 안내, 채팅, 시스템): .text 전체 텍스트, .frame 메시지 영역 번호, .chat = {'channel', 'sender', 'text'}(채팅일 때. 플레이어가 채팅창에 입력한 내용은 여기서 읽음) ui.click / ui.hover / hotkey / mouse.world: UI와 입력(g.ui), .key는 캔버스 key / 단축키 표기 각 항목은 Event(seq, kind, clock, addr, handle, type, owner, a, b, x, y, value, extra)입니다. 공정 모드(fair=True)에서는 다음만 제공합니다: 자기 유닛의 이벤트, 지금 보이는(또는 1초 전까지 보였던) 유닛의 이벤트, 아군이 받거나 가한 피해, 그리고 로컬 UI / 메시지 / 게임 진행 관련 이벤트.

내부 메커니즘 이벤트 링 Local\War3Events_<pid>(발행 간 비교 + 런타임이 포착한 피해 이벤트)

실게임 검증 푸시 스냅샷

로컬 플레이어가 지금 선택한 유닛(주 유닛이 맨 앞, 최대 12개). 선택이 바뀌면 selection.changed 이벤트가 발생합니다.

내부 메커니즘 W3P 월드 블록 확장 영역 selAddrs(런타임이 발행할 때마다 로컬 플레이어의 선택을 함께 담음)

실게임 검증 푸시 스냅샷

마지막 호출 이후 화면 메시지 영역에 새로 나온 메시지: [{'text', 'frame', 'repeat', 'seq', 'game_ms'}]. 게임 안내("농장이 더 필요합니다", "그곳에는 건설할 수 없습니다"), 채팅, 시스템 메시지가 모두 여기에 있으며, frame으로 어느 메시지 영역인지 구분합니다. 이벤트 스트림의 message 이벤트와 같은 메시지입니다(커서는 각자 따로).

내부 메커니즘 공유 메모리 Local\War3Msgs_<pid>(런타임이 포착한 화면 메시지)

실게임 검증 푸시 스냅샷

연구 레벨 / 완성된 건물 수(업그레이드 체인 포함: 성도 htow로 셈). player 기본값은 아군이며, 모든 플레이어를 조회할 수 있습니다.

내부 메커니즘 W3P 쿼리 q_tech (엔진의 플레이어 기술 카운트)

실게임 검증 고속 레인

엔진의 실행 가능성 판정: 0/220 가능, 3 인구 부족, 8 금 부족, 9 목재 부족, 32 대기열 가득 참, 183 선행 조건 부족, 185 제단에서 부활 중, 221 해당 항목 없음/건설 중. ⚠ 일꾼의 건물 건설에는 항상 221이므로 건설 위치 판정에는 쓸 수 없습니다(build_near 사용).

내부 메커니즘 W3P 쿼리 q_feasible (엔진 실행 가능성 검사)

실게임 검증 고속 레인

can_do를 한 번에 여러 개 묻습니다: pairs = [(유닛, 4자 코드), ...], 같은 순서의 판정 코드 목록을 반환합니다(조회하지 못한 것은 None). 한 틱에 무엇을 짓고 뽑을지 계획할 때 먼저 한꺼번에 물어보면 can_do를 하나씩 부르는 것보다 N배 빠릅니다(레퍼런스 브레인 09-23: 건설 계획 76 -> 25 ms).

내부 메커니즘 W3P 쿼리 q_feasible × N, 한 배치로 제출

실게임 검증 고속 레인 × 1

이 지점이 지금 아군에게 보이는지(안개/검은 영역이 아님). 공정 모드 봇은 보이는 적만 사용해야 합니다.

내부 메커니즘 W3P 쿼리 q_visible (보임 / 안개 / 검은 영역)

실게임 검증 고속 레인

컴퓨터 AI의 대장: 병력을 이끌고 어디로 가려는지(출발 전부터 기지의 어디를 칠지 알 수 있음). 컴퓨터 상대에게만 유효하며, 대장을 따르지 않으면 None을 반환합니다.

내부 메커니즘 W3P 쿼리 q_captain (적 병력이 따르는 컴퓨터 대장)

실게임 검증 고속 레인

유닛의 현재 오더. **이번 틱에 방금 내린 것도 포함**합니다(스냅샷이 아직 따라잡지 못했으면 회신의 새 오더를 사용). ⚠ 09-23 실전: hello_bot이 농부를 농장 건설에 막 보냈는데, 같은 틱에 rush_bot이 스냅샷에서 그 농부를 "대기 중"으로 보고 병영 건설에 또 보내서, 농장이 번번이 중간에 포기되었습니다. "놀고 있는/건물을 짓고 있지 않은" 유닛을 고를 때는 u.order 대신 이것을 쓰세요.

내부 메커니즘 스냅샷 오더 + 이 프로세스에서 방금 수락된 명령(회신)

실게임 검증 푸시 스냅샷

지금 금/목재로 code (유닛, 건물)를 살 수 있는지(units.json의 가격 기준). 가격표에 없는 것은 모두 살 수 있는 것으로 취급합니다. ⚠ 테크 업 4자 코드는 표에 누적 가격으로 되어 있어 여기서는 보수적으로 판단됩니다. 최종 판단은 엔진의 회신을 따르세요.

내부 메커니즘 푸시 스냅샷의 아군 자원 + units.json의 가격

실게임 검증 푸시 스냅샷

지금 플레이 중인 맵의 데이터(openwar3.mapdata.MapData): name_of('HC07') 커스텀 유닛/아이템/스킬의 이름, hero_names, tooltip. RPG 맵의 유닛은 대부분 맵이 직접 만든 것이라 내장 이름 테이블에 없습니다. 런처로 시작한 게임이 아니면(맵 파일을 찾을 수 없으면) None을 반환합니다.

내부 메커니즘 맵 파일(런처 --map 경로): w3u/w3t/w3a + wts, 보호된 맵은 맵 안의 TXT를 읽음

실게임 검증 파일 읽기(첫 회 약 0.1초)

명령 28

유닛에게 일을 시킵니다. 약 1프레임 만에 반영되며, 모두 회신이 있습니다.

한 틱의 명령을 한 배치로 묶습니다: with g.batch() as b: g.attack(archers, target) # Pending 반환, 블록이 끝난 뒤 회신이 됨 g.move(wounded, *home) g.cast(hero, "thunderclap") print(b.sent, b.wait_ms, [r.reason for r in b.receipts]) 명령을 하나씩 보내면 매번 게임 스레드가 한 번 처리할 때까지 기다려야 합니다(약 10 ms). 배치는 한 번만 기다립니다 — 레퍼런스 브레인 09-23은 이것으로 한 라운드를 48 -> 26 ms로 줄였습니다. * 중재는 여전히 명령별로 거칩니다(점유된 유닛은 즉시 held 회신을 받고 배치에 들어가지 않음); * 블록 안의 명령은 Pending을 반환합니다: 블록이 끝나기 전에 .ok를 읽으면 예외가 발생하고(회신이 아직 없음), 블록이 끝난 뒤에는 Receipt처럼 씁니다; * 블록 안에서 예외가 발생하면 = 배치 전체 취소(status 97 cancelled), 점유했던 유닛은 반환됩니다; * 쿼리(can_do / tech / visible …)와 build_near, buy는 배치에 들어가지 않고 그 자리에서 바로 묻습니다 — 결과를 즉시 써야 하기 때문입니다; 여러 개를 한 번에 물으려면 can_do_many / tech_many를 쓰세요; * 중첩된 with g.batch()는 가장 바깥 배치에 합쳐집니다. 16개를 넘으면 런타임이 자동으로 여러 구간으로 나눕니다(구간마다 한 번 대기).

내부 메커니즘 블록 안의 명령을 한 배치로 모아 블록이 끝날 때 한 번에 제출(같은 프레임에 실행, 게임 스레드를 한 번만 기다림)

실게임 검증 고속 레인 × 1

(x,y)로 이동하며, 가는 길에 공격하지 않습니다(후퇴할 때 사용). 유닛 하나 또는 목록을 넘길 수 있습니다(같은 프레임에 함께 명령). queue='after': 지금 하는 일을 끝낸 뒤 이동(현재 오더 뒤에 삽입). 회신 values[0] = 명령 후 이 유닛에 쌓인 오더 수(진행 중인 것 포함).

내부 메커니즘 W3P point: move (extra 비트 = 대기열 방식)

실게임 검증 고속 레인

target을 공격합니다. 기본은 우클릭입니다(적에게 = 이 대상 하나를 공격, 09-23 실측 결과 오더 대상/작업 대상 모두 그 대상). ⚠ 대상은 반드시 시야 안에 있어야 하며, 보이지 않으면 거부됩니다(원인 코드 1001). force=True는 공격 오더 0x0F를 사용합니다(아군/중립 동물을 공격할 때 필요) — 실측 결과 공격 오더만 바꾸고 대상을 기억하지 않아, 근처의 다른 적을 공격하러 갑니다. 특정 대상을 공격할 때는 쓰지 마세요.

내부 메커니즘 W3P target: 대상 명령(우클릭 smart)

실게임 검증 고속 레인

하던 일을 모두 멈춥니다(오더 ID 0x000D0004). 대기 중인 오더도 지웁니다.

내부 메커니즘 W3P immediate: stop

실게임 검증 고속 레인

위치 사수(쫓아가지 않고 사거리 안의 적만 공격).

내부 메커니즘 W3P immediate: holdposition

실게임 검증 고속 레인

지면 공격: 포가 한 지점에 포격합니다(은신 유닛, 숲 뒤의 적 공격, 길목 봉쇄). 지면 공격이 가능한 유닛만 받아들입니다.

내부 메커니즘 W3P point: attackground (공성 유닛 / 박격포 / 투석기)

실게임 검증 고속 레인

취소: 훈련/연구 대기열의 마지막 칸(환불), 건설 중인 건물(75% 환불), 업그레이드 중인 본진 건물.

내부 메커니즘 W3P immediate: cancel

실게임 검증 고속 레인

일련의 지점을 순서대로 지나갑니다(Shift 연속 클릭: 경유지, 타워 우회, 정찰 경로). attack=True면 각 구간이 공격 이동입니다. 한 번에 제출하며, 회신은 지점마다 하나씩(points 순서)입니다.

내부 메커니즘 한 배치: 첫 구간은 즉시 실행, 나머지는 역순으로 queue='after'로 삽입(엔진은 현재 오더 뒤 삽입만 지원)

실게임 검증 고속 레인 × 1

금 채집/벌목(target은 금광 또는 trees()의 나무). ⚠ 놀고 있는 일꾼(idle_workers)에게만 맡기세요: 작업 중인 일꾼에게 다시 명령하면 채집 주기가 끊깁니다. 프로의 활용법: 건물을 다 지은 뒤 채광으로 복귀 = build(...) 다음에 gather(worker, mine, queue='after').

내부 메커니즘 W3P target: harvest (금광 또는 나무)

실게임 검증 고속 레인

일꾼이 (x,y)에 code를 짓게 합니다(좌표는 32 단위로 정렬). 회신 수락 = 일꾼의 오더가 이미 이 건물(또는 착공 오더)이 됨. queue='after'일 때 = 일꾼의 오더 대기열에 들어감(회신 values[0]은 대기 수). ⚠ 수락 ≠ 건설 성공: 숲 속 지점도 엔진은 즉시 수락하고, 일꾼이 도착해서야 실패합니다(09-23 실측). 돈이 다른 곳에 쓰여도 기초가 생기지 않습니다. 어디에 지을 수 있는지 모르면 build_near를 쓰세요(결과를 추적하고 실패한 지점을 블랙리스트에 올림). 여러 채를 연달아 지을 때는 build_queue.

내부 메커니즘 W3P build: 건설 오더, 같은 프레임에 일꾼 오더를 다시 읽어 확인

실게임 검증 고속 레인

일꾼 한 명이 여러 건물을 순서대로 연달아 짓습니다(Shift 연속 건설): plan = [(4자 코드, x, y), ...]. 한 번에 제출하며, 회신은 plan 순서입니다. ⚠ 비용은 착공할 때 차감됩니다(대기열에 넣을 때는 차감 안 됨) — 3채를 예약했는데 돈이 1채분뿐이면, 나머지 두 채는 일꾼이 도착했을 때 실패합니다.

내부 메커니즘 한 배치: 첫 건물은 즉시, 나머지는 역순으로 queue='after'

실게임 검증 고속 레인 × 1

(x,y) 주변에서 가까운 곳부터 차례로 지을 수 있는 지점을 찾아 code를 짓습니다. **블로킹하지 않으므로** 매 틱 호출해도 됩니다: * 이 건물의 시도가 아직 진행 중(일꾼이 이동 중) -> 그 지점을 반환하고 명령을 반복하지 않음; * 이전 시도가 성공(기초가 생김) -> 이번에는 필요하면 새 지점을 찾음; * 이전 시도가 실패(일꾼이 도착해서야 지을 수 없음을 알고, 엔진이 오더를 취소했으며 기초가 없음) -> 그 지점을 45초간 블랙리스트에 올리고 다음 지점으로; * 돈이 부족 -> 바로 None 반환(시도하지 않고 블랙리스트에도 올리지 않음); 모든 지점을 시도했으면 None 반환. ⚠ 추적이 필요한 이유: 09-23 실전에서 숲 속 지점을 엔진이 **즉시 수락**하고 일꾼이 도착해서야 실패했습니다(같은 프레임의 회신으로는 판별 불가); 게다가 엔진의 배치 위치 검사는 일꾼의 건물 건설에 대해 항상 221을 반환하므로, 먼저 "조회"하고 지을 수도 없습니다. 명백히 점유된 지점(본진 건물 한가운데)만 즉시 거부됩니다.

내부 메커니즘 지점마다 build + 추적(기초 생성 = 성공, 일꾼이 오더를 포기했는데 기초가 없음 = 그 지점 블랙리스트)

실게임 검증 고속 레인 × 시도한 지점 수

유닛 훈련 / 기술 연구 / 본진 건물 업그레이드(테크 업 = 본진 건물 자체에 목표 본진 건물의 4자 코드를 명령, 예: 'hkee'). 거부되면 회신의 reason에 이유가 적힙니다(인구 부족, 금 부족, 목재 부족, 대기열 가득 참, 선행 조건 부족……).

내부 메커니즘 W3P immediate: 4자 코드, 거부 시 실행 가능성 원인 코드 포함

실게임 검증 고속 레인

영웅이 스킬을 배웁니다(4자 코드, 예: 'AHbz' 눈보라).

내부 메커니즘 W3P learn: 스킬 포인트가 줄어야 습득으로 인정

실게임 검증 고속 레인

스킬을 사용합니다. spell은 오더 문자열('thunderbolt' 폭풍 망치, 'blizzard', 'holybolt' Holy Light…, data/order-ids.txt 참고) 또는 오더 ID. target을 주면 = 유닛 대상, x,y를 주면 = 지면 대상, 둘 다 없으면 = 대상 없음(Thunder Clap, Divine Shield, 물의 정령 소환). 회신 수락은 엔진이 받아들였다는 뜻일 뿐입니다. 실제로 시전됐는지는 cooldown()이 쿨다운에 들어갔는지, buffs()에 버프가 나타났는지로 확인하세요.

내부 메커니즘 W3P target / point / immediate (인자에 따라 선택)

실게임 검증 고속 레인

제단에서 죽은 영웅을 부활시킵니다(hero를 주지 않으면 목록의 첫 번째를 부활). 흔한 거부 원인(회신 reason에 적힘): 인구 부족(영웅도 인구를 차지함), 돈 부족, 죽은 지 얼마 안 됨(사망 후 약 3 게임 초가 지나야 부활 가능), 이미 부활 진행 중(수락될 때 엔진이 그 슬롯을 즉시 비움).

내부 메커니즘 W3P revive: 사망 영웅 목록 -> 제단이 죽은 영웅에게 부활 시전

실게임 검증 고속 레인

영웅이 바닥의 아이템을 주우러 갑니다(item은 items_on_ground에서). 주우면 인벤토리에 나타나고, 바닥 쪽에는 item.removed 이벤트가 발생합니다.

내부 메커니즘 W3P target: 아이템 우클릭

실게임 검증 고속 레인

인벤토리 slot번째 칸(0~5)의 아이템을 사용합니다. 대상 유닛이나 대상 지점을 지정할 수 있습니다. ⚠ 지점 대상 아이템(예: Ivory Tower)은 엔진이 성공해도 0을 반환하므로 회신은 항상 수락으로 처리됩니다 — 인벤토리 그 칸이 비었는지 확인하세요.

내부 메커니즘 W3P use_item (칸 번호 기준)

실게임 검증 고속 레인

인벤토리 slot번째 칸의 아이템을 (x,y)에 내려놓습니다(영웅이 걸어가서 내려놓음).

내부 메커니즘 W3P item_drop (JASS UnitDropItemPoint를 그대로 따름: dropitem 0xD0021 지점 대상 + 아이템 즉시 대상)

실게임 검증 고속 레인

인벤토리 slot번째 칸의 아이템을 to (다른 영웅 / 유닛)에게 줍니다(걸어가서 건네줌). 상점에 주면 = 판매(sell_item 참고).

내부 메커니즘 W3P item_drop (JASS UnitDropItemTarget을 그대로 따름: 유닛 대상 dropitem)

실게임 검증 고속 레인

인벤토리 slot번째 칸의 아이템을 상점에 팝니다(영웅이 상점 옆까지 가야 함. 판매 가능한 아이템만 받으며, 가격의 절반을 돌려줌).

내부 메커니즘 give_item과 같으며 대상이 상점(실측: Staff of Sanctuary를 125 금에 판매)

실게임 검증 고속 레인

인벤토리 안에서 칸을 옮깁니다(slot번째 칸을 to_slot번째 칸으로. 두 칸 모두 아이템이 있으면 서로 바꿈). 단축키 배치를 정리할 때 사용합니다.

내부 메커니즘 W3P target: 오더 0xD0022+칸 번호, 대상 = 아이템(JASS UnitDropItemSlot을 그대로 따름)

실게임 검증 고속 레인

상점에서 아이템을 삽니다(상점 옆에 서 있는 영웅에게). 기술 선행 조건이 부족하면 엔진이 0을 반환하고 돈을 차감하지 않습니다.

내부 메커니즘 W3P buy: 상점이 옆에 있는 영웅에게 판매

추정 고속 레인

휴먼 Call to Arms: 농부가 민병대로 변합니다(1티어 마을 회관에는 이 능력이 없고, 성채/성에서만 유효).

내부 메커니즘 W3P immediate: townbellon/off

실게임 검증 고속 레인

게임 제어 9

배속, 일시 정지, 발행 주기, 머리 위 말풍선, 캔버스, UI와 입력, 메시지.

UI와 입력(openwar3.ui.UI): 클릭할 수 있는 버튼과 선택 카드, 단축키, 지면을 클릭해 위치 고르기, 마우스가 가리키는 곳. 버튼 위를 누른 클릭은 게임에 전달되지 않습니다. 순수한 로컬 입력 + 로컬 드로잉이므로 멀티플레이 게임에서도 안전합니다.

내부 메커니즘 W3P 74 input_enable + 공유 메모리 Local\War3Input_<pid>(런타임이 창 입력을 받음)

실게임 검증 공유 메모리

게임 일시정지 / 재개. 일시정지 중에는 엔진 시계가 멈추지만, 고속 레인으로는 평소처럼 명령을 내릴 수 있습니다(이벤트 디스패치는 계속 돌아감).

내부 메커니즘 W3P pause

실게임 검증 고속 레인

월드 상태의 발행 주기(16~1000밀리초, 기본값 50). 한 번 수집에 약 0.5 ms가 들므로 33 ms도 문제없습니다. 기기 전체가 하나의 값을 공유하며, 마지막에 쓴 값이 적용됩니다.

내부 메커니즘 월드 블록 requestedPeriodMs

실게임 검증 푸시 스냅샷

유닛 머리 위에 채팅 말풍선을 띄웁니다(방송/디버깅용, 게임에 영향 없음). 말풍선이 뜨지 않으면 False를 반환하고, 이유는 g.last_say_error에 있습니다.

내부 메커니즘 액션 56

실게임 검증 제어 채널

게임 왼쪽 아래 메시지 영역에 한 줄을 출력합니다(이 PC에서만 보임). 게임이 먼저 알림을 한 번 띄운 뒤에야 동작합니다(DLL이 그때 메시지 창을 잡음).

내부 메커니즘 액션 45

추정 제어 채널

이 게임 프로세스를 종료합니다(farm.py --keep은 next_game.json에 따라 다음 게임을 자동으로 시작).

내부 메커니즘 액션 22

실게임 검증 제어 채널

캔버스: 게임 화면 위에 텍스트 상자, 패널, 진행 바, 이미지, 지면의 원과 경로를 그립니다(openwar3.canvas.Canvas). 런타임이 직접 그리므로 게임 핸들을 만들지 않고 게임 상태도 바꾸지 않습니다 — 멀티플레이 게임에서도 안전합니다. 스타일은 자유롭습니다(CJK 텍스트, 둥근 모서리, 반투명).

내부 메커니즘 W3P 73 canvas_enable + 공유 메모리 Local\War3Canvas_<pid>(런타임이 매 프레임 게임이 포인터를 그리기 직전에 그림. 포인터가 그 위를 덮음)

실게임 검증 공유 메모리

“계속하려면 아무 키나 누르세요” 로딩 화면에서 스페이스를 한 번 누릅니다. 많은 RPG / 스토리 맵은 로딩이 끝난 뒤 키를 눌러야 시작합니다(09-24 WarChasers 실측: 누르지 않으면 로딩 화면에 계속 머물고, 게임 시계는 0, 고속 레인도 비워지지 않음). openwar3.run 등은 게임에 들어갈 때 알아서 누르므로 보통 직접 호출할 필요가 없습니다.

내부 메커니즘 PostMessage WM_KEYDOWN/UP 스페이스를 게임 창에 전송(포커스를 빼앗지 않음)

실게임 검증 창 메시지

샌드박스 6

JASS 채널: 유닛 생성, 동맹 설정, 이름 변경, 텍스트 표시…… RPG 보조 도구와 동료용입니다. 월드를 바꾸는 것은 싱글플레이 게임과 로컬 도구에서만 가능합니다.

임의의 JASS native를 이름으로 호출합니다: g.jass.CreateUnit(g.jass.Player(1), "Hpal", x, y, 270.0). 인수 I/R/B/S/H는 자동으로 변환되며(유닛/아이템 객체는 그대로 전달), 멀티플레이 게임에서는 읽기 전용 native만 호출할 수 있습니다. 자세한 내용은 openwar3/jass.py와 docs/COMPANION_ZH.md를 참고하세요.

내부 메커니즘 W3P 70 jass(런타임이 이름으로 native 테이블을 조회, 1291개)

실게임 검증 고속 레인

플레이어 슬롯 16개: controller(user 사람 / computer / neutral…), state(empty / playing / left), human, me, ally(나와 동맹인지). RPG 맵에서 동료를 둘 빈 슬롯을 찾거나, 싱글플레이 게임인지 판단할 때 씁니다.

내부 메커니즘 JASS GetPlayerController / GetPlayerSlotState / IsPlayerAlly

실게임 검증 고속 레인

(x,y)에 유닛 하나를 생성하고(player 기본값은 로컬 플레이어) 스냅샷 속 유닛을 반환합니다(다음 월드 발행까지 대기, 약 50 ms). 생성하지 못하면 None을 반환합니다. 반환된 유닛에는 jass_handle 속성이 하나 더 있습니다. ⚠ 싱글플레이 게임에서만 사용할 수 있습니다(멀티플레이에서는 동기화가 어긋남).

내부 메커니즘 JASS CreateUnit + W3P 72 핸들 -> 유닛

실게임 검증 고속 레인

플레이어 a가 b에 대해 갖는 동맹 관계를 설정합니다: allied = 서로 공격하지 않음 + 서로 지원 요청, vision 시야 공유, control 유닛 제어 공유(b가 a의 유닛을 지휘 가능), xp 경험치 공유. both=True이면 양방향을 함께 설정합니다(control은 a -> b만).

내부 메커니즘 JASS SetPlayerAlliance

실게임 검증 고속 레인

플레이어 이름을 바꿉니다(점수판, 채팅, 동맹 패널에 표시되는 이름). 동료에게 이름을 붙일 때 씁니다.

내부 메커니즘 JASS SetPlayerName

실게임 검증 고속 레인

연결과 도구 2

연결 상태와 순수 계산 도구.

연결 상태: pid, 월드 발행(주기, 수집 소요 시간), 고속 레인 카운트.

내부 메커니즘 월드 블록 + 고속 레인 + 클레임 테이블

실게임 검증 로컬 계산

to (유닛 또는 (x,y))에 가장 가까운 하나. 후보가 없으면 None을 반환합니다.

내부 메커니즘 순수 계산

실게임 검증 로컬 계산