¿Por qué MVC y TDD no se emplean más en la arquitectura del juego? [cerrado]

155

Prefiero esto diciendo que no he visto una gran cantidad de fuente de juego, ni he construido mucho en el camino de los juegos.

Pero al tratar de emplear prácticas de codificación 'empresariales' en aplicaciones web, mirar el código fuente del juego me duele mucho la cabeza: "¿Qué está haciendo esta lógica de vista con la lógica de negocios? Esto necesita ser refactorizado ... así que esto, refactor, refactorrr "

Esto me preocupa cuando estoy a punto de comenzar un proyecto de juego, y no estoy seguro de si intentar hacer mvc / tdd el proceso de desarrollo nos va a obstaculizar o ayudar, ya que no veo muchos ejemplos de juegos que usen esto o mucho impulso para mejores prácticas arquitectónicas en la comunidad.

Lo siguiente es un extracto de un gran artículo sobre juegos de prototipos , aunque para mí parecía exactamente la actitud que muchos desarrolladores de juegos parecen usar al escribir el código de producción del juego:

Error # 4: construir un sistema, no un juego

... si alguna vez te encuentras trabajando en algo que no te mueve directamente hacia adelante, detente allí. Como programadores, tenemos la tendencia a tratar de generalizar nuestro código, hacerlo elegante y poder manejar cada situación. Encontramos que una picazón es terriblemente dura, no se rasca, pero necesitamos aprender cómo. Me llevó muchos años darme cuenta de que no se trata del código, sino del juego que envías al final.

No escriba un elegante sistema de componentes del juego, omita el editor por completo y conecte el estado del código, evite la locura basada en datos, el auto-análisis, XML, y simplemente codifique la maldita cosa.

... Solo obtén cosas en la pantalla lo más rápido que puedas.

Y nunca, nunca, use el argumento "si nos tomamos un tiempo extra y hacemos esto de la manera correcta, podemos reutilizarlo en el juego". SIEMPRE.

es porque los juegos están orientados visualmente (en su mayoría), por lo que tiene sentido que el código tenga un gran peso en la vista, por lo tanto, cualquier beneficio de mover cosas a modelos / controladores es bastante mínimo, entonces ¿por qué molestarse?

He escuchado el argumento de que MVC introduce una sobrecarga de rendimiento, pero esto me parece una optimización prematura, y que habría problemas de rendimiento más importantes que abordar antes de preocuparse por los gastos generales de MVC (por ejemplo, canalización de procesamiento, algoritmos de inteligencia artificial, estructura de datos transversal, etc.

Lo mismo con respecto a TDD. No es frecuente que vea juegos que emplean casos de prueba, pero tal vez esto se deba a los problemas de diseño anteriores (vista mixta / negocio) y al hecho de que es difícil probar componentes visuales o componentes que dependen de resultados probablísticos (por ejemplo, operar dentro de simulaciones físicas). )

Quizás solo estoy mirando el código fuente incorrecto, pero ¿por qué no vemos más de estas prácticas 'empresariales' empleadas en el diseño de juegos? ¿Los juegos son realmente tan diferentes en sus requisitos, o es un problema de personas / cultura (es decir, los desarrolladores de juegos provienen de un entorno diferente y por lo tanto tienen diferentes hábitos de codificación)?

timoxley
fuente

Respuestas:

137

Como dice la cita, muchos programadores cometen el error de (intentar) construir un sistema, no un juego. Típicamente, ese sistema se mantiene fuera de control hasta que es tan complejo que teóricamente puede manejar cualquier cosa, pero en la práctica todo lo que tiene es un gran paquete de código. O más a menudo, incluso antes de llegar a una etapa de trabajo, estás tan enredado en el código que no se ejecuta que pierdes el enfoque (si es que tenías algo para comenzar) y la motivación (ya que nada funciona realmente).

Los prototipos y la iteración tienden a funcionar mucho mejor. Al final, puede salir un gran diseño, pero con mayor frecuencia sale algo más simple y refinado. KISS y YAGNI vienen a la mente.

Personalmente, creo que debe haber un equilibrio. Si hay una mecánica básica de tu juego, trabaja en ello. Todavía necesita iterar, pero necesita refinarlo. Sugerencia: la organización de tu código no es una mecánica central de tu juego.

Caso en cuestión: Peggle , de PopCap Games. Una mecánica central del juego es la física de la pelota. ¡Lo perfeccionaron! Estoy seguro de que pasaron mucho tiempo asegurándose de que fuera absolutamente perfecto, porque eso es lo que hace que el juego. Pero al mismo tiempo, puedo imaginarme un prototipo temprano de su juego que tal vez solo dibuja sprites en la pantalla y hace algún tipo de detección de colisión más primitiva y rebote, solo para ver si la idea del juego es divertida. Luego, una vez que descubrieron que disparar una pelota y verla rebotar puede ser realmente divertido, refinaron el rebote de la pelota. (esto es solo especulación, por supuesto)

También depende de tus requisitos técnicos, que debes determinar desde el principio (no el diseño de tu juego, solo los requisitos técnicos). La plataforma en la que se ejecuta tu juego no debe cambiar, o si se debe permitir que cambie, debes saber exactamente en qué medida planeas permitir que cambie, ni más ni menos. Diseño sobre eso. Si estás desarrollando un juego para OpenGL y no te importa DirectX, entonces realmente no te importa. Eso significa que si es más conveniente para usted que cada entidad se dibuje sola y no se preocupe por las Fábricas y otros patrones de diseño como ese, entonces haga eso. Está bien, porque cumple con los requisitos. No deberías tener que cambiarlo más tarde, a pesar de lo que te digas a ti mismo. Y realmente, ¿el peor de los casos? Refactorizar más tarde., obtener un juego que funcione en una plataforma, incluso si eso significa que no puede ejecutarse de manera simultánea y automática en su tostadora.

Sin embargo, el diseño basado en pruebas es un tema más testarudo. Creo que los desarrolladores de juegos deberían hacer más. También creo que los desarrolladores de juegos tienen algunos de los horarios más rigurosos y ajustados, y piensan que no pueden darse el lujo de pasar tiempo en TDD cuando solo quieren poner en marcha un juego. Además, nuevamente con la motivación, TDD es mucho más lento y puedes ver mucho menos un juego funcional (al menos al principio). Esto puede tener serios efectos negativos en la motivación del programador.

Creo que también es solo una falta general de conocimiento y práctica. No creo que TDD sea frecuente en otras áreas tampoco, pero al igual que el desarrollo ágil, creo que se está extendiendo. Se podría decir que está adelantado a su tiempo (o tal vez no, ya que el caso puede ser dentro de unos años). Más importante que TDD es "RDD" - Desarrollo dirigido por requisitos. Acabo de inventarlo.¿Cuál es tu objetivo? Para hacer un juego. Todo lo demás viene en segundo lugar. Si puede probar que TDD aumenta la productividad y ayuda a los equipos a cumplir con los plazos, ¿no cree que todos lo estarían usando? Y tal vez ese es el caso. Pero en este momento, nuestra industria es más competitiva que nunca, hay plazos más duros y más cortos, y las cosas solo necesitan funcionar. Los trabajadores de la construcción no construyen andamios primero; colocan una base, luego levantan algunas paredes y pisos, y solo entonces construyen pedazos de andamios selectivos para realizar tareas específicas que los andamios hacen más convenientes. Creo que lo mismo se aplica al desarrollo de software.

Disculpa por la larga publicación. Espero que hayas adquirido un poco de sabiduría. Solo soy un estudiante, hablando de mis observaciones, con una experiencia muy limitada en la industria pero mucha lectura de expertos de la industria. Así que toma mis palabras con un grano de sal.

Y oye, haz lo que creas que funcionará. Siempre puedes cambiarlo o desecharlo y comenzar de nuevo. Eso es lo bueno de cualquier forma de ingeniería; Si al principio no tienes éxito, prueba algo diferente. (o algo así :-P) No estás vertiendo hormigón; El software es maleable.


Por cierto, he estado haciendo este mismo tipo de pregunta e investigando este tipo de principios de diseño durante algún tiempo. Aquí hay algunas preguntas, tanto aquí como en Stack Overflow, que puede encontrar relevantes:

Ricket
fuente
32

Aquí está mi respuesta original a una pregunta similar sobre SO desde hace un tiempo, al menos en relación con la parte MVC de su pregunta:

Raramente se usa en juegos. Me tomó un tiempo entender por qué, pero aquí están mis pensamientos:

MVC existe para hacer una distinción entre dos representaciones. El modelo es la representación abstracta de sus datos. Así es como la máquina ve el estado de su aplicación. La Vista (y los Controladores) representan una instanciación visible más concreta de ese sistema de una manera significativa para los humanos.

En la mayoría de las aplicaciones de negocios, estos dos mundos son bastante diferentes. Por ejemplo, el modelo de una hoja de cálculo es simplemente una cuadrícula de valores 2D. No tiene que pensar en qué tan anchas son las celdas en píxeles, dónde están las barras de desplazamiento, etc. Al mismo tiempo, la vista de hoja de cálculo no sabe cómo se calculan o almacenan los valores de las celdas.

En un juego, esos dos mundos están mucho más cerca uno del otro. El mundo del juego (modelo) suele ser un conjunto de entidades ubicadas en algún espacio virtual. La vista del juego también es un conjunto de entidades ubicadas en algún espacio virtual. Los volúmenes limitados, la animación, la posición, etc., todas las cosas que consideraría parte de la "vista" también son utilizadas directamente por el "modelo": la animación puede afectar la física y la IA, etc.

El resultado final es que la línea entre el modelo y la vista en un juego sería arbitraria y no sería útil: terminarías duplicando mucho estado entre ellos.

En cambio, los juegos tienden a desacoplar las cosas a lo largo de los límites del dominio: AI, física, audio, renderizado, etc. se mantendrán lo más separados posible.

munificente
fuente
20

Porque MVC no encaja en la arquitectura de un juego. El flujo de datos para un juego es completamente diferente al de una aplicación enterprice, porque no está tan orientado a eventos y a menudo hay un presupuesto (muy) ajustado de milisegundos para realizar estas operaciones. Hay muchas cosas que deben suceder en 16,6 milisegundos, por lo que es más beneficioso tener una tubería de datos 'fija' y rígida que procese los datos que necesita en la pantalla exactamente en ese momento.

Además, la separación está ahí; la mayoría de las veces no está conectado de la misma manera que el patrón MVC. Hay un motor de renderizado (Ver), manejo de entrada del usuario (Controlador) y el resto, como lógica de juego, ai y física (Modelo). Piénsalo; si está buscando la entrada del usuario, ejecutando el ai y renderizando la imagen 60 veces por segundo, entonces ¿por qué necesitaría un Observador entre el modelo y la vista para decirle qué ha cambiado? No interpretes esto como si dijera que no necesitas el patrón Observador en los juegos, sí, pero en este caso realmente no lo necesitas. Estás haciendo todo ese trabajo, cada cuadro, de todos modos.

Aunque TDD casi nunca se usa en estudios de desarrollo, sí utilizamos prácticas ágiles para el desarrollo de software y SCRUM parece ser la opción popular al menos aquí en Europa. La razón es simple, los cambios vienen de todas partes. Los artistas pueden querer más presupuesto de textura, mundos más grandes, más árboles, mientras que los diseñadores quieren una historia más rica (más contenido en el disco), un mundo de transmisión y los editores quieren que termines a tiempo y dentro del presupuesto, al igual que el departamento de marketing. Y aparte de eso, el "estado del arte" sigue cambiando rápidamente.

Eso no significa que tampoco hagamos pruebas, la mayoría de los estudios tienen grandes departamentos de preguntas y respuestas, ejecutan un montón de pruebas de regresión y realizan pruebas unitarias de forma regular. Sin embargo, casi no tiene sentido hacer pruebas unitarias por adelantado porque una gran parte de los errores están relacionados con el arte / gráficos (agujeros en mallas de colisión, texturas incorrectas, falla en la profundidad del sombreador de campo) que las pruebas unitarias no pueden cubrir. Y además del código de trabajo, el factor más importante de cualquier juego es que es divertido y no hay una unidad que lo pruebe.

También recuerde que en el mundo de las consolas esto es aún diferente, porque está programando más para el hardware que para cualquier otra cosa. Esto generalmente (PS2 / PS3) significa que el flujo de datos es mucho más importante que el flujo del código en casi todos los casos; debido a consideraciones de rendimiento. Lo que anula el uso de TDD como herramienta arquitectónica en la mayoría de los casos. Un buen código OOP generalmente tiene un flujo de datos incorrecto, lo que dificulta la vectorización y la paralelización.

Jasper Bekkers
fuente
13

¿Por qué MVC y TDD no se emplean más en la arquitectura del juego?

Advertencia: opinión por delante.

MVC no se usa (mucho) porque:

  1. MVC es un enfoque relativamente nuevo y los juegos generalmente se basan en código antiguo. La mayoría de las personas que crean aplicaciones MVC las crean desde cero cada vez. (Sé que MVC en sí tiene décadas de antigüedad; lo que es nuevo es el interés generalizado en él, que esencialmente proviene de aplicaciones web como RoR). En el software de negocios en el que trabajé que estaba basado en código heredado, tampoco había uso para MVC allí. Es una cuestión de cultura, pero no es específica del juego.
  2. MVC es esencialmente un patrón GUI para programas controlados por eventos. Los juegos no están dominados por GUI ni por eventos, por lo tanto, la aplicabilidad no es tan buena como lo es para las aplicaciones web u otras aplicaciones basadas en formularios. MVC es típicamente el patrón de Observador con algunos roles bien conocidos, y los juegos a menudo no tienen el lujo de esperar para observar algo interesante: tienen que actualizar todo cada cuadro (o alguna variación sobre eso), ya sea que alguien haya hecho clic o no. .

Eso no quiere decir que los juegos no puedan aprender mucho de MVC. Siempre trato de separar el modelo de la vista en los juegos que hago. Sin embargo, la idea tradicional de que la vista y el controlador son 2 partes del mismo objeto (widget) realmente no funciona, por lo que debe ser un poco más abstracto al respecto. Estoy de acuerdo con usted en que es poco probable que el rendimiento sea un problema real aquí. En todo caso, el rendimiento puede beneficiarse al mantener separadas las cosas visuales y las lógicas, ya que es más susceptible a la coherencia de caché, paralelismo, etc.

TDD no se usa (mucho) porque:

  1. Es realmente incómodo de usar en juegos. Una vez más, está bien para el software controlado por eventos en el que las entradas entran y salen, y puedes comparar lo que viste con lo que esperabas y marcarlo como correcto. Para simulaciones con grandes cantidades de estado compartido, es significativamente más incómodo.
  2. No hay evidencia indiscutible de que ayude en algo. Solo una gran cantidad de reclamos, y algunas cifras a menudo se basan en autoinformes y apelaciones a la autoridad. Quizás ayude a los programadores pobres a volverse mediocres pero frena a los buenos programadores. Quizás el tiempo dedicado a escribir pruebas podría emplearse mejor aprendiendo principios SÓLIDOS, o diseñando la interfaz correcta en primer lugar. Tal vez da una falsa sensación de seguridad tener pruebas que pasan sin ninguna prueba real de que tiene suficientes pruebas para garantizar que su objeto haga lo correcto.

Nuevamente, como advertencia, creo que las pruebas unitarias son excelentes, pero no creo que "probar primero" sea beneficioso o sensato. Tampoco creo que sea práctico probar la simulación principal cuando hay tanto cambio de estado compartido muchas veces por segundo. Limito mis pruebas a mi bajo nivel y código de biblioteca, en general.

Sin embargo, como probablemente pueda adivinar, estoy muy predispuesto en contra de las "prácticas de codificación de" empresa ", ya que las empresas son conocidas por exceder los plazos y presupuestos. "¡También los desarrolladores de juegos!" Te escucho decir, bueno, sí. No creo que nadie sepa realmente la mejor manera de desarrollar software en este momento y no estoy convencido de que la adopción de prácticas reglamentadas en el software convencional esté en absoluto un paso adelante de las prácticas más libres en el software de entretenimiento. De hecho, sospecho que es principalmente beneficioso para aquellos que confían en los programadores de productos básicos de Java, donde estos enfoques no son una escalera para subir a mayores alturas, sino una red de seguridad para evitar que caigan demasiado bajo.

Kylotan
fuente
9

Como señala Kylotan, "en los juegos no se puede tratar el aspecto de la presentación como un concepto desmontable y reemplazable como HTML y CSS para aplicaciones web". Después de haber creado un par de juegos usando un patrón MVC simple (no un gran marco), he descubierto que el principal problema es que su modelo necesita saber acerca de su vista. Es muy probable que necesite usar datos de mapa de bits de sprite, datos de hitbox o datos de geometría 3D de sus activos de arte para ayudar a resolver la detección de colisiones (u otra tarea similar). Esto significa que cada modelo necesita una referencia a su vista, lo que rompe el patrón MVC clásico; por ejemplo, ya no puede crear una nueva vista para un modelo existente, etc.

El modelo de componente que ve en, por ejemplo, Unity3D es la mejor manera de organizar el código del juego.

Iain
fuente
4

MVC, en algunos niveles, ya se usa en el desarrollo de juegos. Es forzado por el sistema operativo, que tiene diferentes interfaces para entrada y gráficos. La mayoría de los juegos también tienen algunas instancias más de MVC, por ejemplo, separando la física y los hilos de renderizado y entrada. Esto funciona bien La idea moderna de MVC parece ser que debe repetirse, fractalmente, hasta que ya nadie pueda entender el código. Los juegos no hacen eso, afortunadamente.

TDD no se usa porque rara vez se sabe que un juego "se supone que debe hacer" antes de repetir un prototipo muchas veces. Las prácticas de TDD, como las pruebas continuas o las pruebas de integración, a menudo se usan en el desarrollo de juegos.


fuente
3

Los sistemas de juego se están moviendo lentamente hacia mejores prácticas. Los marcos como XNA proporcionan una idea de cómo hacer que el código sea más generalizado / limpio sin agregar demasiada sobrecarga en el diseño o el tiempo de ejecución. Pero, en general, diría que los sistemas de juego tienen que ver con la optimización de la complejidad frente a la velocidad de ejecución, todo mientras se mantiene un cronograma de desarrollo ajustado y se mantiene motivado. La aplicación de conceptos de ingeniería de software y diseño de sistemas simplemente no es la prioridad n. ° 1 en dicho entorno.

En mis proyectos de juegos personales, trato de comentar el código o al menos hacerlo legible, y organizo sistemas que permitirán un poco más de flexibilidad más adelante (es decir, generalidad) tanto como sea posible, pero al final del día, si no has movido tu juego hacia adelante, simplemente no se siente muy bien.

Por lo general, cuando terminas el juego, tienes al menos 1000 ideas sobre cómo mejorar la mecánica subyacente, los sistemas principales, etc., de tal manera que muy poco de ese código "reutilizable" Realmente sea utilizable. Durante el día trabajo regularmente en SE, y aunque los sistemas en los que trabajamos pueden ser enormes, sinceramente, creo que palidecen en comparación con la complejidad de los juegos.

Deleter
fuente
2

No tengo una opinión particular sobre MVC, aparte del hecho de que la vista a menudo está separada de la lógica por el simple hecho de que el bucle de renderizado está empaquetando un montón de cosas para que algún hardware procese y ese no es el lugar donde quieres "juego lógica "que ocurre simultáneamente. El "controlador" también está separado por hardware, pero desafortunadamente muchos, si no la mayoría de los desarrolladores de juegos hacen un trabajo "interesante" en el controlador del controlador. (OMI, el controlador del controlador debería leer los botones y palos y crear una "presentación" para que el juego lo vea, pero mi caja de jabón no es tan fuerte).

TDD, por otro lado, es algo sobre lo que tengo opiniones muy fuertes. Simplemente cambia el desarrollo de una manera que produce software que es más fácil de construir. Es más difícil de hacer, sin duda. Por supuesto, dado que es más difícil de hacer, no se hace. Algunas personas se quejan de que TDD (o, en general, las pruebas unitarias) no tienen valor porque "el juego es la prueba", pero el hecho es que en TDD, la prueba es casi irrelevante. El punto de TDD es el diseño y la arquitectura del software que surge del proceso.

Abrazando TDD realmente cambia el enfoque de uno a la programación. Tenía algunos sentimientos acerca de lo que estaba bien y lo que estaba mal antes de comenzar a recorrer el camino TDD, pero una vez que salté con los dos pies, realmente entendí mucho más sobre cómo las cosas que estaba haciendo estaban ayudando u obstaculizando el desarrollo futuro . De hecho, este es el punto detrás de la publicación de la sala de códigos, TDD sin la t .

Volviendo a por qué no se usa más en los juegos, más allá de ser difícil, hace que las personas se den cuenta de que la forma en que siempre lo han hecho en el pasado innecesariamente hizo que sus propios trabajos fueran más difíciles, y para los programadores, especialmente, es una píldora amarga incluso para mirar, Mucho menos tragar.

Estoy convencido de que las personas que se niegan a aceptar TDD simplemente no quieren ser mejores programadores. Ya piensan que son "excelentes" en programación, diseño o arquitectura, cuando en realidad su código dice algo completamente diferente.

dash-tom-bang
fuente