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 协议。