Zkt Timer
Hola, soy Ibrahim. Llevo mucho tiempo resolviendo cubos y, cuando empecé a competir, esto dejó de ser solo un pasatiempo para mí y se convirtió en algo mucho más serio. A medida que mis entrenamientos se volvían más exigentes, empecé a hacerme las mismas preguntas después de cada resolución: ¿dónde perdí tiempo, en qué transición me frené, qué algoritmo todavía no tengo del todo asentado? Las herramientas que usaba medían el tiempo perfectamente, pero no me ayudaban demasiado a encontrar esas respuestas. Yo quería una herramienta en la que pudiera analizar mis resoluciones a fondo, practicar mis algoritmos de forma ordenada y hacerlo todo en un solo lugar. Probé distintas aplicaciones, pero en ninguna encontré exactamente lo que buscaba, así que al final decidí construirla yo mismo.
Al principio mi objetivo era bastante modesto: solo quería un timer sencillo para mi propio uso, del que conociera cada detalle. Pero cada pieza que añadía traía consigo una nueva necesidad. Primero escribí herramientas de análisis para estudiar mis resoluciones, después el entrenador para practicar algoritmos y, más tarde, añadí la conexión con cubos inteligentes y la sincronización entre dispositivos. Nada de eso fue tan fácil como podría parecer; el protocolo Bluetooth de cada marca de cubo era un rompecabezas en sí mismo, algo que funcionaba a la perfección en un dispositivo podía fallar en otro por donde menos lo esperaba, y a veces pasé horas, incluso días, persiguiendo un solo error. Aun así, cada problema que resolvía me llevaba un paso más allá, y con el tiempo aquel pequeño timer se convirtió en un ecosistema propio.
El proyecto comenzó en 2025 y desde entonces ha llegado muy lejos de donde empezó. Lo que nació en la web pasó con el tiempo a iOS y Android; hoy el mismo código funciona en el navegador, en el móvil y en la tableta. Recorrí la mayor parte de este camino solo. Desde las revisiones de las tiendas hasta los sistemas de pago, desde el código nativo hasta las partidas en tiempo real, cada paso fue un aprendizaje propio, y casi ninguno encajó al primer intento. En todo este tiempo, mi trabajo nunca consistió solo en añadir nuevas funcionalidades; la verdadera lucha fue revisar los sistemas una y otra vez, rediseñar algunos desde cero más de una vez y lograr que todas las piezas funcionaran en armonía.
Una herramienta que al principio escribí solo para mí se ha convertido en un lugar donde otros cuberos entrenan cada día, compiten entre sí y siguen las competiciones. Ver a alguien a quien nunca he conocido batir su récord personal en Zkt Timer me dice que todo ese esfuerzo no fue en vano. Además, buena parte de las nuevas funciones nace ahora de los comentarios de quienes la usan. No veo Zkt Timer como un producto terminado; es un proyecto en el que sigo trabajando cada día, que no deja de crecer, y, sinceramente, siento que todavía estoy al principio de este camino.

Zkt Timer — ibrhyyme
La persona que diseña y desarrolla Zkt Timer.
Credits
Antes dije que recorrí la mayor parte de este camino solo, pero lo cierto es que nunca estuve realmente solo. El mundo del speedcubing tiene una cultura de código abierto extraordinariamente generosa que ha crecido con los años, y mientras desarrollaba Zkt Timer me nutrí de ella constantemente. Estudié a fondo muchos proyectos; algunos los ejecuté en mi propio ordenador para probarlos, y otros los leí línea por línea solo para entender de verdad cómo funcionaban.
De cada proyecto aprendí algo distinto. Algunos me orientaron en cuestiones técnicas como la generación de mezclas o los enfoques de los solucionadores; otros me ayudaron a ver qué funciona de verdad en el entrenador y en la experiencia de usuario. A veces fue una idea de algoritmo, a veces un modelo de datos y a veces una forma de mirar un sistema completo lo que me abrió camino cuando estaba atascado.
En lugar de tomar esas piezas y usarlas tal cual, retomé cada una para que encajara en la propia estructura de Zkt Timer. Reescribí la mayoría de los sistemas desde cero, simplifiqué algunos y amplié otros según fue haciendo falta. Reunir enfoques de fuentes distintas bajo una sola arquitectura, funcionando en armonía entre sí, fue a la vez la parte más difícil y la más enriquecedora de este proceso.
Por eso la estructura que existe hoy no depende de una sola fuente; tomó forma al reunir y reconstruir lo que aprendí de muchos proyectos distintos. Pero quiero decirlo con claridad: sin el trabajo de los desarrolladores que aparecen a continuación, Zkt Timer jamás habría llegado a ser lo que es hoy en tan poco tiempo.
Creo que llevar algo hacia delante nunca consiste solo en añadir algo nuevo; entender bien el trabajo que se hizo antes que tú, respetarlo y construir sobre él una contribución honesta importa igual. Por eso reconocer el mérito de todas las personas que han tocado este proyecto, directa o indirectamente, es para mí menos una cuestión de cortesía que una deuda que hay que saldar.
Cada uno de los proyectos y desarrolladores que menciono a continuación tuvo un papel distinto en la formación de Zkt Timer. Algunos fueron el punto de partida de una idea, otros me ayudaron a resolver un problema en el que llevaba mucho tiempo atascado, y otros ampliaron mis horizontes y me permitieron ver un enfoque mejor. La mayor parte de este trabajo lo crearon personas que sacrificaron su propio tiempo libre y lo compartieron con todos sin esperar nada a cambio; entendí mucho mejor lo valioso que es eso cuando asumí esa misma carga en mi propio proyecto.
A todas las personas que comparten su esfuerzo, su tiempo y su conocimiento con esta comunidad, les ofrezco mi más profundo respeto y mi agradecimiento más sincero. Gracias por estar ahí.
— ibrhyyme
Novedades de Zkt Timer
Esta sección recoge las funciones diseñadas y desarrolladas para Zkt Timer. Cada una surgió de las necesidades de la propia plataforma y de los comentarios de sus usuarios.
Sistema de Notificaciones y Cuenta Atrás de Competición
Zkt Timer genera notificaciones automáticas para las competiciones que sigues. La apertura de inscripciones, la publicación de grupos y asignaciones, la entrada de resultados y los récords batidos se envían como notificaciones, y se mantiene una cuenta atrás hasta la fecha de la competición. El sistema funciona como tareas programadas en el servidor y produce notificaciones tanto dentro de la aplicación como push.
Radar de Récords
Calcula por adelantado qué récords podrían caer en una competición a la que asistes. Se comparan la lista de competidores, el calendario de eventos y los récords nacionales vigentes para determinar qué récords están en riesgo, y el resultado se muestra en la página de la competición.
Aplicación Móvil Nativa
Zkt Timer se distribuye como aplicación nativa en iOS y Android. La conexión con cubos inteligentes funciona a través de una capa BLE nativa, y el soporte de acelerómetro y háptica se proporciona mediante plugins nativos. Los gestos de borde, las áreas seguras y el comportamiento del teclado se tratan por separado en cada plataforma.
Magnet Timer
Un tipo de timer, exclusivo de las apps de iOS y Android, que mide el tiempo sin tocar la pantalla. El teléfono queda plano sobre la mesa y el cubo descansa junto al extremo de la cámara trasera; el sensor de brújula del teléfono detecta los imanes del interior del cubo. Al levantar el cubo empieza el tiempo, y al dejarlo sobre la mesa se detiene. Como el sensor de cada teléfono se comporta de forma distinta, la calibración se hace por cubo y por modelo de teléfono, con umbrales calculados a partir de los valores brutos del sensor. La capa nativa que lee el sensor se escribió por separado para iOS y Android, y la lógica de detección se probó con grabaciones de dispositivos reales.
Modo Sin Conexión Completo
Se pueden registrar resoluciones, abrir sesiones y consultar estadísticas sin conexión a internet. Cuando la conexión vuelve, las resoluciones pendientes se ponen en cola y se reconcilian con el servidor, los conflictos se resuelven y los registros duplicados se filtran por huella.
Offline Battle (1v1)
Un modo en el que dos personas compiten cara a cara en el mismo dispositivo. En móviles y tabletas la pantalla se divide en dos mitades enfrentadas; en escritorio los jugadores se sientan uno al lado del otro y usan las teclas A y L. Los jugadores empiezan de forma independiente y cada uno puede conectar su propio cubo inteligente. Las penalizaciones y las puntuaciones se registran por separado, y el historial de rondas se guarda con detalle.
Online Battle
Una partida 1v1 que se juega con un cubo inteligente contra otro jugador que busca rival en ese mismo momento. Ambos resuelven la misma mezcla y gana quien se lleve primero tres rondas. El tiempo lo mide el propio reloj del cubo y no internet, así que el retraso de la conexión no afecta al resultado. El emparejamiento amplía su margen de puntuación cuanto más se espera; el servidor dirige la partida y verifica cada resolución con su registro de movimientos y el reloj del cubo. Las puntuaciones se calculan con Glicko-2 y aparecen en la página de Clasificación.
Sets de algoritmos
Una forma de reunir en sets propios los algoritmos que quieres practicar. Casos de categorías distintas, como OLL, PLL y F2L, pueden convivir en el mismo set. Un set puede ser privado, compartirse solo mediante enlace o hacerse público, y el enlace compartido se abre con su propia vista previa. Los sets públicos aparecen en Sets de la comunidad, donde otros pueden guardarlos. Los cambios se guardan al instante y los sets también se conservan en el dispositivo para usarlos sin conexión.
Mensajes
Un sistema de mensajería para conversaciones uno a uno entre usuarios. El primer mensaje de alguien nuevo no llega directamente a la bandeja de entrada; espera aprobación en la pestaña Solicitudes. Se puede adjuntar una resolución a la conversación, y la otra persona ve el tiempo y puede abrir su detalle. Los mensajes enviados se pueden editar o anular. Quién puede escribirte, las confirmaciones de lectura, el indicador de escritura y el punto de conexión dependen de los ajustes de cada usuario, y el bloqueo y las denuncias están integrados.
Personalización
Los colores de los puzles se eligen en grupos separados, de 2x2 a 7x7 además de Square-1, Clock y FTO, y todos los dibujos de la app los siguen: la imagen de la mezcla, la vista del cubo inteligente y el resto. Detrás del timer se puede poner una imagen o un vídeo MP4 de hasta 40 MB; el vídeo se pausa durante la resolución y el ajuste se guarda por dispositivo. En escritorio, los módulos de la pantalla del timer se arrastran libremente a las columnas, a la franja inferior o a cualquier hueco libre, y se redimensionan desde sus bordes.
Cuber Card
Una tarjeta compartible que convierte la información de tu perfil en una sola imagen. En ella aparecen el avatar, el nombre, el número de competiciones, las medallas y los récords WCA. Se conecta al menú de compartir nativo en móvil y a una descarga directa en escritorio.
Referencias
Los proyectos siguientes sirvieron como referencia de distintas formas durante el desarrollo de Zkt Timer. Cada entrada indica dos cosas: qué se tomó de ese proyecto y qué se construyó encima.

Mi referencia más fuerte en el apartado de arquitectura de software de Zkt Timer. Cómo encajan React + SSR, Node.js + GraphQL, PostgreSQL + Prisma y Redis dentro de una plataforma de cubing se dedujo estudiando cubedesk, de kash. Orientó la organización de servicios y la estructura de carpetas. Su influencia no se limitó al lado del servidor: el lenguaje de interfaz que estableció cubedesk también fue una referencia para la disposición de la pantalla del cronómetro, la lista de resoluciones y la organización de los módulos. Donde nos separamos: cubedesk es una aplicación web. Yo quería que el mismo código llegara a iOS y Android mediante Capacitor, así que reconstruí la capa SSR, la gestión de sesiones y la sincronización entre dispositivos para que también sostuvieran el lado nativo.

La base de la generación de mezclas. Los algoritmos de mezcla y la estructura de subconjuntos de los tipos de puzle, el solucionador Kociemba min2phase y la librería de teoría de grupos se construyeron tomando como referencia csTimer y min2phase, de cs0x7f. Al trasladar ese código de JavaScript a TypeScript se reestructuró alrededor de una arquitectura de generadores basada en registro; ahora cada tipo de puzle registra su propio generador y el cliente y el servidor pueden producir la misma mezcla. Encima se añadieron más de 40 subconjuntos de CFOP, Roux, Mehta y ZZ, mis propios renderizadores 2D para Square-1 y Clock, y una capa de Web Workers que ejecuta los solucionadores pesados sin congelar la interfaz.

Una de mis referencias principales en la parte de experiencia de usuario del módulo Trainer. Cómo se conecta un cubo inteligente a un flujo de entrenamiento se dedujo estudiando el proyecto de Pau Oliva Fora. En Zkt Timer esta estructura se dividió en cuatro modos distintos (Estándar, Cubo Inteligente, Reconocimiento, Eficiencia); se guardaron estadísticas por algoritmo, se hizo que el orden de la cola se adapte a los casos en los que el usuario es débil, y se añadieron visualización de patrones en 2D y 3D y exportación a PDF para imprimir hojas de algoritmos.

Una parte importante de la colección de algoritmos usada en el Trainer proviene del conjunto de datos cubingapp creado por spencerchubb y se adaptó al modelo de datos de Zkt Timer. Los algoritmos de preparación se regeneraron con mis propios scripts, las imágenes de patrones pasaron por mi propia canalización de renderizado, la colección se dividió en 31 categorías y se amplió con algoritmos propios.

El punto de partida de la lógica de los solucionadores de Cross, XCross, EOCross y pares F2L. Las implementaciones de IDA* basadas en coordenadas desarrolladas por or18 fueron una referencia fundamental en el diseño del sistema de solucionadores de Zkt Timer. El trabajo en este módulo fue de portado y adaptación: los solucionadores se llevaron a una arquitectura de Web Workers y se conectaron a una interfaz de solución paso a paso. Las matemáticas que hay detrás del algoritmo pertenecen a or18.

La base conceptual de las salas 1v1 y del formato de carrera amistosa viene de este proyecto. Cómo se construye un modelo de resolución compartido y sincronizado se dedujo estudiando el trabajo de coder13. El sistema de salas de Zkt Timer se escribió desde cero sobre esa idea, y se añadieron las siguientes ideas que consideré ausentes en LetsCube: soporte de cubo inteligente dentro de las salas, chat en vivo, modo espectador, moderación de salas y bloqueo de usuarios, un modo de duelo 1v1, y una capa de Socket.IO que transmite entre varios servidores a través de Redis.

Un proyecto creado para que los competidores puedan seguir sus propios grupos y asignaciones en las competiciones WCA, y hace ese trabajo muy bien. No quería que los competidores tuvieran que visitar otro sitio para esa información, así que la misma experiencia se trajo dentro de Zkt Timer. El horario propio del competidor, sus asignaciones de juez y mezclador, sus mejores marcas por evento y sus resultados de ronda se reúnen ahora en una sola pantalla. La disposición de las pantallas de grupos tomó forma bajo la influencia de este proyecto.

Una plataforma creada para seguir en vivo las competiciones WCA, y que resuelve realmente bien el flujo de resultados ronda a ronda. El trabajo del WCA Software Team fue la fuente directa del enfoque estructural de la integración con WCA Live en Zkt Timer. La plataforma de competiciones ZKT en sí se escribió desde cero para Zkt Timer: inscripción, entrada de tarjetas de puntuación, modo de entrada por lotes, gestión de rondas, asignación de jueces, mezcladores y runners, seguimiento de récords nacionales, gestión de delegados, competiciones divididas en días A/B y generación de WCIF. Lo que se tomó de wca-live es la lógica del flujo de trabajo del delegado.

El cubo 3D interactivo de la página de inicio se portó uno a uno desde este proyecto de Dev-tanay. La fuente estaba escrita contra Three.js r95; las API que cambiaron se adaptaron al pasarlo a r125 y el código se convirtió a TypeScript. La estructura de clases y los nombres de métodos se mantuvieron igual que en la fuente. Mi aportación fue conectar el cubo al cronómetro de Zkt Timer: generación de mezcla, detección de resolución y medición de tiempo. En esta entrada el esqueleto del código pertenece a Dev-tanay.

La base directa del módulo Entrenador de Reconocimiento de PLL. La práctica de reconocimiento de PLL por teclado, la guía de reconocimiento de dos caras y la lógica de repetición adaptativa vienen del proyecto de Roman Strakhov. La fuente estaba escrita en Vue; el módulo se reescribió en React y TypeScript. Durante la reescritura se completó la guía de reconocimiento para cubrir los 73 casos y se añadieron una capa de historial en el dispositivo, una vista de glosario y una misión guiada de 13 pasos. Hoy el módulo tiene aproximadamente cuatro veces el tamaño de la fuente.
Bibliotecas Utilizadas
Bibliotecas centrales de cubing utilizadas directamente en la infraestructura de Zkt Timer.

cubing.js — Lucas Garron & the cubing.js team La biblioteca central utilizada para el seguimiento del estado del smart cube, la notación WCA y la coincidencia KPattern. Desarrollada por Lucas Garron y los colaboradores de cubing.js.

La biblioteca que proporciona la gestión de conexión Bluetooth y la lógica de giroscopio/movimiento para los smart cubes GAN. El módulo Smart Cube se construye sobre esta biblioteca.

El sucesor mantenido de gan-web-bluetooth. Muchas correcciones de nuestros controladores GAN, QiYi, MoYu, Giiker y GoCube (leer varios movimientos GAN de un paquete Bluetooth, validación de paquetes, soporte de giroscopio, candidatos de MAC) provienen de esta biblioteca, y sus grabaciones de cubos reales se usan en nuestras pruebas.
Una biblioteca central de resolución de cubos utilizada en varias funciones de análisis y resolución.
Código Abierto
Zkt Timer está construido sobre cientos de paquetes de código abierto, incluyendo React, Apollo, Prisma y Three.js. La lista completa de dependencias puede encontrarse en el archivo package.json. Mi sincero agradecimiento a todas las personas que han desarrollado y mantenido estas bibliotecas durante años.
A la Comunidad
A la WCA y a la comunidad global de speedcubing. Se ha construido una comunidad mundial extraordinaria en torno a un solo puzzle. La verdadera razón por la que Zkt Timer tiene sentido es que puede formar parte de esta comunidad.
Avisos de Derechos de Autor
Partes de este software hacen referencia a código o conceptos de los proyectos mencionados arriba. Cada proyecto conserva sus propios derechos de autor originales. La arquitectura, los sistemas y las funcionalidades propias de Zkt Timer están sujetos a los siguientes derechos de autor:
Este proyecto se publica bajo la Licencia Pública General de GNU v3.0.