UNIR · Máster Diseño y Desarrollo de Videojuegos · 2026

Another Bad Day · Delivery Simulator

NORMAL 01 / 25 ← → navegar · F focus · S notas
TFM 2026 Universidad Internacional de La Rioja Defensa · 18 abril 2026

Another Bad
Day.

Un simulador de delivery en bicicleta sobre la rutina del rider — donde la presión del cronómetro se convierte en juego.

01 · Contexto

La gig economy
que nadie quiso jugar.

Quick commerce — Flink, Gorillas, Getir — explotó en Europa entre 2021 y 2023. Miles de riders en bici a contrarreloj, ropa naranja fluorescente, mochilas térmicas. Un fenómeno cultural masivo que el mundo gamedev ignoró por completo.

Uno de nosotros lo vivió. La rutina, la presión del minuto, la sensación de que cada pedido es una pequeña carrera. Un nicho inexplorado. Un terreno fértil.

10min
tiempo medio entrega Flink
0
simuladores de quick commerce en mercado
1
autor con experiencia real como rider

02 · Tesis

¿Y si esa rutina —el cronómetro, la lluvia, el cliente impaciente, el atajo prohibido— pudiera convertirse en algo divertido?

Esa pregunta es el corazón del proyecto. Convertir la fricción real del trabajo de rider en mecánicas de juego que respeten la experiencia, sin caricaturizarla. Lúdico pero honesto.

03 · El pitch

Casual sim. Bicicleta.
Tres días para no ser despedido.

Género

Simulador casual + rogue-lite ligero (progresión por upgrades diarios)

Motor

Godot 4.5 · GDScript · Blender · GL Compatibility renderer

Plataforma

PC (Windows / Web vía Steam / itch.io). Build web jugable hoy.

Target

16-35 años · jugadores casuales urbanos · sesiones de 15-30 min

04 · USP

Cuatro decisiones
que hacen el juego.

Bici arcade-realista

Inercia y derrape reales, pero con asistencias invisibles para casuales. Mirror's Edge × Crazy Taxi.

Rulay City

Ciudad ficticia inspirada en Berlín. Sin necesidad de conocer geografía real. 400×400 unidades.

Emociones del cliente

NPCs cambian de color en tiempo real (verde → rojo) según puntualidad. Feedback inmediato.

Tres días, una historia

Loop corto pero con stakes: 970 € en 3 días o desahucio. Cartas de upgrade entre día y día.

05 · Referencias

De dónde viene el ADN.

Crazy Taxi

Crazy Taxi

Cliente, destino, propina. Loop arcade adictivo de tres beats.

Death Stranding

Death Stranding

Carga, equilibrio, terreno. Llevar algo es una mecánica.

PowerWash Simulator

PowerWash Simulator

El placer de un trabajo bien hecho. Satisfacción del proceso.

Supermarket Simulator

Supermarket Simulator

Rutina laboral hecha juego. Tareas pequeñas, progresión visible.

Papers, Please

Papers, Please

Trabajo precario como narrativa. Presión sistémica sobre el oficio.

Lonely Mountains: Downhill

Lonely Mountains: Downhill

Bicicleta como protagonista absoluta. Estética low-poly cálida.

Firewatch

Firewatch paleta

Atardecer cálido, soledad luminosa. Dirección artística madura.

06 · El escenario

Rulay City.

Una ciudad pequeña, comprensible, con personalidad. No un open world.

Diseñamos cada calle a mano. El jugador puede memorizar el mapa en una sesión, pero descubre atajos y rutinas durante varias. Berlín ficticia, sí — pero sin pedirte que conozcas Berlín.

400×400 unidades
tamaño real del mapa 400×400

12

casas como destinos de entrega, distribuidas en 3 filas

4

intersecciones con semáforos GTA-style, luz colgante 4 caras

1

hub central QuickBite · zona de recogida

+ Lago, parque, callejones

landmarks que sirven como anclas mentales para orientarse

07 · Las 3Cs

Control. Cámara. Character.

Tres ejes que definen cómo se siente el juego momento a momento.

Sistema Decisión Valor real (código)
Velocidad a pie Caminata rápida, no realista. Sirve para maniobras finas. 5 u/s
Velocidad bici (max) Suficiente para sentirse veloz sin perder control en cruces. ~14 u/s
Sprint (boost) Recurso estratégico, no infinito. Stamina 4 s. +40 % (1.4×)
Cámara FPS 70 % de sensibilidad de ratón. Lean automático ±3.4°. altura 2.2 u
Knockdown FSM FALLING → ON_GROUND → GETTING_UP. Fricción sin frustración. ~3.4 s total

08 · Game loop

El loop que sostiene todo.

5 pasos encadenados — el núcleo del juego. El jugador nunca sale de este ciclo; solo cambia el ritmo.

Cada vuelta dura entre 40 s y 3 min. La densidad asegura que no haya tiempos muertos: si vas justo, sientes la presión; si vas sobrado, optimizas la próxima ruta.

🚲

Una vuelta
40 s – 3 min

1
📱

Aceptar pedido

phone UI · 60 s

2
📦

Recoger en hub

12 productos · max 5

3
🚲

Navegar

GPS · clima · policía

4
🤝

Entregar

€5.50 + propina

5

Feedback

rating · upgrades

09 · Sistemas complementarios

Lo que presiona al jugador.

Día/noche

12 min reales = 12 horas in-game. 1 minuto = 1 hora. 8 AM a 8 PM.

Clima dinámico

5 estados — claro, nublado, lluvia, niebla, tormenta. La lluvia reduce grip −30 %.

🚓

Policía

Saltarse semáforo o circular en acera = warning, después 15 € de multa.

🐕

IA urbana

12 peatones, 14 coches en path3D, perros y zorros como obstáculos vivos.

🚨

Warnings escalados

5 niveles: info → warning → urgent → critical → extreme. Vignette + screen shake.

🃏

Cartas fin de día

3 upgrades a elegir, 10 s de timer. Save persistente. 11 categorías de mejora.

📰

Periódico diario

Reporta eventos del día anterior. Texto generado dinámico según gameplay.

🔊

Audio espacial

8 tracks música, 27 SFX, RiderVoice con 29 categorías contextuales.

10 · Paleta

Firewatch al atardecer.

24 colores, una sola regla: todo es cálido excepto QuickBite. El verde marca es el único color saturado del juego. Donde hay verde, hay marca. Donde hay marca, hay acción.

#2D1B3D
#6B3654
#D4594A
#E8854A
#F5A862
#F8C87A
#0D0A0F
#1A1520
#2A2030
#3D2D3A
#8C5A40
#B87850
#D4956A
#E8B080
#1F1A1A
#3A3030
#5A4A40
#00D44A
#00A83A
#E83030
#F5A040
#FFD080
#F0E6D2
#B8A89A

Tip: haz hover sobre cualquier swatch para ver el HEX. Click para copiar.

11 · Visual storytelling

Atardecer permanente.
Soledad cálida.

Toda la acción transcurre durante un atardecer largo. No es decisión de tiempo, es decisión emocional: el atardecer marca el final de la jornada laboral, la prisa por llegar a casa antes de que oscurezca.

Estilo low-poly cálido. Edificios como siluetas. Iluminación dramática direccional. NPCs minimalistas con shader de color que se interpola según su humor.

«Si pudieras pintar la sensación de un turno de tarde, esto sería».

Moodboard

Firewatch · Sable · Lonely Mountains · The Witness · Concursos #100daysOfArt

Tipografía in-game

Playfair Display (titulares periódico), Rubik (UI), NotoEmoji para reacciones de clientes

Carácter principal

Diseño anónimo intencional — el rider eres tú, no un personaje fijo. Casco amarillo y mochila verde marca como únicas señales de identidad.

12 · Stack

Por qué Godot 4.5.

Open source · gratis

Sin royalties. Sin lock-in. Documentación abierta. Ideal para TFM y para futuros forks.

GDScript

Sintaxis tipo Python, tipado opcional. Iteración rápida sin compilación. Ideal para 2 personas.

Sistema de nodos

Composición sobre herencia. Encaja como guante con event-driven y autoloads.

GL Compatibility renderer

Funciona en navegador y en hardware modesto. El juego corre en Web sin Vulkan.

Blender · 3D pipeline

Modelos low-poly exportados a glTF/FBX. Materiales PBR. Iteración artística rápida.

Git · GitHub Projects

Versionado limpio entre dos personas. Issues como kanban. Release tags por milestone.

13 · El proyecto en números

Cifras reales.

Auditoría directa del código a fecha de hoy.

32 483
líneas GDScript
78
scripts
38
escenas .tscn
6
autoloads (singletons)
4
shaders custom (.gdshader)
8 + 27
tracks música + SFX
544
claves de localización ES/EN
v17
versión actual del build

14 · Arquitectura

Event-driven con seis singletons.

Toda la comunicación entre sistemas pasa por señales (Godot Signals). Sin acoplamiento directo. Cada autoload es un dominio aislado. Sustituir uno no rompe el resto.

GameData

Bus central de estado. 633 líneas. Verdad única para el resto del juego.

AudioManager

660 líneas. 5 buses, pool de 10 SFX, crossfade musical, ducking.

JuiceManager

767 líneas. Screen shake, particles, floating text. Game feel centralizado.

TimeManager

Reloj del juego. 1 min real = 1 hora juego. Emite eventos por período.

ProgressionManager

Save/load persistente. Upgrades, mejor día, total de entregas.

RiderVoice

29 categorías de voice lines contextuales. Reacción del rider en tiempo real.

15 · Innovaciones

Lo que no es de la plantilla.

🎨

Shader emociones NPCs

material shader que interpola color base de NPCs según puntualidad: verde → amarillo → naranja → rojo. Feedback emocional sin texto.

🎲

Generación procedural pedidos

Selección ponderada según distancia, tiempo restante y dificultad acumulada. Sin dos partidas iguales.

🌅

Ciclo día/noche con keyframes

Sky color, sun direction, intensidad, niebla — todo interpolado por keyframes manuales para mantener control artístico Firewatch-style.

🗣

RiderVoice contextual

29 categorías: arrancar, frenar fuerte, esquivar perro, atajo, multa, entrega perfecta. El rider piensa en voz alta.

16 · El código en pequeño

Un snippet, un patrón.

El sistema de señales que mantiene todo desacoplado:


# GameData.gd  (autoload singleton)

signal order_accepted(order: Order)
signal order_completed(order: Order, rating: int)
signal money_changed(new_total: int, delta: int)
signal day_ended(day: int, summary: DayStats)

func add_money(amount: int) -> void:
    money += amount
    money_changed.emit(money, amount)

# Hub.gd, HUD.gd, AudioManager.gd, JuiceManager.gd
# todos se suscriben a money_changed sin conocerse entre sí.
GameData.money_changed.connect(_on_money_changed)

Ningún sistema llama a otro directamente. Si añadimos un nuevo sistema (analytics, cloud save), solo se suscribe — no toca código existente.

17 · Demo en vivo

Juega ahora.

El build web está alojado en itch.io. Lanza la demo a pantalla completa — o usa el ejecutable nativo como respaldo si prefieres mejor rendimiento.

build web · v17

Another Bad Day · Demo jugable

Lanza el juego en una ventana nueva (recomendado para demo). Para correr embebido en esta slide, pulsa Embebido.

▶ Lanzar en itch.io backup: index.exe en escritorio

18 · Postmortem · ✓

Lo que salió bien.

Arquitectura event-driven

Autoloads + Signals permitieron añadir sistemas nuevos (voice lines, juice, progression) sin romper lo anterior. La apuesta técnica fue la correcta.

División de roles limpia

Martin en arte y dirección visual, Abel en código. Trabajo en paralelo, sin pisarnos. Zero merge hell en ocho meses.

Localización desde el día uno

544 claves de traducción ES/EN. Evitamos el refactor doloroso típico de añadir soporte multiidioma al final del proyecto.

19 · Postmortem · ✗

Lo que salió mal.

Reconfiguración del equipo e impacto en calendario

Empezamos siendo cuatro y acabamos dos. Reabsorber responsabilidades y recortar scope sobre la marcha tuvo un coste: el proyecto se entregó en convocatoria extraordinaria, no en ordinaria. Preferimos sostener la calidad antes que forzar la fecha con un equipo reducido.

Scope inicial demasiado ambicioso

Tricks, distritos narrativos, leaderboards… tocó cortar. Parte de ese alcance vive hoy en el slide de Hacia delante como trabajo futuro.

Sin testing automatizado

32 483 líneas de GDScript, cero tests. Los bugs de regresión mordieron en los sprints finales. Deuda técnica reconocida.

20 · Postmortem · ◇

Lecciones aprendidas.

Scope es el enemigo

Mejor un vertical slice pulido que tres sistemas a medias. Aprender a cortar fue clave para poder cerrar el proyecto.

Alineación con el tutor = pivote narrativo

Las primeras iteraciones del juego se veían mecánicamente correctas pero planas. Replanteándolo con el tutor metimos la capa narrativa (rider, voice lines, contexto del día) que cambió completamente la percepción.

Equipos pequeños exigen alineación temprana

En ocho meses no hay margen para fricción sin resolver. Las primeras semanas valen más si se usan para alinear visión que para empezar a producir ya.

21 · Cumplimiento

Cinco objetivos.
Cinco checks.

OE1 ✓ Sistema de control de bicicleta intuitivo. Caminar + bici híbrido, sprint con stamina, knockdown FSM. Asistencias invisibles para casuales, profundidad para experimentados.
OE2 ✓ Sistema de gestión de pedidos completo. Aceptar (60 s), recoger (12 productos, max 5), navegar (GPS), entregar (validación), rating + propinas.
OE3 ✓ Entorno urbano ficticio coherente. Rulay City 400×400 u, 12 casas, 4 intersecciones, hub central, landmarks navegables.
OE4 ✓ Ciclo de juego satisfactorio + progresión. Loop de 5 pasos, 3 días de campaña, cartas fin-de-día con 11 categorías de upgrade, save persistente.
OE5 ✓ Documentación según estándares académicos. GDD completo, arquitectura UML, postmortem honesto, este TFM.

22 · Hacia delante

Lo que todavía
queda por construir.

🪂

Tricks · Combos

Wheelies, manuals, bunny hops, grinds. Sistema de momentum como recompensa expresiva.

📦

Variedad de entregas

Speed run, fragile, VIP, paquete sorpresa. Cada tipo introduce su propia mecánica.

🌆

Distritos narrativos

Tres barrios con identidad propia: financiero, residencial, mercado. Clientes con personalidad por zona.

🎲

Eventos dinámicos

Construcción, accidente de tráfico, manifestación. La ciudad cambia entre días.

🏆

Leaderboards online

Mejor tiempo de entrega, mejor día, racha de 5⭐. Competencia social asíncrona.

🎨

Cosmética bici

Pinturas, pegatinas, manillares. Sin pay-to-win — solo expresión.

🔊

Doblaje cliente

Voces para los NPCs clientes (ES/EN). Pendiente de financiación post-TFM.

📱

Companion app

Móvil como segunda pantalla — recibir pedidos en el teléfono real. Idea exploratoria.

23 · Créditos · Animación 3D

Gracias al equipo de
Animación 3D.

🎬

María Laso

🎬

Walther Ceballos

🎬

Italo Sierra

24 · Gracias

Bad day,
good code.

Repositorio, build jugable y memoria. Listos para el turno de preguntas.

QR a itch.io

Build jugable

hub012.itch.io/another-bad-day

QR a GitHub

Código fuente

github.com/hub012/another-bad-day-2

QR a memoria

Memoria del TFM

PDF · 75 páginas · UNIR 2026

Abel Quiñones · Martin Zarate · UNIR 2026 · Director: Adrián Suárez Mouriño