# Canal JASS

> As 1291 funções JASS que autores de mapas podem usar agora podem ser chamadas pelo nome, de fora do jogo: criar unidades, alterar atributos, efeitos, painéis, caixas de diálogo, sons, câmera, névoa… Quatro formas de uso: console Farsight, linha de comando, HTTP e Python.

Fonte: https://war3ai.com/pt/docs/jass/

As **1291 natives JASS** que autores de mapas podem usar nos scripts dos mapas agora podem ser chamadas pelo nome, de fora do jogo: criar unidades, alterar atributos, desenhar efeitos, abrir painéis e caixas de diálogo, tocar sons, mover a câmera, mudar a névoa… Use isso para personalizar ainda mais o jogo — auxiliares para RPG, [companheiros de IA](https://war3ai.com/pt/docs/companion/), minijogos próprios, ferramentas de depuração.

| Forma de uso | Para quê | Onde |
|---|---|---|
| **Página “Console JASS” do Farsight** | Testar à mão, ajustando enquanto vê o resultado | Barra lateral esquerda, “Sistema → Console JASS”: escreva o script e clique em executar; à direita, consulte as funções por categoria e clique numa delas para inseri-la no script |
| **Linha de comando** | Testar à mão, ou salvar como arquivo de script e rodar várias vezes | `python -m openwar3 jass --inst 20` (interativo), `-e "código"`, `my_script.j`, `--list palavra-chave` |
| **HTTP** | Programas externos em qualquer linguagem | `POST /api/instances/{n}/jass` etc. (veja abaixo); o backend do Farsight só escuta na máquina local |
| **Python** | Escrever esquemas, companheiros e ferramentas | `g.jass.QualquerFunção(...)`; os efeitos visuais e interações mais comuns estão empacotados em `openwar3.visual` |

> **Atenção**
>
> Três limites, todos impostos pelo mecanismo:
> 
> - Só em **partidas solo** (contra o computador, nesta máquina) dá para alterar o mundo. Se esta máquina cria objetos e altera unidades por conta própria, os outros jogadores de uma partida multijogador perdem a sincronia — por isso, em partidas multijogador, só funções de leitura são liberadas (`Get*`, `Is*`, `Count*`…).
> - É só para as ferramentas desta própria máquina; chamadas feitas conectado como jogador (`Game(player=N)`) ou no modo justo são rejeitadas.
> - Só para partidas offline, em rede local ou criadas por você.
> 
> Para acrescentar coisas à tela numa partida multijogador, use o [canvas](https://war3ai.com/pt/docs/canvas/): ele é desenhado pelo próprio runtime e não altera o estado do jogo.

## Como escrever scripts

O console, a linha de comando e o HTTP usam o mesmo tipo de script. Uma instrução por linha; **dá para colar JASS direto** (`call` / `set` / `local`, `true` / `false` / `null`, códigos de quatro caracteres como `'Hpal'`, comentários `//`), ou escrever no estilo Python:

```text
set h = hero()                                   // embutido: o herói principal do meu lado
local texttag t = CreateTextTag()
call SetTextTagText(t, "|cffffcc00+128 Crítico!|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("criei", u, "nível do herói", GetHeroLevel(h))
```

- **As variáveis ficam guardadas**: na mesma instância e na mesma partida, as variáveis definidas com `set` num trecho continuam disponíveis no próximo; ao trocar de partida, elas são limpas automaticamente, e também dá para limpá-las à mão.
- **Funções embutidas**: `hero()` o herói principal do seu lado, `me()` o jogador local, `unit('hfoo')` encontra uma unidade, `unit_at(x, y)`, `wait(segundos)`, `print(...)`. Unidades expõem `.x`, `.y`, `.hp`, `.hp_max`, `.mana`, `.type`, `.owner` e `.level`, com suporte a aritmética e comparações.
- **Sem suporte** a `if`, `loop` e `function` — para escrever lógica, use o `g.jass` do Python (são chamadas de função comuns) ou escreva um [esquema](https://war3ai.com/pt/docs/schemes/).
- Quando há erro, ele diz em que linha e por quê (função inexistente, número errado de parâmetros, variável não definida…); as instruções antes do erro já tiveram efeito.

Parâmetros e valores de retorno:

| Na assinatura | O que passar | Observações |
|---|---|---|
| Inteiro | Número; códigos de quatro caracteres como `'Hpal'` são convertidos automaticamente | |
| Real | Número | O runtime converte para o formato que o motor espera |
| Booleano | `true` / `false` | |
| String | `"..."` | Aceita chinês (e outros caracteres fora do ASCII) e os códigos de cor do jogo; strings que o jogo guarda (texto flutuante, painéis, botões, comandos de chat) são copiadas na hora, com segurança |
| Handle | Um handle guardado numa variável, ou uma unidade (algo como `hero()` vira handle automaticamente) | |
| Função (code) | Só `null` | De fora, não dá para fornecer uma função JASS; algo como `TimerStart(t, 60, false, null)` funciona |
| Retorno string | — | O motor retorna o índice na tabela de strings, e o texto não pode ser lido de volta. Para nomes de unidades, use `g.map_data.name_of` |

## Categorias

As funções são agrupadas em categorias pelo nome; o lado direito do console e o `--list` seguem esse agrupamento:

| Categoria | Quantidade | Exemplos |
|---|---|---|
| Efeitos visuais | 80 | Texto flutuante, raios entre unidades, efeitos especiais, imagens no chão, marcas no chão, cor / escala / animação de unidades |
| Painéis de interface | 146 | Painéis de várias linhas, placares, janelas de contagem regressiva, caixas de diálogo, missões, texto na tela, pings no minimapa, diálogo com retrato, filtros de tela cheia |
| Câmera | 44 | Campos da câmera, panorâmica, tremor de câmera |
| Sons e música | 50 | Criar e tocar sons, tocar música |
| Névoa e visão | 25 | Áreas visíveis, ligar e desligar a névoa |
| Itens / heróis / unidades | 63 / 32 / 161 | Criar itens, definir o nível do herói, trocar de dono, adicionar habilidades |
| Jogadores / alianças / recursos | 71 | Definir alianças, alterar ouro e madeira |
| Gatilhos / eventos / temporizadores | 62 | Criar gatilhos, registrar eventos, temporizadores |
| Terreno / clima / destrutíveis | 45 | Efeitos de clima, alterar o terreno, criar destrutíveis |
| Fluxo da partida | 57 | Velocidade do jogo, pausa, hora do dia |
| Outros | … | Grupos de unidades e regiões, armazenamento, scripts de IA do computador, conversão de tipos e matemática, respostas de evento… |

Em 2026-09-24, **94** delas foram chamadas uma a uma em partidas reais, com o efeito conferido a olho; as demais passam pelo mesmo caminho, só não tiveram o efeito conferido uma a uma.

> **Nota**
>
> Funções de “resposta de evento” (`GetTriggerUnit`, `GetClickedButton`…) só têm valor no instante em que um gatilho está executando; chamadas de fora recebem 0 ou vazio. Para saber “se aconteceu”, use a contagem de eventos descrita mais abaixo.

## HTTP

Backend do Farsight (padrão `127.0.0.1:8866`, só escuta na máquina local):

```http
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": {...}}
     -> erro: {"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  limpa as variáveis guardadas
```

Parâmetros de unidade são escritos como `{"unit": endereço}`, onde o endereço é o `addr` da unidade no snapshot. Medido: 60 ~ 90 ms por requisição.

## Python: g.jass e openwar3.visual

```python
j = g.jass
t = j.CreateTextTag()
j.SetTextTagText(t, "Olá", 0.024)      # mesmas regras de parâmetros do script; objetos de unidade e de item do snapshot podem ser passados direto
j.signature("CreateImage")             # consulta a assinatura
```

`openwar3.visual.Visual(g)` empacota os efeitos visuais comuns já testados, uma linha para cada (chame `v.tick()` a cada tick: remove o que expirou e move as linhas e os círculos que seguem unidades; `v.clear()` remove tudo):

| Método | Efeito |
|---|---|
| `float_text(texto, unidade ou ponto, ...)` | Texto flutuante: números de dano, avisos sobre a cabeça; aceita chinês e cores |
| `link(a, b, kind)` | Uma linha entre duas unidades, que acompanha as unidades: Magic Leash / Spirit Link / Drain Life / Healing Wave |
| `effect(modelo, unidade ou ponto, ...)` | Modelo de efeito: sobre a cabeça, nos pés, ou tocado uma vez (explosão, coluna de luz) |
| `ring(unidade ou ponto, raio, color)` | Círculo de alcance no chão: alcance de habilidade, área de perigo, ponto de encontro; pode seguir uma unidade |
| `ping(ponto, color)` | Ping no minimapa |
| `board(título, linhas...)` | Painel de várias linhas no canto superior direito (com ícones), editável célula a célula |
| `countdown(título, segundos)` | Janela de contagem regressiva no canto superior direito; o próprio jogo conta os segundos |
| `scene(nome, fala, portrait)` | Diálogo com retrato: o retrato na parte de baixo passa a ser a unidade que fala, e aparece a legenda “nome: fala” na tela |
| `screen_tint(color, alpha)` | Filtro de tela cheia (padrão: bordas avermelhadas, aviso de vida baixa) |
| `sound(caminho)` / `reveal(ponto, raio, segundos)` / `look(unidade, ...)` | Tocar um som / dissipar a névoa numa área / mudar a cor de uma unidade, aumentá-la, tocar uma animação, fazê-la piscar |

## Interação: saber o que o jogador fez sem escrever funções JASS

Em JASS, reagir ao jogador exige escrever funções de gatilho, e de fora não dá para fornecer funções. A saída é: **criar um gatilho vazio, sem condições nem ações, só registrar o evento e contar quantas vezes ele executou.** Nos testes, gatilhos vazios contam normalmente.

| Método | Uso |
|---|---|
| `chat_commands(["-follow", "-stay"])` → `.poll()` | Comandos que o jogador digita no chat (correspondência exata ou pelo início) |
| `menu(título, [botões...])` → `.clicked()` | Menu de botões no centro da tela: qual deles foi clicado |
| `hotkeys(("left", "right", "up", "down", "esc"))` → `.poll()` | Quantas vezes as setas e o Esc foram pressionados |
| `on("TriggerRegister...Event", parâmetros...)` → `.poll()` | Quantas vezes qualquer evento JASS aconteceu: morte de unidade, entrada numa região, dano recebido, temporizador… |

A limitação é que você só sabe “quantas vezes aconteceu”, não “quem foi, o que foi digitado”. Para distinguir quem foi, crie um contador para cada objeto. Os comandos de chat do [companheiro de IA](https://war3ai.com/pt/docs/companion/) foram ligados exatamente assim.

## Cuidados

- **O que você cria, você mesmo precisa remover**: textos flutuantes, linhas, imagens, painéis, gatilhos… se não forem removidos, ficam lá para sempre (`Visual.clear()` remove o que ele mesmo criou). O jogo suporta no máximo cerca de 100 textos flutuantes ao mesmo tempo.
- **Funções BJ não são natives**: `CreateTextTagUnitBJ` e similares são montadas com natives nos scripts dos mapas e não existem aqui — chame as natives seguindo a implementação delas.
- **Algumas constantes precisam ser convertidas antes**: por exemplo, `ConvertPlayerColor(1)` e `ConvertFogState(4)` (os valores estão em common.j).
- Cerca de 13 ms por chamada (incluindo a conversão de handles); na camada de protocolo, são os opcodes W3P 70 ~ 72; veja [Protocolo W3P](https://war3ai.com/pt/docs/protocol/).
