JASS 通道
地圖作者能用的 1291 個 JASS 函式,現在可以從遊戲外面依名稱直接呼叫:造單位、改屬性、特效、面板、對話框、聲音、鏡頭、迷霧……遠見指揮台、命令列、HTTP、Python 四種用法。
地圖作者在地圖腳本裡能用的 1291 個 JASS native,現在都能從遊戲外面依名稱直接呼叫:造單位、改屬性、畫特效、彈出面板和對話框、播放聲音、移動鏡頭、改迷霧……拿來為遊戲做進一步的自訂 —— RPG 輔助、AI 玩伴、自製小玩法、偵錯工具。
| 用法 | 適合 | 入口 |
|---|---|---|
| 遠見「JASS 控制台」頁 | 手動試、邊看邊改 | 左側欄「系統 → JASS 控制台」:寫好腳本點執行,右邊依分類查函式,點一下就插入腳本 |
| 命令列 | 手動試,或寫成腳本檔案反覆執行 | python -m openwar3 jass --inst 20(互動)、-e "程式碼"、my_script.j、--list 關鍵字 |
| HTTP | 任何語言的外部程式 | POST /api/instances/{n}/jass 等(見下文),遠見後端只監聽本機 |
| Python | 寫方案、寫玩伴、寫工具 | g.jass.任意函式(...);常用的畫面和互動封裝在 openwar3.visual |
三條邊界,都是機制決定的:
- 只有單人局(和本機的電腦打)能修改世界。本機單方面建立物件、修改單位會讓多人局裡其他玩家不同步 —— 多人局只放行唯讀的函式(
Get*、Is*、Count*……)。 - 只給本機自己的工具使用;以玩家身分連線(
Game(player=N))或在公平模式下呼叫會被拒絕。 - 只用於單機、區域網路自建的遊戲。
要在多人局裡往畫面上加東西,用 畫板:它是執行環境自己畫的,不修改遊戲狀態。
腳本寫法
控制台、命令列、HTTP 用的是同一套腳本。一行一句,可以直接貼上 JASS(call / set / local、true / false / null、'Hpal' 四字碼、// 註解),也可以寫成 Python 的樣子:
set h = hero() // 內建:我方主英雄
local texttag t = CreateTextTag()
call SetTextTagText(t, "|cffffcc00+128 爆擊!|r", 0.024)
call SetTextTagPosUnit(t, h, 60)
call SetTextTagVelocity(t, 0, 0.03)
call SetTextTagPermanent(t, false)
call SetTextTagLifespan(t, 4)
call SetTextTagVisibility(t, true)
call PingMinimapEx(h.x, h.y + 300, 3, 255, 0, 0, false)
set u = CreateUnit(Player(0), 'hfoo', h.x + 200, h.y, 270)
print("造了", u, "英雄等級", GetHeroLevel(h))
- 變數一直記著:同一個實例、同一局裡,這一段
set的變數下一段可以接著用;換局自動清空,也可以手動清除。 - 內建函式:
hero()我方主英雄、me()本機玩家、unit('hfoo')找一個單位、unit_at(x, y)、wait(秒)、print(...)。單位能讀.x、.y、.hp、.hp_max、.mana、.type、.owner、.level,支援四則運算和比較。 - 不支援
if、loop、function—— 要寫邏輯,就用 Python 的g.jass(它就是普通的函式呼叫),或者寫成 方案。 - 出錯時會告訴你第幾行、為什麼(沒有這個函式、參數個數不對、變數未定義……);出錯之前的語句已經生效。
參數和回傳值:
| 簽章裡 | 傳什麼 | 說明 |
|---|---|---|
| 整數 | 數字;'Hpal' 四字碼自動轉換 | |
| 實數 | 數字 | 執行環境轉成引擎要的格式 |
| 布林 | true / false | |
| 字串 | "..." | 支援中文和遊戲的顏色碼;會被遊戲存起來的那些(浮動文字、面板、按鈕、聊天命令)都是當場複製一份,安全 |
| 控制代碼 | 變數裡的控制代碼,或者單位(hero() 這種會自動換成控制代碼) | |
| 函式(code) | 只能 null | 從外面給不出 JASS 函式;TimerStart(t, 60, false, null) 這種可以 |
| 回傳字串 | —— | 引擎回傳的是字串表編號,讀不回文字。單位名稱用 g.map_data.name_of |
分類
函式依名稱分了類,控制台右邊和 --list 都依這個分:
| 分類 | 個數 | 例子 |
|---|---|---|
| 畫面效果 | 80 | 浮動文字、閃電連線、特效、地面貼圖、地面印記、單位變色 / 縮放 / 播放動作 |
| 介面面板 | 146 | 多行面板、排行榜、倒數計時視窗、對話框、任務、螢幕文字、小地圖閃點、頭像對白、全螢幕濾鏡 |
| 鏡頭 | 44 | 鏡頭欄位、平移、鏡頭震動 |
| 聲音音樂 | 50 | 建立和播放聲音、播放音樂 |
| 迷霧視野 | 25 | 可見區域、開關迷霧 |
| 物品 / 英雄 / 單位 | 63 / 32 / 161 | 造物品、設英雄等級、換擁有者、加技能 |
| 玩家 / 同盟 / 資源 | 71 | 設同盟、改金錢木材 |
| 觸發器 / 事件 / 計時器 | 62 | 建立觸發器、註冊事件、計時器 |
| 地形 / 天氣 / 可破壞物 | 45 | 天氣效果、改地形、造可破壞物 |
| 遊戲流程 | 57 | 遊戲速度、暫停、晝夜時間 |
| 其他 | …… | 單位組與區域、儲存、電腦 AI 腳本、型別轉換與數學、事件回應…… |
2026-09-24 逐一實機呼叫、親眼看過效果的有 94 個;其餘走的是同一條路,只是沒有逐一看過效果。
「事件回應」類函式(GetTriggerUnit、GetClickedButton……)只在觸發器執行的那一刻有值,從外面呼叫拿到的是 0 或空值。想知道「發生了沒有」,用下文的事件計數。
HTTP
遠見後端(預設 127.0.0.1:8866,只監聽本機):
GET /api/jass/natives?q=TextTag&cat=visual
POST /api/instances/20/jass {"code": "set h = hero()\ncall PingMinimapEx(h.x, h.y, 3, 255, 0, 0, false)"}
-> {"ok": true, "rows": [...], "printed": [...], "vars": {...}}
-> 出錯:{"ok": false, "error": "第 2 行:...", "line": 2}
POST /api/instances/20/jass/call {"name": "SetUnitScale", "args": [{"unit": 599669636}, 1.4, 1.4, 1.4]}
POST /api/instances/20/jass/reset 清掉記住的變數
單位參數寫 {"unit": 位址},位址就是快照裡單位的 addr。實測一次請求 60 ~ 90 ms。
Python:g.jass 和 openwar3.visual
j = g.jass
t = j.CreateTextTag()
j.SetTextTagText(t, "你好", 0.024) # 參數規則和腳本一樣;快照裡的單位、物品物件可以直接傳
j.signature("CreateImage") # 查簽章
openwar3.visual.Visual(g) 把實測過的常用畫面效果封裝成一句話一個(每拍呼叫一次 v.tick():到期的刪掉、跟著單位的線和圈移過去;v.clear() 全部刪除):
| 方法 | 效果 |
|---|---|
float_text(文字, 單位或點, ...) | 浮動文字:傷害數字、頭頂提示,中文和顏色都行 |
link(a, b, kind) | 兩個單位之間一條線,跟著單位走:牽引 / 靈魂鏈 / 吸血 / 治療波 |
effect(模型, 單位或點, ...) | 特效模型:頭頂、腳下,或者播放一次(爆炸、光柱) |
ring(單位或點, 半徑, color) | 地上的範圍圈:技能範圍、危險區、集合點,可以跟隨單位 |
ping(點, color) | 小地圖閃點 |
board(標題, 行...) | 右上角多行面板(帶圖示),可以逐格修改 |
countdown(標題, 秒) | 右上角倒數計時視窗,遊戲自己走秒 |
scene(名字, 話, portrait) | 頭像對白:底部頭像換成會說話的單位,畫面上出現「名字:話」字幕 |
screen_tint(color, alpha) | 全螢幕濾鏡(預設四周泛紅:殘血警告) |
sound(路徑) / reveal(點, 半徑, 秒) / look(單位, ...) | 播放聲音 / 驅散一片迷霧 / 單位變色、放大、播放動作、閃一下 |
互動:不寫 JASS 函式,也知道玩家做了什麼
在 JASS 裡回應玩家要寫觸發器函式,而從外面給不出函式。辦法是:建一個沒有條件、沒有動作的空觸發器,只註冊事件,然後數它執行了幾次。 實測空觸發器照樣計數。
| 方法 | 用途 |
|---|---|
chat_commands(["-follow", "-stay"]) → .poll() | 玩家在聊天框裡輸入的命令(完全比對,或依開頭比對) |
menu(標題, [按鈕...]) → .clicked() | 畫面中央的按鈕選單,點了哪一個 |
hotkeys(("left", "right", "up", "down", "esc")) → .poll() | 方向鍵、Esc 按了幾次 |
on("TriggerRegister...Event", 參數...) → .poll() | 任意 JASS 事件發生了幾次:單位死亡、進入區域、受傷、計時器…… |
局限是只知道「發生了幾次」,不知道「是誰、打了什麼字」。要分清是誰,就為每個物件各建一個計數器。AI 玩伴 的聊天命令就是這樣接上的。
注意事項
- 建立出來的東西要自己刪:浮動文字、連線、貼圖、面板、觸發器……不刪就一直在(
Visual.clear()會刪它自己建立的)。遊戲裡同時最多約 100 個浮動文字。 - BJ 函式不是 native:
CreateTextTagUnitBJ這類是地圖腳本裡用 native 組出來的,這裡沒有 —— 照著它的實作去呼叫 native。 - 有些常數要先轉換:例如
ConvertPlayerColor(1)、ConvertFogState(4)(取值見 common.j)。 - 一次呼叫約 13 ms(含控制代碼換算);協定層是 W3P 操作碼 70 ~ 72,見 W3P 協定。