Después de analizar un poco la optimización, descubrí (literalmente en todas partes) que parece ser un pecado universalmente reconocido optimizar un juego demasiado pronto.
Realmente no entiendo esto, ¿no sería increíblemente difícil cambiar algunas de las estructuras centrales del juego al final, en lugar de desarrollarlas la primera vez teniendo en cuenta el rendimiento?
Entiendo que esperar hasta que el juego termine te dirá si incluso necesitas optimizaciones, pero si no lo haces de todos modos, después de todo, podría ampliar la variedad de dispositivos en los que el juego podría ejecutarse, lo que aumentaría la cantidad de potencial jugadores
¿Podría alguien explicarme por qué es una mala idea optimizar demasiado pronto?
performance
optimization
señor-mate
fuente
fuente
Respuestas:
Preámbulo:
Se han planteado algunas objeciones en los comentarios, y creo que en gran parte se derivan de un malentendido de lo que queremos decir cuando decimos "optimización prematura", por lo que quería agregar una pequeña aclaración sobre eso.
"No optimizar de forma prematura" no significa "escribir código que sabes que es malo, porque Knuth dice que no puedes limpiarlo hasta el final"
Significa "no sacrifique el tiempo y la legibilidad para la optimización hasta que sepa qué partes de su programa realmente necesitan ayuda para ser más rápido". Dado que un programa típico pasa la mayor parte de su tiempo en algunos cuellos de botella, invertir en optimizar "todo" podría no obtener el mismo aumento de velocidad que centrar esa misma inversión en solo el código de cuello de botella.
Esto significa que, en caso de duda , debemos:
Prefiere código simple de escribir, claro de entender y fácil de modificar para empezar
Verifique si se necesita una mayor optimización (generalmente perfilando el programa en ejecución, aunque un comentario a continuación señala que hace un análisis matemático: el único riesgo es que también debe verificar que sus matemáticas sean correctas)
Una optimización prematura no es :
Decisiones arquitectónicas para estructurar su código de una manera que se adapte a sus necesidades, eligiendo los módulos / responsabilidades / interfaces / sistemas de comunicación apropiados de una manera considerada.
Eficiencias simples que no requieren tiempo extra o hacen que su código sea más difícil de leer. Cosas como el uso de mecanografía fuerte puede ser eficiente y hacer que su intención sea más clara. El almacenamiento en caché de una referencia en lugar de buscarla repetidamente es otro ejemplo (siempre que su caso no exija una lógica de invalidación de caché compleja, tal vez espere a escribir eso hasta que haya perfilado la forma simple primero).
Usando el algoritmo correcto para el trabajo. A * es más óptimo y más complejo que buscar exhaustivamente un gráfico de trazado de ruta. También es un estándar de la industria. Repetir el tema, apegarse a métodos probados y verdaderos como este puede hacer que su código sea más fácil de entender que si hace algo simple pero contrario a las mejores prácticas conocidas. Si tiene experiencia en cuellos de botella al implementar la función X del juego de una manera en un proyecto anterior, no necesita volver a tocar el mismo cuello de botella en este proyecto para saber que es real: puede y debe reutilizar soluciones que han funcionado en el pasado. juegos.
Todos esos tipos de optimizaciones están bien justificados y, por lo general, no se etiquetarían como "prematuros" (a menos que se esté yendo por un agujero de conejo que implementa la búsqueda de caminos de vanguardia para su mapa de tablero de ajedrez 8x8 ...)
Entonces, con eso aclarado, sobre por qué podríamos encontrar esta política útil en los juegos específicamente:
Especialmente en gamedev, la velocidad de iteración es lo más preciado. A menudo implementaremos y volveremos a implementar muchas más ideas de las que finalmente se enviarán con el juego terminado, tratando de "encontrar la diversión".
Si puede crear un prototipo de un mecánico de una manera sencilla y tal vez un poco ingenua y probarlo al día siguiente, está en una posición mucho mejor que si pasara una semana haciendo primero la versión más óptima. Especialmente si resulta que apesta y terminas descartando esa característica. Hacerlo de manera simple para que pueda realizar la prueba antes puede ahorrar una tonelada de trabajo desperdiciado optimizando el código que no conserva.
El código no optimizado también es generalmente más fácil de modificar y probar diferentes variantes que el código que está afinado para hacer una cosa precisa de manera óptima, que tiende a ser frágil y difícil de modificar sin romperlo, introducir errores o ralentizarlo. Por lo tanto, mantener el código simple y fácil de cambiar a menudo vale un poco de ineficiencia en el tiempo de ejecución durante la mayor parte del desarrollo (generalmente estamos desarrollando en máquinas por encima de la especificación objetivo, para que podamos absorber los gastos generales y centrarnos en obtener la experiencia objetivo primero) hasta que podamos Hemos bloqueado lo que necesitamos de la función y podemos optimizar las piezas que ahora sabemos que son lentas.
Sí, refactorizar partes del proyecto tarde en el desarrollo para optimizar los puntos lentos puede ser difícil. Pero también se está refactorizando repetidamente a lo largo del desarrollo porque las optimizaciones que realizó el mes pasado no son compatibles con la dirección en la que ha evolucionado el juego desde entonces, o estaban arreglando algo que resultó no ser el verdadero cuello de botella una vez que obtuvo más características y contenido en.
Los juegos son extraños y experimentales: es difícil predecir cómo evolucionará un proyecto de juego y sus necesidades tecnológicas y dónde el rendimiento será más ajustado. En la práctica, a menudo terminamos preocupándonos por las cosas equivocadas: busque entre las preguntas de rendimiento aquí y verá surgir un tema común de desarrolladores que se distraen con cosas en papel que probablemente no sean un problema en absoluto.
Para tomar un ejemplo dramático: si su juego está vinculado a la GPU (no es raro), todo ese tiempo dedicado a la hiperoptimización y al enhebrado del trabajo de la CPU podría no producir ningún beneficio tangible. En su lugar, podrían haberse invertido todas esas horas de desarrollo implementando y puliendo las características del juego, para una mejor experiencia del jugador.
En general, la mayor parte del tiempo que pasas trabajando en un juego no se gastará en el código que termina siendo el cuello de botella. Especialmente cuando trabajas en un motor existente, las cosas súper caras del bucle interno en los sistemas de representación y física están en gran parte fuera de tu alcance. En ese momento, su trabajo en los guiones de juego es básicamente mantenerse fuera del camino del motor, siempre que no arroje una llave inglesa, entonces probablemente saldrá bastante bien para una primera compilación.
Por lo tanto, aparte de un poco de higiene de código y presupuesto (por ejemplo, no busque / construya repetidamente cosas si puede reutilizarlo fácilmente, mantenga modestas sus consultas de búsqueda de caminos / física o lecturas de GPU modestas, etc.), con el hábito de no terminar -optimizar antes de saber dónde están los problemas reales resulta ser bueno para la productividad, ahorrándonos la pérdida de tiempo optimizando las cosas incorrectas y manteniendo nuestro código más simple y fácil de ajustar en general.
fuente
nota: esta respuesta comenzó como un comentario sobre la respuesta de DMGregory, por lo que no duplica los muy buenos puntos que hace.
"¿No sería increíblemente difícil cambiar algunas de las estructuras centrales del juego al final, en lugar de desarrollarlas la primera vez teniendo en cuenta el rendimiento?"
Esto, para mí, es el quid de la cuestión.
Al crear su diseño original, debe intentar diseñar para obtener eficiencia, al más alto nivel. Esto es menos optimización y se trata más de la estructura.
Ejemplo:
necesita crear un sistema para cruzar un río. Los diseños obvios son un puente o un ferry, entonces, ¿cuál eliges?
La respuesta, por supuesto, depende del tamaño del cruce y del volumen del tráfico. Esto no es una optimización, sino comenzar con un diseño adecuado para su problema.
Cuando se le presentan opciones de diseño, elige la que mejor se adapte a lo que desea hacer.
Entonces, digamos que nuestro volumen de tráfico es bastante bajo, por lo que decidimos construir dos terminales y comprar en un ferry para manejar el tráfico. Una implementación sencilla y agradable
Lamentablemente, una vez que la tenemos en funcionamiento, descubrimos que está viendo más tráfico del esperado. ¡Necesitamos optimizar el ferry! (porque funciona, y construir un puente ahora no es un buen plan)
Opciones:
Aquí es donde debe intentar hacer que su diseño original sea lo más modular posible.
Todo lo anterior son posibles optimizaciones, e incluso podría hacer las tres.
Pero, ¿cómo hacer estos cambios sin grandes cambios estructurales?
Si tiene un diseño modular con interfaces claramente definidas, entonces debería ser sencillo implementar estos cambios.
Si su código no está estrechamente acoplado, los cambios en los módulos no afectan la estructura circundante.
Echemos un vistazo a agregar un ferry adicional.
Se podría construir un programa 'malo' en torno a la idea de un solo ferry, y tener los estados del muelle y el estado y la posición del ferry agrupados y compartiendo el estado. Esto será difícil de modificar para permitir que se agregue un ferry adicional al sistema.
Un mejor diseño sería tener los muelles y el ferry como entidades separadas. No existe un acoplamiento estrecho entre ellos, pero tienen una interfaz, donde un ferry puede llegar, descargar pasajeros, tomar nuevos y partir. El muelle y el ferry comparten solo esta interfaz, y esto hace que sea fácil realizar cambios en el sistema, en este caso agregando un segundo ferry. El muelle no se preocupa por los transbordadores que hay en realidad, todo lo que le preocupa es que algo (cualquier cosa) esté usando su interfaz.
tl; dr:
Luego puede cambiar los mecanismos dentro de cada módulo sin reestructurar toda la base de código cuando necesite optimizar.
fuente
IRiverCrossing
, y cuando quede claro que el volumen de tráfico es demasiado grande para la configuración del ferry, implemente el puente comoIRiverCrossing
y suéltelo. El truco, por supuesto, es reducir la API externa del Ferry y el puente a la funcionalidad común para que puedan ser representados por la misma interfaz."No optimizar temprano" no significa "elegir la peor forma posible de hacer las cosas". Aún debe tener en cuenta las implicaciones de rendimiento (a menos que solo esté creando prototipos). El punto no es paralizar otras cosas más importantes en ese punto del desarrollo, como la flexibilidad, la confiabilidad, etc. Elija optimizaciones simples y seguras: elija las cosas que limita y las que mantiene libres; realizar un seguimiento de los costos. ¿Deberías usar tipeo fuerte? La mayoría de los juegos funcionaban y funcionaban bien; ¿cuánto le costaría eliminar eso si encuentra usos interesantes de la flexibilidad para gamemplay?
Es mucho más difícil modificar el código optimizado, especialmente el código "inteligente". Siempre es una elección que hace que algunas cosas sean mejores y otras peores (por ejemplo, podría estar cambiando el tiempo de CPU por el uso de memoria). Al tomar esa decisión, debe ser consciente de todas las implicaciones: pueden ser desastrosas, pero también pueden ser útiles.
Por ejemplo, Commander Keen, Wolfenstein y Doom fueron construidos sobre un motor de renderizado optimizado. Cada uno tenía su "truco" que permitía que el juego existiera en primer lugar (cada uno también tenía más optimizaciones desarrolladas con el tiempo, pero eso no es importante aquí). Eso está bien . Está bien optimizar en gran medida el núcleo del juego, la idea que lo hace posible; especialmente si estás explorando un nuevo territorio donde esta característica optimizada en particular te permite considerar diseños de juegos que no fueron muy explorados. Las limitaciones que introduce la optimización también pueden brindarle un juego interesante (por ejemplo, los límites de conteo de unidades en los juegos RTS pueden haber comenzado como una forma de mejorar el rendimiento, pero también tienen un efecto de juego).
Pero tenga en cuenta que en cada uno de estos ejemplos, el juego no podría existir sin la optimización. No comenzaron con un motor "completamente optimizado", comenzaron con la simple necesidad y avanzaron. Desarrollaban nuevas tecnologías y las usaban para hacer juegos divertidos. Y los trucos del motor se limitaron a una parte tan pequeña de la base de código como sea posible: las optimizaciones más pesadas solo se introdujeron cuando el juego se realizó en su mayoría, o cuando permitió que surgiera una nueva característica interesante.
Ahora considera un juego que tal vez quieras hacer. ¿Existe realmente algún milagro tecnológico que haga o rompa ese juego? Tal vez estás imaginando un juego de mundo abierto en un mundo infinito. ¿Es realmente la pieza central del juego? ¿El juego simplemente no funcionaría sin él? Tal vez estás pensando en un juego donde el terreno es deformable sin límite, con una geología realista y tal; ¿Puedes hacer que funcione con un alcance más pequeño? ¿Funcionaría en 2D en lugar de 3D? Obtenga algo divertido lo antes posible, incluso si las optimizaciones pueden requerir que modifique una gran parte de su código existente, puede valer la pena; e incluso te darás cuenta de que hacer las cosas más grandes realmente no mejora el juego.
Como ejemplo de un juego reciente con muchas optimizaciones, señalaría Factorio. Una parte crítica del juego son los cinturones: hay muchos miles de ellos y llevan muchos trozos individuales de materiales por toda la fábrica. ¿Comenzó el juego con un motor de correa altamente optimizado? ¡No! De hecho, el diseño original del cinturón era casi imposible de optimizar: hacía una simulación física de los elementos del cinturón, lo que creaba algunas cosas interesantes que podía hacer (esta es la forma en que obtiene un juego "emergente", un juego que sorprende el diseñador), pero significaba que tenía que simular cada elemento del cinturón. Con miles de correas, obtienes decenas de miles de elementos simulados físicamente, incluso solo quitándolos y dejando que las correas hagan el trabajo te permiten reducir el tiempo de CPU asociado en un 95-99%, incluso sin considerar cosas como la localidad de memoria. Pero solo es útil hacerlo cuando realmente alcanzas esos límites.
Casi todo lo que tenía que ver con los cinturones tuvo que rehacerse para permitir que los cinturones se optimizaran. Y los cinturones necesitaban ser optimizados, porque necesitabas muchos cinturones para una gran fábrica, y las grandes fábricas son una atracción del juego. Después de todo, si no puedes tener grandes fábricas, ¿por qué tener un mundo infinito? Es curioso que preguntes: las versiones anteriores no lo hicieron :) El juego fue reelaborado y remodelado muchas veces para llegar a donde están ahora, incluida una nueva versión del 100% cuando se dieron cuenta de que Java no es el camino a seguir para juego como este y se cambió a C ++. Y funcionó muy bien para Factorio (aunque todavía era algo bueno, no estaba optimizado desde el principio, especialmente porque se trataba de un proyecto de pasatiempo, que podría haber fallado simplemente por falta de interés).
Pero la cosa es, no sonPuedes hacer muchas cosas con una fábrica de alcance limitado, y muchos juegos han demostrado eso. Los límites pueden ser aún más motivadores para la diversión que las libertades; ¿Sería más divertido Spacechem si los "mapas" fueran infinitos? Si comenzaste con "cinturones" muy optimizados, te verías obligado a seguir ese camino; y no podría explorar otras direcciones de diseño (como ver qué cosas interesantes puede hacer con cintas transportadoras simuladas por la física). Estás limitando tu potencial espacio de diseño. Puede que no parezca así porque no ves muchos juegos sin terminar, pero la parte difícil es hacer la diversión correcta: por cada juego divertido que ves, probablemente haya cientos que simplemente no pudieron llegar y fueron descartados (o peor, lanzado como desorden horrible). Si la optimización lo ayuda a hacerlo, continúe. Si no es así ... Es probable que sea prematuro. Si crees que una mecánica de juego funciona muy bien, pero necesita optimizaciones para brillar realmente, adelante. Si no tienes una mecánica interesante,No los optimices . Encuentra la diversión primero: encontrarás que la mayoría de las optimizaciones no ayudan con eso, y a menudo son perjudiciales.
Finalmente, tienes un gran juego divertido. ¿Tiene sentido optimizar ahora ? ¡Decir ah! Todavía no está tan claro como podría pensar. Hay algo divertidopuedes hacer en su lugar? No olvides que tu tiempo aún es limitado. Todo requiere un esfuerzo, y desea centrar ese esfuerzo en donde más importa. Sí, incluso si estás haciendo un "juego gratis" o un juego de "código abierto". Mira cómo se juega el juego; observe dónde el rendimiento se convierte en un cuello de botella. ¿La optimización de esos lugares es más divertida (como construir fábricas cada vez más grandes y enredadas)? ¿Le permite atraer a más jugadores (por ejemplo, con computadoras más débiles o en diferentes plataformas)? Siempre debe priorizar: busque la relación esfuerzo / rendimiento. Es probable que encuentres mucha fruta baja simplemente jugando tu juego y viendo a otros jugar el juego. Pero tenga en cuenta la parte importante: para llegar allí, necesita un juego . Concéntrate en eso.
Como guinda, considera que la optimización nunca termina. No es una tarea con una pequeña marca de verificación que finaliza y pasa a otras tareas. Siempre hay "una optimización más" que puede hacer, y una gran parte de cualquier desarrollo es comprender las prioridades. No optimiza por el bien de la optimización, lo hace para lograr un objetivo particular (por ejemplo, "200 unidades en la pantalla a la vez en un Pentium de 333 MHz" es un gran objetivo). No pierda la noción del objetivo terminal solo porque se concentra demasiado en los objetivos intermedios que tal vez ya no sean requisitos previos para el objetivo terminal.
fuente
Muchas de las respuestas parecen centrarse mucho en el aspecto del rendimiento de la "optimización", mientras que a mí mismo me gusta mirar la optimización y toda la experiencia de optimizar demasiado pronto a un nivel más abstracto.
Compláceme mientras intento elaborar mi perspectiva con la ayuda de los poliominós.
Supongamos que tenemos algunos límites fijos establecidos por el marco o motor con el que estamos trabajando.
Luego procedemos a crear nuestra primera capa / módulo del juego así.
Continuando construimos nuestra segunda capa / módulo.
En este punto, podríamos notar que hay algo de espacio disponible entre los dos módulos y podríamos sentir la tentación de optimizarlo para aprovechar al máximo los límites asignados a nosotros.
Perfecto, ahora la aplicación está utilizando todos los recursos disponibles, la aplicación es mejor, ¿verdad?
Procedemos a construir la tercera capa / módulo de nuestra aplicación y de repente nos damos cuenta (tal vez incluso una que no podríamos haber previsto durante la planificación inicial) de que la tercera capa / módulo no funciona para nosotros.
Buscamos una alternativa, encontramos una, y al final, esto también requiere que cambiemos el segundo módulo de nuestra aplicación, ya que es incompatible con nuestro tercer módulo recién seleccionado. (Afortunadamente, es algo compatible con nuestro primer módulo, por lo que no tenemos que volver a escribir todo desde cero).
Así que lo juntamos todo ...
Hmm, ¿puedes ver lo que pasó?
Al optimizar demasiado pronto, ahora hemos empeorado las cosas en términos de eficiencia, ya que lo que optimizamos no es lo que terminamos en el futuro.
Y si hubiéramos querido agregar algunos módulos adicionales o cositas adicionales después, es posible que ya no tengamos la capacidad de hacerlo en este momento.
Y ajustar el nivel más bajo de nuestro sistema ya no es tan factible ya que se ha enterrado debajo de todas las otras capas.
Sin embargo, si hubiéramos optado por esperar con nuestro impulso de optimizarlo de inmediato, habríamos terminado con algo como esto:
Y ahora, si realizamos la optimización en este punto, obtenemos algo satisfactorio a la vista.
Esperemos que al menos algunos de ustedes se hayan divertido tanto leyendo esto como yo me haya divertido haciendo esto :) y si ahora sienten que tienen una mejor comprensión del tema, mucho mejor.
fuente
Dinero.
Todo se reduce a eso. Dinero. Como el tiempo es dinero *, cuanto más tiempo pase en actividades que no se garantiza que generen más dinero (es decir, no puede considerar estas actividades como inversiones ), más dinero corre el riesgo de desperdiciar y menos dinero ganará con el juego.
Estos son algunos de los posibles efectos secundarios de la optimización demasiado pronto y las razones por las que debe evitarlo:
* Otras respuestas han resaltado bastante bien la parte del "tiempo"
Como nota al margen, en general , la experiencia ayuda a determinar qué es y qué no es una optimización prematura y qué tiene valor para el negocio y qué no.
Por ejemplo, si has trabajado en el juego A y te has dado cuenta al final del proyecto de que la característica XYZ era particularmente pesada en tu ciclo de juego, y eventualmente comienzas a trabajar en el juego B que tiene exactamente la misma característica, decidiendo reescribir la función y optimizarla desde el principio no es una optimización realmente prematura, ya que sabe que será un cuello de botella si no se hace nada.
fuente
La optimización es, por definición, el proceso de aumentar la eficiencia de una solución hasta el punto en que pierde su eficacia. Este proceso implica entonces una reducción del espacio de la solución.
En una etapa temprana del desarrollo del software todavía puede haber "requisitos ocultos": si reduce demasiado el espacio de su solución, podría terminar en una situación en la que no puede cumplir un "requisito oculto" cuando aparece en una etapa posterior del desarrollo, lo que lo obliga a modificar la arquitectura agregando de esta manera inestabilidad y un posible conjunto de comportamientos no deseados.
La idea es hacer que funcione toda la solución y solo entonces, cuando todos los requisitos estén arreglados e implementados, ajuste el código. Verá entonces que muchas optimizaciones que habría implementado de manera alegre a la vez mientras codifica, ya no son factibles debido a la interacción con los requisitos tardíos.
El espacio real de la solución siempre es mayor que el que esperamos al principio porque no podemos tener un conocimiento perfecto de un sistema muy complejo.
Haz que funcione primero. Luego apriete las cuerdas.
fuente
En resumen, la optimización temprana se convierte en un esfuerzo desperdiciado si desea cambiar las cosas más tarde, y luego resulta que ha optimizado las estructuras de código fácilmente cambiables en un nivel mucho más bajo, y ahora necesita volver a cambiarlo a un nivel alto enfoque de nivel y optimizar el resultado una vez más.
Este es un error común para los desarrolladores novatos a quienes les gusta enfocarse en obtener placer de "haber hecho un trabajo útil", como la optimización, no pensar si es el momento adecuado para hacerlo. A medida que adquiera experiencia en la programación de grandes proyectos como juegos, aprenderá cuándo se justifica optimizar la base de código existente y cuándo es demasiado pronto. No tenga miedo de cometer este error, solo se beneficiará al aprender de él.
En general, solo optimice si realmente no puede trabajar con la construcción de desarrollo en este momento. Como si estás creando y eliminando millones de objetos 60 veces por segundo.
Por lo tanto, diría que es bueno, en términos de experiencia de aprendizaje, optimizar temprano algunas veces: p
fuente
La optimización se centra en hacer que la computadora funcione mejor en el código, mientras que el desarrollo requiere que el programador funcione mejor en el código.
La optimización no aporta ideas. Hace que la computadora funcione menos y el programador más.
Por supuesto, hay diferentes categorías, como diseñar un automóvil. No hay nada de malo en optimizar un motor antes de construir su primer chasis, pero optimizar el chasis antes de que no sepa la forma del motor puede terminar siendo una pérdida de tiempo. La modularidad y las especificaciones pueden obtener varios lugares viables para el trabajo de optimización incluso antes de que se ensamble el producto en su conjunto.
fuente
Estoy totalmente en desacuerdo con todas esas declaraciones de que el código no debe optimizarse en las primeras etapas. Depende de en qué etapa te encuentres. Si este es el prototipo MVP y solo estás tratando de ver el juego que lleva de 1 a 2 semanas, estás listo para reescribir todo lo que ya escribiste. Sí, la optimización no importa. Pero si ya está trabajando en un juego que sabe que se lanzará, debería tener un código optimizado todo el tiempo. Los cuentos que la gente dice sobre nuevas características y cosas que podrían agregarse son conceptos erróneos. Es una arquitectura de código mal diseñada en lugar de un código optimizado. No necesita reescribir nada para agregar nuevos elementos si tiene un buen diseño de código.
Por ejemplo, si tiene un algoritmo de búsqueda de ruta A *, ¿no sería mejor escribirlo de la manera más óptima posible? ¿En lugar de cambiar más tarde la mitad del código que tiene porque tuvo que hacer algunos cambios en el algoritmo porque ahora necesita otro método de llamadas y devoluciones de llamada? Y si ya tiene un código optimizado desde el principio, le ahorrará mucho tiempo. Debido a que puede establecer relaciones entre los objetos y cómo interactúan, en lugar de crear a ciegas toneladas de nuevos scripts y hacer todas las conexiones de inmediato, esto conduce a un código sphagetti poco claro.
Lo último que quiero agregar es que más tarde, incluso si ya no quieres hacer el juego, tienes tu algoritmo A * optimizado que puedes usar para tus próximos juegos. Reusabilidad Por ejemplo, muchos juegos tienen inventario, búsqueda de caminos, generación de procedimientos, interacciones entre npc, sistema de lucha, IA, interacción de interfaz, gestión de entrada. Ahora debes preguntarte: "¿Cuántas veces he reescrito esos elementos desde cero?" Son el 70-80% del juego. ¿Realmente necesitas reescribirlos todo el tiempo? ¿Y qué pasa si no son optimizados?
fuente