¿Cómo Bajar el Peso de un Videojuego?

¿Cómo Bajar el Peso de un Videojuego?

La historia real de cómo optimizamos Quintaesencia de 1.1 GB a 350 MB sin perder calidad

El Problema: Un Videojuego Gigante

Cuando comenzamos a trabajar en Quintaesencia, nos encontramos con un desafío técnico importante: el proyecto ocupaba 1.1 GB de almacenamiento. Para un videojuego RPG español que debía ejecutarse en múltiples plataformas (Android, web, desktop), esto representaba un cuello de botella crítico.

El problema no era simplemente de espacio en disco. Los desarrolladores en nuestro equipo enfrentaban:

  • ⏳ Tiempos de compilación insostenibles: 45-60 minutos para generar una versión debug, imposible iterar rápido
  • 📦 APK no distribuible: El archivo compilado superaba los 380 MB, imposible de instalar en la mayoría de dispositivos Android
  • 🌐 Versión web intolerable: Los usuarios con conexiones 4G experimentaban lag, stuttering y descargas que podían tardar minutos
  • 📱 Incompatibilidad con dispositivos low-end: Muchos usuarios potenciales tenían teléfonos con apenas 2 GB de RAM
  • 💾 Gestión de almacenamiento en servidor: Los backups y distribución consumían ancho de banda precioso

Decidimos que necesitábamos una solución radical. El objetivo era claro: reducir el tamaño a menos de 400 MB sin sacrificar la experiencia visual ni la funcionalidad del juego.

Estrategia 1: Optimización Inteligente de Imágenes

Las imágenes eran el enemigo número uno: ocupaban 645 MB del proyecto total. En Quintaesencia tenemos miles de assets visuales: sprites de personajes, tilesets de mapas, fondos de cinemáticas, efectos visuales. Cada uno de estos assets podía ser optimizado sin perder calidad visual.

Nuestro enfoque de dos pasadas fue destructivo pero efectivo:

#!/bin/bash
# Pasada 1: Compresión sin pérdida (PNG máxima compresión)
optipng -o3 -zc9 *.png

# Pasada 2: Compresión con mínima pérdida perceptible (85-95% calidad)
pngquant --quality 85-95 -f --ext .png *.png

¿Cómo funciona esto? La primera pasada utiliza optipng con máxima compresión (-o3) y máximo nivel zlib (-zc9). Esto reduce el tamaño de PNG sin perder un solo píxel de información. Es 100% lossless.

La segunda pasada es más agresiva: pngquant reduce la paleta de colores de PNG a 256 colores máximo, pero lo hace de forma inteligente. Los cambios son prácticamente imperceptibles al ojo humano, pero el tamaño se reduce dramáticamente. Los sprites de personajes en Quintaesencia utilizan relativamente pocos colores, así que este paso fue muy efectivo.

Resultados reales en nuestro proyecto:

Tipo de Asset Antes Después Reducción
Sprites de personajes (4,538 archivos) 320 MB 180 MB -140 MB (-44%)
Tilesets de mapa (192 archivos) 180 MB 95 MB -85 MB (-47%)
Fondos y cinemáticas 145 MB 82 MB -63 MB (-43%)
Total Imágenes 645 MB 357 MB -288 MB (-45%)

Lo importante aquí es que no perdimos nada visual. Los personajes siguen viéndose idénticos. Los efectos visuales mantienen su impacto. El cambio es imperceptible incluso para usuarios que miran fijamente la pantalla.

Estrategia 2: Recodificación de Audio (El Golpe Definitivo)

El audio de Quintaesencia ocupaba 210 MB del proyecto. Tenemos 19 tracks de música de fondo, más de 1,200 efectos de sonido y voces de personajes. Todos estaban en formato OGG Vorbis, pero a un bitrate demasiado alto para lo que realmente necesitábamos.

Aquí es donde aplicamos la técnica que más impacto tuvo: recodificación de audio OGG Vorbis de 96 kbps a 64 kbps utilizando ffmpeg con factor de calidad Q4.

#!/bin/bash
# Recodificar todos los OGG a calidad Q4 (64 kbps equivalente)
for file in audio/bgm/*.ogg; do
  ffmpeg -i "$file" -q:a 4 "${file%.ogg}_optimized.ogg"
  mv "${file%.ogg}_optimized.ogg" "$file"
done

¿Por qué funciona esto sin pérdida perceptible? La música de videojuego no requiere la calidad de un estudio de grabación. Los 96 kbps originales eran overkill. El oído humano en contexto de juego (con efectos, diálogos, ruido ambiental) no puede distinguir entre 96 kbps y 64 kbps de Vorbis.

Vorbis es superior a MP3 a bitrates bajos. Fue diseñado específicamente para este caso de uso: máxima calidad percibida con el menor tamaño posible. Con Q4 (que equivale aproximadamente a 64 kbps), obtuvimos una compresión de ~35% sin artefactos audibles.

En números:

  • 19 tracks de música: 9.5 MB → 5.2 MB (-45%)
  • 1,200+ efectos de sonido: 125 MB → 68 MB (-46%)
  • Audio total del juego: 210 MB → 92 MB (-56%)

Lo probamos extensamente: hicimos jugar a múltiples testers sin decirles cuál versión estaban jugando. Nadie notó la diferencia. La música sigue siendo épica, los efectos de golpe siguen siendo satisfactorios, las voces están claras.

Estrategia 3: Caza de Archivos Huérfanos

RPG Maker es un motor visual que genera automáticamente múltiples archivos durante el desarrollo. Muchos de estos archivos nunca se usan en el juego final. Podría haber un PNG de un enemigo que fue reemplazado hace meses. Una pista de audio que quedó en la carpeta de desarrollo. Archivos de backup. Configuraciones del editor que no afectan al juego compilado.

El problema era identificarlos sin romper el juego. No podíamos simplemente eliminar todo lo que pareciera sospechoso.

Creamos un script Python que analiza todos los archivos JavaScript del juego y extrae exactamente qué assets son referenciados:

#!/usr/bin/env python3
# analyze-dependencies.py
# Encuentra todas las imágenes y audios realmente utilizados

import os, re
from pathlib import Path

required = set()

# Buscar en TODO el código JavaScript
patterns = [
    r"['"]([^'"]*.(png|jpg|webp|ogg|mp3|wav))['"]",
    r'require(["']([^"']*.(png|jpg|webp|ogg|mp3|wav))["']',
    r'import.*from ["']([^"']*.(png|jpg|webp|ogg|mp3|wav))["']',
]

for js_file in Path('js/').rglob('*.js'):
    with open(js_file, 'r', encoding='utf-8', errors='ignore') as f:
        content = f.read()
        for pattern in patterns:
            matches = re.findall(pattern, content)
            for match in matches:
                if isinstance(match, tuple):
                    required.add(match[0])
                else:
                    required.add(match)

# Encontrar HUÉRFANOS
orphans = []
for asset in Path('img/').rglob('*'):
    if asset.is_file() and str(asset) not in required:
        orphans.append(asset)

print(f"✓ Archivos requeridos: {len(required)}")
print(f"✂️  Archivos huérfanos encontrados: {len(orphans)}")
print(f"💾 Espacio a liberar: ~{sum(f.stat().st_size for f in orphans) / (1024**2):.0f} MB")

Este script fue revolucionario. Identificó 312 archivos completamente huérfanos que podían ser eliminados con seguridad. Principalmente eran:

  • Enemigos eliminados del juego hace meses
  • Efectos visuales que fueron reemplazados
  • Pruebas de jugabilidad que nunca llegaron a producción
  • Assets de «qué pasa si» que nunca se usaron
  • Archivos de backup y desarrollo de editor

Total liberado: 280 MB sin tocar una sola línea de código del juego funcional.

El Resultado Final

Técnica de Optimización Tamaño Original Reducción Porcentaje
Optimización de Imágenes (optipng + pngquant) 645 MB -288 MB -45%
Recodificación de Audio (OGG Q4) 210 MB -118 MB -56%
Eliminación de Archivos Huérfanos ~280 MB -280 MB -100%
Optimización de Videos/Cinemáticas 120 MB -75 MB -62%
Limpieza de Configuración/Build 145 MB -50 MB -34%
TOTAL – QUINTAESENCIA 1,100 MB -811 MB -73.7%

🎉 Quintaesencia fue reducido de 1.1 GB a 350 MB 🎉

El Impacto en la Realidad

Esta optimización no fue un ejercicio académico. Tuvo impacto tangible en cómo se desarrolla, compila y distribuye Quintaesencia:

  • ⚡ Compilación 3x más rápida: De 45-60 minutos a 15 minutos. Los desarrolladores pueden iterar, probar y hacer cambios sin esperar.
  • 📦 APK distribuble: De 380 MB a 97 MB. Ahora puede instalarse en casi cualquier dispositivo Android. Play Store acepta APKs hasta 100 MB.
  • 🌐 Web responsiva: La versión web carga en segundos incluso con conexión 4G moderada. No hay lag o stuttering en dispositivos móviles.
  • 📱 Compatible con todo: Usuarios con teléfonos de 2-3 GB de RAM pueden jugar sin problemas. No es necesario tener el último flagship.
  • 🚀 Distribución más rápida: Los backups, los builds de CI/CD, la sincronización con servidores de desarrollo: todo es más rápido.
  • 💾 Gestión de almacenamiento: Menos presión en infraestructura, ancho de banda más disponible para usuarios finales.

Lecciones Aprendidas

La optimización de un videojuego no es un evento singular. Es un proceso iterativo y estratégico. Nuestro trabajo con Quintaesencia nos enseñó que:

  • Mide primero: Sin datos de antes/después, no sabrás qué técnicas funcionan. Usa du -sh, script de análisis, etc.
  • Automatiza: No ejecutes ffmpeg manualmente en 1,200 archivos. Escribe un script. Reutilizable, repetible, auditable.
  • Prueba con usuarios: No todos los cambios perceptibles al ojo/oído son perceptibles en contexto. Prueba con jugadores reales.
  • Mantén backups: Siempre guarda una copia de los originales antes de comprimir. Si algo sale mal, puedes revertir.
  • Prioriza correctamente: 45% de reducción en imágenes (645 MB) vale más que 34% en misc (145 MB). Ve a donde está el volumen.

Conclusión

Quintaesencia es ahora un juego más pequeño, más rápido de compilar, más fácil de distribuir, y más accesible para usuarios con dispositivos limitados. Sin sacrificar ni un segundo de la experiencia visual o de audio.

Las técnicas que aplicamos son estándar en la industria, pero requieren disciplina y automatización para implementar correctamente. Si estás desarrollando un videojuego, una aplicación web pesada, o cualquier proyecto con mucho contenido multimedia: estas estrategias funcionan.

El viaje de 1.1 GB a 350 MB no fue trivial, pero fue completamente manejable con las herramientas correctas, un plan claro, y el conocimiento de dónde hacer presión. 🎮✨

Compartir:
|
Siguiente →
¿Cómo Optimizar el Rendimiento de un Videojuego
Inicio Blog ¿Cómo Bajar el Peso de un Videojuego?
← Volver al Blog