Principio de KISS en desarrollo

El próximo informe de Pixonic DevGAMM Talks, que hemos descifrado, es un poco filosófico: este es un discurso de Konstantin Gladyshev. Fue el Programador principal de juegos en 1C Game Studios y habló sobre el principio de administrar la complejidad del desarrollo en el contexto de todo el producto, y no de las características individuales. Y con ejemplos, mostró por qué lo principal en el desarrollo es determinar qué no se debe hacer. Para otros informes, lea los enlaces al final del artículo.


Quería hablar sobre el norte, pero decidí hacer un informe filosófico sobre lo que debería hacerse más fácilmente. Trabajé en Postal III, Indestructible, War Robots y actualmente estoy haciendo Calibre, un juego de disparos en línea de 1C y Wargaming.



¿Por qué decidimos hablar sobre KISS (Mantenlo simple, estúpido)? Porque incluso las personas mayores con 20 años de experiencia o CTO a menudo continúan esculpiendo e inventando algo. Pero necesitas hacerlo más fácil. De hecho, hay más sobre YAGNI (no lo vas a necesitar) y un poco de filosofía.

Debo decir de inmediato que no estamos hablando de soluciones completamente idiotas, como "encontrar x", estamos hablando de soluciones más o menos simples.



¿Por qué a veces es demasiado difícil? Todo comienza con buenas intenciones y, como saben, conducen al infierno. Aquí hay una tira cómica sobre esto.



Las razones para esto son aproximadamente las mismas, pero las llamé de manera diferente:

  • Soluciones universales . Hay algún tipo de característica e inmediatamente hacemos una biblioteca, un millón de casos adicionales. ¿Y de repente nuestro tirador se convertirá en una granja? O "la próxima vez haré otro exactamente el mismo tirador". Es poco probable que lo más probable sea que cambie para usted.
  • Prueba de futuro . Casi lo mismo: estos son problemas inexistentes. "Y si tengo un millón de usuarios de inmediato, ¿tengo que soportar 22 servidores intermedios?" etc. Para comenzar a ganar, un servidor es suficiente para ti.
  • Usando las herramientas equivocadas . Cuando usa herramientas que no encajan y persisten en su engaño.
  • Y todos conocen la optimización prematura .

Teníamos un ejemplo cuando hicieron Calibre. Los chicos que nos estaban ayudando decidieron hacer inmediatamente un superserializador en el último C ++.

Como resultado, no funcionó como se deseaba, fue inconveniente enviar un estado parcial, porque las plantillas realmente no entienden dónde es necesario, dónde no lo es, o si hace algunos indicadores. Los errores que estaban en este código repetitivo, incluso el autor no entendió con el tiempo.



Luego, uno de los programadores en solo dos horas reescribió todo esto en una página de código C, que hizo justo lo que necesitábamos en ese momento. Y funcionó maravillosamente.

Otro ejemplo. Teníamos Postal III y fue hecho en el motor Source. Hay un mundo tan abierto que puedes caminar entre mapas, una cámara en tercera persona, muchas casas de un piso de estilo americano con ventanas, los robots pueden correr y entrar en pánico abriendo puertas. Como resultado, todo el BSP no funcionó. Se consideró durante mucho tiempo, debido a las ventanas, resultó un millón de sectores y todavía no hizo nada. Tomó mucha memoria y se cargó durante mucho tiempo.



Half-Life, para el que se fabricó el motor, es un juego de disparos en primera persona, y desde el tercero fue inconveniente hacer algunas cosas. Todo lo útil de Half-Life no nos convenía en absoluto. Además, se suponía que se debía realizar una gran cantidad de animación, porque desde una tercera persona debes escalar, etc. Era necesario cambiar el motor, pero no había opción.

¿Qué hacer cuando todo es malo, difícil, pero nos empujan? En primer lugar, hacer las funciones en el orden correcto, porque la optimización anticipada es uno de los problemas. Algunos comienzan a pegar strassiks antes de coser el vestido, y luego no pueden coser, porque los straziks interfieren.

Primero, haga el chip más simple para que simplemente funcione, luego estabilícelo y luego optimice. Es en este orden que todo lo demás está mal.



Por visualización, entendemos que es mínimamente operativo, es decir MVP (producto mínimo viable).



Luego evalúas su potencial. Supongamos que los diseñadores de juegos presentan funciones, el programador recurre y dice: "Lo haré bien, no lo haré mal, así que dibuje inmediatamente un diseño de juego funky". ¿Pero cómo lo sabe? No jugó, no sabía si era bueno o malo. Por lo tanto, idealmente, haces una función, juegas, si es normal, luego hazlo más. No es normal, descartado, no es una pena.

Hace mil años, Sun Tzu dijo que ganar 100 batallas no es el pico, el pico es ganar sin una batalla. Es decir no hagas lo que no puedes hacer.

Estabilización Ha realizado funciones y estabilizarlas aún más sin adiciones innecesarias. ¿Necesitas una rueda en un árbol, en una cuerda? Esta colgando. Nada mas.



En consecuencia, si de repente se descubrió (sin ninguna prueba futura) que la característica debería cambiar, comience nuevamente. Solo prototipo, estabilícese y no intente adivinar. Aún no lo adivinarás.

Bueno, optimización prematura. Esto siempre es malo. Debe optimizar al final, cuando sepa con certeza que esta característica es importante, debe optimizarse y no cambiará fundamentalmente en el futuro cercano.



Porque la optimización es un conjunto de casos especiales. La legibilidad del código empeora, las abstracciones se rompen y la portabilidad, como regla, también empeora enormemente.



Esta es una diapositiva provocativa, porque las muletas son realmente malas. Pero aquí se muestra la situación cuando hay un montón de características y prototipos aburridos, todo está mal y parece que todo colapsará. Pero esto no es así. Mire, este es el encofrado, se vierte hormigón sobre él y las "muletas" se sostienen mientras se seca. Es decir la situación es absolutamente normal, las "muletas" serán removidas, pero no inmediatamente, sin pánico.

Brevemente sobre filosofía. No hay soluciones universalmente válidas. No intente crear un marco con 100 años de anticipación o para todas las ocasiones.



Es mejor hacer muchas piezas pequeñas que hagan bien su trabajo. Deseche lo innecesario lo antes posible, no intente apoyarlo. Y al escribir código, explíquelo. A veces es mejor escribir código explícito que serializas con tus manos, en lugar de reflexionar u otra cosa. Usar una acción de dependencia cuando no la necesita también es una mala idea. Es muy difícil de leer, la mitad de los errores en tiempo de ejecución. Explícito es mejor que implícito. Y haga que sea lo más simple posible para evitar errores cuando alguien no entiende algo o incluso se olvida por completo.

Como dijo Bruce Lee, la simplicidad es el más alto grado de arte. Una vez, un actor a quien le enseñó su Jeet Kune-Do le preguntó: "¿Cuál es la esencia de tu arte marcial Jeet Kune-Do?" En ese momento, Bruce Lee dejó caer su billetera, el actor la recogió y Bruce Lee dijo: "Ves, simplemente te agachaste y recogiste la billetera, y si te pararas en la pose de un jinete, hiciste kata, nunca la hubieras levantado".

Preguntas de la audiencia


"Dijiste que la optimización prematura es malvada". ¿Vale la pena escribir pruebas prematuras cuando un proyecto recién comienza?

- En mi opinión, todo lo prematuro es dañino. En las pruebas, no soy muy fuerte, porque en el desarrollo del juego (en muchos casos), las pruebas están más cerca del final del desarrollo. Al principio, todo cambia tan rápido que mientras escribes una prueba, el diseñador del juego ya lo cambiará todo. Creo que es malo gastar energía en una prueba de lo que cambiará en dos horas. Esto debe hacerse en la etapa de estabilización. Pero no en la etapa de prototipo. Pero si el equipo puede escribir pruebas rápidamente, esto probablemente sea bueno. Si no, entonces no.

- Usted mencionó que se quitarán las muletas, pero hay una tesis maravillosa: no hay nada más permanente que temporal. Todos trabajamos en desarrollo de juegos, tenemos plazos, productores, luego una nueva característica, etc. ¿Con qué frecuencia has visto una situación en la que estabas limpiando muletas? ¿Y los llevaron a cero?

- Probablemente no a cero. Si el proyecto está en vivo, siempre tendrá algunas muletas. Todo funciona si se limpian sistemáticamente. Es decir Hiciste una función, inmediatamente grabada.

- I.e. ¿Se debe construir un cierto proceso en la empresa? ¿Tipo de fase oficial de limpieza de muletas?

- Sí, creo que esto debería incluirse en la tarea. Es decir si necesita refactorizar en el proceso de la tarea, refactorice. Hablando en términos generales, incluso la palabra refactorización no lo es, está dentro de la tarea.

- ¿Logras hacer esto en la práctica? Usted viene al productor y le dice al planear una nueva iteración que necesitamos dos semanas para limpiar, refactorizar, etc. Y dice que el valor del negocio es cero, ahora presentamos la función x, y luego la limpiará más tarde en la noche después del trabajo. ¿Cómo estar en esta situación?

- Lo logramos. El productor es consciente de que hay algunas deudas que está corrigiendo, pero de manera oportuna. No es que tenga una nueva versión, no tiene una sola característica nueva, pero aquí hay algún tipo de refactorización. Simplemente elija el productor correcto.

"Con la experiencia, llega la comprensión, cuanto más simple, mejor". Pero los programadores novatos intentan crear sistemas complejos, aterradores, grandes y gigantescos. Pregunta: ¿cómo mantenerlos alejados de esto, excepto por un duro "no"?

- Creo que este es un problema de aprendizaje. Es necesario mostrar lo antes posible qué soluciones funcionan, cuáles no y por qué. Cuando tenga experiencia y pueda explicar por qué no necesita hacer esto, solo puede dar muchos ejemplos y ya funciona bien. Para mostrar y monitorear constantemente con su propio ejemplo para que todo sea simple. Póngase prototipos para que reescriban más a menudo: cuando reescribe a menudo, no tiene ganas de escribir mucho y escriben cada vez más simple.

- Si ya hay algo muy complicado que se usa en varios proyectos, y esta complejidad ya no ayuda, sino que interfiere, ¿qué tan fácil es cambiar a soluciones simples?

- Mi opinión es, simplemente comienza a hacerlo de nuevo. Idealmente, un equipo separado, desde cero. Lo más probable es que recupere el 80% de la funcionalidad muy rápidamente. En una biblioteca nueva y limpia. Y luego te pondrás al día.

- Por ejemplo, hay un poderoso serializador y editor de lógica de juegos, ahora está bastante desactualizado ...

- Estas son las mismas herramientas inconvenientes. Tómatelo cómodo. Unidad, por ejemplo.

- Dime, ¿cuál es tu planificación en el código, qué tan detallado es? ¿El programador principal resuelve todos los problemas menores, todas las tareas?

- Tenemos tal anarquía, una estructura bastante plana, no mucha gente. Confiamos en todos y simplemente distribuimos quién tomará el prototipo y quién no. Puede ser cualquier persona arbitraria.

Más conversaciones con Pixonic DevGAMM Talks


Source: https://habr.com/ru/post/es427797/


All Articles