##Verlo funcionar
##Abrir un mundo es preguntar
Cada mundo tiene un UUID permanente y un código corto para compartir. Al abrirlo, jukz le pregunta a la red si alguien ya lo tiene abierto. Si sí, entras a jugar en vivo en el mundo de esa persona, como cuando alguien abre su partida a LAN. Si no, el mundo se abre en tu PC y quedas anunciado como host. No hay copias que sincronizar: el mundo vive en un solo lugar a la vez
##Encontrarse
En la misma red, los PCs se encuentran por multicast, sin internet. Para jugar desde casas distintas hay un servidor rendezvous propio en Cloudflare (un Worker con Durable Objects), donde cada host se anuncia. El host abre el puerto de su router con UPnP; si no se puede (por ejemplo detrás de CGNAT), el rendezvous hace de relay por WebSocket y une las dos conexiones salientes
##Nunca dos hosts
Cada anuncio lleva un token con un número de generación. Si dos personas abren el mismo mundo a la vez, gana la generación más nueva y la otra se entera: puede quedarse con su copia local o entrar como invitada a la partida en vivo
##Pasar el mundo
Cuando el host cierra con invitados conectados, guarda, toma una foto del mundo con JGit y se la pasa al invitado por la misma conexión del juego; el invitado la aplica y sigue como host. Si cierra sin nadie, la foto se sube a la nube (R2) y el siguiente que abra el mundo la descarga y sigue desde ahí
##Tus mundos en cada PC
Con una cuenta de Microsoft, cada mundo que subes a la nube queda anotado en tu cuenta. Al abrir el juego en otro PC o en una instancia nueva, los mundos vienen solos. Una pantalla dentro del juego (el icono de persona en el menú principal) muestra tu plan y las subidas de hoy, lista los mundos de la nube para traerlos u olvidarlos, y los que solo están en este PC, con un botón para subirlos. Tener cuenta es opcional: sin ella el juego funciona igual, con límites más chicos en la copia de la nube (40 MB y 30 días, contra 95 MB y 180 días)
##Quién puede entrar
El código del mundo sirve para encontrarlo y pedir entrar, pero el mundo tiene además una llave Ed25519 que viaja con sus archivos: anunciarse, renovar el anuncio y subir o bajar la copia de la nube se firman con ella. Quien solo tiene el código no puede quedarse con el mundo en vivo, pisar la copia ni pedir el traspaso. Los invitados los verifica Mojang como en un servidor normal, y el host puede cerrar el acceso para volver el mundo privado
##Cosméticos
Sombreros, gafas, mochilas y alas dibujados sobre tu personaje, y una insignia de píxeles junto a tu nombre en la lista de jugadores. Todos ven lo que llevas puesto si usan jukz. Están hechos con arte ASCII: cada pieza es una pila de capas de texto que el mod convierte en una malla 3D, así que agregar una nueva no necesita actualizar el mod. Hoy son gratis, y cualquiera puede diseñar uno en Blockbench y mandarlo desde la página de creadores
##Tu skin, con o sin cuenta de Mojang
Desde el hub eliges un PNG (o lo sueltas sobre la ventana), brazos clásicos o finos, y te lo ves puesto antes de aplicarlo. Con cuenta de Mojang, jukz cambia tu skin de verdad por la API de Mojang, y tu sesión solo va a Mojang. Sin cuenta, la skin se queda en tu PC: al jugar por jukz, tu juego se la pasa al host por la conexión de juego y el host la reparte al resto del mundo, solo en memoria. Ningún servidor de jukz la guarda
##Cómo se probó
La lógica difícil (elegir host, los tokens, el protocolo) vive en un módulo de Kotlin puro, sin Minecraft, con 94 pruebas. Lo demás se probó dentro del juego con dos clientes contra el servidor real, forzando el relay: entrar, pasar el mundo, cerrar el acceso y la subida a la nube. Después se probó entre dos redes de verdad: un PC en la red de la casa y el otro con datos del celular, detrás de CGNAT. Entrar con el código, pasar el mundo en las dos direcciones y las copias de la nube pasaron por el relay
abrir un mundo (UUID)
│
▼
¿alguien lo está hosteando?
│ LAN: multicast · internet: rendezvous (Cloudflare)
├─ sí ─► entrar como invitado, en vivo
└─ no ─► abrir en este PC y anunciarse
│ UPnP, o relay por WebSocket
▼
al cerrar el mundo
├─ con invitados ─► foto JGit ─► nuevo host
└─ sin nadie ─────► foto a R2 ─► el siguiente




##Bitácora
- EncontrarseDescubrimiento por multicast en la red local y un servidor rendezvous para internet; UPnP y STUN para atravesar el NAT de cada casa
- Primera partidaHost e invitado jugando de punta a punta. La DHT que había planeado quedó descartada: el rendezvous era más simple y más confiable
- El mundo se desincronizabaAl pasar el mundo al siguiente host se perdían cambios. Solución: un relay por WebSocket en el rendezvous por donde viaja la copia del mundo
- Que el mundo no se pierdaSi el último en jugar cierra sin nadie más conectado, el mundo se sube a la nube (R2) y el siguiente lo retoma. Y se arregló el caso de dos hosts a la vez
- Mudanza a Cloudflare y pantallas nuevasEl servidor en Fly.io ya no existía, así que el rendezvous pasó a un Worker de Cloudflare con Durable Objects. Las pantallas se rehicieron en owo-ui con un tema común y recarga en caliente. Y cerrar el acceso ya no deja el mundo partido en dos
- Cosméticos, cuentas y dos redesLlegaron los cosméticos 3D, las llaves de cada mundo y los mundos que siguen a tu cuenta, con una copia de la nube casi a la mitad del tamaño. Se probó entre la red de la casa y datos móviles detrás de CGNAT, y todo pasó por el relay
- Tu cuenta, dentro del juegoUna pantalla para ver tu plan, traer mundos de la nube a otro PC y subir los que solo están en este. Aparecieron dos errores: el mundo quedaba marcado una generación atrás después de hostear, y por eso se re-descargaba su propia copia. Salió la versión 0.2.0
- El hub y las skinsCuenta, cosméticos, skin y mundos en una sola ventana a pantalla completa, con un estilo pixel propio dibujado sin texturas para que funcione igual en las tres versiones de Minecraft. Cambiar la skin desde el juego, también sin cuenta de Mojang: la skin viaja de PC a PC por la conexión de juego. Salió como la versión 0.4.0