Tinselcity

tl;dr: Lo haremos en web, con un servidor y con cada jugador en un navegador web.

Planteamientos generales

Pensando un poco en la idea de hacer Espías y Confidentes, o en general un juego de mesa cualquiera, podría llegarse a un número de soluciones bastante diferentes entre sí.

Podría, por ejemplo, plantear la idea de hacer un programa que se ejecute de forma local en un ordenador o similar, y que todos los jugadores estén frente a él y vayan jugando por turno. Hay una dificultad con una solución de este tipo: La privacidad de las jugadas. Es decir, si todos comparten la misma pantalla, ¿cómo podríamos hacer que cada jugador solo viera su propia agenda de claves? Sería fácil que intencionada o accidentalmente un jugador mirara a la pantalla cuando está jugando su turno otro jugador y viera su agenda. Más aún, ¿cómo compaginar la idea de que cada jugador ve solo sus cosas, pero además todos los jugadores ven el tablero? Es un problema que va más allá del software, más allá de la programación. Pero a la vez, como suele ocurrir, es algo que afecta directamente a la programación, porque limita lo que podemos hacer y lo que no.

Así que, pensando en esto, parecería más apropiado pensar en que el juego ocurra de forma remota. Cada jugador juega desde su propio ordenador y estos se comunican entre sí. Parece bastante claro. Pero aún así aún quedan detalles por resolver.

Por ejemplo, ¿deberíamos tener un servidor central? Podemos hacer que cada jugador instale un programa cliente y tener un servidor al que todos se conectan. O podrían conectarse los jugadores ellos solos sobre algún otro tipo de conexión descentralizada. SI lo pensamos un poco, parece mejor la idea de tener un servidor central. ¿Por qué? Al analizar el juego vimos pronto que había algunas tareas y acciones que convenía verificar. Por ejemplo la tirada de dados y la validez del movimiento. O la comprobación final de las claves. De hecho toda la gestión de claves (salvo las agendas) parece que sería bueno que estuvieran manejadas por el programa. Y aunque podríamos pensar en algún modo por el que todos los programas clientes verifiquen las acciones de todos los demás para ver que nadie hace trampas, parece mucho más fácil que esto se haga en un único sitio y que este esté fuera del control de ningún jugador.

Es más, si lo pienso un poco más, un juego de este tipo parece encajar bastante bien con la idea de hacerlo funcionar en la web. Los jugadores pueden conectarse desde cualquier navegador o dispositivo y un único servidor gestiona la partida. Además, la interfaz de usuario y la forma de funcionar parece encajar relativamente bien con una página web. No todo encaja completamente. El tablero en sí es gráfico, pero no tiene unos requerimientos gráficos muy complejos y podemos hacerlo con un <canvas> o con SVG. Ambos son más que suficientes y relativamente fáciles de usar. Y también necesitaremos actualizar el navegador de cada jugador cuando uno de ellos hace su jugada. Pero este es un problema bastante habitual hoy en día y lo podemos solucionar fácilmente con, por ejemplo, websockets.

Todas estas cosas que voy pensando podría pensarlas de otra forma, por supuesto. Podría pensar en otras opciones que podrían ser tanto o más válidas. ¿Por qué yo pienso en esta opción? ¿Cómo podrías tú saber en qué opciones pensar? No te voy a engañar: mucho depende de la experiencia. Yo sé, porque ya lo he hecho otras veces, que hacer el interfaz con HTML y JS, y usar un servidor web, es una plataforma que funciona bastante bien para un formato como este de un juego de mesa por turnos. No es necesariamente el mejor, pero funciona bien. Además de eso es sencillo, el soporte de plataforma es muy amplio y, bueno, hoy por hoy es una solución muy popular para muchos desarrollos. Como digo no es necesariamente la mejor opción. En este juego los requerimientos gráficos son bastante sencillos, pero ¿y si necesitáramos un interfaz en 3D por el motivo que fuera? Entonces quizá lo plantearía de otro modo. ¿Y si quisiera publicar esto en una consola de videojuegos, qué cosas pensaría entonces? Pues probablemente lo que más pensaría es la necesidad de tener 6 jugadores y la privacidad. Quizá me plantearía una consola portátil que se pudiera conectar en red localmente. Quizá eso encajaría bien con el tipo de juego.

Como esto es un ejercicio y tampoco quiero que se complique excesivamente, creo que la opción web es una opción bastante razonable. Además es una plataforma común y habitual. Creo que cualquier lector puede tener cierta familiaridad con ella. En cualquier caso mucho de lo que haga no va a depender tanto de que funcione en web o en otra plataforma. Como mucho la idea de que sea cliente-servidor marcará algunas cosas, pero poco más. La mayoría sería trasladable a otra plataforma similar.

También hay algunos meta-motivos para elegir la web como plataforma. Principalmente está el hecho de que es, seguramente, la plataforma más accesible para cualquier lector que quiera seguir esto.

Ahora, más allá de esto podría elegir cosas muy variadas. En la primera parte no traté el tema de seleccionar una plataforma, librería, herramienta, etc. El problema es que hay muchos factores que entran en juego. Factores técnicos, pero también sociales, económicos, y otros. En una decisión así intervienen prácticamente todos los elementos que existen alrededor del proyecto.

Por eso, esta decisión, en este caso, tiene en cuenta esos otros factores, sobre todo el hecho de ser un ejemplo con intención didáctica y de intentar llegar a todo el mundo con sencillez. Más adelante es posible/probable que haya que tomar alguna otra decisión similar. Entonces, ya veremos cómo tomar ese tipo de decisiones con más calma.

More projects, more problems

Hacer un proyecto en la web suele tener una consecuencia. No es obligatorio que ocurra así, pero antes o después termina siendo necesario considerarlo. La plataforma nos impone una frontera bastante marcada: tendremos cosas que ocurran en el servidor y tendremos otras que ocurrirán en los clientes.

Como digo esto no ocurre en absolutamente todos los casos, pero es muy frecuente y en nuestro caso sí va a ocurrir. Hay, entonces, dos aproximaciones a esta realidad:

  1. Una es la de intentar mantener la cohesión entre ambas partes lo más posible. Difuminar al máximo esa frontera para hacerla lo más transparente posible.
  2. La otra es la opuesta, claro: Aprovechar esta división respetándola cuanto más mejor y haciéndola lo más marcada posible.

Hay mucha discusión posible aquí, por supuesto, y no voy a pretender decir que yo tenga más razón que otros defendiendo una u otra opción. Lo que haré será explicar cuál es mi criterio para elegir.

Yo tiendo a decantarme por la segunda opción. Lo que intento hacer habitualmente cuando establezco una división, del tipo que sea, es obtener partes independientes y de menor complejidad. En este caso la división ni siquiera la establezco yo, me viene impuesta por la plataforma y va a existir quiera o no quiera. Lo único que puedo hacer sobre esta frontera es colocar algunas cosas a un lado o a otro.

Tomemos por ejemplo un par de elementos que encontramos en el análisis: los dados y el mecanismo de movimiento. La generación de la tirada de dados es algo que sabemos que vamos a tener que hacer. Podríamos situarla esta en el servidor o en el cliente. Si generamos la tirada de dados en cliente, básicamente estamos poniendo la integridad de la partida en manos del cliente; estamos confiando en que el jugador no manipulará el cliente para hacer trampas. Si la generamos en servidor, será un elemento que tengamos centralizado y más controlado, pero necesitaremos pasar el dato al cliente cada vez porque es ahí donde se toma la decisión de cómo mover (esta es una decisión del jugador). Las ventajas de conservar la integridad pesan más que el coste de pasar este resultado, así que optaremos por hacerla en servidor.

Para el mecanismo de movimiento (lo que comenté de tener que validar que efectivamente se puede llegar a un cierto destino con una cierta tirada), en principio, podremos hacerlo en uno o en otro lado, dependiendo de cómo lo hagamos. Este es un problema que ya veremos en más detalle cuando llegue el momento. Ahora bien, también podemos optar por hacerla en ambos lados. En algunos casos, según cómo queramos hacerlo, inevitablemente deberemos hacerla en ambos lados. Y entonces podríamos pensar en tratar de minimizar esa “repetición” a base de suavizar la frontera, de hacerla más transparente y que solo tengamos una vez la funcionalidad pero, de alguna forma que no nos importa ahora, se comparta entre ambos lados.

Como decía, yo prefiero mantener la frontera bien delimitada. El coste será ese, que en ocasiones puede que tengamos que duplicar alguna cosa o, dicho más generalmente, que en alguna ocasión aumentemos la complejidad total del conjunto. Esto es cierto. Sin embargo, el beneficio obtenido es que separamos mejor la complejidad de cada parte y eso nos permitirá manejar más fácilmente cada parte por separado. En mi opinión, este beneficio suele superar con creces el posible coste añadido.

Nótese que esto no implica necesariamente que tengamos que gestionar el código de los dos proyectos por separado. Yo prefiero hacerlo, pero podríamos perfectamente gestionar el código de ambos proyectos como una sola unidad. Me refiero a repositorios de código o la gestión de carpetas y ficheros, procesos de compilación, etc. Hay gente que prefiere, y no me parece mal, mantener la unidad en esos aspectos. No tengo una opinión demasiado fuerte sobre esta parte del problema y creo que se puede gestionar bien en cualquier caso.

Lo que sí hay que tener claro es que la presencia de esa “frontera impuesta”, sea cual sea la aproximación que elijamos, va a tener implicaciones que afectarán a las decisiones que necesitemos tomar.


Discusión

Joan, 2019/04/15 02:44

Me ha gustado mucho lo que has escrito. Con ganas de que continue.

Saludos.

Escribe el comentario. Se permite la sintaxis wiki: