Depuración y rendimiento
Por qué un tick va lento, por qué un comando no surtió efecto, por qué el juego no se mueve. Diagnostica por síntomas y confírmalo con los scripts de verificación en vivo incluidos.
Mira el recibo
El recibo de cada comando es la primera pista:
r = g.cast(hero, "blizzard", x=tx, y=ty)
if not r:
print(r.reason, r.verdict) # rejected(…) y el código de motivo
print(r.exec_us, r.engine_us) # microsegundos en el hilo del juego / de ellos, cuánto tardó la propia función de órdenes del motor
Lo normal es que un comando tarde entre unos microsegundos y unos cientos de microsegundos en el hilo del juego. Al terminar un bloque de lote, g.last_receipts contiene el recibo de cada comando del lote.
Míralo en el juego
g.say(unit, "¡Retirada!") # burbuja de chat sobre la unidad (no afecta al juego)
g.message("Voy a hacer creeping") # una línea en el área de mensajes de abajo a la izquierda (solo se ve en tu equipo)
Lo que imprimas con print aparece en la terminal donde se ejecuta el Bot. Imprimir las decisiones clave de cada tick, junto con las burbujas, es mucho más rápido que leer el código.
Un tick va lento
Primero comprueba si es uno de estos casos:
| Causa | Solución |
|---|---|
| Enviar los comandos uno a uno, cada uno esperando un fotograma | Envuélvelos en with g.batch():; decenas de comandos esperan una sola vez |
Llamar a g.visible() / g.can_do() una y otra vez (cada llamada va por el carril rápido y espera un fotograma) | Para la visibilidad, usa u.visible_to() del snapshot; para la viabilidad, pregunta en lote con g.can_do_many([...]) |
sleep o esperas dentro de on_tick | Anota el tiempo de juego y vuelve a comprobarlo en el siguiente tick |
| Recalcular cosas caras en cada tick (rutas, barridos de todo el mapa) | Cachea el resultado y recalcula cada varios ticks. g.grid() trae una caché de 2 segundos, y los niveles de tecnología de g.stats() se cachean 5 segundos |
El juego no se mueve / el Bot nunca entra en la partida
| Síntoma | Causa probable |
|---|---|
| Se queda siempre “esperando a la partida” | Número de instancia incorrecto, o la ventana del juego está minimizada: al minimizarla, la simulación se detiene (el reloj no avanza) |
| El juego corre, pero las órdenes del Bot no hacen nada | Estás dando órdenes a unidades ajenas (recibo not_owner), o el Bot se conectó con el rol observer (forbidden) |
Comandos held | Una capa de mayor prioridad retiene esa unidad (la capa de reflejos del cerebro de referencia, las órdenes manuales de la consola) y no se enviaron |
| Se pueden dar comandos en pausa | Es normal: en pausa el reloj del motor se detiene, pero el despacho de eventos sigue funcionando y los comandos se ejecutan |
Conéctate y mira el estado
python -m openwar3 status --inst 5
Muestra el estado de la conexión: pid del juego, ciclo de publicación del mundo y tiempo de cada recogida, contadores del carril rápido, si hay partida en curso, número de unidades y reloj del juego.
Scripts de verificación en vivo
Abre una instancia de prueba y comprueba, punto por punto, que las capacidades del SDK funcionan en tu máquina:
python tools/sdk_live_check.py --inst 20 # todo
python tools/sdk_live_check.py --inst 20 --only prod # solo una sección
Secciones: lotes, tiempo, producción, órdenes en cola, estadísticas de combate, rutas, modo justo. Cada sección da comandos en una partida real, lee el efecto e imprime cuántas comprobaciones pasan.
Las pruebas offline no necesitan abrir el juego:
python tools/run_tests.py
Cosas que “parecen un bug”
- El recibo de construcción fue aceptado, pero nunca aparecen los cimientos: el motor acepta al momento incluso un punto dentro de un bosque; falla cuando llega el trabajador. Usa
build_near, que hace el seguimiento y veta durante un tiempo los puntos que fallan. - El recibo del hechizo fue aceptado, pero no se lanzó: lo interrumpieron o faltaba maná. En el tick siguiente, comprueba si
g.cooldown()ha entrado en enfriamiento. - La orden de ataque fue aceptada, pero las tropas atacan a otro: para atacar un objetivo concreto, usa
g.attack(unidad, enemigo)(semántica de clic derecho). La orden de ataque en bruto sobre un objetivo solo cambia la orden sin fijar el objetivo, y la unidad acaba atacando a otra cosa cercana. - El número de trabajadores no cuadra: los trabajadores que están dentro de la mina de oro no aparecen en el snapshot.
- No puedo entrenar al héroe que murió: el héroe es único; usa
g.revive(altar). Revivir requiere comida y solo es posible unos 3 segundos de juego después de su muerte.