1 puntos por GN⁺ 2024-12-27 | 1 comentarios | Compartir por WhatsApp
  • CobolCraft es un servidor de Minecraft implementado en COBOL y es compatible con Minecraft 1.21.4, la versión más reciente al momento de su creación
  • Ya implementa generación de terreno infinita, carga dinámica de chunks, guardado en disco de datos del mundo y de jugadores, importación de mundos existentes, multijugador, visualización del estado del servidor, destrucción y colocación de bloques, inventario, crafting, recolección de ítems, chat, comandos y más
  • Los bloques con múltiples estados, direcciones e interacciones requieren mucho código dedicado para implementar correctamente su comportamiento, y todavía hay muchos bloques no compatibles
  • Fue desarrollado con GnuCOBOL en Linux x86_64 o arm64, y también se puede distribuir usando Docker, pero no se ha probado la compatibilidad con otros sistemas operativos como Windows
  • Extrae datos JSON del datapack predeterminado de Minecraft y de los .jar oficiales del servidor y del cliente, y los usa para generar código COBOL en tiempo de compilación y cargar datos en tiempo de ejecución

Funcionalidades del servidor de Minecraft implementadas por CobolCraft

  • CobolCraft es un servidor de Minecraft escrito en COBOL y es compatible con Minecraft 1.21.4
  • Las funcionalidades implementadas incluyen lo siguiente
    • Generación de terreno infinita y carga dinámica de chunks
    • Guardado en disco de los datos del mundo y de los jugadores
    • Compatibilidad con formatos de archivo de Minecraft e importación de mundos existentes
    • Multijugador con cantidad configurable de jugadores conectados simultáneamente
    • ping/server status para aparecer en línea en la lista de servidores
    • Destrucción y colocación de bloques, y código de loot tables generado automáticamente
    • Interacción con bloques basada en clic derecho
    • Inventario del jugador
    • Crafting 2x2 y 3x3
    • Entidades de ítems y recolección de ítems
    • Chat
    • Comandos dentro del juego y comandos interactivos de consola
    • Configuración basada en server.properties
    • whitelist persistente guardada en whitelist.json
    • Colisiones muy básicas de bloques y jugadores, y física de entidades
    • Daño por caída, daño por void, muerte y respawn

Alcance y límites de compatibilidad con bloques

  • Los bloques con varios estados, direcciones e interacciones requieren mucho código especializado para comportarse correctamente
  • Todavía hay muchos bloques no compatibles
  • Entre los bloques que funcionan se incluyen
    • torches
    • slabs
    • stairs
    • rotated pillars como logs
    • buttons sin interacción
    • doors
    • trapdoors
    • beds
    • signs

Entorno de compilación y ejecución

  • CobolCraft fue desarrollado con GnuCOBOL y está pensado para ejecutarse en Linux
    • Las arquitecturas objetivo son x86_64 y arm64
    • No se ha probado la compatibilidad con otros sistemas operativos como Windows
    • Con Docker es posible distribuirlo de forma independiente de la plataforma
  • Los requisitos para distribuirlo en Linux son los siguientes
    • GnuCOBOL 3.1.2 o superior
    • Por rendimiento, se recomienda GnuCOBOL 3.2 o superior
    • make
    • gcc, g++
    • zlib
    • curl, necesario para descargar el .jar oficial del servidor
    • Java 21 o superior, necesario para extraer datos del .jar del servidor
  • Los comandos de compilación y ejecución son los siguientes
make --jobs=$(nproc)
make run
  • Se puede usar la imagen de Docker Hub o compilarla directamente y ejecutarla
docker pull meyfa/cobolcraft:latest

git clone https://github.com/meyfa/CobolCraft.git cobolcraft && cd cobolcraft
docker build --tag meyfa/cobolcraft .

Configuración del servidor y acceso por red

  • La configuración del servidor se realiza modificando el archivo server.properties
  • Este archivo se genera automáticamente en el primer arranque con los valores predeterminados de todas las opciones compatibles
    • server-port: valor predeterminado 25565
    • level-name: valor predeterminado "world"
    • white-list: valor predeterminado false
    • motd: valor predeterminado "CobolCraft"
    • max-players: valor predeterminado 10, máximo 100
  • De forma predeterminada, solo se puede acceder al servidor desde el propio sistema mediante localhost:25565
  • Para permitir acceso externo, como desde una red local, VPN, port forwarding o un servidor alquilado, se puede enlazar el puerto como 0.0.0.0:25565:25565 al ejecutar Docker
docker run --rm -it -p 0.0.0.0:25565:25565 meyfa/cobolcraft

Por qué crear un servidor de Minecraft en COBOL

  • El desarrollador no tenía experiencia previa con COBOL, pero quería conocer mejor el lenguaje tras ver los rumores y estigmas sobre COBOL
  • Eligió escribir algo por su cuenta como la mejor forma de aprender el lenguaje
  • Considera que elegir escribir un servidor de Minecraft en COBOL fue una idea buena y mala a la vez, por la complejidad y escala del código de Minecraft
  • Tuvo que construir desde cero tareas que en otros lenguajes son sencillas
    • Parseo y codificación de JSON
    • Procesamiento de varios tipos de datos binarios
    • Networking multijugador en tiempo real
    • Trasladar a un lenguaje procedural un sistema de Minecraft orientado a objetos
  • Señala que la curva de aprendizaje pronunciada lo llevó a investigar y entender en profundidad COBOL y sus conceptos, y que el proceso fue gratificante
  • Para quienes usan COBOL por primera vez, recomienda la GnuCOBOL Programmer's Guide
  • Como material para aprender el protocolo de Minecraft, se puede consultar la documentación de wiki.vg
  • En algunos casos, ver tráfico real de servidores con herramientas como Wireguard también puede ayudar a entender el flujo de información

Estructura del código fuente y binario ejecutable

  • El código fuente COBOL está principalmente en el directorio src/
    • src/main.cob es el punto de entrada
    • src/server.cob contiene el código de arranque del servidor y la lógica del juego
  • El directorio codegen/ contiene generadores de código escritos en COBOL
    • Generan código fuente adicional a partir de datos JSON, como el datapack predeterminado de Minecraft
  • El directorio cpp/ contiene código fuente en C++ para integración con el sistema operativo que es difícil de manejar en COBOL
    • Gestión de sockets TCP de bajo nivel
    • Temporización precisa
    • Manejo de señales de procesos
  • Todo el código fuente COBOL y C++ se compila en un único binario cobolcraft

Extracción de datos de Minecraft y procesamiento de JSON

  • Las aplicaciones oficiales de servidor y cliente de Minecraft Java Edition contienen muchos datos
    • Bloques, ítems y tipos de entidades
    • biomes
    • ID de protocol de paquetes
    • tags, como bloques que se pueden minar con pico
    • recipes
    • loot tables que indican qué ítems caen bajo qué condiciones cuando se rompe un bloque
  • El Makefile de CobolCraft incluye targets para descargar el .jar oficial y extraer los datos como JSON
  • Los datos JSON extraídos se usan de dos formas
    • Generar automáticamente, en tiempo de compilación, código COBOL como las loot tables de bloques
    • Cargar datos en memoria durante la ejecución
  • Ambas tareas usan un parser JSON de propósito general, escrito en COBOL y con pruebas unitarias completadas

Pruebas y actualizaciones

  • Las pruebas unitarias están en el directorio tests/
  • Las pruebas usan un framework de testing personalizado basado en copybooks
    • Hace seguimiento de suites de prueba, unidades y assertions
    • Entrega un resumen al finalizar la ejecución
  • El comando para ejecutar las pruebas es make test
  • El objetivo principal de las pruebas es verificar áreas difíciles de depurar, como la codificación y decodificación de datos JSON y binarios
  • Las pruebas de la lógica del juego en sí no se consideran tan importantes
  • El procedimiento para actualizar el servidor a una nueva versión de Minecraft y los pasos de prueba están en Updating.md

Licencia y marcas comerciales

  • CobolCraft se distribuye bajo la MIT License
  • “Minecraft” es una marca comercial de Mojang Synergies AB
  • CobolCraft no está afiliado a Mojang ni cuenta con el respaldo de Mojang

1 comentarios

 
GN⁺ 2024-12-27
Opiniones en Hacker News
  • Hay muchos rumores y estigmas alrededor de COBOL; estaría bueno que escribieras qué aprendizajes concretos sacaste
    Yo también solo he escuchado esas historias, y me da curiosidad saber con qué se topó un principiante en COBOL al implementar un primer proyecto bastante complejo

    • Existe un estigma medio en broma de que la variante orientada a objetos de COBOL tiene un nombre inmanejable: ADD ONE TO COBOL YIELDING COBOL
      Aun así, no pasaba como con el FORTRAN antiguo, que ignoraba los espacios y podía compilar silenciosamente DO 10 I=1.10 no como un error de sintaxis de bucle, sino como una asignación DO10I = 1.10. El código pretendido seguramente era DO 10 I=1,10
    • Este tipo de aprendizajes está bueno
      Si te interesa, aquí hay cosas que aprendí creando un compilador de COBOL a C#: https://github.com/otterkit/otterkit-cobol/issues/40
      Ahora estoy convencido de que COBOL no es más que un ensamblador de alto nivel
  • Realmente genial
    Para mi proyecto de graduación de la secundaria hice un sistema completo en COBOL que automatizaba cuotas de apuestas de fútbol. Ya era una tecnología pasada de moda, pero la escuela todavía no se había puesto al día
    Era absurdamente inadecuado, pero disfruté cada línea. Hay algo raramente satisfactorio en un lenguaje que, cada vez que tipeas, te susurra “¿te acuerdas de las tarjetas perforadas?”

    • Que hayas usado COBOL en mayúsculas para un proyecto de secundaria encaja perfecto con la época. Debe haber quedado como un gran recuerdo de secundaria. Espero que todos los nombres de variables hayan sido nombres de dioses griegos
  • Puede que sea una impresión equivocada, pero siento que veo bastante seguido proyectos personales pequeños e impresionantes escritos en lenguajes simples y comunes, como C o COBOL en este caso
    En cambio, proyectos similares en Rust parecen tener unas 10 veces más líneas de código y aun así casi no funcionar
    Mi hipótesis es que un lenguaje simple facilita capturar una idea rápidamente, como un plano, y hacer que una base de código desordenada al menos funcione. En cambio, los lenguajes modernos te obligan a escribir código que aguante más tiempo. O quizá los lenguajes modernos estén haciendo algo mal

    • Un servidor de Minecraft no es exactamente un proyecto personal pequeño
      Hay servidores que llevan 3 a 5 años en desarrollo y todavía no están terminados, y también hay otros enfocados en funciones específicas, como https://github.com/MCHPR/MCHPRS para exhibiciones de redstone
      Este servidor en COBOL todavía no implementó el procesamiento de iluminación, y la generación de mobs también depende de eso, así que es una de las partes más difíciles. Algunos bloques tampoco están completamente implementados. Terminar un servidor de Minecraft requiere años, así que hacer algo rápido no siempre es el mejor camino
    • No creo que sea necesariamente una impresión equivocada
      Estoy trabajando en 2 juegos en Rust y, si eliges el motor adecuado, fue bastante fácil hacer un prototipo de gameplay muy mínimo. Pero a medida que fui agregando funciones, el código creció muchísimo, y pasar de single-player a multiplayer fue un desastre. También perdí tiempo siguiendo modas y luego quitándolas
      Rust odia de verdad las estructuras de grafos complejos donde los objetos del juego están conectados entre sí. Cada vez que un evento del juego deriva en actualizaciones de varios tipos, aparece fricción. Una opción era simplemente aceptarlo y escribir un poco más de código; otra era buscar una solución sistemática que ahorrara tiempo más adelante, aunque exigiera escribir más código al principio
      Elegí la segunda e hice varios experimentos, pero siento que el punto de equilibrio queda demasiado lejos para proyectos pequeños con punto de equilibrio en 1
      Incluso dentro del mismo lenguaje la diferencia puede ser de más de un orden de magnitud. En Rust hay 2 motores 3D utilizables: uno es famoso, tiene muchos colaboradores y recibe patrocinio suficiente como para reemplazar un salario del Bay Area. El otro lo mantiene casi una sola persona, alternando entre vivir de sus ahorros y trabajar full time
      Pero el primer motor se enfoca mucho en la promoción y lleva años prometiendo varias funciones con poco para mostrar, mientras que el segundo está adelante tanto en cantidad de funciones como en calidad de implementación
      Al final creo que es una diferencia de actitud. Hay gente que programa por diversión, gente con objetivos claros que se enfoca en cumplirlos, gente que lo hace por dinero y gente atraída por el reconocimiento público. Una base de código desordenada no es necesariamente imprescindible, pero existe un punto medio productivo. Cuanto más se enfoca alguien en lucirse, más fácil es que persiga modas y arquitecturas llamativas
    • Rust ha tenido bastantes dificultades para despegar en desarrollo de juegos
      La premisa central de Rust es intercambiar velocidad de desarrollo y flexibilidad por seguridad de memoria, pero en desarrollo de juegos quedó claro que la velocidad de desarrollo y la flexibilidad importan mucho más que la seguridad de memoria
      Si tienes un microkernel con especificación formal ya delineada hasta el detalle, Rust puede ser una excelente opción. En cambio, si necesitas tirar barro rápido contra la pared para ver qué termina siendo gameplay divertido, Rust hace ese proceso más difícil que casi cualquier otro lenguaje y sus ventajas no son evidentes. El resultado es, como mucho, una pieza rápida y desordenada de gameplay que tardó más en hacerse y es apenas más segura en memoria
      No soy el único que, después de hacer desarrollo de juegos en Rust, lo dejó claramente para ese uso. Por ejemplo, está “Leaving Rust gamedev after 3 years” [0], que hasta ahora es uno de los posts relacionados con Rust más discutidos y votados en Hacker News
      En un plano más amplio, es evidente que Rust recibe muchísima más atención exagerada que COBOL. Por eso hay muchos ejemplos de desarrolladores vulnerables a esa ola de hype —normalmente principiantes entusiastas— que se lanzaron valientemente a proyectos open source o de hobby en Rust. En cambio, escribir un servidor de Minecraft en COBOL requiere un poco más de ingenio y audacia, y eso por lo general se asocia con más experiencia
      [0] https://news.ycombinator.com/item?id=40172033
    • Al final parece la diferencia entre los verdaderos hackers™ que aman los lenguajes simples y pueden construir un universo entero con cualquier cosa que les des, y los code monkeys que persiguen la última moda
      Por cierto, yo me pongo a mí mismo en la segunda categoría
    • La gente que termina las cosas normalmente no se preocupa demasiado por la calidad del código
      En algún momento, por intentar escribir código que durara mucho, terminé en un estado en el que no terminaba nada. Con los años encontré el equilibrio, aprendí que si mejoras iterativamente código basura al final se convierte en algo decente, y desde entonces hago eso
  • https://raw.githubusercontent.com/meyfa/CobolCraft/main/src/...
    Para alguien con experiencia en lenguajes procedurales, en realidad no es tan difícil de entender, y me recuerda un poco a esos servidores de juegos escritos en VB que vi hace unos 20 años.

  • Desde que dejé de usar COBOL en 1978, nunca volví a admitir que conocía este lenguaje.
    Me persigno esperando no ver este código y me voy por un café bien cargado :-)
    Aun así, es impresionante que lo hayan logrado.

  • Pueden burlarse si quieren, pero el código es bastante fácil de leer.
    Contrasta con algunos lenguajes modernos en los que hay que quedarse mirando varios minutos para entender qué está pasando.

    • En una época trabajé en una empresa FAANG y tenía acceso a expertos mundiales en C++. Algunos formaban parte de comités internacionales de estandarización del lenguaje.
      Pregunté en una lista interna de C++ si una línea específica de código podía provocar una fuga de memoria; era código que usaba puramente plantillas de STL y conversiones de tipo. Pero los expertos no lograron ponerse de acuerdo sobre si lo estaba haciendo correctamente. Algunos decían que habría una fuga, otros opinaban que no.
      Esta pequeña historia real dice mucho sobre C++. JavaScript también está lleno de cosas así.
    • Esa era la fortaleza de COBOL.
      Empecé a programar en 1976 y aprendí COBOL e ICL PLAN; usé tarjetas perforadas y, después de terminar la capacitación, terminales. Los programas eran 100% programas batch.
      Había un sesgo muy fuerte hacia la legibilidad para que cualquiera pudiera leer y entender el código fuente. Aunque eso se compensaba en parte con la necesidad de leer y entender los core dumps que se generaban cuando un programa fallaba. En el mejor de los casos podías rastrear la falla hasta una línea específica de código, así que se te quedaba grabado el hábito de ejecutar el programa mentalmente.
      Cuando dejé una agencia gubernamental y pasé a la programación comercial, hasta principios de los 80 seguía siendo COBOL y programas batch. Hice soporte nocturno durante 3 años, y ahí se notaba el valor de COBOL. Incluso tomando un listado y un core dump que veía por primera vez, por lo general podía arreglarlo bastante rápido. Claro, siempre con la salvedad de que eran correcciones tácticas.
    • Por eso me gustan Ada y VHDL.
      Pueden ser algo verbosos, pero son mucho más fáciles de leer que lenguajes más “modernos”.
    • COBOL fue diseñado para que también lo pudieran usar y leer personas que no eran programadoras.
      Al menos en teoría.
    • MOVE FUNCTION MIN(BLOCK-ENTRY-MINIMUM-STATE-ID(LK-BLOCK), STATE-ID) TO BLOCK-ENTRY-MINIMUM-STATE-ID(LK-BLOCK)
  • En la secundaria aprendí un poco de COBOL en una ciudad pequeña de Pakistán.
    No estaba mal, e hice un proyecto que imitaba estados financieros. Tenía sus rarezas, pero para la mayoría de los humanos, es decir, para los no programadores, cualquier lenguaje de programación debe parecer bastante raro, así que no entiendo bien el estigma que carga COBOL.
    Por la misma época también aprendí C, y ese sí se quedó conmigo :-)

  • Siempre escucho que los programadores de Cobol son escasos y ganan sueldos altos.
    Me pregunto si a esta persona le llovieron ofertas de trabajo por este proyecto.

    • Lo escaso no son los programadores de Cobol, sino las personas que entienden la lógica de negocio.
      Cobol se usa a menudo en operaciones de negocio muy complejas.
    • Como dijeron otros, pesa más la complejidad de la lógica de negocio existente y la comprensión de los sistemas mainframe en los que normalmente corre ese código.
      Si no fuera así, bastaría con crear un cross-compiler y listo.
    • Esas personas son valiosas más por su conocimiento de sistemas muy complejos y por lo general sin documentar, y de su contexto de negocio, que por sus habilidades de programación.
  • COBOL en realidad parece un lenguaje bastante genial.
    El código también está muy bien organizado.

  • Me gusta que tenga pruebas unitarias.