BotStrikes

Desarrollo temprano Todavía no hay versión pública · FPS táctico 5v5 · PC

Novedades

Lo que cambió, medido

La bitácora pública del desarrollo. Sin fechas de lanzamiento y sin «pronto»: si algo no avanzó, esta página dice qué lo frenó.

Bitácora · actualizada el

Hito por hito, con su medición

Una entrada por hito verificado: qué cambió, la cifra con su escenario, el enlace a la evidencia y lo que se probó y se descartó, con la medición que lo descartó. Lo que todavía no está medido dice «pendiente», y lo que espera la prueba de una persona lo dice también. Ninguna fase se declara cerrada acá.

· F1–F6 · ADR 0017 El hash coincidía en Clang porque lo decíamos, no porque se comprobara

El archivo de hashes fijados del proyecto y la página de evidencia afirman que un millón de pasos de simulación dan el mismo hash en tres builds: GCC optimizado, GCC con sanitizers y Clang. La verificación completa compilaba dos. Ahora compila las tres y compara los tres hashes en cada corrida, y si no encuentra Clang falla en vez de saltarse la pata. Las tres dan a59ca4f6e2299d88 en el corpus de movimiento y f7d2406fd5b56d4d en el de combate, con 72.863 disparos y 3.478 impactos. En el mismo movimiento se publicó el registro de la verificación completa del 24 sep 2026, que es de donde salen el tick, el ancho de banda y la escena de render que el sitio publica.

  • Clang 21.1.8, GCC optimizado y GCC con sanitizers dan los mismos dos hashes que están fijados, a un millón de pasos cada uno
  • Si no hay Clang, la verificación completa falla: antes la pata se saltaba en silencio y la afirmación quedaba sin comprobar
  • El registro de esa verificación completa ya está publicado entre los registros en crudo, con las siete cifras del sitio que respalda y con lo que no respalda
  • El árbol entero todavía no compila con Clang: dos constantes duplicadas y sin usar en el código de OpenGL rompen la compilación con los avisos como errores. Las dos sondas de determinismo no arrastran render, así que la pata nueva corre igual; queda anotado en vez de tapado

Las tres patas, un millón de pasos cada una Movimiento a59ca4f6e2299d88 y combate f7d2406fd5b56d4d en GCC optimizado, GCC con sanitizers y Clang 21.1.8, con 72.863 disparos y 3.478 impactos en las tres. Los dos hashes son los que el archivo del proyecto tiene fijados y no se movieron.

Probado y descartado

  • Degradar el aviso de Clang con un envoltorio del compilador para que el árbol compilaraEl envoltorio existía sólo para que una constante sin usar dejara de romper la compilación. Medido antes de borrarla: esa constante no entraba en ninguna cuenta, porque las 18 poses del rig salen idénticas con su valor del árbol, con 0 y con 90 grados, con la misma huella en los tres casos, y la sección de código del objeto compilado es la misma antes y después de borrarla. Era código muerto: se borró y ya no hace falta ningún envoltorio.
  • Dar por cubierta con ese registro la escena poblada del mapa vestidoEl plan decía que el registro cubría las cuatro primeras filas del panel de presupuestos, y cubre tres y media: su puerta de render es el campo de tiro vacío, 4,1434 ms, y la escena poblada, 9,6242 ms contra 8,3333 de objetivo, es de un ADR del día siguiente. El registro lo dice en sus límites, y la lista de cifras sin registro publicado sigue teniendo entradas.
  • Publicar el log crudo de la verificación junto al registroLos registros publicados hasta hoy traen el archivo y el sha256 de su log, no el log, y ese criterio se mantiene: el log se pide por correo y ese sha256 sirve para comprobar que lo que llegue sea lo mismo con que se midió. Cambiarlo para un registro y no para los otros trece haría la carpeta menos legible, no más.

· F5 · ADR 0101, 0102 La pared se acuerda del disparo, y el cuerpo se para como un soldado

La marca de bala era un cubo de color plano de 1,8 cm que caducaba a los 10 s. Ahora es un quad con textura y alfa en el plano de la cara golpeada, con la luz horneada de esa misma pared, tres familias de material y cuatro formas cada una: 192 vivas, toda la ronda, y se borran al cambiar de ronda. En paralelo, la marcha se corrigió donde importa, en los datos de los dos rigs, y no bajando valores en el cliente.

  • El quad mide 6,0 cm y el cráter 1,8: el 1,8 era el tamaño del agujero y se estaba usando como el de toda la marca
  • Criterio de aceptación cumplido: treinta tiros a 40 cm dejan quince agujeros separados, sin el manchón que se había rechazado
  • Tobillo a tobillo de pie 35,5 → 29,0 cm y punta a punta 49,1 → 34,3, horneado en los dos rigs
  • Falta que una persona lo juegue y lo acepte: la postura y las marcas las valida el fundador (checkpoint H3)
  • El desplazamiento de peso de la pelvis de pie queda bloqueado por decisión humana: 0 mm de recorrido
Coste del cuadro en el peor caso, tarjeta de referencia+0,09 ms / 8,3333

Divergencia entre el cuerpo dibujado y sus cajas de impacto de pie 6,17 → 2,91 cm y puntera 9,49 → 2,09: la justicia mejora con el horneado, no empeora

Probado y descartado

  • Meter el sampler de las marcas en el sombreador del mundoEl cuadro pasó de 1,97 a 4,72 ms sin dibujar una sola marca: ese programa va justo de registros en la tarjeta de referencia. Las calcomanías tienen su propio programa, y cualquier palanca que agregue un sampler al programa compartido hay que medirla aunque no dibuje nada.
  • Corregir la postura bajando tres valores del clienteDejaba el tobillo dibujado unos 5,4 cm por dentro del de las cajas de impacto, o sea el pie fuera de su caja. Horneado en los datos, la divergencia de pie baja de 6,17 a 2,91 cm.

· F6 · ADR 0099, 0100 El contrato del cable queda escrito, y el peor caso medía de menos

El servidor hablaba el protocolo 11 y la API de agentes 10, pero la documentación del cable llegaba a la 10 y declaraba 8 para la API. Ahora está escrita desde el código y no desde la bitácora: el bloque de la bomba con sus 18 bytes y sus reglas de quién sabe qué, la acción de usar, y el orden canónico completo del snapshot con el tamaño de cada bloque y quién recibe cada uno. Cada tamaño se comprobó codificando de verdad: un snapshot vacío mide 136 bytes.

  • El peor caso real de bajada 5v5, una IA viva bajo modelo motor, es de 795 bytes y 55.552 B/s con cabeceras, y no 54.400: quedan 8.448 B/s de margen contra el tope de 64.000
  • No hay regresión de presupuesto: era una cuenta que medía de menos, y el test fija ahora las dos familias de cifras, con objetivo y sin él
  • Lo que sí se quedó sin margen, y se anota en vez de taparse: el formato admite hasta dieciséis asientos, y ese caso daría 65.152 B/s con el bloque de la bomba, por encima del tope. Ofrecer una partida de dieciséis asientos con objetivo necesita antes una decisión escrita y una persona
Peor caso de bajada por cliente, 5v5 con objetivo55.552 B/s / 64.000

Probado y descartado

  • Subir el tope de ancho de banda para que la bomba entraraNo se subió ni se bajó nada: el tope sigue en 64.000 B/s. Lo que estaba mal era la cuenta, que no sumaba los 18 bytes de la bomba aunque viajan en todos los snapshots de una partida con objetivo.
  • Dejar el comentario de versión y la lista de pendientes como estabanEl comentario del encabezado decía 10 con la constante en 11, y la lista declaraba pendiente la adaptación de reloj entre máquinas, que está implementada y probada desde la v2. Las dos divergencias se corrigieron en el mismo cambio.

· F3b · ADR 0098 El reloj de presentación dibuja donde apuntás

El cliente dibujaba 0,80 ticks detrás del snapshot más nuevo en vez de los 2 que pedía su propio diseño, y el 4,7 % de los cuadros dejaba el cuerpo remoto quieto. La causa: el error que gobierna el reloj se medía después de adelantar su objetivo, así que el controlador leía un error del tamaño de un cuadro entero y el reloj corría adelantado. De ahí que el atraso fuera menor cuanto peor andaba la máquina. Ahora el error se mide antes y el objetivo se arrastra en vez de replantarse.

  • Atraso 0,8006 → 1,2674 ticks y diferencia entre dibujar y apuntar 0,458 → 0,001
  • Cuadros por debajo de un tick 65,65 % → 20,91 %, congelados 0,93 % → 0,65 %, paso máximo sobre el medio 1,102 → 1,064
  • El búfer de interpolación no se tocó: cuesta 7,3 ms más de ver a los demás con atraso, que es exactamente lo que el diseño pedía
  • Falta jugarlo, y volver a medir el porcentaje de cuadros congelados con el cliente conectado

Reproducción banco determinista sin red: 0,800649 de atraso y 65,65 % de cuadros bajo un tick, iguales a la partida conectada

Pruebas 115 casos y 88.357 aserciones en las pruebas de red; verificación rápida 12 de 12

Probado y descartado

  • Bajar el techo del recorte del relojLos cuadros congelados empeoraron a 1,49 %.
  • Dar más autoridad al controlador del relojLos congelados subieron a 3,35 %.

· F6 · ADR 0089, 0094 El radar del género, sin regalar un solo enemigo

El servidor manda ahora dónde están los compañeros vivos aunque no se vean, que es el radar del género. Viajan asiento y posición, 13 bytes, y nada más. La regla con la que se decidió: si un campo cambia por algo que pasa fuera de él, no entra. Así quedan afuera vida, arma, gatillo y puntería, porque cambian cuando hay un enemigo cerca: hacia dónde mira un compañero quieto es dónde está el enemigo que él ve. Y un jugador muerto ya no mira el suelo: espectra por los ojos de un compañero vivo, con la percepción de ese compañero y sin sus eventos privados.

  • Cuesta cero en el peor caso del cable: un compañero está entre los visibles o en el bloque nuevo, nunca en los dos
  • Espectar a un compañero al morir viaja en 17 bytes y elimina un apagón medido de hasta 2:17 mirando el suelo
  • Las IAs reciben lo mismo, en el mismo tick y con los mismos bytes, y sin retraso de percepción: saber dónde está tu propio equipo no apunta a nadie
  • Que no se filtre un enemigo lo comprueban el plantel, el codificador y el decodificador, por separado
  • Pendiente de decisión: dibujar el contorno del compañero a través de la pared cuesta +0,16 ms en el peor caso, cinco compañeros tapados, contra un margen de 0,05 ms. La alternativa barata, acotarlo a los dos más cercanos, está propuesta y sin aplicar
Contorno del compañero tapado, peor caso, contra el margen que hay+0,16 ms / 0,05

Probado y descartado

  • Un contador de compañeros siempre presente en el snapshotHabría costado 1 byte y llevado el caso de dieciséis asientos de 64.000 B/s exactos a 64.064. En vez de bajar el presupuesto se cambió el diseño: el bloque sólo aparece cuando hay algo que mandar.

· F5 · ADR 0092 Variedad de material en el mapa a coste cero, y el cielo deja de bandear

Tres pieles por barrio elegidas con un hash fijo, familias que no se cruzan y el material físico conservado: la bala encuentra lo mismo que antes. Y dos arreglos de imagen que salieron de una revisión por ejes: el tramado antes de cuantizar a 8 bits, y el muestreo completo de cada piel de modelo, que se subía con media configuración mientras el array del mundo ya llevaba las tres.

  • Píxeles sin textura local: mediana 39,8 % → 32,6 %, por +180 triángulos sobre 15.920, cero texturas, cero capas y cero llamadas de dibujo nuevas
  • Props a cero grados 16 → 4, y ángulos distintos 24 → 45
  • Tramado antes de cuantizar a 8 bits, coste 0,00 ms: el cielo bandeaba una franja cada 6,7–10 px
  • Mipmaps, anisotropía ×8 y sesgo −0,5 al subir cada piel: el cuerpo conserva el 99 % del detalle legible y pierde el 6 % del ruido cerca de Nyquist, y el arma conserva el 96 %
  • Falta que una persona lo mire en partida: la identidad visual y la legibilidad las valida el fundador (checkpoint H3)
Coste del tramado en el cuadro+0,00 ms / 8,3333

Probado y descartado

  • Poner el tramado antes del suavizado de bordesEn ese orden el peor canal daba 42, porque el suavizado decide bordes por umbral de luminancia y medio nivel le cambia la decisión. En su sitio, después, da 1.
  • Dejar el muestreo a medias en las pieles de modeloSin anisotropía el arma conservaba entre el 90 y el 92 % del detalle legible, contra el 96 % de ahora.

· F3b · ADR 0087, 0088 La trazadora dejó de mentir, y el comando se aplica con un solo código

El haz que dibujaba el cliente en el momento del clic no era el disparo que resolvía el servidor: el cliente no sabe qué bala salió hasta que el servidor se lo dice. Ahora el haz lo dibuja la respuesta del servidor para esa misma bala. Y cliente y servidor pasaron a preparar y aplicar el comando con el mismo código, en vez de con dos órdenes de operaciones parecidos.

  • El haz honesto no cuesta un byte nuevo en el cable: ya viajaba la respuesta del disparo
  • Cliente y servidor preparan y aplican el comando con el mismo código, y el formato del cable no cambia un byte
  • Codificar un snapshot ya no puede tumbar el servidor: la función devuelve un opcional, y el bucle cuenta el rechazo, lo nombra y saltea ese snapshot
  • Hasta que aparece el haz pasa un viaje de ida y vuelta, 30–60 ms. Lo inmediato —fogonazo, retroceso y sonido— sigue siendo inmediato, pero eso lo valida una persona jugando

Banco tres vistas del mismo instante, parado y corriendo, más una partida conectada de 900 cuadros y seis contratos nuevos

Probado y descartado

  • Dibujar el haz en el cliente en el momento del clicErraba 10 cm parado y 8,94 m corriendo respecto de la bala que resolvía el servidor. Un haz que no coincide con el disparo enseña a apuntar mal.
  • Mantener el orden viejo de preparación del comando por compatibilidadEl test nuevo midió 283 desacuerdos sobre 300 entre lo que dibujaba el cliente y lo que aplicaba el servidor. Con el código compartido: 0.

· F5 · ADR 0083, 0090 «Cinta»: tres alturas de cobertura y una boca de servicio por sitio

El mapa competitivo son dos arenas unidas por tres caminos, compacto. Convivían cinco alturas de cobertura baja; ahora hay tres y ninguna otra, 1,00 / 1,60 / 2,20 m, con la franja de 1,20 a 1,50 m prohibida porque corta la caja de impacto justo donde el ojo no la juzga. Y la defensa tiene dos bocas por sitio: se agregó una boca de servicio con dintel a 2,40 m, cuatro metros al sur de la que ya tenía.

  • 1.328 brushes, 0 caras en conflicto y huella jugable de 84 × 62 m
  • 18 % de suelo elevado, con la banda del banco en 15–25 %; 14 % cubierto; y 0 % de suelo abierto lejos de toda pared, que antes era 1 %
  • Ocho pilares de 1,60 m nuevos, y la cobertura baja unificada en 1,00 m exacto
  • Tiempos medidos con la grilla del SDK: defensa al sitio 6,5 s, ataque 12,3 s, rotación entre sitios 12,8 s y spawn a spawn 12 s
  • Falta que el fundador lo recorra y lo juegue
Recta de tiro más larga, contra el máximo del contrato36,2 m / 40,0

Probado y descartado

  • La línea de rifle de 40 a 45 m que pide el banco de referenciaNo cabe en 84 × 62 m: la recta más larga que da la geometría es 36,2 m, y volver a correr el generador no movió el máximo ni un metro. Conseguir 45 m obligaría a abrir el mapa, así que se dice en vez de estimarlo.
  • Abrir una entrada nueva atravesando el mapaUn intento automático dejó una recta de 79,7 m, el doble del máximo del contrato, y caras peleadas. La verificación lo cazó en el primer intento, con tres pruebas del mapa en rojo, y se revirtió: una entrada nueva se abre con un codo o una puerta.

Entradas anteriores

FechaQué cambióCifraFase
El recorte por cámara cierra parte del hueco, y el presupuesto sigue sin entrarmedia 9,6097 → 9,3372 ms contra un objetivo de 8,3333: todavía 12,0 % arribaF5
Banda competitiva de combate, y escaleras que no dan saltosarmadura del rifle 0,5 → 0,75; salto del ojo por tick 15 → 5 cmF5
Partida por rondas con marcador, y el mapa de pruebas deja de ser una arenaprimero a 13, mitades de 12, ronda de 1:55; suelo abierto 35 % → 1 %F6