Introducción al Desarrollo de Videojuegos con GameMaker · Módulo 11: Desarrollo completo de un videojuego de plataformas 2D.
Prueba integral del videojuego de principio a fin
Clase 55 de 60 · 60 min
También disponible en: EN
Introducción a la prueba integral y el aseguramiento de calidad
A lo largo de los diez módulos previos y de las clases anteriores de este Módulo 11, has construido componente por componente los pilares de un videojuego de plataformas bidimensional: el motor de movimiento con simulación de inercia y gravedad, la detección de colisiones horizontales y verticales, las máquinas de estados finitos para la animación, los enemigos patrulleros, los coleccionables, el sistema de interfaz gráfica (HUD), el gestor de audio y la transición entre múltiples niveles. Sin embargo, un ensamblaje técnico no garantiza por sí solo una experiencia sólida y libre de fallos.
La prueba integral (a menudo denominada en la industria como *End-to-End Playtesting* o pruebas de extremo a extremo) consiste en evaluar el videojuego como una unidad cohesiva e ininterrumpida. En lugar de comprobar un script o un objeto de manera aislada dentro de una sala de prueba provisional (*sandbox room*), la prueba integral recorre el camino real que experimentará el usuario final: desde el inicio de la aplicación en el menú principal, pasando por la pantalla de introducción, el desarrollo de todos los niveles secuenciales con sus riesgos y recompensas, hasta desembocar en la pantalla de victoria o en el reinicio tras el temido *Game Over*.
Es fundamental distinguir entre dos actividades que a menudo se confunden en los desarrolladores principiantes: jugar al propio juego por diversión y evaluar metódicamente el software con mentalidad de control de calidad (*Quality Assurance* o QA). Cuando juegas como creador, tu subconsciente tiende a tomar los caminos previstos, respetar los tiempos programados y evitar los bordes problemáticos de la geometría. La prueba metodológica exige exactamente lo opuesto: forzar los límites de la lógica, presionar teclas de manera inesperada, ejecutar combinaciones de acciones simultáneas y explorar cada rincón con el objetivo explícito de hacer que el juego falle para poder subsanarlo antes del lanzamiento.

El flujo completo del juego (Game Flow) y transiciones críticas
Para asegurar que el flujo de juego sea hermético, es necesario mapear de manera estricta todas las transiciones que conectan las salas (*rooms*) del proyecto. En GameMaker, la gestión inadecuada de salas suele ser la fuente principal de errores de referencia nula, duplicación de objetos gestores o fugas de memoria por estructuras de datos no liberadas.
Analicemos las fases del recorrido completo que debes verificar en tu proyecto:
| Estado / Sala de origen | Evento desencadenante | Destino esperado | Riesgos técnicos comunes |
|---|---|---|---|
| rm_menu | Presionar botón 'Iniciar Juego' | rm_level_1 | Variables globales sin inicializar; falta de reinicio de puntuación y vidas. |
| rm_level_1 | Colisión del jugador con obj_door / meta | rm_level_2 | Duplicación de instancias persistentes (como obj_game_manager); datos de salud no propagados. |
| Cualquier nivel de juego | Presionar la tecla de pausa (vk_escape) | Menú de pausa en pantalla | El tiempo sigue corriendo; animaciones o alarmas se ejecutan de fondo; solapamiento de audio. |
| Cualquier nivel de juego | Salud del jugador llega a 0 o cae al abismo | Reinicio de checkpoint o rm_gameover | El objeto jugador queda destruido y los scripts que lo buscan provocan un error fatal (Crash). |
| rm_level_2 (Nivel final) | Superación de la última meta | rm_victory | Música del nivel anterior continúa sonando sobre la música de victoria; bloqueo de botones de salida. |
| rm_victory o rm_gameover | Presionar 'Reintentar' o 'Menú' | rm_level_1 o rm_menu | Persistencia de inventario o estadísticas previas que deberían volver a cero. |
Cualquier irregularidad en esta cadena interrumpe la inmersión del jugador. Si al perder todas las vidas y pulsar 'Reintentar' el jugador reaparece en el segundo nivel en lugar de comenzar desde el inicio con su puntuación reseteada, existe una desconexión en la lógica de control del gestor global. Si al cambiar de sala la música del nivel 1 se solapa con la del nivel 2 creando una cacofonía, la función de gestión de audio está fallando al detener el flujo previo.
Diseño y aplicación de una lista de comprobación (QA Checklist)
Una sesión de prueba exhaustiva nunca debe abordarse al azar. Los equipos profesionales emplean listas de comprobación estandarizadas (*checklists*) organizadas por áreas funcionales. A continuación, desglosamos la matriz de prueba que debes aplicar de forma secuencial sobre tu prototipo completo.
1. Mecánicas del Jugador y Físicas Básicas
Comienza verificando la respuesta de los controles en un entorno estático y bajo movimiento continuo:
| Elemento de prueba | Procedimiento de comprobación | Criterio de éxito |
|---|---|---|
| Respuesta de aceleración y fricción | Caminar brevemente y soltar el control; cambiar de dirección súbitamente. | El personaje frena gradualmente según la fricción definida, sin quedarse 'congelado' ni patinar infinitamente. |
| Altura de salto variable | Pulsar la tecla de salto de forma rápida (tap) y mantenerla presionada. | El salto corto produce una elevación significativamente menor que el salto sostenido. |
| Margen de coyote (*Coyote Time*) | Correr y salir deliberadamente por el borde de una plataforma antes de presionar salto. | El salto responde dentro de la ventana de fotogramas configurada (p. ej., 6 a 8 steps) tras perder el suelo. |
| Colisión con techos y esquinas | Saltar raspando verticalmente una pared sólida o impactar techos diagonales. | La velocidad vertical (vsp) se cancela inmediatamente a 0; el sprite no se incrusta en el bloque sólido. |
| Inversión de orientación (image_xscale) | Girar a izquierda y derecha mientras se camina, salta y cae. | El sprite se invierte sobre su origen centrado sin desplazamientos anómalos de posición. |
2. Combate, Riesgos y Puntos de Control
A continuación, somete al personaje a las amenazas del nivel para certificar que el ciclo de vida y daño funcione con solidez matemática:
| Mecánica | Condición a evaluar | Resultado esperado |
|---|---|---|
| Ataque con salto sobre enemigo | Caer exactamente sobre la parte superior del objeto enemigo patrullero. | El enemigo es destruido o pasa al estado de muerte; el jugador experimenta un rebote vertical positivo (rebote elástico). |
| Impacto lateral con enemigo | Caminar hacia el enemigo e impactar por un costado. | El jugador pierde 1 punto de vida, activa fotogramas de invulnerabilidad (parpadeo visual) y retroceso (knockback). |
| Zona de muerte / Abismo | Dejarse caer por los huecos inferiores del mapa. | Al salir de la vista o colisionar con obj_killzone, se resta una vida y se posiciona en el último checkpoint activo. |
| Activación de Checkpoints | Atravesar la bandera o pedestal de control y morir posteriormente. | El jugador no reaparece en el punto de inicio de la sala, sino en las coordenadas x e y registradas por el checkpoint. |
3. Coleccionables, Interfaz y Audio
Finalmente, valida la sincronización sensorial y visual con los datos lógicos internos:
| Componente | Prueba requerida | Verificación visual y sonora |
|---|---|---|
| Monedas y gemas | Recoger coleccionables aislados y en filas consecutivas a alta velocidad. | Cada instancia ejecuta su animación o sonido de recolección y se destruye; el HUD incrementa el contador de inmediato sin desfases. |
| Dibujado en Draw GUI | Cambiar la escala de la ventana o moverse a través de mapas con cámara móvil. | Los elementos del HUD permanecen fijos en las coordenadas relativas a la pantalla, sin vibrar ni desplazarse con la cámara del juego. |
| Bucle de música (Loop) | Permanecer en el nivel durante varios minutos sin interactuar. | La pista musical reinicia de forma suave sin silencios perceptibles ni chasquidos en el punto de ciclado. |
| Efectos de sonido (SFX) | Ejecutar múltiples acciones en un segundo (saltar, aterrizar, golpear enemigo, recoger moneda). | Los sonidos se mezclan limpiamente mediante canales de audio adecuados sin recortarse mutuamente ni distorsionar la salida. |
Casos límite (Edge Cases) y pruebas de esfuerzo
Un caso límite (*edge case*) es una situación que ocurre únicamente en extremos de los parámetros de operación, a menudo cuando dos o más eventos que raramente coinciden se ejecutan exactamente en el mismo fotograma de simulación (*step*). Estos errores son los más difíciles de detectar en pruebas superficiales, pero son los que con mayor frecuencia frustran a los jugadores que adquieren o prueban una versión pública.
Veamos los tres casos límite más críticos en juegos de plataformas 2D desarrollados en GameMaker y cómo ponerlos a prueba:
💡 Regla de oro de la desactivación de instancias: Si utilizas 'instance_deactivate_all(true)' para pausar tu juego, asegúrate siempre de que el objeto que contiene el evento que escucha la pulsación de despausa sea persistente y no sea desactivado. En caso contrario, el motor jamás volverá a evaluar el evento Step del gestor, requiriendo forzar el cierre del proceso.
Implementación de herramientas de asistencia para pruebas (Debug Suite)
Probar un juego completo una y otra vez de forma lineal es sumamente ineficiente si cada vez que modificas una variable en el nivel 2 debes completar el nivel 1 de forma manual. Para acelerar las pruebas integrales, los desarrolladores profesionales incorporan atajos de teclado para depuración (*debug hotkeys*). Estas funciones permiten saltar de sala, modificar recursos al instante o visualizar datos de telemetría.
Es indispensable estructurar estos atajos de manera que dependan de una única variable macro o condicional que pueda deshabilitarse de inmediato al momento de compilar la versión definitiva, evitando que los usuarios finales accedan a ellos de manera accidental.
A continuación, se presenta la implementación recomendada para integrar un sistema de control de pruebas dentro de nuestro gestor global de juego (denominado comúnmente obj_game_manager).
// ====================================================================
// OBJETO: obj_game_manager
// EVENTO: Create
// ====================================================================
// Bandera que activa o desactiva las herramientas de depuración.
// Antes de exportar el juego comercial, debe establecerse en false.
global.debug_mode = true;
// Bandera para visualización de máscaras de colisión e información técnica
global.show_debug_overlay_custom = false;// ====================================================================
// OBJETO: obj_game_manager
// EVENTO: Step
// ====================================================================
// Evaluar únicamente si el modo de depuración está habilitado
if (global.debug_mode) {
// F1: Reiniciar la sala actual de inmediato para probar escenarios repetitivos
if (keyboard_check_pressed(vk_f1)) {
room_restart();
}
// F2: Avanzar directamente a la siguiente sala en la jerarquía del Asset Browser
if (keyboard_check_pressed(vk_f2)) {
if (room_next(room) != -1) {
room_goto_next();
} else {
// Si no hay más salas, regresar a la primera (bucle de prueba)
room_goto(rm_menu);
}
}
// F3: Restaurar salud al máximo y recuperar vidas en el objeto del jugador
if (keyboard_check_pressed(vk_f3)) {
if (instance_exists(obj_player)) {
obj_player.hp = obj_player.max_hp;
global.player_lives = 3;
}
}
// F4: Otorgar coleccionables y puntuación inmediata para probar el HUD
if (keyboard_check_pressed(vk_f4)) {
global.coins += 10;
global.game_score += 100;
}
// F5: Alternar el panel de telemetría e información interna en pantalla
if (keyboard_check_pressed(vk_f5)) {
global.show_debug_overlay_custom = !global.show_debug_overlay_custom;
}
}Además del manejo de atajos por teclado, disponer de información en tiempo real sobre el estado del motor resulta invaluable para diagnosticar caídas de rendimiento (*stuttering*), fugas de memoria o problemas en la frecuencia de actualización de fotogramas. Para ello, aprovechamos el evento Draw GUI del mismo gestor.
// ====================================================================
// OBJETO: obj_game_manager
// EVENTO: Draw GUI
// ====================================================================
// Solo dibujar el panel si las funciones de depuración están encendidas
if (global.debug_mode && global.show_debug_overlay_custom) {
// Configuración estética del panel de depuración
draw_set_color(c_black);
draw_set_alpha(0.7);
draw_rectangle(10, 10, 320, 190, false);
draw_set_alpha(1.0);
draw_set_color(c_lime);
draw_set_font(-1); // Usar la tipografía predeterminada del sistema para máxima legibilidad
// Métricas del motor y la sala actual
draw_text(20, 20, "--- TELEMETRÍA DE DEPURACIÓN ---");
draw_text(20, 40, "FPS reales: " + string(fps_real));
draw_text(20, 60, "FPS objetivo: " + string(fps));
draw_text(20, 80, "Instancias activas: " + string(instance_count));
draw_text(20, 100, "Sala actual: " + room_get_name(room));
// Telemetría específica del jugador si existe en la sala
if (instance_exists(obj_player)) {
draw_text(20, 125, "Jugador X: " + string(round(obj_player.x)) + " | Y: " + string(round(obj_player.y)));
draw_text(20, 145, "Velocidad H: " + string(obj_player.hsp) + " | V: " + string(obj_player.vsp));
draw_text(20, 165, "En el suelo (grounded): " + string(obj_player.grounded));
} else {
draw_set_color(c_red);
draw_text(20, 125, "Jugador: [NO DETECTADO EN SALA]");
}
// Restaurar el color base de dibujado para no alterar otros elementos del GUI
draw_set_color(c_white);
}Con estas herramientas activas, verificar el balance de los niveles se vuelve una tarea ágil y metódica. Puedes saltar directamente al segundo nivel con la tecla F2, probar si una plataforma es alcanzable observando los valores exactos de hsp y vsp en pantalla con F5, y restaurar la salud de inmediato con F3 tras probar un salto riesgoso contra pinchos.
Registro, documentación y corrección metódica de incidencias
Durante la prueba integral es común encontrar irregularidades sutiles: un sonido que no se detiene al cambiar de nivel, un enemigo que se desvía de su patrulla si se le ataca en un borde, o un texto que se superpone en resoluciones no estándar. Intentar corregir cada fallo de inmediato en cuanto se descubre es una mala práctica: interrumpe el ritmo del testeo general y con frecuencia conduce a arreglos precipitados (*hotfixes*) que introducen nuevos problemas en otros sectores del código.
El flujo de trabajo profesional exige registrar el fallo en un reporte de incidencias (*bug report*) estructurado. Un informe de error bien elaborado debe contener los siguientes campos mínimos:
| Campo | Descripción | Ejemplo práctico de un reporte |
|---|---|---|
| ID y Título | Identificador único y resumen descriptivo del fallo. | #BUG-014: Pérdida de control al reanudar la pausa durante un salto. |
| Severidad | Impacto: Crítico (cuelgue), Alto (bloqueo), Medio (lógica), Bajo (cosmético). | Severidad Alta (impide el avance normal del nivel). |
| Reproducibilidad | Frecuencia con la que ocurre: Siempre (100%), Frecuente (~50%), Raro (<10%). | Siempre (100% de los intentos siguiendo los pasos exactos). |
| Pasos para reproducir | Instrucciones cronológicas, precisas y detalladas para forzar el fallo. | 1. Iniciar rm_level_1. 2. Saltar con barra espaciadora. 3. En el punto culminante, pulsar Escape para pausar. 4. Pulsar Escape de nuevo para reanudar. |
| Comportamiento observado | Lo que el programa hizo erróneamente. | El personaje se queda flotando en el aire sin gravedad; el valor vsp permanece congelado en 0 y no responde al input. |
| Comportamiento esperado | Lo que el juego debería haber hecho según el diseño. | El personaje debe retomar la inercia vertical que tenía almacenada y caer normalmente hacia el suelo. |
Veamos cómo se traduce este reporte en una corrección real de código mediante un ejemplo trabajado:
Pruebas de regresión: Garantizar la solidez continua
El término *prueba de regresión* se refiere a la verificación metódica de que las modificaciones introducidas para corregir un fallo existente no hayan desconfigurado o estropeado mecánicas que ya funcionaban a la perfección. Es uno de los fenómenos más frecuentes y frustrantes en el desarrollo de videojuegos independientes: un ajuste en el código de colisión para evitar que el jugador se quede atascado en una esquina puede provocar que los enemigos ya no detecten los precipicios y se caigan de sus plataformas.
Para ejecutar una prueba de regresión efectiva en nuestro videojuego de plataformas, cada vez que apliques un cambio en un script central (como el cálculo de colisiones horizontales o la gestión de variables de salud), debes realizar obligatoriamente un barrido básico de control sobre las siguientes tres áreas:
| Área central | Puntos de verificación de regresión inmediata |
|---|---|
| Colisiones universales | Comprobar colisión del jugador contra paredes verticales sólidas; comprobar que el enemigo patrullero sigue rebotando contra los marcadores invisibles o muros; verificar que las monedas flotantes no son empujadas. |
| Gestión de estados del jugador | Verificar la transición suave entre: quieto (idle) -> correr (run) -> salto ascendente (jump) -> caída libre (fall) -> aterrizaje (land). Confirmar que ningún sprite se congele en un fotograma estático. |
| Persistencia y datos globales | Verificar que tras perder una vida y revivir, el número de monedas no se reinicie a cero prematuramente ni se duplique al cruzar la siguiente puerta de nivel. |
Ejercicios prácticos
Pon en práctica los procedimientos explicados para diagnosticar, blindar y certificar la estabilidad de tu proyecto final de plataformas 2D:
Ejercicio 1: Ejecución completa del ciclo de vida y matriz de calidad
Inicia tu proyecto desde la sala inicial 'rm_menu' y completa una partida continua de principio a fin sin usar trucos ni atajos de teclado. Realiza el siguiente itinerario exacto: pulsa 'Iniciar', supera el Nivel 1 recogiendo al menos 5 monedas, entra por la puerta de transición hacia el Nivel 2, recibe daño de un enemigo patrullero de forma intencional para verificar la pérdida de salud y el parpadeo de invulnerabilidad, alcanza la meta final y observa la transición a la pantalla de victoria 'rm_victory'. Finalmente, pulsa el botón para regresar al menú principal y comprueba que los valores de vidas, salud y puntuación comiencen totalmente reseteados al dar inicio a una nueva partida.
**Criterios de comprobación:** La partida no debe arrojar errores en la consola de salida de GameMaker, las salas deben encadenarse fluidamente sin duplicar objetos persistentes y las variables del HUD deben reiniciar sus valores iniciales al regresar al menú principal.
Ejercicio 2: Integración de la suite de atajos de depuración
Incorpora en tu objeto 'obj_game_manager' los eventos Create, Step y Draw GUI descritos en esta lección para dotar a tu proyecto de una suite de atajos de desarrollo. Añade un atajo adicional con la tecla F6 que teletransporte al jugador de forma instantánea a las coordenadas x e y del último checkpoint alcanzado, o bien a las coordenadas iniciales de la sala si no se ha activado ninguno aún. Comprueba que todo el bloque de depuración quede estrictamente condicionado por la variable 'global.debug_mode'.
**Criterios de comprobación:** Al pulsar F6 durante el juego, el personaje debe trasladarse sin colgarse a la ubicación del checkpoint. Al cambiar manualmente 'global.debug_mode = false;' en el código y recompilar, ninguna de las teclas de depuración (F1 a F6) ni el cuadro de telemetría gráfica deben responder o dibujarse en pantalla.
Ejercicio 3: Simulación, reporte y corrección de un caso límite
Diseña en una sala de pruebas un escenario donde el jugador salte contra un techo sólido mientras choca simultáneamente contra una pared vertical en una esquina cerrada. Observa si el personaje se incrusta parcialmente en la geometría sólida o si queda atascado sin poder caer. Si detectas un atasco, documéntalo siguiendo el formato de informe de fallos (ID, Severidad, Reproducibilidad, Pasos, Esperado vs. Observado) y ajusta la rutina de colisiones en el evento Step del jugador para garantizar que 'vsp = 0' y 'hsp = 0' resuelvan la posición de forma no destructiva empleando funciones de aproximación con 'sign()'.
**Criterios de comprobación:** Tras la corrección, el personaje debe rebotar o resbalar limpiamente de la esquina sin importar el ángulo de entrada, manteniéndose siempre fuera de la máscara del bloque sólido.
Resumen
- La prueba integral (End-to-End) evalúa el videojuego como una experiencia continua desde el menú principal hasta las pantallas de victoria y derrota, en lugar de testear componentes de forma aislada.
- Existe una diferencia sustancial entre jugar libremente y aplicar aseguramiento de calidad (QA): el evaluador técnico busca deliberadamente romper la lógica del sistema mediante combinaciones inhabituales de acciones.
- El uso de listas de comprobación estandarizadas garantiza una cobertura sistemática de mecánicas de control, colisiones, combate, transiciones de sala, sonido e interfaz gráfica.
- Los casos límite (edge cases), como muertes simultáneas a transiciones de sala o pausas en instantes transitorios, representan los puntos más vulnerables para la estabilidad de la aplicación.
- La implementación de una suite de herramientas de depuración (Debug Suite) con atajos protegidos por variables globales acelera drásticamente la verificación sin comprometer la versión final del videojuego.
- Cada fallo identificado debe documentarse de manera estructurada antes de ser intervenido, y cada corrección debe someterse a pruebas de regresión para garantizar que no se introduzcan nuevos errores en sistemas previamente validados.
Practica lo aprendido
Ejercicio 1 · 1 punto
¿En qué consiste la prueba integral (End-to-End Playtesting) según lo expuesto en la lección?
Ejercicio 2 · 1 punto
Al implementar un sistema de pausa con instance_deactivate_all(true), el objeto que detecta la tecla para reanudar el juego debe ser persistente y estar excluido de la desactivación para evitar congelar el proceso.
Ejercicio 3 · 1 punto
Relaciona cada caso límite o concepto técnico con la situación o riesgo que describe la lección:
- Efecto túnel (Tunneling)
- Muerte y transición simultáneas
- Pausar en estados transitorios
- Atajos de depuración (Debug hotkeys)
Ingresa para guardar tu progreso — Ingresar