文件 玩法擴展

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 協定。