Docs Conceitos centrais

Modo justo

Um cliente injetado no jogo consegue ler o mapa inteiro. O modo justo faz o Bot enxergar só o que está na sua visão — como um jogador humano, e como na regra da Arena.

A capacidade de observação deste projeto vem do fato de que “o cliente guarda o estado de todos os jogadores”: o snapshot traz todas as unidades do mapa inteiro, inclusive inimigos na névoa de guerra. Isso é ótimo para depurar, mas injusto numa competição.

O modo justo faz o SDK filtrar tudo pela sua visão:

python tools/play.py --bot my_bot.py --fair
python -m openwar3 run my_bot.py --inst 5 --fair
from openwar3 import Game, run
g = Game(inst=5, fair=True)            # usando Game diretamente
run(MyBot, inst=5, fair=True)          # ou deixando com o executor

O que é filtrado

ConteúdoNo modo justo
UnidadesTodas as suas + as unidades inimigas e neutras que o seu lado vê neste momento
Itens no chãoSó os que estão na visão das suas unidades (visão de dia / de noite calculada separadamente, pela tabela de dados)
Tabela de produçãoSó construções visíveis (você não vê o que o adversário está treinando)
EventosOs seus; os visíveis (ou vistos no último 1 segundo); o dano causado pelo seu lado

De onde vem a visão

  • Cada unidade no snapshot traz uma máscara de visibilidade: bit p = o jogador p a vê neste momento (só contam os jogadores 0 ~ 11 com unidades em campo; suas próprias unidades são sempre visíveis para você). u.visible_to(g.me()) lê isso direto, sem espera.
  • Para qualquer ponto: g.visible(x, y) pergunta ao motor (visível / névoa de guerra / máscara preta), pela via rápida, cerca de um frame por chamada. Quando precisar checar muitas unidades num tick, use u.visible_to() do snapshot em vez de chamar g.visible() uma a uma.

A memória dos inimigos: last_seen

Um jogador humano lembra que “agora há pouco viu um grupo de Wolf Riders ali”. O SDK também lembra por você: a cada atualização do snapshot, registra as unidades inimigas e os creeps que o seu lado vê naquele momento (última posição, vida, tempo); quando vê um deles morrer, apaga o registro; ao trocar de partida, limpa tudo.

for u, t, age in g.last_seen(max_age=60):         # inimigos vistos nos últimos 60 segundos de jogo
    print(u.type, u.x, u.y, f"há {age:.0f}s")

heroes = [r for r in g.last_seen() if r[0].is_hero]   # onde os heróis inimigos estavam da última vez
camps  = g.last_seen(owner="creep")                   # creeps já vistos

No modo justo, esta é a sua única “fonte de informação sobre o adversário” — como para um jogador humano. O modo normal também registra pela visão, então o mesmo código serve para os dois.

Comandar como um jogador específico

python tools/play.py --bot my_bot.py --player 1 --attach

--player N (ou Game(player=N)) faz o Bot comandar como o jogador N, e ele só pode comandar unidades do jogador N. Duas IAs se enfrentando são dois canais desses na mesma partida.

No modo local, o jogo limpo é um acordo, não uma barreira de segurança

Na sua própria máquina, não há como impedir um programa de ler o mapa inteiro. --fair é uma restrição que você impõe a si mesmo; partidas de verdade são garantidas pelo processo árbitro da Arena: o Bot nunca toca na memória compartilhada, só recebe as observações que o árbitro filtrou pela visão, só pode enviar ações, e cada ação tem a propriedade das unidades verificada antes.

Por que ativar desde já

  • Quando você for para a Arena, a regra vai ser esta; escrevendo para o modo justo agora, você não vai precisar mudar uma linha depois;
  • Só sem a informação do mapa inteiro você descobre o nível real do seu Bot (hoje, o cérebro de referência depende muito da informação do mapa inteiro, como o ponto-alvo do capitão do computador — e isso é um bom teste);
  • Reconhecimento, memória e julgamento escritos no modo justo são a capacidade de IA que realmente tem valor.