Halo 2 HD: un proyecto de remasterización que desafía los límites de la Xbox original
(icode4.coffee)- El parche Halo 2 HD para la Xbox original fue un proyecto que combinó modificaciones del ejecutable, cambios de hardware en la consola y la creación de herramientas de benchmark para intentar renderizar en 720p y 1080p más allá de 480p
- A diferencia de lo que indicaba Halo 2 con 480p, internamente dibujaba en un back buffer de 640×480 y luego la GPU lo escalaba a 720×480, por lo que para soportar HD había que cambiar tanto los buffers D3D como el manejo de modos de video
- Ejecutar en 720p no era posible con los 64 MB de RAM base, así que se necesitó una actualización a 128 MB de RAM y un hot patch del kernel, evitando la limitación para que la memoria física contigua destinada a la GPU también pudiera asignarse en los 64 MB superiores
- El rendimiento mejoró con triple buffering, tiling del render target texaccum y overclocking de la GPU de 233.33 MHz a 300 MHz; la escena de benchmark de Zanzibar subió de unos 19 FPS a alrededor de 27~28 FPS
- La RAM adicional también se aprovechó para ampliar las cachés de texturas y geometría, y para mejorar la velocidad de transferencia del HDD; el parche final hizo que 720p fuera usable en la práctica, mientras que 1080p quedó más como un extra para capturas de pantalla
Objetivos del proyecto y supuestos de hardware
- El objetivo era agregar soporte para resoluciones HD a la versión de Halo 2 para la Xbox original y comprobar hasta dónde podía llegar el hardware modificado de la consola
- El alcance del trabajo incluyó parchear el juego, modificar el hardware de la consola Xbox y escribir herramientas personalizadas para benchmarks de rendimiento
- La Xbox modificada que sirvió de base para el proyecto era llamada “god box” e incluía los siguientes cambios
- Reemplazo del CPU Pentium 3 de 733 MHz original por una variante de Pentium 3 a 1.4 GHz mediante una placa interposer personalizada
- Posibilidad de hacer overclock del CPU hasta unos 2 GHz
- Uso de RAM adicional y SSD
- Uso de un kernel personalizado o una imagen de BIOS compatible con modificaciones de hardware
- La resolución de video máxima soportada por Halo 2 era 480p, y el objetivo era agregar soporte para 720p y, si era posible, 1080i
- Al aumentar la resolución, se incrementa la cantidad de cálculos de pixel shaders y crece la carga sobre la GPU, así que se consideró que el trabajo solo valía la pena si era posible hacer overclock de la GPU
- Más adelante se logró un overclock de la GPU de alrededor del 15%, y se preparó una consola “GENESIS-3” para desarrollo
480p en Halo 2 y su estructura de renderizado interno
- Aunque Halo 2 indicaba en la caja que soportaba 480p, no tenía configurado
D3DPRESENTFLAG_PROGRESSIVEen los parámetros de presentación de D3D, y la escala del tamaño de pantalla siempre era1.0f - Los
screen_boundsinternos se configuraban en 640×480 sin importar el modo de video- En la Xbox original, 480p se trata como 720×480
- Halo 2 renderizaba en un back buffer de 640×480 y luego la GPU lo escalaba a 720×480 para enviarlo al codificador de video
- En modo widescreen, usaba una cámara anamórfica de 1.33:1 para renderizar una imagen más amplia comprimida en la misma superficie de 640×480
- Este método podría haber buscado compensar la compresión horizontal en el modo stretch del televisor
- El parche también agregó una opción para desactivar el escalado anamórfico
Parche D3D para renderizado HD
- Para soportar resoluciones, tres funciones se convirtieron en los principales objetivos de modificación
_rasterizer_detect_video_mode: se cambió para que progressive scan también se activara en 720p_rasterizer_init_screen_bounds: configura tamaños de 640×480, 720×480, 1280×720 y 1920×1080 según el modo de videorasterizer_device_initialize: configura el back buffer de D3D y los present flags
- En modo 1080i, tras comprobar que el ancho de pantalla fuera 1920, se elimina
D3DPRESENTFLAG_PROGRESSIVEy se configuraD3DPRESENTFLAG_INTERLACED - Tras los cambios iniciales, desapareció el filtro azul del menú principal y aparecieron problemas de patrones de líneas repetidas y recorte de la geometría del agua
- Algunos problemas se debían a vistas hardcodeadas de 640×480 para los buffers back/front/depth
- Al crearse vistas de textura/superficie que interpretan la misma memoria con anchos distintos, la disposición de las scan lines quedaba desalineada
Memoria D3D y reconstrucción de render targets
- La Xbox original usa una arquitectura de memoria unificada en la que CPU y GPU comparten la misma RAM
- No es una estructura como en PC, donde D3D crea asignaciones en VRAM y la GPU las administra
- El CPU puede crear memoria para texturas, render targets, vertex buffers, etc., y pasar direcciones directamente a la GPU
- Halo 2 usa alrededor de 25 render targets, pero las asignaciones de buffers únicos reales son apenas 4 o 5
- Varios render targets comparten la misma memoria mediante diferentes vistas de recursos para ahorrar memoria
rasterizer_primary_targets_initializecreaba render targets y vistas de textura adicionales a partir de los buffers back/front/depth creados por D3D, con un tamaño hardcodeado de 640×480- El parche envuelve esa función con un hook para modificar, después de ejecutar la función original, el tamaño de las texturas/superficies de acuerdo con la resolución actual del back buffer
- El pitch de la memoria tiled puede diferir del
width * bpptípico, por lo que se calcula conD3D_CalcTilePitch - Un pitch incorrecto puede generar efectos de líneas, especialmente en 1080i
- El pitch de la memoria tiled puede diferir del
Corrección del tamaño del render target texaccum
- El recorte de la geometría del agua en el menú principal se debía a que el render target texaccum estaba fijado en 640×480
- La implementación de DirectX en Xbox solo permite muestrear 4 texturas por pasada de pixel shader
- Los objetos que necesitan más de 4 texturas de entrada deben renderizarse en varias pasadas
- La capa texaccum primero compone las texturas de detalle y luego se usa como entrada para la pasada de lightmap
rasterizer_targets_initializeasignaba el render target texaccum en 640×480- Se envolvió
_rasterizer_alloc_and_create_render_targetcon un hook para cambiar el ancho y el alto del target texaccum cuyotarget_index == 1al tamaño actual del back buffer - Tras este cambio desapareció el recorte de la geometría del agua, y tampoco quedaron problemas de renderizado visibles al cargar mapas
- El problema del filtro azul se resolvió con una simple actualización de una comprobación de tamaño, pero se omiten los detalles del proceso
Límites de memoria que impedían ejecutar en 720p
- Al configurar 720p, el juego crasheaba al iniciar; la causa era la falta de memoria por el mayor tamaño de los buffers front/back/depth y de los rasterizer targets
- La Xbox original existía en modelos de consumo con 64 MB de RAM y en dev kits/debug consoles de 128 MB de RAM para desarrollo
- Incluso en las placas retail existen físicamente los lugares para chips de RAM adicionales
- Soldando chips de RAM y usando un kernel modificado se puede acceder a 64 MB adicionales
- Para ejecutar en 720p o más era necesaria una actualización a 128 MB de RAM
- Para que incluso el 480p normal se ejecutara sin actualizar la RAM, había que tomar memoria de la caché de texturas en memoria del juego, lo que aumentaba el pop-in de texturas
Parche del administrador de memoria de Halo 2
- Al iniciar, Halo 2 asigna alrededor de 48.9 MB de los 64 MB disponibles a una gran región de datos de runtime
- Esa región se divide entre metadatos de niveles, texturas, geometría, animaciones, caché de sonido, rasterizer targets, recursos de red/simulación, etc.
- Para visualizar el uso de memoria se escribió XboxImageGrabber
- Recorre las entradas de la tabla de páginas y visualiza el estado de uso de la RAM como un bitmap
- La región de datos de runtime se asigna en una dirección hardcodeada, 0x80061000
- Los tag data de los archivos map están serializados con esa dirección base, así que esos datos deben estar siempre en la misma dirección
- Otros datos de runtime sí pueden moverse
- Las regiones elegidas para mover fueron rasterizer targets, texture cache y geometry cache
- Se hookean llamadas de asignación específicas para moverlas a la debug memory region
- En momentos de liberación, como al cargar un nuevo nivel, se agregan las llamadas
freecorrespondientes - También se reduce el tamaño de la región de datos de runtime para disminuir desperdicio
physical_memory_mallocestaba inlineado por el compilador, así que se necesitó un parche separado en cada call site
Hot patch del kernel de Xbox y memoria física en los 64 MB superiores
- Las direcciones de memoria que se pasan a la GPU deben ser direcciones físicas, y el rango de memoria debe ser contiguo
- La GPU no tiene concepto de tablas de páginas ni de traducción de direcciones virtuales
- Incluso con un kernel de 128 MB de RAM, por defecto las asignaciones físicas contiguas solo podían hacerse en los primeros 64 MB, mientras que las asignaciones virtuales podían usar los 128 MB completos
- Una prueba usando manualmente entradas de la tabla de páginas de los 64 MB superiores como memoria para GPU fue exitosa
- La restricción que impedía usar memoria física para la GPU en los 64 MB superiores era una limitación de software del kernel, no de hardware
- Dentro de
MmAllocateContiguousMemoryExhabía una comprobación deMAX_USABLE_PFN- El valor existente era 0x83FE0000, equivalente a 64 MB - 128 KB
- Los 128 KB superiores están reservados para un área scratch de GPU de 64 KB y una tabla de páginas de CPU de 64 KB
- El parche, al arrancar el juego, verifica si la consola tiene 128 MB de RAM y luego busca el valor
mov edx, 0x3FDFenMmAllocateContiguousMemoryExpara reemplazarlo por un nuevo valor adecuado para la configuración de 128 MB - Después de eso, se usa
MmAllocateContiguousMemoryExyMmFreeContiguousMemorypara asignar y liberar memoria física contigua en los 128 MB completos - También hubo efectos secundarios
- Tras salir del juego, si se volvía al dashboard o se expulsaba la bandeja del DVD mediante un warm reboot sin cold reboot, la siguiente app o juego podía mostrar artefactos gráficos graves y crashear
- Para ocultarlo, se agregó un parche adicional que fuerza un cold reboot al salir del juego
Resultados de renderizado en 720p/1080p y cuellos de botella de rendimiento
- El renderizado en 720p mejoró visualmente, pero el rendimiento era tan bajo que en escenas pesadas los FPS podían caer por debajo de 10
- En 1080p es posible renderizar de forma nativa, pero la salida de la consola Xbox solo permite señal 1080i
- Al volcar directamente el back buffer de D3D, se podían obtener capturas 1080p antes de que la GPU las convirtiera en half frames para el codificador de video
- Las mediciones de rendimiento compararon tres configuraciones: Xbox base, god box con overclock solo de CPU y god box con overclock de CPU+GPU
- Se usó un punto pesado de Zanzibar como “zanzibar benchmark scene”
- En las mediciones iniciales, los FPS de las tres configuraciones eran casi iguales, y el gráfico de rendimiento reveló que la causa era el swap stall
- Halo 2 usa vsync activado y double buffering
- Se producía una situación en la que la GPU esperaba el vblank y no podía rotar la swap chain, quedando en stall
Triple buffering y confirmación del cuello de botella en la GPU
- Como solución, se aplicó triple buffering aumentando el conteo de back buffers a 2, para usar 1 front buffer y 2 back buffers, 3 buffers en total
- En
D3DPRESENT_PARAMETERSse configuróBackBufferCount = 2,D3DSWAPEFFECT_DISCARDyD3DPRESENT_INTERVAL_ONE - Como el motor de renderizado de Halo 2 intercambiaba los punteros de back/front buffer en cada frame asumiendo double buffering, también hubo que modificar el swap hook y el primary target initialize hook
- Se cambió para que las dos primary render surfaces y texture views siempre referencien el back buffer actual
- Aunque el juego intercambie internamente los dos punteros, ambos apuntan a la misma memoria, por lo que en la práctica queda como un no-op
- En la escena de benchmark de Zanzibar, los FPS con la GPU base pasaron a unos 22 FPS
- Un aumento de alrededor de 3 FPS respecto a antes
- Alrededor de 10% más tomando como referencia el límite de 30 FPS
- Al desaparecer el swap stall y maximizarse el uso de GPU, se confirmó que el cuello de botella era la GPU
Overclock de GPU y RAM
- Al convertir el render target texaccum a memoria tiled, se obtuvieron 1~2 FPS adicionales
- La escena de benchmark de Zanzibar mejoró de unos 19 FPS a 23~24 FPS
- Con la GPU de la god box overclockeada, la escena de benchmark de Zanzibar registró 27~28 FPS
- Al recorrer el mapa, en general se mantenían 30 FPS y solo caía en algunas zonas pesadas
- Para evitar requerir reflashear la BIOS, se ajusta directamente al iniciar el juego el registro de memory-mapped IO del clock generator de la GPU
- El cálculo del reloj de la GPU se basa en los valores M, N y P de
NVPLL_COEFFy en un base clock de 16.6667 MHz- El valor N predeterminado de 28 produce un reloj de GPU de 233.33 MHz
- Ajustando el valor N se pudo configurar en pasos de alrededor de 8 MHz, y hacerlo configurable mediante un archivo ini
- El overclock de GPU a 300 MHz agregó unos 3 FPS adicionales en el benchmark de Zanzibar frente a la GPU base
- Los límites de overclock variaban según cada GPU
- En las GPU de consolas revisiones 1.0~1.4, muchas veces el límite aparecía en el rango bajo de 300 MHz
- Hubo casos de GPU en consolas revisión 1.6 que funcionaban de forma estable por encima de 400 MHz
- También se probó el reloj de la RAM
- El ancho de banda teórico máximo del bus de memoria de Xbox es de 6.4 GB/s, y se considera que lo usable en la práctica es alrededor del 70%, unos 4.5 GB/s
- La RAM ya trabaja cerca de 200 MHz por defecto, por lo que subirla apenas unos 10 MHz puede volverla inestable
- En una prueba configurada a unos 208 MHz se observó un aumento de 0.7 FPS
- También se pidieron chips de RAM capaces de 250 MHz, pero al momento de escribir el artículo no se habían instalado ni probado más
Reducción del pop-in y expansión de cachés
- Halo 2 ya tenía originalmente problemas de pop-in de texturas y geometría, algo que se hacía más notorio en una consola con HDD mecánico de principios de los 2000
- Se aprovechó la RAM adicional para expandir la texture cache y la geometry cache
- La geometry cache predeterminada es de 6.5 MB en mapas single-player y de 7 MB en mapas multiplayer
- La texture cache varía según el tamaño del map y usa el espacio restante entre los tag data y la low detail texture cache
- Las cachés funcionan con un esquema LRU
- Cada 30 frames eliminan datos que no se hayan usado durante los últimos 30 frames
- Si la caché está llena, el llamador especifica una eviction forzada, o la solicitud de carga falla y se reintenta en el frame siguiente
- Las texturas pueden tener buffers LOD low/medium/high
- Si falla la carga del LOD high, intenta cargar medium o low
- Puede aparecer primero un LOD bajo y luego cambiar a uno más alto, generando pop-in
- Los mapas también incluyen una emergency low detail texture cache con tamaños de 2×2 hasta 8×8
- Se usa para dibujar temporalmente un modelo en pantalla aunque falle la carga de texturas normales
- El fenómeno en el que el terreno se veía con texturas de resolución extremadamente baja tras abrir y cerrar el menú de amigos de Xbox Live está relacionado con el uso de esta caché
- Se reconstruyó la función de visualización de gráficos del debug build de Bungie para ver directamente el uso de caché y ajustar los tamaños
- La configuración final aumenta la geometry cache a 20 MB y la texture cache a 30 MB fijos
- Ambas cachés quedan casi al doble respecto a la configuración predeterminada
- En la cinemática inicial de Outskirts, Master Chief se muestra de inmediato con texturas de alta resolución y aún queda espacio libre en caché
- Para reducir el pop-in restante también se aumentó la velocidad de transferencia del HDD
- UDMA 2 predeterminado ofrece unos 33.3 MB/s
- UDMA 3 ofrece unos 44.4 MB/s
- Con un cable IDE de 80 hilos se puede configurar hasta UDMA 5, unos 100 MB/s
- Con el cable IDE predeterminado ofrece alrededor de 10% de mejora de velocidad de transferencia; con el cable IDE actualizado, teóricamente hasta 300%
- El perfil de memoria final en 720p usa más del 75% de los 128 MB de RAM
- En modo 1080p, el uso de memoria de la swap chain y de los rasterizer targets era demasiado grande, por lo que había que reducir los tamaños de caché y, en la práctica, se usaba casi toda la memoria de 128 MB
Resultado
- En general, el parche 720p mejoró hasta un nivel jugable, mientras que el soporte 1080p quedó más como un extra para capturas de pantalla
- Todavía queda margen para mejorar el rendimiento y los cambios de memoria, pero el resultado empujó bastante los límites de Halo 2 y de la consola Xbox
- La descarga del parche Halo 2 HD y su código fuente están publicados en GitHub
1 comentarios
Comentarios de Hacker News
Enlace al video al final del artículo: https://www.youtube.com/watch?v=O_nk21389u8
El video incluye una comparación lado a lado del escalado original en 480p y 720p, y desde alrededor del minuto 7 explica qué hace falta para obtener 720p manteniendo una jugabilidad de unos 30 fps
El artículo es excelente, pero también está muy bien el video que resume los cambios necesarios para lograr una resolución más alta
Decir que 720×480 no es una resolución 16:9 o que no es “480p real” en realidad hay que reclamárselo a la estandarización de la ITU de los años 70: https://tech.ebu.ch/docs/techreview/trev_304-rec601_wood.pdf
En un memorando de febrero de 1980 se decía que, para abarcar por completo el período de exploración activa de los estándares europeos, el número de muestras por línea activa tenía que ser mayor que 715.5, y luego las 720 muestras usadas en Rec. 601 y SMPTE 125 se establecieron como el primer valor que “funcionaba”
Rec. 601 proporcionaba 720 muestras por línea activa para el canal de luminancia y 360 muestras para cada una de las señales de diferencia de color, y al definir HDTV se duplicó la resolución horizontal de estos sistemas de TV existentes y se aplicó una relación de aspecto 16:9, lo que llevó a 1920 muestras por línea y 1080 líneas
El sistema de barrido progresivo de 1280×720 también pertenece a esta misma familia de 720 píxeles, y la mayoría de los sistemas de TV digital, DVD y basados en MPEG derivan de este formato estándar base 4:2:2
El “espíritu hacker” en sí es totalmente válido, pero me pregunto si realmente hay una razón para jugar Halo 2 de esta forma, metiéndose en el trabajo de añadir memoria a la consola y overclockear la GPU, en lugar de usar la versión de PC
Hay muchos videos que cubren los defectos en detalle y en varios niveles
https://youtu.be/03K2Uz3s1hg?si=zaFO1XdzMcFvI1F6
Da la sensación de demostrar que sí se puede, o incluso que puede hacerlo mejor
Tal vez se parezca más a una barrera psicológica, pero por lo general es algo ligero y divertido, y se siente como lo opuesto de la obsesión por comprar antes que nadie el modelo más reciente de un dispositivo popular
Ambas cosas dan una especie de sensación de superioridad
Incluso ahora se puede jugar Halo 2 en línea en lobbies o en campaña, y también se puede elegir entre los gráficos originales que ofrece 343 o los gráficos HD remasterizados
En el texto se dice que “el sistema de datos de etiquetas fue diseñado para ser lo más flexible y rápido posible, y su funcionamiento interno es una proeza de ingeniería. Solo por la razón de que creo que es lo que hace que el motor Blam sea uno de los motores más flexibles, podría escribir un artículo entero, pero eso no viene al caso aquí”, y me encantaría leer ese artículo si de verdad llega a escribirse
Era demasiado principiante como para siquiera seguir cómo funcionaba, y era tan dinámico que ni siquiera entendía de forma fundamental que una estructura así pudiera existir
No entendía cómo podía ser posible que la posición del jugador estuviera en el mismo contexto que un arma con configuración, y que hasta los efectos estuvieran dentro de la misma lista
Muchas de las cosas que me interesan ahora, al final, siguen orbitando alrededor de estos conceptos
Ojalá regresara en tiempos modernos la era del Xbox y el modding de Halo 2
Esa época influyó mucho en la elección de mi carrera, y todavía creo que Halo 2 es el juego en línea más innovador de todos los tiempos
Bastaba con comprar una herramienta sencilla para cargar partidas guardadas y podías hacer un softmod a un Xbox en pocos minutos, pero las consolas de ahora queman e-fuses, bloquean los downgrades y además tienen mucha más seguridad
Junto con el proyecto de Insignia para empezar a dar soporte a Halo 2, de verdad es un muy buen momento para el Halo 2 clásico
Una de las razones por las que hoy soy ingeniero de software es que antes era fácil mirar cómo funcionaba una página web, tocar la memoria de un programa y abrir el hardware para ver qué había dentro
Aprendí mucho sobre lo que entra en un juego modeando niveles en la época de Halo PC, y saber qué es un “BSP” puede ser trivia inútil, pero me dio la confianza de que podía entender más cosas
Todavía se puede entrar a la tecnología y aprender, pero ya casi no se ve ese camino de llegar ahí a base de cacharrear de verdad
El software se ha vuelto mucho más difícil de crackear o depurar; no es imposible, pero la barrera de entrada es muchísimo más alta
Las páginas web todavía se pueden inspeccionar, pero muchos sitios hoy son montones de divs para sostener monstruos de JavaScript minificado y ofuscado, y los juegos a veces son directamente más difíciles porque dependen cada vez más de hacer streaming de contenido desde el servidor
El hardware también implica procedimientos de seguridad que pueden dejarte el dispositivo inservible, pistolas de calor para abrir biseles pegados y el riesgo de causar daño permanente
Seguramente hubo motivos para cada uno de esos cambios, pero en el proceso también desapareció casi toda la diversión, y aunque hoy las herramientas sean técnicamente mejores, el modding de juegos ya no se siente como antes
Incluso ahora todavía se puede cacharrear bastante con una PC o con consolas basadas en PC como el Steam Deck, así que no entiendo por qué alguien querría pelearse con consolas cerradas diseñadas para estar bloqueadas
Tampoco queda claro qué se gana, más allá de obtener acceso a hardware x86 personalizado que se puede comprar barato en el mercado
Los FPS competitivos en línea con comunidades fuertes de modding ya llevaban más de 10 años activos en PC
Tiene una comunidad activa gracias a Project Cartographer: https://halo2.online/home/
Esta persona parece más comprometida con Halo 2 que lo que Bungie hoy invierte en su propia IP
Microsoft es dueña de la IP y el desarrollo está a cargo de 343 Industries
Bungie ahora tiene Destiny/Destiny 2 y el próximo extraction shooter Marathon
Le dediqué una cantidad enorme de tiempo a ese juego, y me alegra ver que hay otra persona igual de atrapada por esa magia que yo
Aun así, un nivel de dedicación así merece respeto
Puede sonar excesivamente cínico, pero el proyecto en sí está realmente genial
Solo que me pregunto si cambiar el CPU, hacer overclock, aumentar la RAM, añadir almacenamiento de estado sólido y hasta hacer overclock al GPU realmente cuenta como llevarlo al límite del Xbox original
En ese punto ya casi no parece un Xbox
Si a un Honda Civic le haces un montón de modificaciones al motor y la suspensión para llevarlo al límite, preguntar “¿pero de verdad sigue siendo un Civic?” puede ser técnicamente válido, pero también puede sonar a discusión por nimiedades
El autor tiene derecho a ponerle el título que quiera, y en tu cabeza puedes leerlo como “modear un OG Xbox hasta dejarlo al borde de la muerte” o algo así
Halo 2 puede correr a mayor resolución en 360, así que dejar claro que es un proyecto de modding centrado en el Xbox original sí resulta útil
No se refiere literalmente a un Xbox sin modificar, sino a que el objeto del modding fue el Xbox original
También dice que en una consola con cable IDE estándar la velocidad de transferencia sube 10%, y que con un cable IDE mejorado en teoría podría subir hasta 300%
Si tienes 128MB de RAM, puedes aprovechar la RAM extra para activar los modos de video 720p y 1080i y ampliar la caché de memoria de texturas y geometría para eliminar casi por completo el pop-in
Si solo quieres 480p, basta con hacer overclock al GPU en una consola stock y usar otro cable IDE
La parte sobre el SSD parece haber causado confusión sin querer, y tal vez se refería a la combinación de cable de 80 pines con SSD
El CPU con overclock no hace falta, el CPU tampoco es el cuello de botella, y la RAM ampliada solo es necesaria si quieres más de 720p
Ya transmití este comentario, así que puede que la entrada del blog se actualice para dejar esta parte más clara
La escena de las computadoras retro es así, y el tuning de autos se parece bastante
Hay gente que quiere un Corvette perfecto de fábrica, y hay gente que quiere un Model A con un motor 50 años más moderno
Torcer a tu manera algo conocido y familiar tiene su encanto
La carga de trabajo es enorme
También es interesante que el amigo “doom” no quisiera revelar su identidad