Qué es un sistema de control de versiones (y cómo podemos usarlo con Game Maker Studio)
Hoy vamos a hablar de una de las opciones más interesantes que nos ofrece Game Maker Studio. Si miramos en la ayuda veremos que lo comenta muy por encima, y que una vez la conoces piensas:
¿Cómo podía vivir antes sin esto?
Además de utilizar como excusa un meme, quizás estoy exagerando un poquito, claro… La verdad es que yo nunca lo he utilizado porque no sabía ni lo que era, pero he hecho un breve curso (para otros proyectos) y veo el potencial a la hora de trabajar con un proyecto de Game Maker: estoy hablando del control de versiones.
Vamos a ver en profundidad que es todo esto. Aviso que lo que viene ahora es un poco de teoría (¡preparados que viene el tocho!), sobre que es un sistema de control de versiones, cual usaremos nosotros y como se configura con Game Maker Studio. ¡Al ataque!
- 1 ¿Qué es un sistema de control de versiones?
- 2 Qué es Git y como funciona
- 3 Ramas en Git
- 4 GitHub o BitBucket: Git en un servidor
- 5 Configurar Game Maker Studio con control de versiones
- 6 Opciones adicionales en un proyecto de Game Maker con Git
- 7 Resolviendo conflictos de Git con un proyecto de Game Maker Studio
- 8 Resumen final
¿Qué es un sistema de control de versiones?
Un sistema de control de versiones sirve para gestionar todos los cambios que le hacemos a un proyecto. Podemos decir que el sistema/nosotros va haciendo fotos de la situación del proyecto en cada momento, así que si por algún motivo queremos volver a ese estado anterior, podemos hacerlo sin ningún problema. Imagina que eliminas un recurso, o cambias el código de algún evento, y ves que te has equivocado… sólo tienes que volver a la situaciónq ue quieres. Es como la típica opción de menú de Deshacer – Rehacer, ¡pero a nivel de todo el proyecto de Game Maker!
Los sistemas de control de versiones son muy populares en cualquier lenguaje de programación, y los IDEs famosos, como puede ser Visual Studio, ya lo tienen incorporados a la hora de programar, aunque suele utilizarse sobre todo para proyectos web (para controlar los ficheros HTML, CSS, JS, etc.).
Existen herramientas o programas que nos ayuda con este sistema de control de versiones, Game Maker soporta Git, Mercurial y SVN (todos ellos son SCMs). En Game Maker Studio 2 sólo se puede usar Git, y no está disponible en la versión trial, así que veremos como configurar Game Maker con Git. Pero antes haremos un pequeño repaso de lo que es Git y como funciona.
Qué es Git y como funciona
Git es un programa de control de versiones, creado por Linus Torvalds, famoso por ser el creador de Linux. Git ahora es bastante famoso gracias a su facilidad de uso, y sobretodo porque permite la posibilidad de que un proyecto (o repositorio) sea gestionado remotamente por varios usuarios. Imagina que estás haciendo un juego en Game Maker, que haya varios programadores, diseñadores, etc. ya sea en una oficina o en diferentes lugares del mundo, todos tocando el mismo proyecto: podría ser un verdadero caos.
Con un SCM (sistema de control de versiones), te aseguras que puedes controlar todos los cambios que se hace sin que se pierda nada. No voy a explicar en detalle como funciona Git, si te interesa, y te debería de interesar, puedes hacer algún curso (yo hice uno en Udemy sobre GitHub que está muy bien) o simplemente puedes leer en esta página como funciona Git (en español). Yo sólo voy a dar cuatro pinceladas para poder entender como funciona.
Git trabaja de forma local
Aunque aún no hemos entrado a hablar de poner el proyecto o repositorio en un servidor, debemos de saber que Git siempre trabaja de manera local. Por ejemplo, si estamos participando en un proyecto con otro programador, todos los cambios que hagamos se harán en nuestro ordenador, y al otro programador le pasará lo mismo. Luego habrá que sincronizar los cambios hechos para que no haya conflictos, sobretodo si dos personas están tocando la misma parte del código (para eso sería importante tener claras las tareas de cada uno).
La ventaja de trabajar así es que no necesitas estar conectado para poder trabajar, además de poder ver todos los cambios hechos a un objeto (por ejemplo) sin necesidad de conectarte a ningún sitio.
Los estados de un archivo en Git
Si comparamos las dos líneas siguientes
if (obj_player.x > 0) if (obj_player.x > 0 and obj_player.y > 0)
vemos claramente que hemos modificado la línea, porque hemos añadido una condición más. Git detecta que esa línea se ha modificado, pero lo que hará es eliminar la línea y añadir la segunda como una línea nueva. Puede parecer un poco confuso, pero de esta manera es como puedes ver los diferentes cambios que hay en nuestro código.
Un fichero en Git puede estar confirmado (o committed) que significa que los cambios se han guardado, modificado (o modified) que significa que hemos modificado el fichero (como el ejemplo anterior), pero si aún no hemos confirmado los cambios estará preparado (staged), que significa que hemos marcado el fichero para que en la siguiente confirmación se guarde. Tenemos que tener claro estos tres estados para saber en que momento nos encontramos en el fichero y que no haya sorpresas (¿lo he guardado o no?).
Qué es y como funciona un repositorio en Git
Un repositorio no deja de ser nuestro proyecto de Game Maker. No hay mucho más que decir, pero aquí ya podríamos introducir la manera de trabajar de Git. Hemos dicho que Git trabaja de forma local, pero porque siempre se clonan los repositorios. Pensemos que nuestro proyecto está en un servidor y queremos hacer un cambio: lo que haríamos es clonar/descargar el proyecto (si no lo hemos hecho ya), hacer el cambio, confirmarlo y luego sincronizarlo con el servidor. De esta manera, si perdemos los datos en nuestro ordenador, o incluso en nuestro servidor, siempre podemos recuperarlo prácticamente igual. De la misma manera, si hemos hecho un cambio que al final destroza algo, podemos recuperar hasta una versión más estable. Y todo esto sin pensar en hacer copias de seguridad… porque ya lo estamos haciendo.
Así que más o menos estos serían los pasos:
- Clonamos un proyecto que tenemos en un servidor (luego veremos las opciones que tenemos):
- Trabajamos con nuestro proyecto clonado.
- Modificar código.
- Añadir recursos.
- Eliminar recursos.
- Vamos confirmando los cambios. todo esto en nuestro proyecto clonado.
- Subimos los cambios al servidor.
También podíamos modificar directamente el proyecto del servidor, el repositorio remoto, pero no es lo recomendable (y menos con Game Maker, ya que la estructura de ficheros y el contenido no la conocemos y no es tán fácil como modificar un archivo HTML). Ahora veremos como funcionan las ramificaciones, otra de las características potentes de Git.
Ramas en Git
Recuerda que cuando confirmamos un proyecto, lo que hacemos es una foto del estado actual. Podemos decir que cada foto o confirmación es un número de versión, aunque hablar de versiones no es del todo correcto. Ahora imagina que quieres añadir una funcionalidad nueva, un ejemplo sencillo en Game Maker sería crear una nueva room para añadir un nivel. En este caso no estamos modificando ningún objeto o sprite, simplemente queremos probar y diseñar un nuevo nivel. Eso lo podemos hacer como hasta ahora, o podemos hacer en paralelo. Trabajar en paralelo es el equivalente a crear una nueva rama en nuestro proyecto. Nuestro proyecto principal está en la rama master, y todos los cambios confirmados se encuentran en esa rama.
Creamos una nueva rama, añadimos la room nueva y creamos el nuevo nivel. Podemos ir confirmando todos estos cambios sin que afecten al proyecto principal. Si luego decidimos descartar ese nivel, simplemente olvidamos la rama (o la borramos). Si nos gustan, fusionamos la rama con la principal.
Fijate que en la rama podemos confirmar varias veces, y al fusionar quedarán todos los cambios como un commit en master. ¿Alguien ha cambiado algo en los objetos? No pasa nada, en el proceso de fusión o merge de las ramas, Git comprobará si hay algún tipo de conflicto con los ficheros, si los hay habrá que hacer algunas modificaciones a mano, poco más.
Obviamente, podemos crear una rama de una rama de una rama, o varias ramas en paralelo…
pero tampoco tendríamos que complicarnos mucho. Al final, tendríamos que acabar siempre en la rama master.
GitHub o BitBucket: Git en un servidor
Hemos visto como funciona Git (independientemente de si usamos Game Maker o si estamos haciendo una página web). Hemos hablado del repositorio remoto, o tener nuestro proyecto en un servidor. No es necesario tener que crear un servidor que funcione con Git, o no ser que quieras tener uno propio en una red local. Existen dos opciones en itnernet bastante populares: GitHub y Bitbucket. Tanto GitHub como BitBucket son plataformas para alojar proyectos con Git. Su fuerte, sobretodo de GitHub por su popularidad, es su vertiente colaborativa: un proyecto alojado puede clonarlo cualquiera, adaptarlo (o corregir fallos), incluso reportar esos cambios y el propietario del proyecto decidir si incorporarlos o no. Hay proyectos muy famosos que funcionan de esta manera: Bootstrap de la gente de Twitter, Visual Studio Code de Microsoft, o Brackets de Adobe.
¿Cuál es la diferencia entre GitHub y BitBucket?
La diferencia principal entre GitHub y BitBucket, aparte de la apariencia web, es la posibilidad de alojar proyectos privados. En Github pesa mucho todo el tema del desarrollo colaborativo, así que todos los proyectos alojados son públicos, a no ser que pagues una pequeña cuota mensual. En cambio en BitBucket, con tu cuenta gratuita puedes decidir que proyectos son públicos y privados. Así que yo me decanto por BitBucket, dónde pondré como proyectos públicos todos los ejemplos de la web (poco a poco) y en privado todos los juegos que haré. De esta manera también lo usaré como copia de seguridad, además, como he dicho antes, de poder probar funcionalidades nuevas sin miedo de perder parte del código.
Configurar Game Maker Studio con control de versiones
Antes de empezar con un proyecto con control de versiones, debemos de configurar Game Maker Studio para que funcione con Git. Primero de todo, solo puedes hacerlo a partir de la versión Profesional, con la gratuita no puedes. Por defecto, GMS 1.4 está configurado con SVN, un control de versiones que para nuestro proyecto en local, en nuestro disco duro, puede ser suficiente, pero olvídate de hacer una copia en la web. También acepta Mercurial, que con BitBucket funcionaría, pero vamos a ver si podemos hacerlo con Git.
Puedes descargar Git desde su página oficial, pero yo me he descargado SourceTree, un programa que facilita la interacción entre Git y BitBucket (sino tocaría hacerlo todo por la línea de comandos), y viene con una versión de Git. Una vez instalado, nos vamos a Game Maker Studio, en el menú File – Preferences, y vamos a la pestaña Source Control.
En el combo elegimos Custom, en Executable Location buscamos el fichero git.exe (fíjate que está dentro de la carpeta de instalación de SourceTree) y en SCM Config File, le damos al botón de buscar el fichero (el que tiene los tres puntos), y elegimos el fichero git.scmconfig.xml, que ya nos lo trae Game Maker configurado.
Ahora que ya lo tenemos configurado para Git, repasaremos antes de nada las opciones que veremos a la hora de trabajar con un proyecto.
Opciones adicionales en un proyecto de Game Maker con Git
En el árbol de recursos, aparecen unos iconos nuevos al lado de cada sprite, objeto, room, etc. Vamos a explicar cada icono:
- Añadido: significa que se ha creado un nuevo recurso de cualquier tipo y hay que añadirlo al repositorio. Se añadirá en el momento que guardemos el proyecto (o compilemos).
- No versionado: si vemos este icono, el recurso no es reconocido por Git (o el SCM que usemos). Luego veremos el menú especial de Source Control para saber que hacer.
- Modificado: si cambiamos un recurso, aparecerá este icono para saber que es diferente el recurso del que tenemos en el repositorio Git.
- Actualizado: nos indica que el icono está en la misma versión que la del repositorio.
- Conflicto: significa que tenemos un conflicto, lo más habitual es que alguien más ha tocado el mismo recurso que tú, y Git no puede resolver los cambios automáticamente. Desde Git habrá que fusionar el recurso o editar manualmente el archivo .GMX correspondiente.
Algunas opciones pueden dar un poco de miedo, pero tampoco hay de que preocuparse. Lo habitual de un conflicto sería cambiar el origen de un sprite: en el repositorio está de una manera, el compañero lo ha cambiado, y entre el commit que tú has recuperado y el que se ha hecho es diferente del tuyo: sólo toca decidir cuál poner. También puede ocurrir con una parte del código, entonces hay que ver los cambios introducidos y fusionarlos.
Aparte de los iconos de cada recurso que nos indica en cada momento en qué va afectando, al hacer click derecho sobre cualquiera del árbol de recursos nos aparecerá un menú contextual con algunas opciones más de las habituales (las habituales son añadir un recurso, carpeta, eliminarlo, renombrarlo, etc.). Estas opciones son:
- Add to Source Control – Añadir al control de código: esta opción añadirá un recurso al repositorio. Cuando tenemos una opción No versionada, tal y como hemos comentado, podemos añadirlo con esta opción.
- Commit to Source Control – Confirmar al control de código: el recurso seleccionado se confirmará al repositorio de Git. Si dentro del árbol de recursos tenemos una carpeta, esta opción le afectará a todos los recursos de la carpeta. Cada commit pide un comentario para explicar los cambios aportados, y así podemos verlo en cada grabación.
- Update from Source Control – Actualización desde el SCM: el recurso seleccionado se actualizará al proyecto. Recordemos que en la carpeta .git está el repositiorio.
- Source Control: este menú abre un submenú con más opciones:
- Edit Conflicts / Editar conflictos: si tenemos conflictos, esta opción de menú abre Git para solucionarlos.
- Show Log / Mostrar registro: podemos ver un log del repositorio conforme hemos ido vamos grabando/confirmando nuestro proyecto.
- Show Status / Mostrar estado: aparece una ventana del estado de cada recurso. Las letras que aparecen son:
- A: añadido.
- M: modificado.
- D: eliminado.
- R: renombrado.
- C: copiado.
- U: actualizado pero sin fusionar.
- ”: sin modificar.
Cada una de las letras es propia de Git, y nos muestra que hará a la hora de confirmar al repositorio.
- Commit All / Confirmar todo: confirma todo el repositorio.
- Refresh / Refrescar: actualiza los iconos del recurso comparado con el repositorio.
- Refresh All / Refrescar todo: actualiza todos los iconos del árbol de recursos.
- Revert / Revertir: si te arrepientes de algún cambio que has hecho, puedes recuperar a la última versión del recurso o carpeta que has confirmado en el repositorio.
- Revert All / Revertir todo: con esto reviertes todos los cambios del último commit.
- Update All / Actualizar todo: actualiza todos los recursos desde el repositorio a tu copia local del proyecto. Muy útil si alguien ha añadido recursos nuevos.
- Add All / Añadir todo: añade todo los recursos que no se han añadido al repositorio.
- Clean / Limpiar: analiza el estado de repositorio, mostrando como tenemos cada recurso.
Estas son las opciones que aparecen en la ayuda, es decir, serían comunes a todos los SCMs que soporta Game Maker: SVN, Mercurial y Git. Pero al haber cogido el fichero de configuración git.scmconfig.xml, nos aparece tres funciones extras: Blame, Push y Pull. Con Blame nos dice quién ha hecho los últimos cambios del repositorio de un fichero y Push y Pull son opciones si tenemos un repositorio en remoto. Si le damos al botón Edit SCM Config que hemos comentado antes, vemos que podemos añadir todas las funciones que queramos (de las tres pestañas, la última llamada Functions), en el apartado Aditional Functions.
En el momento que queramos crear una rama o subir nuestro proyecto a un repositorio remoto, debemos crear más funciones adicionales que nos interesa.
Resolviendo conflictos de Git con un proyecto de Game Maker Studio
Si tenemos algún conflicto en alguno de nuestros recursos que queremos agregar al repositorio, recordemos que tendrá este icono , podemos mirar en la opción de menú del botón derecho Edit Conflicts. Nos aparecerá una ventana y nos informará cuál es el conflicto. En la ventana tenemos algunos botones para decidir que hacer.
- Edit Conflict – Editar conflicto: podemos editar el conflicto, usando el programa que hemos configurado (por defecto git).
- Resolved – Resuelto: marcamos el conflicto como resuelto.
- Use Theirs – Usar otros: actualizamos el recurso del conflicto para usar la versión correspondiente.
- Use Mine – Usar el mío: actualiza el fichero para usar la versión que queremos grabar.
- Refresh – Actualizar: actualiza el estado de la versión, si hemos arreglado el conflicto manualmente.
Una vez hemos acabado, cerramos la ventana con el botón Close y volvemos a darle a commit para ver si funciona.
Resumen final
Hemos visto, ¡y espero que también se haya entendido!, que es un sistema de control de versiones y como funciona. Hemos decidido usar Git, principalmente porque es por el que han apostado en Game Maker Studio 2, y nos da la oportunidad de configurarlo en Game Maker Studio 1.4. También hemos configurado Game Maker para que podamos usar un proyecto con GIT, y hemos visto las distintas opciones que aparecen y que podemos hacer con ellas.
En el próximo post veremos un tutorial de como usar un proyecto con un SCM y Git, y ver como hacer una copia de seguridad en BitBucket. Cualquier duda podéis preguntarlo en los comentarios.