Skip to content

v5.32.0

Choose a tag to compare

@odegaard12 odegaard12 released this 27 Sep 15:17
· 8 commits to main since this release
  • Traducción al gallego del jugador. Unos 70 textos salían en el idioma
    equivocado: avisos con números dentro (el puente de idioma no podía
    traducirlos), algunos fijos en inglés ("Centered on node.") y otros fijos
    en gallego que veía también quien jugaba en castellano ("Saíches do
    camiño", "Sen cobertura…"). Ahora salen en el idioma de la misión.

  • TODO.md: el acceso escalonado ya estaba hecho (lo decía PROGRESS.md).

  • Los minijuegos sparkRadar y teamRelay llevan un README: son prototipos
    sin terminar y sin conectar al juego.

  • Misión en gallego: el aviso "Activa GPS para obtener una posición…"
    salía en castellano; ya tiene su traducción.

  • Panel "Antes de salir" en un solo idioma. Mezclaba gallego
    ("Movemento", "Seguir sen iso") y castellano ("Lo denegaste…"). Ahora
    cada texto sale en el idioma de la misión.

  • El aviso de permiso denegado dice qué tocar según el móvil: en
    iPhone, Ajustes › Safari; en Android, el candado de la barra de
    direcciones › Permisos. Antes decía Safari a todo el mundo.

Admin: funciones del servidor que el panel no usaba.

  • Actividad (menú "Seguimiento"): el registro de eventos del servidor
    (latidos, QR escaneados, acciones de admin), con filtro por estado y
    "marcar como leído".

  • Datos personales (en Jugadores): ver cuántas fotos de campo y
    posiciones GPS hay guardadas y borrarlas. La misión, los nodos y el
    progreso no se tocan. Borra datos de personas reales sin vuelta atrás,
    así que hay que escribir BORRAR para confirmarlo.

  • Editor de nodos: fuera 120 líneas muertas (pestañas que nunca se
    conectaron, un panel sin usar y una cabecera duplicada oculta).

  • Sin halos en los nodos completados ni en los pendientes. Su halo de
    color en el suelo "quedaba fatal sobre el terreno". Ahora sólo llevan la
    sombra de contacto, y el único halo es el del nodo que toca: su radio
    real de entrada.

  • Primera carga del mapa mucho más rápida. El paquete offline (unas
    3.000 teselas) se bajaba tesela a tesela, y cada una tardaba ~0,7 s en ir
    y volver por el túnel de Cloudflare aunque la Pi la sirviera de su disco
    en 60 ms: medido en un móvil nuevo, más de 20 minutos. Ahora se baja por
    lotes de 120 (nueva ruta /api/teselas/lote), tres a la vez; si el
    servidor no sabe dar lotes, se vuelve a la descarga de una en una.

  • Relieve de cerca sin cobertura. El paquete apenas traía el relieve
    z12 (3 teselas), que es el que usa la forma del terreno: sin cobertura
    el monte de cerca salía plano. Ahora entra el de toda la zona de misión.

  • Relieve menos exagerado (×1,5, era ×2,2). Con 2,2, cerca de un monte
    la cámara quedaba dentro del relieve y MapLibre le bajaba a la fuerza la
    inclinación y el zoom: saltos al ampliar y centrado descolocado.

  • Las fotos de cada nodo, en un montón al lado de su base. No se veían
    hasta ampliar mucho (zoom 18) y entonces salían en fila, pequeñas y encima
    del camino. Ahora cada nodo con fotos lleva un montón con la primera y
    cuántas hay, que crece con el nodo y se ve desde lejos; al tocarlo se
    abren todas en grande. Las fotos sueltas por el campo, como antes.

  • Centrado exacto también al volver de "ver la ruta". Medido con un
    móvil simulado en la ruta real: tras ver la ruta (centro en un alto) y
    volver a ti, el centro del mapa estaba en tus coordenadas pero tú salías
    100 px más abajo, porque MapLibre dejaba la cámara con la altura del
    terreno del sitio anterior. Al acabar cada movimiento se iguala la altura
    del centro con la del terreno.

  • "Centrar en mí" ya centra. El precalentado de la pantalla de carga
    (pasa por varios zooms y vuelve) seguía moviendo la cámara si la carga se
    quitaba por tope antes de acabar, y al terminar devolvía la cámara a
    donde estaba al empezar: pisaba el centrado y el seguimiento del GPS, y
    al entrar el jugador podía quedar fuera de la pantalla. Ahora se para en
    cuanto tocas el mapa, pides encuadrar o el GPS te sigue, y no restaura
    nada.

Repaso del panel de administración, que estaba abandonado:

  • Menú por grupos: Misión (Crear, Ajustes) · Contenido (Juegos,
    Objetos) · Personas y pruebas (Jugadores, Simular). "Crear" (el asistente
    de plantillas) sólo existía en el menú del móvil; ahora también en
    escritorio. "Familias" pasa a llamarse "Juegos".

  • Cambio de contraseña: si el servidor pide cambiarla, el panel ya
    tiene pantalla para hacerlo (antes se quedaba en "Access denied" sin
    salida). Pantalla de acceso en castellano y centrada.

  • Seguridad: fuera un último intento de carga que mandaba la
    contraseña en la dirección (?password=…) a una ruta que ni existía.

  • Barra de datos de la ruta (distancia, tiempo, desnivel, PLAY): tapaba
    la fila de botones cuando éstos ocupaban dos líneas y se metía bajo el
    menú. Ahora se coloca debajo, midiendo la barra de verdad.

  • Las cinco familias de juego en los recuentos del servidor (contaba tres)
    y sus nombres en castellano (Reto de movimiento, Caza de rumbo, Matriz de
    circuitos, Reto de sonido).

  • Textos que no se actualizaban, en toda la app. El puente de idioma
    (traduce los textos de la página por detrás de React) guardaba el texto
    de la primera vez y, cuando React lo cambiaba, lo devolvía a aquel: un
    estado, un contador o la etiqueta de un botón que alterna se quedaban
    congelados con el primer valor. Ahora acepta el texto nuevo.

  • Un bucle que no paraba. El mismo puente reescribía cada texto aunque
    fuera igual, eso volvía a dispararlo y recorría la página entera en cada
    fotograma, siempre. Ahora sólo escribe si cambia: menos trabajo para el
    móvil y más fluidez.

  • Fotos de los nodos, sólo de cerca. De lejos quedaban apiladas y
    clavadas en el poste del nodo. Ahora no se ven hasta el zoom 18, donde
    salen repartidas bajo el nodo; tocar el nodo de lejos ya no las abre.
    Las fotos en campo abierto siguen viéndose (una por sitio).

  • El nodo en juego marca su radio de entrada real. Su halo medía lo
    mismo en pantalla a cualquier zoom y de lejos quedaba enorme, más grande
    que el trazado. Ahora es el círculo donde el juego te deja entrar, a su
    tamaño de verdad sobre el mapa: velo suave y un anillo que late en el
    borde, del color del tipo.

  • Fotos juntas de lejos. Repartidas a cualquier zoom quedaban fatal.
    Ahora se ve una por sitio hasta el zoom 18 y sólo de muy cerca se
    reparten bajo el nodo para poder tocarlas. Tocar la de lejos abre todas.

  • Los nodos ya no "se recargan" más grandes al ampliar. MapLibre topaba
    el tamaño de cada símbolo en el del zoom siguiente a su tesela: ampliando
    deprisa, el nodo se quedaba quieto hasta que llegaba la tesela y pegaba
    el salto. Ahora el tamaño crece sin escalones (nodos, fotos y jugador),
    con la misma curva.

  • Fotos de los nodos, que se pueden tocar. Estaban todas en el mismo
    punto, apiladas y debajo del nodo: al ampliar no se separaban. Ahora las
    de cada sitio se reparten en filas bajo la peana del nodo, por encima del
    halo, y al tocar una se abre el visor con todas empezando por esa.

  • La guía por caminos se guarda. Al volver a abrir la app en el mismo
    sitio sale al instante, sin esperar a que se cargue la red y se calcule.

  • Centrar en mí encuadra una sola vez: el punto nuevo del GPS ya no
    vuelve a mover el mapa con otro encuadre.

  • El mapa no se vuelve a cargar al desampliar. Guarda en memoria ocho
    niveles de zoom en vez de cinco, pide 32 teselas a la vez en vez de 16
    (salen de la caché, no de la red) y las enseña sin fundido. La pantalla
    de carga pasa por cada nivel de zoom hacia fuera, no a saltos.

  • Botones de posición. "Centrar en mí" centra al momento con la
    última posición. Antes pedía el GPS de nuevo cada vez: reiniciaba la
    escucha, avisaba "Solicitando permiso de ubicación…" aunque funcionara y
    no centraba hasta el punto siguiente. Si el punto es viejo, se pide otro
    en silencio. "Ver la ruta" ya no pide GPS: no lo necesita.

  • Quieto más de 45 s ya no desapareces del mapa: se te pinta en tu última
    posición de esta sesión. Para abrir nodos sigue haciendo falta un punto
    reciente.

  • Zoom y arrastre más fluidos. Las animaciones del mapa (pulso del
    trazado, moneda que flota, halo, guía) se pausan mientras el mapa se
    mueve. Cada una cambia el estilo, y con relieve MapLibre repinta
    entonces todas las texturas del terreno: diez veces por segundo en pleno
    pellizco eran tirones.

  • Nodos y fotos que aparecían y desaparecían. Con cada cambio de
    estilo -diez por segundo, por las animaciones- se volvían a cargar todos
    los datos del mapa: trazado, nodos, fotos y guía se recortaban y
    recolocaban sin parar. Ahora sólo se cargan cuando cambian de verdad.

  • La guía late en opacidad con un trazo fijo. Su "trazo que crece"
    cambiaba line-dasharray cada 160 ms, y esa propiedad obliga a
    recargar la fuente entera cada vez.

  • Sin saltos al ampliar y desampliar. La forma del relieve se queda
    en una sola resolución desde el zoom 12: el dato es de ~30 m y los
    niveles 13 y 14 eran ese mismo dato remuestreado, distinto en cada uno;
    con la exageración, al cruzar de zoom el suelo y los nodos saltaban.
    De cerca, además, el relieve sale más suave. El sombreado sigue a z14.

  • Nodos asentados. El halo y la sombra de cada nodo van tumbados
    sobre el mapa, con su perspectiva real en cualquier punto de la
    pantalla, y los nodos van a 2 m del suelo en vez de 3.

  • Check integrado. Es una chapa verde en 3D pegada al canto de la
    moneda: gira, flota y se ilumina con ella. Antes era una pegatina plana.

  • La pantalla de carga deja el mapa preparado. Antes de quitarse
    hornea todos los nodos (salían tarde, al llegar a la zona, y el mapa se
    trababa mientras) y pasa por dos zooms más lejanos y por la ruta entera,
    así que al desampliar ya no se queda en blanco 2-3 segundos.

  • Nodos y fotos sin fundido al cambiar de zoom: ya no desaparecen y
    aparecen al desampliar. Las teselas pedidas no se cancelan a mitad del
    pellizco.

  • Nodos más grandes a zoom medio (de 15 a 17), sin cambiar el de cerca.

  • Halo del suelo más ancho, y el trazado cosido a sus nodos: la línea del
    camino llega hasta el nodo aunque el track se grabara a unos metros.

  • Los nodos, un 30 % más grandes, con la peana y el aro de la base más
    anchos.

  • Los completados, en gris del todo (poste, cubo, moneda y brillo del
    suelo) y con el check verde más grande. A medio apagar quedaban raros.

  • Los nodos son poképaradas (boceto A, elegido por Óscar). Base blanca
    con aro, poste, cubo con el icono del tipo y una moneda con el número
    grande que flota subiendo y bajando. Como en Pokémon GO, el color es el
    tipo: verde checkpoint (bandera), azul QR, dorado coleccionable (cofre),
    magenta jugable (mando). El que toca es más grande y brilla; el hecho
    sale apagado con un check verde, como una poképarada visitada. La vista
    2D usa los mismos colores.

  • Los nodos crecen al acercarse. Con una escala casi fija en píxeles,
    al ampliar parecían cada vez más pequeños frente a las casas y los
    caminos, que sí crecen. Ahora su tamaño sube un 50 % por nivel de zoom.

  • El código QR ocupa el cartel entero: la geometría biselada repartía la
    textura por coordenadas del mundo y el código salía diminuto en el
    centro. Ahora va en un plano pegado a la cara.

  • Nodos rediseñados del todo, con objetos reconocibles. Bandera a
    cuadros ondeando en un poste alto el checkpoint; cartel blanco con un
    código QR de verdad (localizadores, líneas de tiempo, datos) el QR;
    cofre del tesoro abierto, de madera y oro, con luz dentro y destello,
    el coleccionable; mando de juego con cruceta, botones y palancas el
    jugable. Cantos redondeados y biselados. El estado va en el poste, en el
    brillo del suelo y en el cartel del número, que va encima.

  • Cada tipo de nodo tiene su objeto. Bandera en mástil alto el
    checkpoint; panel cuadrado con un código QR en la cara el QR; gema
    facetada flotando, con destello, el coleccionable; dado con sus puntos
    el minijuego. El color sigue siendo el estado, y el cartel del número
    va encima del objeto. La silueta se distingue de lejos.

  • El servidor clasificaba mal los nodos. El motor normaliza los tipos
    al cargar (checkpoint pasa a signal_hunt con game_id simple_checkpoint;
    qr_collectible a circuit_matrix con game_id qr_collectible), y la
    clasificación miraba sólo el tipo: en la ruta real los diez salían como
    minijuego o coleccionable. Ahora mira el juego de verdad: un checkpoint,
    dos QR, tres coleccionables (los QR que dejan objeto en el mapa) y cuatro
    jugables.

  • La guía desde lejos ya no tarda un minuto. Quien ya tenía el mapa
    guardado se saltaba la pantalla de carga, y la red de caminos se bajaba
    entonces por detrás mientras jugaba, dos veces a la vez (la pasada de
    fondo del paquete y el worker de la guía). Ahora el paquete se vuelve a
    comprobar una vez (rápido) y baja la red en la pantalla de carga; la
    pasada de fondo no la toca, y no se baja si ya está guardada.

  • Una forma por tipo de nodo. Salían todos iguales porque sólo los
    distinguía la chapa pequeña. Bola lisa el checkpoint, dado de veinte
    caras el minijuego, gema el coleccionable, cubo el QR. Sólidos, sin
    partes finas.

  • Los nodos, un 40 % más grandes. Eran demasiado pequeños para leer
    el número.

  • Fuera el círculo del radio de entrada. El nodo en juego se marca
    con su propio brillo en el suelo.

  • La guía va por carretera cuando estás lejos. El servidor guarda
    ahora la clase de cada vía (autovía, primaria, secundaria, terciaria,
    calle, servicio, pista, senda) y el móvil pondera: a menos de 3 km del
    trazado valen las pistas; a partir de 8 km una pista cuesta tres veces y
    media su longitud y una senda cinco, así que desde casa la línea sigue
    la carretera y no "un camino raro por el monte". Hay que reconstruir la
    red de caminos en el panel para que lleve la clase.

  • El trazado y las fotos dejan de aparecer "mucho después". La red de
    caminos (21 MB) se analizaba en el hilo principal nada más entrar y
    dejaba el mapa congelado unos segundos, además de competir con las
    teselas y las fotos por la conexión. Ahora se descarga en la pantalla
    de carga, como fase propia, y se analiza y se calcula en un worker.

  • Las fotos aparecen y no desaparecen. Dos causas: el mapa pedía la
    foto ENTERA para una chincheta de 40 px (decenas de megas), y con
    relieve MapLibre esconde un símbolo cuyo anclaje queda por debajo de la
    malla basta del terreno. Ahora hay miniaturas de 360 px hechas en el
    servidor, y las fotos, los nodos y tú vais tres metros por encima del
    suelo.

  • Los nodos 3D son objetos renderizados una vez, no dibujados en vivo.
    Dentro del lienzo del mapa salían serrados y parpadeaban al girar. Ahora
    la bola se renderiza con three.js una vez, con luz, sombra y brillo, a
    tres veces la resolución y con sobremuestreo, en un lienzo propio con
    antialiasing, y el mapa la coloca como símbolo en el mismo fotograma
    que el terreno. Una bola sobre un mástil se ve igual desde cualquier
    lado, así que no cambia nada al girar.

  • Fuera la peana negra de los nodos. En cuesta salía medio enterrada
    o flotando por un lado. En el suelo queda sólo el brillo difuminado; la
    forma del tipo sigue en la chapa del cartel.

  • El mástil ya no se transparenta. Con 10 cm de radio era un píxel a
    la distancia de juego y el suavizado lo dejaba translúcido. Ahora tiene
    22 cm y se ve sólido.

  • El suavizado usa todas las muestras que dé el móvil (4 u 8).

  • Fuera el aro dentado alrededor de la bola. Eran el halo transparente
    y el anillo del nodo en juego: dos superficies finas que en el móvil
    salían como un aro con píxeles y que ningún suavizado arregla del todo.
    La bola queda sola, lisa; el nodo en juego se distingue por el pulso en
    el suelo y por respirar más.

  • Vuelven los nodos con volumen, y sin dientes de sierra. La escena
    3D se pinta ahora en un objetivo propio con cuatro muestras por píxel y
    se vuelca al lienzo del mapa como una textura ya suavizada: el
    antialiasing es nuestro y el mapa no se entera, así que las fotos no se
    ven afectadas. En 3D, los modelos; en 2D, las bolas horneadas como
    símbolos.

  • Los nodos salen del lienzo 3D. Dibujarlos con three.js dentro del
    lienzo de MapLibre daba dientes de sierra en el móvil (sin antialiasing
    de contexto, y activarlo rompía las fotos) y temblores al mover. Ahora
    son símbolos del propio mapa con la bola horneada en la imagen, a tres
    veces la resolución de pantalla: luz, sombra, brillo, número, chapa del
    tipo y peana con la forma del tipo. MapLibre los pinta en el mismo
    fotograma que el terreno y a su altura exacta; nítidos a cualquier
    zoom, sin nada que parpadee, en 2D y en 3D. El nodo en juego lleva un
    resplandor que late.

  • Las fotos del mapa dejan de aparecer y desaparecer. Era el
    antialiasing de contexto de la 5.25.24: con relieve, MapLibre decide qué
    símbolos tapa el terreno leyendo profundidad, y con el lienzo
    multimuestreado eso se rompía. Fuera; en el móvil no se notaba de todos
    modos.

  • Tope de zoom en 19,5. La foto aérea no tiene más detalle que z19 y
    por encima el mapa estira píxeles: eso era la pixelación al ampliar
    mucho, y no la arregla ningún antialiasing.

  • La bola lleva más caras, y la animación va a treinta fotogramas por
    segundo: repintar sin parar hacía parpadear a las fotos.

  • El aro del suelo es un brillo difuminado, no una línea. Era un
    anillo de geometría que a la distancia de juego medía dos píxeles: se
    veía serrado con o sin antialiasing y temblaba al mover el mapa. Un
    degradado con transparencia no tiene canto que serrar, y en cuesta se
    lee como luz sobre el suelo. El pulso del nodo en juego, igual.

  • Se acaban los saltos al mover el mapa. La cota del terreno bajo cada
    nodo se consultaba en cada fotograma mientras el mapa se movía, y al
    cambiar de tesela devolvía un valor distinto cada vez: el nodo subía y
    bajaba a tirones. Ahora se toma con el mapa quieto, cada medio segundo.

  • Los nodos 3D se dibujan con antialiasing. MapLibre crea el contexto
    WebGL sin él, y las bolas, los aros y la peana salían con dientes de
    sierra. Se activa el MSAA del contexto, la opción que MapLibre documenta
    para las capas personalizadas.

  • La animación va al ritmo de la pantalla, no a veinte fotogramas por
    segundo: la bola flotaba a tirones.

  • El cartel del número se pinta a 512 px para verse nítido de cerca.

  • Los nodos son bolas. Una esfera del color del estado flotando sobre
    un mástil fino, con el número en un cartel redondo delante y la chapa del
    tipo en su esquina; la peana del suelo lleva la forma del tipo y un aro
    de color. Una esfera se ve igual desde cualquier lado: ni se deforma al
    girar ni al acercarse. Más grandes que el monolito, y crecen un poco al
    acercarse en vez de parecer cada vez más pequeñas frente a las casas.

  • El radio de entrada deja de ser una mancha oscura sobre el terreno:
    relleno al 10 % y borde más fino.

  • El paquete offline guarda lo que el mapa pide de verdad. Con
    teselas de 256 px el mapa pide un nivel más que el zoom que enseña: al
    desampliar hasta ver todos los nodos pedía z15 en toda la zona y sólo
    estaba el corredor; junto a un nodo pedía z19 y no había nada. Se añaden
    la zona de misión a z15-z16 y el detalle de nodo a z19; el paquete se
    vuelve a comprobar solo.

  • La barra de la pantalla de carga se recoloca con animación cuando se
    recoge la tarjeta de permisos, en vez de saltar de arriba al medio.

  • Barra de carga: porcentaje sólo cuando descarga de verdad. La escala
    única repartida entre fases acababa mintiendo ("avanzó 3, 5 % y de golpe
    pasó a 100"). Ahora sólo la descarga de teselas lleva número, y nunca
    retrocede; conectar, calcular y comprobar van con la barra en movimiento
    y sin cifra.

  • Los nodos 3D dejan de cambiar de tamaño al girar. El tamaño se medía
    por nodo y por fotograma con la perspectiva, así que al girar el mapa
    cada nodo cambiaba de tamaño a su aire: parpadeo. Ahora el tamaño depende
    sólo del zoom, igual para todos, y el cercano se ve mayor que el lejano
    como todo lo demás del mapa.

  • La cota del terreno bajo el nodo se toma al instante, sin arrastre: el
    suavizado hacía que el modelo subiera y bajara despacio al hacer zoom.

  • El tamaño del nodo ya no se queda clavado al acercarse. El factor
    partía del fotograma anterior: un modelo que de lejos medía 600 m tenía
    la punta detrás de la cámara al acercarse, la medida fallaba y se
    quedaba en 600 m con la cámara encima (medido: 618 m a zoom 19,4). Era
    el "se corta" de cerca. Ahora se parte siempre de una sonda de un metro.

  • Los nodos 3D dejan de "buguearse" de cerca y al mover la cámara. La
    malla del terreno es basta vista de cerca y su superficie queda metros
    por encima o por debajo del suelo real: al respetar su profundidad se
    comía trozos del modelo, y como eso depende del ángulo, los trozos iban
    y venían al mover la cámara. El cuerpo se pinta entero, siempre. La cota
    del terreno se suaviza en unos fotogramas para que el modelo no brinque
    al cambiar de nivel de tesela.

  • Las cuatro franjas de luz sueltas, que de cerca flotaban separadas del
    cuerpo, son ahora dos bandas con la misma forma del cuerpo que lo
    abrazan.

  • En 3D no hay chinchetas planas a ningún zoom. Los modelos menguan de
    lejos y con eso basta.

  • La guía hasta el nodo está desde el principio. La red de caminos se
    pide al arrancar, no después de pintar el mapa: el juego empezaba sin
    esa línea y aparecía segundos después.

  • La barra de carga avanza despacio mientras espera al servidor, en vez
    de quedarse clavada en el 3 % y saltar luego.

  • Vuelven los nodos 3D. El relevo a la chincheta plana estaba puesto en
    zoom 16,5 y el mapa del jugador vive en 16: no se veía un solo modelo,
    sólo chinchetas dentro de una vista 3D. El relevo baja a 14,5 y el tope
    de 120 m desaparece, que era lo que dejaba el nodo en treinta píxeles.

  • El tamaño se mide en la pantalla, no en el suelo. Con el mapa
    inclinado, un metro de suelo ocupa muchos más píxeles al pie de la
    pantalla que arriba: por eso un nodo cercano llegaba a taparla entera al
    girar. Ahora se proyectan el pie y la punta del modelo con la matriz del
    mapa y se ajusta el alto real en píxeles.

  • Los permisos vuelven a pedirse antes de salir. Lo concedido se
    recordaba para siempre, así que la tarjeta no salía nunca y se entraba al
    juego sin que nadie pidiera nada; si el sistema había retirado la cámara,
    se descubría en el monte. Ahora la memoria dura lo que dura la sesión, y
    si el navegador dice que la cámara no está concedida se olvida.

  • La barra de carga, una sola y sin parpadeos. Cada fase mandaba su
    propia cuenta y entre medias había tramos sin total, que la ponían en
    modo indeterminado. Ahora cada fase ocupa su trozo, el valor no retrocede
    y lo que queda se recorre andando, no de un brinco.

  • La guía deja de pintar una recta mientras carga la red de caminos.
    Fuera del trazado dibujaba el tramo recto y lo recolocaba al terminar la
    descarga. Mientras no hay red, ese tramo no se pinta.

  • Las franjas de color se ven en los cuatro tipos: iban por dentro del
    cuerpo hexagonal del coleccionable, que salía blanco liso y sin estado.

  • El coleccionable remata en punta, como la gema de su icono. De lejos la
    silueta distingue más que la forma de la base.

  • Los nodos se meten en el terreno. El monolito se pintaba siempre por
    delante de todo, también de un monte que estuviera en medio: parecía
    pegado al cristal. Ahora se pinta en dos pasadas: el cuerpo respeta la
    profundidad del relieve y el cartel del número va siempre encima, así
    que un nodo detrás de una loma se sigue sabiendo dónde está.

  • El icono del tipo va dentro del cartel, como una chapa en la
    esquina del número. Suelto medía 1,2 m pegado al cuerpo y a la
    distancia a la que se juega no se leía.

  • La cota del terreno bajo cada nodo se vuelve a medir en cada fotograma
    mientras el mapa se mueve. Con medio segundo de retraso, al girar o al
    ampliar el modelo se quedaba flotando o hundido.

  • Los nodos dejan de crecer al desampliar. El tamaño en pantalla era
    constante sin tope: a zoom 12 el factor pasaba de 800 y el monolito era
    un pilar de kilómetros atravesando los montes. Ahora el modelo no pasa
    de 120 m en el mundo y por debajo de zoom 16,5 no se pinta: de lejos
    manda la chincheta plana del mapa, de cerca el modelo.

  • Cada clase de nodo tiene su forma. Los diez nodos de la ruta salían
    iguales porque el servidor los mandaba todos como "minijuego": cinco de
    ellos llevan algo que recoger y eso no llegaba al mapa. Se añade la
    clase coleccionable —base hexagonal e icono de gema— junto a las de
    siempre: redonda el checkpoint, cuadrada el QR, triangular el
    minijuego. El coleccionable va antes que el QR: lo que importa es que
    ahí hay algo que recoger, aunque se recoja escaneando.

  • Nodos 3D: el cuerpo sale blanco de verdad. Las caras laterales reciben
    mitad cielo y mitad suelo de la luz hemisférica; con el suelo verde
    oscuro quedaban grises. Suelo claro y más luz ambiental.

  • Nodos 3D: se ven el número, el icono y los anillos. En Mercator la
    y crece hacia el sur; la matriz del modelo tiene determinante negativo
    y three.js pasaba a frontFace(CW), pero la proyección de MapLibre no
    espeja: WebGL descartaba las caras delanteras. Los planos de una sola
    cara (número, icono, anillos del suelo) no se pintaban nunca y de los
    sólidos se veía el interior. Se invierte el índice de caras de cada
    geometría al construir el nodo, sin tocar normales. Además se apaga el
    recorte por frustum de three.js, que con esa matriz descartaba 71 de
    las 102 mallas aunque estuvieran en pantalla.

  • Diagnóstico de la capa 3D: __sagaCapa3D() en el banco da acceso a la
    escena viva.

  • Diagnóstico de la capa 3D: el asa expone la escena viva (solo en el
    banco) para tocar materiales sin redesplegar. Se investiga por qué el
    cartel del número y el anillo del suelo, los únicos con transparencia,
    no aparecen.

  • Nodos 3D: luz y proporciones. Las luces apuntaban al +y de three.js,
    pero en Mercator el cielo está en +z: el cuerpo blanco salía gris oscuro.
    Ahora la hemisférica y el sol vienen de arriba de verdad. El cuerpo es
    más ancho (0,85 m de radio), el zócalo y el anillo crecen a juego y el
    cartel del número pasa de 1,9 a 3,2 m, para leerse desde cualquier
    distancia (118 px el nodo actual, 92 los demás, 76 los pendientes).

  • Los nodos 3D se ven: tenían tamaño real, no de pantalla. El
    diagnóstico de 5.25.9 lo dejó claro: se pintaban en el lienzo, en el
    sitio correcto, pero un monolito de 4,6 m mide 2 píxeles a zoom 17
    (0,49 px por metro medidos). Ahora cada nodo se escala cada fotograma
    para medir un tamaño fijo en pantalla (92 px el actual, 70 los demás,
    58 los pendientes), como un pin, y nunca por debajo de su tamaño real.

  • Diagnóstico de la capa 3D: framebuffer enlazado al entrar y color del
    píxel del nodo antes y después de pintar, para saber si no se dibuja o
    si se dibuja y algo lo pisa.

  • Los nodos 3D se pintan encima del terreno. Con la proyección medida
    y correcta seguían sin verse: MapLibre deja puestos su viewport, su
    recorte y el búfer de profundidad del terreno al llamar a la capa. Ahora
    la capa fija el viewport entero, quita el recorte y limpia la
    profundidad antes de pintar. Un señalizador debe verse siempre, también
    detrás de una loma.

  • La altura de los nodos 3D vuelve a ser absoluta. Medido proyectando a
    mano con la matriz que pasa MapLibre: con la elevación absoluta el nodo
    cae exactamente donde el mapa lo pinta; relativa al objetivo de la
    cámara (5.25.4) se iba fuera de plano. Aquel cambio fue un error; los
    fallos reales eran los dos anteriores (matriz de MapLibre 6 y matriz de
    mundo de three.js), ya corregidos.

  • Diagnóstico de la capa 3D: el asa expone también lo último que MapLibre
    pasa a render() (matrices y coordenadas de tesela), para averiguar en
    qué sistema de coordenadas espera los modelos.

  • Diagnóstico de la capa 3D: el asa de depuración enseña dónde cae el primer
    nodo en el espacio de recorte y en pantalla, para comprobar la
    convención de la matriz sin ver la pantalla.

  • Los nodos 3D estaban en el cielo. Con relieve, MapLibre expresa las
    alturas de las capas 3D relativas a la altura del terreno bajo el
    objetivo de la cámara, no absolutas. Con la absoluta, un nodo a 892 m se
    dibujaba 892 m por encima del suelo, fuera de plano. Medido en el banco
    (elevación del nodo 892, del objetivo 892, nada en pantalla). Ahora la
    altura es la diferencia.

  • El mapa nunca estaba "idle", y de idle colgaba casi todo. El pulso del
    trazado (5.18.0) cambia una propiedad del estilo diez veces por segundo,
    así que el mapa no está ocioso nunca: el aviso de "mapa pintado" al velo
    de carga, la carga de la red de caminos y la animación de los nodos 3D
    no se ejecutaban jamás. De ahí la guía recta, el velo esperando su tope
    y los modelos invisibles (se quedaban a cota 0, bajo el monte, porque su
    altura sólo se refresca al animar). Ahora "pintado" es "capas y teselas
    cargadas", preguntado cada cuarto de segundo con tope de ocho.

  • Con relieve, un nodo 3D no se pinta hasta conocer la altura del terreno
    bajo él: a cota 0 quedaba enterrado.

  • Los nodos 3D seguían sin verse: estaban en el origen del mundo. Con
    matrixAutoUpdate apagado, three.js no recalcula la matriz de mundo
    aunque cambie matrix; había que marcarla. Los monolitos se quedaban en
    lat 85° N, lon -180°, sin un solo error.

  • El banco de mapa enseña las estadísticas de la capa 3D (piezas,
    fotogramas pintados, último error) para poder diagnosticarla desde una
    captura.

  • Los nodos 3D no se dibujaban. MapLibre 6 pasa a la capa un objeto con
    la matriz dentro (defaultProjectionData.mainMatrix); se leía "a la
    antigua" y la proyección salía inválida, sin un solo error. Ahora se lee
    de donde está, y el asa de depuración enseña cuántos fotogramas pintó la
    capa y su último error.

  • La guía fuera del trazado volvía a salir recta. La capa 3D pedía
    repintados sin parar desde el primer fotograma, así que el mapa nunca
    llegaba a "idle", y de idle dependían el aviso de "mapa pintado" y la
    carga de la red de caminos. La animación arranca ahora DESPUÉS del
    primer idle.

  • Nodos 3D de verdad dentro del mapa. Una capa personalizada de MapLibre
    dibuja con three.js sobre el mismo lienzo, con la matriz de proyección
    del mapa: los modelos viven en metros sobre el relieve y se inclinan, se
    tapan y se escalan con él. Diseño acordado: monolito blanco sobrio; la
    base y la tapa con la forma del tipo (redonda checkpoint, cuadrada QR,
    triangular minijuego); el color es el estado (verde hecho, azul en juego,
    rojo pendiente) en una franja de luz, la tapa y un disco en el suelo; el
    número grande siempre de frente e icono pequeño del tipo. Animación
    mínima: la luz respira; el nodo en juego, un anillo fino girando y un
    pulso en el suelo. En cuesta, el zócalo se hunde 30 cm y muerde la
    ladera en vez de flotar. A ~20 fotogramas por segundo y sólo con la
    pestaña visible, por la batería. En 2D siguen las chinchetas planas.

  • El servidor manda siempre kind (checkpoint / qr / minijuego) en cada
    nodo: sólo dice qué clase de sitio es, nada del contenido.

  • La barra de carga ya no se queda en 0 % ni en 100 %. El grafo de
    caminos (21 MB) había entrado en el paquete como "una tesela más": la
    barra cuenta teselas, las 4 000 ya estaban (0 → 100 de golpe) y luego se
    quedaba en 100 % minutos esperando ese único fichero, compitiendo con la
    carga del mapa. Sale del paquete: el mapa lo pide después de pintar y el
    service worker lo guarda al pasar, para el modo sin cobertura.

  • La imagen instala libexpat1: pyosmium la carga en tiempo de ejecución
    y la imagen slim no la trae, así que import osmium moría y la red de
    caminos caía a Overpass (bloqueado). Medido en el contenedor.

  • La red de caminos sale del extracto de OpenStreetMap de Galicia, no de
    Overpass.
    Overpass es un servicio público y compartido: con zonas
    grandes devolvía 504 y, tras varias peticiones pesadas, bloqueó la IP del
    servidor (406 hasta a su página de estado). Ahora el servidor baja UNA
    vez el extracto de Geofabrik (~250 MB, se queda en data/osm/ y se
    renueva a los 60 días), lo lee en local con pyosmium, recorta los
    caminos del rectángulo de la ruta y construye el grafo. Sin límites, sin
    bloqueos, reproducible. Overpass queda sólo de reserva si el extracto
    no se puede bajar. El panel enseña la fase (descargando, leyendo nodos,
    leyendo caminos, construyendo) y el porcentaje.

  • La baldosa de red de caminos que falla se parte en cuatro y se vuelve
    a pedir (hasta 3 km de lado). El 504 de Overpass casi siempre es
    "demasiado para una petición" -una ciudad entera dentro de una baldosa de
    25 km-, no "no funciona"; reintentar la misma baldosa en tres espejos
    sólo la atascaba. Pausas más cortas.

  • La red de caminos se construye en segundo plano en el servidor, y el
    panel enseña el progreso ("7 de 25 baldosas"). Con 40 km son cinco o seis
    minutos y una petición HTTP tan larga caducaba por el camino.

  • Baldosas de 25 km con pausa entre ellas y espera antes de reintentar:
    Overpass concede pocas ranuras por IP y las peticiones encadenadas sin
    pausa acababan en 504 en todos los espejos.

  • La red de caminos se descarga por baldosas de 15 km y con espejos de
    reserva. El servidor público de Overpass devolvía 504 con zonas de 30-40
    km de una vez; en trozos pequeños cada petición es liviana, se unen y se
    quitan los elementos repetidos. Con test de cobertura de las baldosas.