# Como criar um bot para jogos Android no MAS

> Como criar um bot para jogos Android no Macro Automation Studio: instale um do Marketplace, peça ao MAS Agent ou programe em Python no BlueStacks.

Source: https://automationmacro.com/pt-BR/docs/make-a-bot-for-any-game (Guias, updated 2026-09-05)

Este tutorial mostra como criar um bot para jogos Android no Macro Automation Studio (MAS), de um jogo instalado até um bot que roda em um agendamento, em uma conta ou em várias. Os bots do MAS trabalham a partir da tela: encontram botões por imagem, leem contadores com OCR e tocam com tempo humanizado. Ele é para quem está montando o primeiro bot, no Windows ou no Mac.

<div class="doc-video" data-video="SDrdMIV49a8" data-title="How to make a bot for any game"></div>

## Antes de começar

- O MAS está instalado e você fez login com o teste gratuito ou um plano. Veja [Instalar o MAS](/docs/install).
- O jogo roda em um dispositivo que o MAS consegue controlar: um emulador neste computador, um dispositivo na nuvem ou o seu próprio celular. Veja [Dispositivos](/docs/devices).
- O dispositivo está em um grupo de dispositivos e o card dele mostra Parado, não Erro. A página [Primeiros passos](/docs/getting-started) mostra como adicionar um.
- Para o caminho em Python, você não precisa de mais nada. O MAS traz o próprio ambiente Python com o pacote `mas`.

## Como criar um bot para jogos Android: três caminhos

### Instalar um do Marketplace

O caminho mais rápido quando alguém já montou um bot para o seu jogo.

1. Abra o **Marketplace** e pesquise o jogo.
2. Abra a listagem e clique em **Baixar**. O bot aparece em **Macros**.
3. Em **Grupos de dispositivos**, abra o seu grupo, escolha o bot no seletor **Macro** do dispositivo e clique em **Iniciar**.

O passo a passo completo com capturas de tela está em [Como rodar uma macro do Marketplace](/docs/run-macro-from-marketplace). Existem bots prontos para [Whiteout Survival](/whiteout-survival-bot), [Kingshot](/kingshot-bot) e [Last Asylum: Plague](/last-asylum-plague-bot).

### Pedir ao MAS Agent

O caminho sem código para um jogo sem listagem.

1. Abra **Agent** e escolha o dispositivo.
2. Descreva a rotina em uma frase, incluindo quando ela deve parar, e clique em **Gerar**.
3. Responda quando o agente perguntar. Ele para e pergunta em vez de adivinhar.
4. Quando a macro passar em 3 execuções de validação, clique em **Adicionar às minhas macros**.

Gerar a macro consome créditos de IA; rodar a macro pronta não consome nenhum. O resultado é um projeto Python normal que você pode abrir e editar. Veja [MAS Agent](/docs/agent).

### Montar em Python

Controle total sobre toda decisão que o bot toma. O resto desta página é esse caminho.

## Automatizar jogos Android com Python

### 1. Liste o que o bot precisa ver

Jogue a rotina uma vez à mão e anote toda tela que ela toca. Isso inclui o botão que você aperta, os pop-ups que interrompem, o contador que mostra a sua energia e a mensagem que significa que acabou. Cada item vira uma imagem template ou uma região de OCR. Um bot que conhece o seu estado de parada nunca roda às cegas.

### 2. Crie o projeto

1. Abra **Macros** e clique em **Criar novo projeto**.
2. Escolha **Baseado em código**, defina **Dispositivo alvo** como mobile, dê um nome ao projeto e clique em **Criar projeto**.
3. Abra o projeto. O Code Editor mostra `src/app.py`, o arquivo que o MAS executa.

### 3. Capture os templates no Asset Lab

1. Abra o jogo no dispositivo e vá até a tela com o botão.
2. No Code Editor, abra o painel **Assets** e clique em **Abrir o Asset Helper**. O Asset Lab abre com a tela ao vivo.
3. Recorte um retângulo justo em volta do botão e salve. Ele entra na sua Biblioteca de imagens com um ID numérico.
4. Repita para o botão de fechar pop-up, o botão de confirmar e a mensagem de "sem energia".
5. De volta ao painel **Assets**, use **Copiar ID** em cada imagem e cole os IDs em `mas.images` no topo do seu script.

Mantenha os recortes pequenos e distintos. Uma tela inteira só corresponde àquela tela exata; um botão corresponde onde quer que o botão apareça. Os templates podem ser jpg, png, gif ou webp, com até 10 MB cada. A página [Asset Lab](/docs/asset-lab) cobre a ferramenta em detalhe.

### 4. Capture uma região de OCR

1. No Asset Lab, desenhe uma caixa em volta do contador que você quer ler.
2. Rode o teste de OCR ao vivo e aperte a caixa até os dígitos voltarem limpos.
3. Copie as coordenadas para uma `Region(x1, y1, x2, y2)` no seu script.

O [guia de OCR](/docs/guides/ocr-text-reading) explica os modos de segmentação e a conversão de cor se o texto for lido mal.

### 5. Escreva o loop

O loop abaixo é a forma que todo bot de jogo compartilha. Cada linha corresponde a uma chamada do SDK:

- `find_object_retry` procura o botão até `total_tries=3` vezes, com `time_sleep=2.0` segundos de intervalo, e retorna `None` quando nada corresponde.
- `click(x, y, delay_ms=1000)` toca no centro da correspondência e espera um segundo para o jogo reagir.
- `read_text(region, psm=7)` lê o contador como uma única linha.
- `time.sleep(random.uniform(0.8, 2.0))` adiciona uma pausa humana entre as rodadas.
- `mas.save` e `mas.retrieve` guardam o contador de rodadas, então uma execução interrompida retoma de onde parou.
- As condições de parada encerram o loop. O exemplo usa cinco: um número máximo de rodadas, um limite de tempo, o template "sem energia", um contador baixo e falhas demais em sequência.

### 6. Rode e leia os logs

Escolha o dispositivo no Code Editor e clique em **Executar** (<kbd>F5</kbd>). Toda linha de `mas.log` aparece no console de execução. **Parar** é <kbd>Shift</kbd>+<kbd>F5</kbd>. Corrija uma coisa de cada vez: quando um template não é encontrado, recorte-o de novo antes de mexer na lógica.

### 7. Agende

1. Abra o **Agendador** e clique em **Criar novo agendamento**.
2. Preencha o **Nome**, escolha a **Macro** e a **Porta do emulador**, defina **Data** e **Hora**.
3. Defina a **Recorrência** como **Diária** e clique em **Criar agendamento**.

O app precisa ficar aberto; o agendador roda dentro dele. Veja [Agendador](/docs/scheduler) e [Loops e agendamento](/docs/guides/loops-and-scheduling).

### 8. Rode em um grupo de dispositivos

Adicione a instância de emulador de cada conta como um dispositivo em um grupo, atribua o bot a cada dispositivo e clique em **Iniciar todos**. Os valores por dispositivo, como o nome da conta, vêm de um perfil de configurações. Veja [Farm multi-instância](/docs/guides/multi-instance).

## Um bot de exemplo completo

Troque os IDs de imagem e a região pelos que você capturou. O script farma um recurso até a energia ficar baixa, o limite de tempo passar ou trinta rodadas terminarem, e sobrevive a uma reinicialização.

```python
import random
import sys
import time

import mas
from mas import Region

images = mas.images({
    "attack_button": 101,
    "confirm_button": 102,
    "close_popup": 103,
    "out_of_energy": 104,
})

ENERGY_REGION = Region(x1=380, y1=20, x2=520, y2=60)
TASK = "farm_bot"
MAX_ROUNDS = 30
TIME_BUDGET_S = 20 * 60
MIN_ENERGY = 10


def pause(low=0.8, high=2.0):
    time.sleep(random.uniform(low, high))


def read_energy():
    result = mas.read_text(region=ENERGY_REGION, psm=7)
    digits = "".join(ch for ch in result.text if ch.isdigit())
    return int(digits) if digits else None


def clear_popups():
    popup = mas.find_any_object([images.close_popup, images.confirm_button])
    if popup:
        mas.click(popup.x, popup.y, delay_ms=800)
        return True
    return False


def main():
    rounds = mas.retrieve(TASK).get("rounds", 0)
    misses = 0
    started = time.monotonic()
    mas.log(f"Starting at round {rounds}")

    while rounds < MAX_ROUNDS:
        if time.monotonic() - started > TIME_BUDGET_S:
            mas.log("Time budget reached", level="warning")
            break
        if clear_popups():
            continue
        if mas.find_object(images.out_of_energy):
            mas.log("Out of energy, stopping")
            break
        energy = read_energy()
        if energy is not None and energy < MIN_ENERGY:
            mas.log(f"Energy {energy} is below {MIN_ENERGY}, stopping")
            break
        button = mas.find_object_retry(images.attack_button, total_tries=3, time_sleep=2.0)
        if button is None:
            misses += 1
            mas.log(f"Attack button not found ({misses})", level="warning")
            if misses >= 5:
                mas.log("Giving up after 5 misses", level="error")
                sys.exit(2)
            continue
        misses = 0
        mas.click(button.x, button.y, delay_ms=1000)
        pause()
        rounds += 1
        mas.save(TASK, {"rounds": rounds})
        mas.log(f"Round {rounds} of {MAX_ROUNDS}")

    if rounds >= MAX_ROUNDS:
        mas.clear(TASK)
    mas.log(f"Finished with {rounds} rounds")


if __name__ == "__main__":
    main()
```

`sys.exit(2)` marca a execução como falha, então um webhook inscrito em `macro.failed` fica sabendo. Uma saída limpa informa `macro.completed`. Veja [Webhooks](/docs/webhooks).

## Dicas que mantêm um bot estável

- **Resolução.** Templates e regiões pertencem à resolução e ao DPI em que você os capturou. Mantenha todo dispositivo que roda o bot na mesma configuração; os guias de emulador usam 540x960 em retrato a 240 DPI como base.
- **Higiene dos templates.** Recorte só o botão, nunca o fundo em volta. Recorte de novo depois que uma atualização do jogo mudar a arte. Quando um botão tem duas aparências, capture as duas e procure com `find_any_object`.
- **Condições de parada.** Todo loop precisa de pelo menos duas: um contador ou limite de tempo, e um estado de tela que significa "acabou". Um bot sem elas roda até você perceber.
- **Vá devagar.** Uma pausa de um a dois segundos entre as rodadas custa pouco e parece menos mecânica.
- **Registre a decisão, não o toque.** `mas.log("Energy 8, stopping")` diz por que uma execução terminou; um log de cem cliques não diz.

## O que pode dar errado

### O botão nunca é encontrado

O recorte é grande demais, o limiar é rígido demais para a arte, ou o dispositivo roda em uma resolução diferente daquela em que você capturou. Recorte mais justo, depois tente `threshold=0.7` na chamada. O [guia de reconhecimento de imagem](/docs/guides/image-recognition-macros) tem a lista completa.

### O contador lê o número errado

A região inclui um ícone vizinho, ou o texto é claro sobre fundo escuro. Aperte a caixa no Asset Lab e passe `color_conversion=ColorConversion.BLACK_WHITE`. O [guia de OCR](/docs/guides/ocr-text-reading) mostra como conferir a confiança.

### O bot para na hora no segundo dia

O contador guardado já está no limite. O exemplo limpa o armazenamento ao chegar em `MAX_ROUNDS`; se você mudou isso, chame `mas.clear("farm_bot")` uma vez a partir de um script de rascunho.

### Os cliques caem ao lado do botão

A resolução ou o DPI do emulador mudou depois da captura, ou a janela não está em retrato. Volte a tela do emulador para a configuração da captura e capture de novo tudo o que ainda errar.

Nenhuma ferramenta de automação é 100% livre de riscos, por isso automatize com responsabilidade e a seu próprio critério.
