Каталог API

Методов: 103. И у каждого указано
«проверен ли, насколько быстр и как устроен»

Генерируется из кода командой python -m openwar3 catalog --write и обновляется вместе с SDK — модели не нужно гадать, какой метод существует и какой действительно работает. Те же данные доступны в JSON — их можно сразу отдать агенту.

58 Наблюдение
28 Команды
9 Управление игрой
6 Песочница
2 Подключение и утилиты
98 Проверено в игре
0 Экспериментальный
5 Выведено / не полностью проверено
103 шт.

Наблюдение 58

Чтение состояния без изменения игры. Почти всё читается напрямую из push-снимка, без ожидания.

Полное состояние всей карты (WorldState): .units .players .items .clock .me; повторные вызовы в пределах max_age секунд возвращают одну и ту же копию. ⚠ Рабочих внутри золотого рудника в списке нет; по умолчанию видна вся карта (в модели lockstep локально есть всё), фильтрация по зоне обзора — только при Game(fair=True).

Механизм Блок мира W3P Local\War3World_<pid> (рантайм публикует каждые 50 ms, seqlock)

Проверено в игре Push-снимок

Последние замеченные юниты противника (или крипов — 'creep', или игрока с заданным номером): [(как юнит выглядел тогда, игровые часы в тот момент, сколько секунд прошло)], новые первыми. Если видели, как юнит погиб, он удаляется из списка. И в честном, и в обычном режиме запись ведётся по принципу «что мы видим прямо сейчас» — это та самая карта в голове игрока: разведанные силы, где последний раз видели вражеского героя, когда противник занял экспансию. max_age — только записи не старше указанного числа игровых секунд.

Механизм visibleTo из push-снимка (при каждом обновлении снимка запоминаются видимые юниты противника и крипы)

Проверено в игре Push-снимок

Таблица рельефа этой партии MapInfo: .walkable(x,y) .buildable(x,y) .at(x,y) .bounds (игровая область) .starts (стартовые позиции) .cells (bit0 — непроходимо, bit1 — нельзя строить). После начала партии вычисляется несколько секунд; пока не готово, возвращает None. Деревьев здесь нет (используйте trees()).

Механизм Блок карты W3P Local\War3Map_<pid> (рантайм вычисляет порциями после начала партии; IsTerrainPathable для прохода/постройки)

Проверено в игре Push-снимок

Номер нашего игрока (0~11).

Механизм Заголовок блока мира

Проверено в игре Push-снимок

{'gold','lumber','food_used','food_cap','gold_gathered','lumber_gathered'}; player по умолчанию — мы, читать можно любого игрока. Если прочитать не удалось, возвращает None — не принимайте это за 0.

Механизм Блок мира players[16]

Проверено в игре Push-снимок

Все 16 слотов игроков: Player(id, gold, lumber, food_used, food_cap, gold_gathered, lumber_gathered, race, known).

Механизм Блок мира players[16]

Проверено в игре Push-снимок

Найти юнит по паре дескрипторов (lo, hi) (цель приказа, текущая цель и события отдают именно пары дескрипторов).

Механизм Блок мира by_handle

Проверено в игре Push-снимок

Является ли юнит зданием (включая башни). Определяется по нулевой скорости передвижения в таблице юнитов; у главного здания Нежити площадь застройки равна 0, так что по площади не определяйте.

Механизм Снимок + units.json (spd==0 = здание)

Проверено в игре Push-снимок

Наши рабочие (крестьяне/батраки/послушники/огоньки).

Механизм Push-снимок

Проверено в игре Push-снимок

Рабочие без дела: нет ни приказа, ни задания (те, кому вы дали работу в этом тике, не считаются). ⚠ Повторный приказ добычи рабочему, у которого есть задание, прерывает цикл добычи (доход падает до нуля).

Механизм Push-снимок (слот приказа + слот задания)

Проверено в игре Push-снимок

Наши живые герои (погибшие — в списке воскрешения алтаря, см. revive).

Механизм Push-снимок

Проверено в игре Push-снимок

Наши боевые юниты: не рабочие и не здания.

Механизм Push-снимок + units.json

Проверено в игре Push-снимок

Наши здания (включая башни и строящиеся фундаменты); через types можно запросить только некоторые виды, например {'hbar'}.

Механизм Push-снимок

Проверено в игре Push-снимок

Строит ли этот рабочий здание прямо сейчас (или идёт строить / помогает чинить; включая назначенных в этом тике). Выбирая строителя, пропускайте таких, иначе предыдущий фундамент встанет.

Механизм Push-снимок (приказ = четырёхсимвольный код здания либо приказ строительства/ремонта)

Проверено в игре Push-снимок

Здание ещё не достроено (здоровье не полное). ⚠ У повреждённого здания здоровье тоже не полное — в начале партии этого хватает, а после начала боёв учитывайте ещё и время.

Механизм Push-снимок (здоровье фундамента растёт от очень малого до полного)

Проверено в игре Push-снимок

Золотые рудники на карте. ⚠ У Entangled Gold Mine Ночных эльфов и у нейтрального рудника в одной и той же точке по отдельному юниту — на добычу отправляйте к своему.

Механизм Push-снимок (ngol/egol/ugol)

Проверено в игре Push-снимок

Юниты вражеских игроков (без крипов). fighters_only: без рабочих и зданий.

Механизм Push-снимок

Проверено в игре Push-снимок

Крипы (нейтрально-враждебные). ⚠ Ночью обзор короче: когда дальний лагерь уходит в туман войны, команды на цель по нему отклоняются (код причины 1001).

Механизм Push-снимок (owner 12 = нейтрально-враждебные)

Проверено в игре Push-снимок

{'hp','hp_max','mana','mana_max'} (float, исходные значения движка). В u можно передать юнит прямо из снимка (он будет заменён на самую свежую копию).

Механизм Юнит блока мира: hp/hpMax/mana/manaMax

Проверено в игре Push-снимок

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

Механизм Юнит блока мира: level/xp/skillPoints

Проверено в игре Push-снимок

[{code, level, cooldown, flags}]; баффы — в buffs(u). Есть только у юнитов «с деталями» (герои > юниты игроков > крипы, не больше 256).

Механизм Детали блока мира: способности (код/уровень/флаги/оставшаяся перезарядка)

Проверено в игре Push-снимок

Коды баффов на юните (например, 'BHds' — Божественный щит, 'Bslo' — Замедление). Какому эффекту соответствует код, см. data/game/buffs.json.

Механизм Детали блока мира: объекты способностей, начинающиеся на B

Проверено в игре Push-снимок

Сколько ещё секунд (игровых) перезаряжается способность; 0 = можно применять; если такой способности нет (или у юнита нет деталей), возвращает None.

Механизм Детали блока мира: оставшаяся перезарядка способности (таймер способности)

Проверено в игре Push-снимок

Четырёхсимвольные коды предметов в 6 ячейках (пустая ячейка — None); если инвентаря нет, возвращает None.

Механизм Детали блока мира: 6 ячеек инвентаря

Проверено в игре Push-снимок

{'order','target','x','y'}: приказ, который юнит выполняет сейчас (order — 0x000D00xx или четырёхсимвольный код здания, 0 = простой). target — пара дескрипторов; превратить её в юнит можно через g.unit(target).

Механизм Юнит блока мира: order / цель приказа / точка цели приказа

Проверено в игре Push-снимок

Юнит, которого этот юнит **реально атакует/преследует** (если такого нет — None). ⚠ После приказа атаки слот приказа быстро пустеет, а атака висит на задании — чтобы понять, «кого бьёт» юнит, используйте это, а не current_order.

Механизм Юнит блока мира: текущая цель (задание)

Проверено в игре Push-снимок

Игровые часы движка (игровые секунды, во время загрузки 0). На повышенной скорости игры идут быстрее реального времени.

Механизм Заголовок блока мира clockMs (игровые часы движка)

Проверено в игре Push-снимок

Что сейчас производит здание: 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 игровой секунды)

Проверено в игре Push-снимок

Четырёхсимвольные коды в очереди найма/исследований ([0] — делается сейчас); если здание простаивает или не производит ничего — [].

Механизм Таблица производства блока мира

Проверено в игре Push-снимок

Всё текущее производство [(здание, Production)]. owner — как в units(): 'me' / 'enemy' / номер игрока / 'all'. Как используют профи: смотреть, каких юнитов нанимает противник, что исследует и когда улучшает ратушу (если его здания разведаны).

Механизм Таблица производства блока мира

Проверено в игре Push-снимок

Длина пути наземного юнита от a до b (a и b — юниты или (x,y)); если не дойти — None. На островных картах, чтобы понять, «можно ли дойти по земле до этого лагеря крипов/экспансии», используйте это — надёжнее расстояния по прямой (обходит лес, обрывы, здания). Точность — одна клетка 128; проход уже одной клетки считается непроходимым.

Механизм Блок карты (IsTerrainPathable движка) + блок деревьев + площадь зданий, A* на стороне SDK (клетка 128)

Проверено в игре Push-снимок + локальный расчёт

Можно ли дойти по земле (блок карты ещё не вычислен = None).

Механизм То же, что выше

Проверено в игре Push-снимок + локальный расчёт

Точки поворота пути [(x,y)...] (последняя — b); вместе с path(units, список_точек) ведёт отряд этим маршрутом (в обход башен, обходными тропами).

Механизм То же, что выше

Проверено в игре Push-снимок + локальный расчёт

Уровень содержания: {'level': 'none'/'low'/'high', 'income': 1.0/0.7/0.4, 'next_at': пища, с которой начинается следующий уровень (нет = None)}. Азбука профи: пока улучшаете ратушу до третьего уровня / исследуете улучшения атаки/брони, держитесь на 50 пищи, а до 80 поднимайтесь только перед решающим боем.

Механизм Фиксированное правило 1.27: 0~50 пищи — без налога, 51~80 — доход ×0.7, 81~100 — ×0.4

Выведено Push-снимок

Сколько опыта не хватает герою до следующего уровня (на 10 уровне = 0).

Механизм level/xp блока мира + формула NeedHeroXP из MiscGame

Проверено в игре Push-снимок

Группирует (видимых) крипов на поле в лагеря: [{'x','y','units','level','hp','max_level'}], от ближних к нашей главной базе к дальним. level = суммарный уровень лагеря (обычная мера сложности крипинга), hp = суммарное здоровье. Выбирайте лагерь вместе с time_to_kill / path_distance.

Механизм Push-снимок (крипы объединяются в группу в радиусе 600) + уровни из units.json

Проверено в игре Push-снимок

Что означает код баффа: {'ability','effect','dur','hero_dur','targets'} (например, 'Bslo' -> Замедление). Если коду соответствует несколько строк, возвращается первая.

Механизм data/game/buffs.json (BuffID из AbilityData.slk -> способность/эффект/длительность)

Проверено в игре Локальные данные

Боевые характеристики юнита combat.UnitStats: максимум здоровья/маны, броня (с учётом улучшений атаки/брони и ловкости героя), тип брони, скорость передвижения, дневной/ночной обзор, оружие (по каким целям бьёт, дальность, интервал атаки, диапазон урона, тип атаки, урон по площади). u — юнит (автоматически берутся технологии его владельца и уровень героя) или четырёхсимвольный код (player по умолчанию — мы). Дальше — .dps_vs(противник) / .hits_to_kill(противник) / combat.time_to_kill(группа, противник). ⚠ Предметы, ауры и баффы не учитываются.

Механизм Таблицы данных (UnitBalance/UnitWeapons/UpgradeData/MiscGame) + текущие уровни технологий + уровень героя

Проверено в игре Push-снимок + быстрая полоса (пачка раз в 5 секунд)

За сколько игровых секунд эта группа юнитов вместе убьёт target (по текущему здоровью target; учитываются контры, броня, улучшения атаки/брони; не учитываются перемещение, урон по площади, лечение). Как используют профи: фокус огня сначала на того, кто «умрёт быстрее всех» (минимальный time_to_kill), а не на ближайшего. Не могут атаковать = None.

Механизм stats() + текущее здоровье

Проверено в игре Push-снимок

Игровое время суток (часы, 0~24). Партия начинается в 8 утра; полные сутки = 480 игровых секунд (день и ночь по 240 секунд, масштабируются скоростью смены дня и ночи). Если прочитать не удалось (старый рантайм / не в партии), возвращает None.

Механизм Область расширений блока мира: GetFloatGameState(GAME_STATE_TIME_OF_DAY)

Проверено в игре Push-снимок

Ночь ли сейчас (18:00~6:00). Приём профи: ночью крипы спят (можно ударить первым и не попасть в окружение), у всех юнитов обзор короче (хорошее время для внезапной атаки), часовые/юниты Ночных эльфов ночью становятся невидимыми у деревьев. Если прочитать не удалось, возвращает None.

Механизм Область расширений блока мира (день — с 6 до 18)

Проверено в игре Push-снимок

Сколько игровых секунд осталось до игрового времени hour (например, seconds_until(18) = сколько осталось до темноты; удобно для планирования ночного крипинга).

Механизм Область расширений блока мира + сутки по 480 секунд (измерено: 20 игровых секунд в час)

Проверено в игре Push-снимок

Предметы на земле [Item(addr, handle_lo, handle_hi, type, x, y, life)]. При подборе/использовании приходит событие item.removed.

Механизм Блок мира items[] (только лежащие на земле: дескриптор владельца — все FF)

Проверено в игре Push-снимок

Живые деревья (из DestructableData, у которых targType содержит tree); если задано (x,y), сортируются по расстоянию от ближних к дальним, не больше limit штук. Каждое — Tree(addr, handle_lo, handle_hi, type, x, y, life), его можно сразу передать в gather для рубки леса.

Механизм Блок деревьев Local\War3Trees_<pid> (обновляется каждые 2 секунды)

Проверено в игре Push-снимок

Что произошло с прошлого вызова: 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 = четырёхсимвольный код готового, .done_kind = 'training' (войска/герой/воскрешение) / 'research' / 'construction' (здание построено) / 'upgrade' (улучшение ратуши/башни), .value = сколько игровых секунд заняло Добавлено 09-25: spell.cast: юнит = заклинатель, .spell — четырёхсимвольный код способности, 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: интерфейс и ввод (g.ui), .key — key на холсте / запись горячей клавиши Каждое — Event(seq, kind, clock, addr, handle, type, owner, a, b, x, y, value, extra). В честном режиме (fair=True) приходят только: события своих юнитов, события юнитов, видимых прямо сейчас (или ещё видимых в течение последней 1 секунды), урон по нам и урон, нанесённый нами, а также локальные события интерфейса / сообщений / матча.

Механизм Кольцо событий Local\War3Events_<pid> (сравнение публикаций + события урона, которые фиксирует рантайм)

Проверено в игре Push-снимок

Юниты, которые сейчас выбраны у локального игрока (главный юнит — первым; не больше 12). При изменении выделения приходит событие selection.changed.

Механизм Область расширений блока мира W3P, selAddrs (рантайм при каждой публикации добавляет выделение локального игрока)

Проверено в игре Push-снимок

Новые строки в окнах сообщений на экране с прошлого вызова: [{'text', 'frame', 'repeat', 'seq', 'game_ms'}]. Здесь и подсказки игры («Нужно больше ферм», «Здесь строить нельзя»), и чат, и системные сообщения; frame показывает, в каком окне сообщений появилась строка. Это те же сообщения, что и события message в потоке событий (у каждого свой курсор).

Механизм Общая память Local\War3Msgs_<pid> (экранные сообщения, которые фиксирует рантайм)

Проверено в игре Push-снимок

Уровень исследования / число построенных зданий (цепочка улучшений учитывается: Замок тоже считается как htow). player по умолчанию — мы, запрашивать можно любого игрока.

Механизм Запрос W3P q_tech (счётчик технологий игрока в движке)

Проверено в игре Быстрая полоса

Вердикт движка о выполнимости: 0/220 — можно; 3 пища, 8 не хватает золота, 9 не хватает древесины, 32 очередь заполнена, 183 нет нужного здания или технологии, 185 алтарь воскрешает, 221 такого нет/строится. ⚠ Для постройки здания рабочим всегда 221 — выбирать место этим нельзя (используйте build_near).

Механизм Запрос W3P q_feasible (проверка выполнимости в движке)

Проверено в игре Быстрая полоса

Много can_do за раз: pairs = [(юнит, четырёхсимвольный_код), ...], возвращает список кодов вердикта в том же порядке (где ответа нет — None). Планируя, что строить/нанимать в этом тике, сначала спросите всё разом — это в N раз быстрее, чем can_do по одному (эталонный мозг 09-23: планирование построек 76 -> 25 ms).

Механизм Запрос W3P q_feasible × N, отправка одной пачкой

Проверено в игре Быстрая полоса × 1

Много счётчиков технологий/зданий за раз: {четырёхсимвольный_код: количество или None}.

Механизм Запрос W3P q_tech × N, отправка одной пачкой

Проверено в игре Быстрая полоса × 1

Видим ли мы эту точку сейчас (не в тумане войны/чёрной маске). Bot в честном режиме должен использовать только видимых врагов.

Механизм Запрос W3P q_visible (видно / туман войны / чёрная маска)

Проверено в игре Быстрая полоса

Сколько золота осталось в руднике.

Механизм Запрос W3P q_mine_gold (остаток золота в руднике по данным движка)

Выведено Быстрая полоса

Капитан компьютерного AI: куда он ведёт войска (ещё до выхода известно, какую часть вашей базы он будет атаковать). Работает только против компьютерного противника; если юнит не следует за капитаном — None.

Механизм Запрос W3P q_captain (компьютерный капитан, за которым следует вражеский юнит)

Проверено в игре Быстрая полоса

Текущий приказ юнита, **включая отданный вами в этом тике** (пока снимок не догнал, берётся новый приказ из квитанции). ⚠ 09-23, реальная игра: hello_bot только что отправил крестьянина строить ферму, а в том же тике rush_bot увидел в снимке, что тот «свободен», и отправил его строить казарму — ферма раз за разом бросалась на полпути. Выбирая «свободные/не занятые стройкой» юниты, используйте это, а не u.order.

Механизм Приказ из снимка + команды, только что принятые в этом процессе (квитанции)

Проверено в игре Push-снимок

Хватает ли сейчас золота/древесины на code (юниты, здания; по ценам из units.json). Всё, чего нет в таблице цен, считается доступным. ⚠ У четырёхсимвольных кодов улучшения ратуши в таблице накопленная цена, так что оценка здесь будет консервативной; окончательное слово — за квитанцией движка.

Механизм Наши ресурсы из push-снимка + цены из units.json

Проверено в игре Push-снимок

Данные карты текущей партии (openwar3.mapdata.MapData): name_of('HC07') — имена пользовательских юнитов/предметов/способностей, hero_names, tooltip. Большинство юнитов на RPG-картах созданы самой картой, во встроенной таблице имён их нет; если игра запущена не лаунчером (файл карты не найден), возвращает None.

Механизм Файл карты (путь из --map лаунчера): w3u/w3t/w3a + wts; у защищённых карт читаются TXT внутри карты

Проверено в игре Чтение файла (в первый раз ≈ 0.1 s)

Команды 28

Приказы юнитам. Исполняются примерно за кадр, у каждой есть квитанция.

Объединяет команды одного тика в пачку: 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 = способ постановки в очередь)

Проверено в игре Быстрая полоса

Атака с движением (A по земле): атакует врагов, встреченных по пути. queue — как в move.

Механизм W3P point: attack в точку

Проверено в игре Быстрая полоса

Атаковать target. По умолчанию — правым кликом (по врагу = атаковать именно его; 09-23 измерено: и цель приказа, и текущая цель — он). ⚠ Цель должна быть в зоне обзора, невидимую отклонят (код причины 1001). force=True использует приказ атаки 0x0F (нужен, чтобы бить своих/нейтральных зверьков) — по измерениям он лишь подменяет приказ на атаку и не запоминает цель, и юнит уходит бить других врагов поблизости; для атаки конкретной цели его не используйте.

Механизм W3P target: команда на цель (правый клик smart)

Проверено в игре Быстрая полоса

Прекратить всё (номер приказа 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 (золотой рудник или дерево)

Проверено в игре Быстрая полоса

Ремонт / помощь в строительстве (стройка Людей и Орды без строителя замирает).

Механизм W3P target: repair

Проверено в игре Быстрая полоса

Рабочий строит code в (x,y) (координаты выравниваются по сетке 32). Квитанция «принята» = приказ рабочего уже — это здание (или приказ начала стройки); при queue='after' = поставлено в очередь приказов рабочего (values[0] в квитанции — длина очереди). ⚠ «Принята» ≠ «построено»: точку в лесу движок тоже принимает сразу, а неудача наступает, когда рабочий дойдёт (измерено 09-23); если деньги потрачены в другом месте, фундамент тоже не появится. Если не знаете, где есть место, используйте build_near (он отслеживает результат и заносит неудачные точки в чёрный список). Для нескольких зданий подряд — build_queue.

Механизм W3P build: приказ постройки, приказ рабочего перечитывается в том же кадре для подтверждения

Проверено в игре Быстрая полоса

Один рабочий строит несколько зданий подряд (стройка через Shift): plan = [(четырёхсимвольный_код, x, y), ...]. Отправляется за один раз; квитанции — в порядке plan. ⚠ Деньги списываются только в момент начала стройки (не при постановке в очередь) — если поставили 3 здания, а денег хватает на 1, последние два сорвутся, когда рабочий до них дойдёт.

Механизм Пачка: первое здание сразу, остальные в обратном порядке через queue='after'

Проверено в игре Быстрая полоса × 1

Ищет вокруг (x,y) от ближнего к дальнему место, куда влезет code, и строит. **Не блокирует**, можно вызывать каждый тик: * для этого здания уже идёт попытка (рабочий в пути) -> возвращает ту же точку, приказ не повторяется; * прошлая попытка удалась (появился фундамент) -> при необходимости ищет новую точку; * прошлая попытка провалилась (рабочий дошёл и обнаружил, что места нет; движок снял приказ, фундамента нет) -> точка попадает в чёрный список на 45 секунд, берётся следующая; * не хватает денег -> сразу возвращает None (не пробует и в чёрный список не заносит); все точки перепробованы — возвращает None. ⚠ Зачем отслеживать: 09-23, реальная игра — точку в лесу движок **сразу принимает**, а неудача случается, только когда рабочий дойдёт (по квитанции того же кадра этого не понять); а проверка места в движке для постройки рабочим всегда возвращает 221, так что «сначала проверить, потом строить» тоже не выйдет. Сразу отклоняются только явно занятые точки (центр ратуши).

Механизм Команда build по точкам + отслеживание (появился фундамент = успех; рабочий бросил приказ, а фундамента нет = точка в чёрный список)

Проверено в игре Быстрая полоса × число пробных точек

Нанять юнит / исследовать технологию / улучшить ратушу (улучшение = приказ самой ратуше с четырёхсимвольным кодом целевого здания, например 'hkee'). При отказе reason в квитанции объяснит почему (не хватает пищи, золота, древесины, очередь заполнена, нет нужного здания или технологии…).

Механизм W3P immediate: четырёхсимвольный код; при отказе — с кодом причины из проверки выполнимости

Проверено в игре Быстрая полоса

Герой изучает способность (четырёхсимвольный код, например 'AHbz' — Снежная буря).

Механизм W3P learn: изучено, только если уменьшились очки навыков

Проверено в игре Быстрая полоса

Применить способность. spell — строка приказа ('thunderbolt' — Молот бурь, 'blizzard', 'holybolt' — Свет небес…, см. data/order-ids.txt) или номер приказа. Задан target — на юнит; заданы x,y — на землю; ничего не задано — без цели (Раскат грома, Божественный щит, призыв Элементаля воды). «Принята» в квитанции означает лишь, что движок принял команду; применилась ли способность, смотрите по тому, ушла ли она на перезарядку в cooldown() и появился ли бафф в buffs().

Механизм W3P target / point / immediate (выбирается по аргументам)

Проверено в игре Быстрая полоса

Воскресить погибшего героя в алтаре (если hero не задан — первого в списке). Частые причины отказа (будут в reason квитанции): не хватает пищи (герой тоже занимает пищу), не хватает денег, герой погиб слишком недавно (воскрешать можно примерно через 3 игровые секунды после смерти), воскрешение уже идёт (при принятии движок сразу очищает этот слот).

Механизм W3P revive: список погибших героев -> алтарь применяет воскрешение к погибшему герою

Проверено в игре Быстрая полоса

Герой идёт подбирать предмет с земли (item — из items_on_ground). После подбора предмет появляется в инвентаре, а для земли приходит событие item.removed.

Механизм W3P target: правый клик по предмету

Проверено в игре Быстрая полоса

Использовать предмет из ячейки инвентаря slot (0~5); можно указать целевой юнит или целевую точку. ⚠ При использовании предмета в точку (например, Башни из слоновой кости) движок и при успехе возвращает 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: магазин продаёт предмет стоящему рядом герою

Выведено Быстрая полоса

Призыв к оружию у Людей: крестьяне превращаются в Ополчение (у Ратуши первого уровня этой способности нет — работает только у Крепости/Замка).

Механизм W3P immediate: townbellon/off

Проверено в игре Быстрая полоса

Управление игрой 9

Скорость игры, пауза, период публикации, облачка реплик, холст, интерфейс и ввод, сообщения.

Интерфейс и ввод (openwar3.ui.UI): кликабельные кнопки и карточки выбора, горячие клавиши, выбор точки кликом по земле, куда указывает мышь. Клик по кнопке до игры не доходит; только локальный ввод + локальная отрисовка, поэтому безопасно и в многопользовательской игре.

Механизм W3P 74 input_enable + общая память Local\War3Input_<pid> (рантайм получает ввод окна игры)

Проверено в игре Общая память

Скорость игры (100 = обычная).

Механизм Действие 47 (25~800%)

Проверено в игре Канал управления

Поставить игру на паузу / снять с паузы. На паузе часы движка стоят, но через быструю полосу приказы отдавать можно (диспетчеризация событий продолжает работать).

Механизм W3P pause

Проверено в игре Быстрая полоса

Период публикации состояния мира (16~1000 миллисекунд, по умолчанию 50). Один сбор — около 0.5 ms, так что и 33 ms не проблема; значение одно на всю машину, действует последнее записанное.

Механизм requestedPeriodMs блока мира

Проверено в игре Push-снимок

Показать облачко чата над юнитом (для трансляций/отладки, на игру не влияет). Если облачко не появилось, возвращает False; причина — в g.last_say_error.

Механизм Действие 56

Проверено в игре Канал управления

Вывести строку в области сообщений в левом нижнем углу игры (видно только на этой машине). Сначала игра должна сама показать хотя бы одну подсказку (DLL перехватывает окно сообщений именно в тот момент).

Механизм Действие 45

Выведено Канал управления

Завершить этот процесс игры (farm.py --keep автоматически начнёт следующую партию согласно next_game.json).

Механизм Действие 22

Проверено в игре Канал управления

Холст: рисует поверх игрового экрана текстовые блоки, панели, индикаторы прогресса, изображения, круги и маршруты на земле (openwar3.canvas.Canvas). Рисует сам рантайм, не создаёт игровых дескрипторов и не меняет состояние игры — поэтому безопасен и в многопользовательской игре; стиль любой (китайский текст, скругления, полупрозрачность).

Механизм 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 преобразуются автоматически (объекты юнитов/предметов передаются как есть); в многопользовательской игре можно вызывать только функции чтения. Подробнее — 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

Проверено в игре Быстрая полоса

Показать строку текста в левом нижнем углу экрана (такой текст выводят триггеры карты), по умолчанию — локальному игроку. Поддерживаются цветовые коды |cffRRGGBB.

Механизм JASS DisplayTimedTextToPlayer

Проверено в игре Быстрая полоса

Подключение и утилиты 2

Состояние подключения и чисто вычислительные утилиты.

Состояние подключения: pid, публикация мира (период, время сбора), счётчики быстрой полосы.

Механизм Блок мира + быстрая полоса + таблица захватов

Проверено в игре Локальный расчёт

Ближайший к to (юнит или (x,y)); если кандидатов нет — None.

Механизм Чистое вычисление

Проверено в игре Локальный расчёт