El punto de partida fue un incremental centrado en una única pelea: un boss con muchísima vida al que derrotar mandando héroes desechables uno detrás de otro. El loop se definió antes de escribir ninguna línea de código:
Al conocerse el tema de la jam, Count Down, el encaje fue directo: el temporizador de 10 segundos de cada héroe es la cuenta atrás central del juego.
The starting point was an incremental game built around a single fight: a boss with a huge amount of health, defeated by sending disposable heroes one after another. The loop was defined before writing a single line of code:
Once the jam theme was announced, Count Down, the fit was immediate: each hero's 10-second timer is the game's central countdown.
Con el combate automático, todo el peso jugable recae en la tienda entre rondas. Se definieron mejoras con funciones distintas para que no fueran todas "+daño": daño básico, daño mayor, tiempo de combate extra y un multiplicador de monedas.
El coste de cada mejora escala de forma exponencial, y la duración total de la partida (15-30 minutos) se ajustó jugando directamente en vez de calculando, la herramienta de balance más rápida con el tiempo disponible.
With combat fully automatic, all the gameplay weight falls on the shop between runs. Upgrades were designed with distinct roles so they weren't all just "+damage": base damage, heavy damage, extra combat time, and a coin multiplier.
Each upgrade's cost scales exponentially, and the target run length (15-30 minutes) was tuned by playtesting directly rather than calculating it, the fastest balancing tool available given the time constraints.
La arquitectura se resolvió con una máquina de estados simple gestionada desde un único GameManager, con paneles de UI activándose y desactivándose según el estado en vez de usar varias escenas.
Durante el desarrollo aparecieron varios problemas que se resolvieron sobre la marcha:
private float bossHealthAtRunStart;
void StartCombat()
{
// se guarda la vida al inicio de la ronda, no se sigue restando sobre el valor grande
bossHealthAtRunStart = bossCurrentHealth;
damageDealtThisRun = 0f;
// ...
}
void DealHit()
{
damageDealtThisRun += heroDamage;
// Antes: bossCurrentHealth -= dmgTick; → acumulaba error de redondeo en cada resta sobre un valor muy alto
// Después: una única resta desde el valor guardado al inicio de la ronda
bossCurrentHealth = bossHealthAtRunStart - damageDealtThisRun;
UpdateHealthUI();
}
The architecture was built around a simple state machine managed from a single GameManager, with UI panels toggling on and off depending on the state instead of using multiple scenes.
A few problems came up during development and were solved on the fly:
Con los recursos visuales limitados a un único sprite de personaje, la limitación se convirtió en parte del diseño narrativo: todos los héroes pertenecen a la misma familia, generándose con un nombre y un grado de parentesco al azar, con un chiste ocasional sobre lo idénticas que son todas entre sí.
With visual resources limited to a single character sprite, the constraint became part of the narrative design: every hero belongs to the same family, generated with a random name and degree of kinship, with an occasional joke about how identical they all look.
El tramo final se completó con poco tiempo de margen. La prioridad fue confirmar que el proyecto compilaba, generar el build y subirlo a itch.io antes que perseguir cualquier pulido adicional. El resultado incluye el loop completo jugable, sistema de mejoras, nombres generados y pantalla de victoria, sin efectos de sonido ni juice visual, que quedaron fuera por el plazo.
The final stretch was completed with very little time to spare. The priority was confirming the project compiled, producing the build, and uploading it to itch.io rather than chasing extra polish. The result includes the full playable loop, upgrade system, generated names, and a victory screen, without sound effects or visual juice, which didn't make it in time.