# data[].attributes.body
El jueves de la primera semana me puse en contacto con el doctor Eduardo para poder agendar una reunión y platicar del proyecto.

# data[].attributes.body
En esta primera junta se me introdujo el proyecto "OptiChAIn: Innovación en predicción y optimización del supply chAIn". Aprendí que se trata de una simulación en la que se busca promover la colaboración entre minoristas en una cadena de distribución. El juego consiste en 4 minoristas que deben cumplir con una demanda establecida teniendo un proveedor con inventario limitado. El proveedor da prioridad a la orden con mayor cantidad de unidades y esto causa que haya minoristas que se queden sin su pedido. Mi trabajo inicial en este proyecto sería pasar el juego a una modalidad multijugador en línea. Quedamos en tener una segunda junta para ver el juego funcionando y recibir el código.

# data[].attributes.body
En la segunda junta pude ver el juego corriendo en modalidad local con TKINTER y recibí el código para poder adaptarlo a la modalidad en línea. Esto iba a representar un reto para mí porque tengo experiencia con desarrollo web, pero no con una comunicación a un servidor en Python. Pensé en pasar la lógica a otro lenguaje de programación que conociera mejor, pero decidí no hacerlo ya que esto sería mi oportunidad de aprender nuevas habilidades y considero que tener la lógica en Python ayudaría a tener mejor legibilidad y ayudará a darle un mejor mantenimiento al código.

# data[].attributes.body
Decidimos hacer un grupo de WhatsApp con Eduardo Bastida y Carlos Peña (mis líderes de proyecto) para que yo pueda ir enviando actualizaciones de mis avances, hacer dudas rápidas y poder agendar siguientes sesiones. En este grupo se empezó a discutir la posibilidad de tener el servicio en un servidor. No tengo experiencia con servidores propios, pero sí con servicios de alojamiento, quedamos en esperar y durante la fase de prueba alojar el servicio en un servidor gratuito.

# data[].attributes.body
Me puse a trabajar en un diseño básico de la interfaz del jugador individual en HTML, junto con la lógica de conexión múltiple. Esta conexión serviría utilizando un "host" que crearía la partida y generaría un link para que los minoristas puedan entrar. 4 minoristas llenarán la partida y el host decidirá cuando iniciar el juego.

# data[].attributes.body
Empecé a aprender cómo funcionaría el servidor en Python con la lógica del juego para manejar distintas conexiones. Realicé un proyecto prototipo con una lógica muy básica para poder tener una base en qué apoyarme. El plan fue utilizar inteligencia artificial para asistirme en el desarrollo de la solución, pero yo sé que no es tan fácil como pasarle el código base y decirle que lo haga en línea. Tengo que documentar mejor el código base, crear plantillas de las interfaces de cada pantalla y generar una lógica básica del servidor para después generar un prompt estricto y que una inteligencia artificial solo se encargue de adaptar la lógica del juego a un modelo establecido.

# data[].attributes.body
El domingo, después de mucho tiempo batallando con ChatGPT para que pudiera entender bien la arquitectura del juego que quería manejar, le pude pasar el código fuente de manera local y pudo integrarlo al servidor en línea y a los templates de pantallas que había diseñado la semana pasada. Primero lo corrí de manera local. y cuando vi decidí esperar a tener otra junta para ver si había que hacer algún cambio significativo al MVP del juego. La semana anterior había agendado una junta para el martes de esta semana 4, entonces esperé a la junta para hacer una serie de preguntas. Estas fueron mis notas para la junta:

Tengo que incluir que no hubo consenso o incluir cuando sí hubo consenso?

Que las gráficas y los detalles se puedan esconder.

Que cada jugador esté identificado hasta arriba de la pantalla?

Me falta poner unidades y arreglar selecciones como que se comparta transporte.

# data[].attributes.body
En la tercera junta le pude enseñar el MVP del juego a Eduardo. En ese momento todavía no estaba alojado para todo el público, pero le comenté que quería que mi avance de esa semana fuera tenerlo en un servicio de alojamiento público para que tanto él como Carlos lo pudieran probar e irme dando retroalimentación conforme vaya haciendo cambios. El servicio que utilicé se actualiza automáticamente cada vez que guardo cambios en mi proyecto, por lo que siempre tendrá la misma liga. Los cambios para la siguiente semana fueron traducir la pantalla de jugador a inglés, ver si el host podía cambiar los valores de la simulación y agregar un indicador cuando se llegue a un consenso. También se platicó sobre la posibilidad de conseguir un nombre de dominio para la página y ver si el Tec nos podía proporcionar alguna forma de alojar el servicio en sus servidores.

# data[].attributes.body
Durante el fin de semana tenía pensado agregar los cambios que se discutieron en la junta de la semana 3. Estos fueron: traducir el portal del jugador a inglés, avisar cuando se haya logrado un consenso en el juego, que las secciones de gráficas y detalles fueran elementos colapsables y que el host de una partida pudiera cambiar los valores predeterminados de las variables constantes de la partida. Esto último resulto ser bastante más complicado de lo que esperaba y no lo pude tener listo durante la semana. Mandé un mensaje al grupo pidiendo que tuviéramos la junta hasta que hubiera terminado esta última feature para que no se acumularan los pendientes y pudiera recibir retroalimentación completa de lo que acababa de desarrollar.

# data[].attributes.headline
Modificación de Constantes por parte del Host

# data[].attributes.subject
Modificación de Constantes por parte del Host

# data[].attributes.body
Hasta el jueves en la tarde pude tener terminada la feature de que el host pudiera modificar las cantidades constantes. Las cantidades que eran parte de un diccionario de transportes no están traducidas ya que el nombre se usa en otras partes del código. Voy a seguir trabajando en tener esta parte traducida para que ya todo el código pueda funcionar con variables en inglés.

# data[].attributes.body
Esta semana probé el juego con unos amigos para recibir feedback y uno de los comentarios que más resaltó fue el hecho de que falta algo de "aleatoriedad" o eventos que hagan del juego algo más dinámico. También falta mejorar el diseño y la forma de presentar los resultados de la semana para que los jugadores sepan si les está yendo bien o mal.

En base a esto desarrollé lo que el doctor Eduardo llama Magic Card, un evento de "Hazard" en donde hay una cierta probabilidad de que el proveedor no vaya a surtir unidades en una semana y los jugadores se vean afectados en su inventario y la única forma de recibir unidades sería vender entre ellos.

# data[].attributes.body
El doctor Eduardo me dio una gran cantidad de retroalimentación que me ayudó mucho a planear los futuros avances que podía realizar con el proyecto. Hubo cambios fáciles como cambiar los mensajes para que sean un poco más amigables y entretenidos, pero también me pedía disminuir el riesgo de desconexión.

Este último ha sido algo que me había preocupado implementar desde el inicio del juego porque no tengo mucha experiencia con juegos multijugador y considero que esto es un requerimiento un poco avanzado. Aún así me comentó que se iba a probar el juego con varios estudiantes de preparatoria y en el campus habían tenido problemas constantes de desconexión. Esto sucede porque el servidor está alojado en un servicio gratuito y no es muy estable. No es posible arreglar la desconexión, pero se puede crear un token o cookie que mantenga la sesión de un jugador cuando se desconecta.

# data[].attributes.body
Esta semana estuve investigando como se podía hacer para que un jugador mantenga la sesión aún y cuando se refresca la página o se desconecta del servidor. Hay un proceso que se conoce como "tokenization" para que el navegador mantenga un código único del jugador. Cuando un jugador accede a una partida, antes de revisar si está llena o ya empezó, revisa si el jugador debe de estar dentro de la partida. Si sí, el servicio este al jugador dentro de la partida de la que se salió.

Pude hacer que la mayoría de los componentes del juego mantuvieran su información cuando el usuario se vuelve a conectar, pero el resumen semanal no se pudo mantener. La información persiste y se recupera una vez que el jugador juega la primera semana después de su reconexión. Esto ayudó a que la prueba con los estudiantes de preparatoria saliera bien y se pudiera recibir retroalimentación valiosa del juego.

# data[].attributes.body
Se había platicado en la junta de la semana pasada que debería haber una forma de guardar los datos del juego para poder analizar los efectos del juego. Para esto, intenté ir por una solución general y simple en donde los datos se guardan en un google sheets. Esto resultó ser mucho más complicado de lo que esperaba, entonces, aunque me tomara más tiempo, diseñé la arquitectura de los datos de una base de datos relacional en SQL y desplegué una instancia de un servidor gratuito para poder subir los datos de una partida cada vez que esta termina.

# data[].attributes.body
Para evitar que se acceda a la base de datos directamente desde otros dispositivos que no sean la app, quise empezar una visualización de los datos en una aplicación de dashboards. Escogí Looker Studio porque Power BI hubiera sido difícil de utilizar con Mac. Hice 3 vistas generales de tabla como si se tratara de un Excel para que se pueda ver la información de las 3 tablas que se usan en el modelo. Les pasé el link a mis líderes de proyecto para que pudieran tener acceso a los datos cuando se realicen más partidas.

# data[].attributes.body
Antes de esta semana, cuando terminaba un juego solo se mostraba la información en formato JSON de la historia de la partida. Tenía pendiente mostrar información más valiosa al final de una partida en forma gráfica y realicé unas gráficas que toman la historia de la partida y despliegan las estadísticas de veces que se compartió transporte, que se realizó un reparto equitativo del inventario del proveedor, las emisiones totales por ronda y los costos totales por ronda.

# data[].attributes.body
Cuando desarrollo soluciones, me gusta que el diseño visual se mantenga lo más básico posible durante el desarrollo para no sentir que tengo que realizar mucho trabajo cuando tengo que deshacerme de algo o cambiar una funcionalidad drásticamente. También porque el diseño de interfaz de usuario es de las cosas que más me cuestan. Después de 10 semanas pensé en que ya podría ser buen momento para que la pantalla del jugador se empezara a ver un poco más como un juego. Agregué iconos a los medios de transporte, botones de ayuda que explican un poco más algunas opciones del juego y en general una interfaz con mejores componentes y colores.

A partir de esto queda pendiente generar nuevos iconos que se parezcan más a los medios de transporte descritos en el juego y también tuve que arreglar el botón que procesa la seaman para los jugadores porque no agregué una vista deshabilitada, esto hacía que pareciera que no estaba funcionando el botón.

# data[].attributes.body
Esta última semana fue un poco difícil porque implementar porque el día que realicé los cambios justo se estaban realizando pruebas con otros alumnos y surgieron varios errores de mi implementación. Reflexionando sobre el jueves de esta semana pienso que estuvo bien haber tenido toda esa retroalimentación de golpe para poder mantener la concentración y estar más al pendiente del código.

Arreglé problemas con la conexión a la base de datos y las gráficas finales y agregue la opción de que los usuarios que vendan unidades puedan establecer un precio de venta y los usuarios que las compran puedan establecer el precio máximo al que están comprando unidades.

También se agregó una nueva Magic Card para que los usuarios estén más motivados a compartir su transporte ya que existe la posibilidad de que se pierda un porcentaje establecido de su orden durante el transporte.

# data[].attributes.body
Esta semana me dediqué a probar la integración de una Inteligencia Artificial local corriendo en mi computadora con el juego. Utilicé LM Studio y la función que había credo la semana pasada para poder generar retroalimentación para cada uno de los jugadores dentro de la partida. Ahora procesar cada semana tarda un poco más pero va a ser muy valioso que los jugadores tengan esta retroalimentación valiosa de su progreso semana con semana y de manera personalizada. Se tiene que investigar la forma de tener este juego corriendo en una red local a la que se pueda acceder a un servidor con una inteligencia artificial local o la manera de llamar a una IA remota gratuita o de paga.

# data[].attributes.body
Esta semana me puse a investigar de formas de llamar a la inteligencia artificial. Tenía dos partes que elegir. La primera fue elegir si iba a probar el juego con una inteligencia artificial local o remota. La inteligencia artificial local necesitaría que el juego corriera en un servidor del Tec, pero es completamente gratuita. Decidí la opción local y probé una computadora que me envió el doctor Eduardo para ver si tenía un buen rendimiento con inteligencia artificial y si lo tenía. La probé con el open ai oss 20b, un modelo bastante robusto. También, empecé a diseñar la función en el código para llamar al modelo y que regrese los resultados esperados. Incluyo captura del prompt que se diseñó.

# data[].attributes.headline
Mejora de configuración y corrección de errores

# data[].attributes.subject
Mejora de configuración y corrección de errores

# data[].attributes.body
A lo largo de las siguientes semanas estuve trabajando en corregir errores con la lógica existente y en mejorar el aspecto visual del juego. Me apoyé de la inteligencia artificial para pensar en un diseño mucho más gamificado y mi primera prueba fue con el módulo de configuración del host.

# data[].attributes.body
Otro avance significativo en el juego fue poder agregar que la cantidad de jugadores fuera variable. Esto fue un poco complicado porque todo el desarrollo lo hice pensando en que siempre serían 4jugadores, pero me dio gusto poder superar este reto ya que pude hacer pruebas con menos jugadores y otras partes del código demostraron estar diseñadas de manera modular, esto me dio mucha satisfacción ya que el código siempre debe de estar preparado para ser escalable.

# data[].attributes.body
Dentro de este avance se agregó la métrica para poder medir la distribución del mercado según las órdenes. No se menciona el número concreto para evitar mostrar la mayor cantidad de información sobre otros jugadores posible y se acerque el juego a la realidad. Dentro de este avance también se agregó el dinero al juego para poder tener una mejor métrica del avance del jugador en la partida y que se pueda tener un mejor control de gastos. Finalmente, se corrigieron errores sobre los events "hazards" no sucediendo en las semanas en las que debían de suceder y también se arregló que se estaba cobrando transporte cuando el usuario pedía 0 unidades.

# data[].attributes.body
Ahora el transporte no afecta en el costo sino solamente en las emisiones para que se pueda obtener un mayor impacto del lado ambiental por parte de los jugadores. Se agregaron los elementos visuales del presupuesto junto con los cambios a este mismo por cada ronda/semana. También se agregó la métrica del beneficio por colaborar en trasporte. Cuando un usuario decide compartir transporte se muestran los beneficios en emisiones de esta interacción.

# data[].attributes.body
Se agregó una métrica dinámica para que el jugador pueda saber qué esperar en costos de transporte para cada uno de los vehículos que tiene disponibles y dependiendo de las unidades que está ordenando. Esto va a variar según los costos de transporte establecidos por el host de la partida antes de empezarla.