Le prochain entretien avec Pixonic DevGAMM Talks, que nous avons déchiffré, est un peu philosophique - il s'agit d'un discours de Konstantin Gladyshev. Il était le principal programmeur de jeux chez 1C Game Studios et a parlé du principe de gestion de la complexité du développement dans le contexte de l'ensemble du produit, plutôt que des fonctionnalités individuelles. Et avec des exemples, il a montré pourquoi l'essentiel du développement est de déterminer ce qui ne doit pas être fait. Pour d'autres rapports, veuillez lire les liens à la fin de l'article.
Je voulais parler du Nord, mais j'ai décidé de faire un rapport philosophique sur ce qui devrait être fait plus facilement. J'ai travaillé sur Postal III, Indestructible, War Robots et je fais actuellement Calibre, un jeu de tir en ligne de 1C et Wargaming.

Pourquoi avons-nous décidé de parler de KISS (Keep it simple, stupid)? Parce que même les seniors avec 20 ans d'expérience ou CTO continuent souvent de sculpter et d'inventer quelque chose. Mais vous devez le faire plus facilement. En fait, il y a plus sur YAGNI (vous n'en aurez pas besoin) et un peu de philosophie.
Je dois dire tout de suite que nous ne parlons pas de solutions complètement idiotes, comme «trouver x», nous parlons de solutions plus ou moins simples.

Pourquoi est-ce parfois trop difficile? Tout commence par de bonnes intentions et, comme vous le savez, mène à l'enfer. Voici une bande dessinée à ce sujet.

Les raisons en sont à peu près les mêmes, mais je les ai appelées différemment:
- Solutions universelles . Il y a une sorte de fonctionnalité et nous en faisons immédiatement une bibliothèque, un million de cas supplémentaires. Et puis soudain notre tireur va se transformer en ferme? Ou "la prochaine fois, je ferai un autre exactement le même jeu de tir." Il est peu probable que cela change pour vous.
- Preuve d'avenir . Presque la même chose - ce sont des problèmes inexistants. "Et si j'ai un million d'utilisateurs tout de suite, dois-je supporter 22 serveurs intermédiaires?" etc. Pour commencer à gagner, un serveur vous suffit.
- Utiliser les mauvais outils . Lorsque vous utilisez des outils qui ne correspondent pas et qui persistent dans votre illusion.
- Et tout le monde connaît l' optimisation prématurée .
Nous avons eu un exemple quand ils ont fait Calibre. Les gars qui nous aidaient ont alors décidé de faire immédiatement un supersérialiseur dans le dernier C ++.
En conséquence, cela n'a pas fonctionné comme souhaité, il n'était pas pratique d'envoyer un état partiel, car les modèles ne comprennent pas vraiment où cela est nécessaire, où il ne l'est pas, ou si vous créez des indicateurs. Les bogues qui étaient dans ce code passe-partout, même l'auteur n'a pas compris au fil du temps.

Ensuite, l'un des programmeurs en seulement deux heures a réécrit tout cela sur une seule page de code C, ce qui a fait exactement ce dont nous avions besoin à ce moment-là. Et cela a fonctionné à merveille.
Un autre exemple. Nous avions Postal III et il a été fait sur le moteur Source. Il y a un tel monde ouvert, vous pouvez vous promener entre les cartes, une caméra à la troisième personne, de nombreuses maisons à un étage de style américain avec des fenêtres, des robots peuvent courir et paniquer les portes ouvertes. En conséquence, l'ensemble du BSP n'a pas fonctionné. Il a été considéré pendant très longtemps, à cause des fenêtres, il s'est avéré un million de secteurs et n'a toujours rien fait. Il a pris beaucoup de mémoire et s'est chargé pendant longtemps.

Half-Life, pour lequel le moteur a été fabriqué, est un jeu de tir à la première personne, et à partir de la troisième, il était gênant de faire certaines choses. Tout ce qui était utile dans Half-Life ne nous convenait pas du tout. Une grande quantité d'animation était également censée être réalisée, car à partir d'une troisième personne, vous devez grimper, etc. Il était nécessaire de changer le moteur, mais il n'y avait pas d'autre option.
Que faire quand tout est mauvais, difficile, mais qu'ils nous poussent? Tout d'abord, faire les fonctionnalités dans le bon ordre, car l'optimisation à l'avance est l'un des problèmes. Certains commencent à coller des strassiks avant de coudre la robe, puis ils ne peuvent pas coudre, car les straziks interfèrent.
Créez d'abord la puce la plus simple pour qu'elle fonctionne, puis stabilisez-la, puis optimisez-la. C'est dans cet ordre que tout le reste est faux.

Par visualisation, nous comprenons qu'il est peu opérationnel, c'est-à-dire MVP (produit minimum viable).

Ensuite, vous évaluez son potentiel. Supposons que les concepteurs de jeux proposent des fonctionnalités, le programmeur recourt et dit: "Je ferai bien, je ne ferai pas de mal, alors dessinez immédiatement un design de jeu génial." Mais comment sait-il? Il ne jouait pas, ne savait pas si c'était bon ou mauvais. Par conséquent, idéalement, vous créez une fonctionnalité, jouez, si c'est normal, puis faites-le plus loin. Pas normal - jeté, pas dommage.
Il y a mille ans, Sun Tzu a déclaré que gagner 100 batailles n'est pas le pic, le pic est de gagner sans bataille. C'est-à-dire ne faites pas ce que vous ne pouvez pas faire.
Stabilisation. Vous avez créé des fonctionnalités et stabilisé davantage sans ajouts inutiles. Avez-vous besoin d'une roue sur un arbre, sur une corde? C'est suspendu. Rien de plus.

En conséquence, si tout à coup il a été découvert (sans aucune preuve future) que la fonctionnalité devrait changer - recommencer. Protégez, stabilisez et n'essayez pas de deviner. Vous ne devinerez toujours pas.
Eh bien, l'optimisation prématurée. C'est toujours mauvais. Vous devez optimiser à la toute fin, lorsque vous savez avec certitude que cette fonctionnalité est importante, elle doit être optimisée et elle ne changera pas fondamentalement dans un avenir proche.

Parce que l'optimisation est un ensemble de cas particuliers. La lisibilité du code s'aggrave, les abstractions se brisent et la portabilité, en règle générale, s'aggrave également considérablement.

C'est une diapositive provocante, car les béquilles sont vraiment mauvaises. Mais ici, la situation est montrée quand il y a un tas de fonctionnalités et de prototypes ternes, tout est mauvais et il semble que tout va s'effondrer. Mais ce n'est pas le cas. Regardez - c'est le coffrage, le béton y est coulé et les «béquilles» sont calées pendant qu'il sèche. C'est-à-dire la situation est tout à fait normale, les «béquilles» seront alors supprimées, mais pas immédiatement, sans panique.
Brièvement sur la philosophie. Il n'y a pas de solutions universellement valables. N'essayez pas de créer un cadre pendant 100 ans à l'avance ou pour toutes les occasions.

Mieux vaut faire beaucoup de petites pièces qui font bien leur travail. Jetez l'inutile dès que possible, n'essayez pas de le soutenir. Et lors de l'écriture du code, rendez-le explicite. Parfois, il vaut mieux écrire du code explicite que vous sérialisez avec vos mains, plutôt que de réfléchir ou autre chose. L'utilisation d'une action de dépendance lorsque vous n'en avez pas besoin est également une mauvaise idée. Il est très difficile à lire, la moitié des erreurs d'exécution. Explicite vaut mieux qu'implicite. Et simplifiez le plus possible pour éviter les erreurs lorsque quelqu'un ne comprend pas quelque chose ou qu'il a même complètement oublié.
Comme l'a dit Bruce Lee, la simplicité est le plus haut degré d'art. Une fois, un acteur à qui il a enseigné son Jeet Kune-Do lui a demandé: "Quelle est l'essence de votre art martial Jeet Kune-Do?" À ce moment, Bruce Lee a laissé tomber son portefeuille, l'acteur l'a ramassé et Bruce Lee a déclaré: "Vous voyez, vous vous êtes simplement penché et avez ramassé le portefeuille, et si vous vous teniez dans la pose d'un cavalier, faites du kata, vous ne l'auriez jamais soulevé."
Questions du public
"Vous avez dit que l'optimisation prématurée est mauvaise." Vaut-il la peine d'écrire des tests prématurés lorsqu'un projet ne fait que commencer?- À ma connaissance, tout ce qui est prématuré est nocif. Dans les tests, je ne suis pas très fort, car dans le développement de jeux (dans de nombreux cas), les tests sont plus proches de la fin du développement. Au début, tout change si vite que pendant que vous écrivez un test, le game designer va déjà tout changer. Je pense qu'il est mauvais de dépenser de l'énergie pour tester ce qui va changer dans deux heures. Cela doit être fait au stade de la stabilisation. Mais pas au stade du prototype. Mais si l'équipe peut écrire des tests rapidement, c'est probablement bien. Sinon, alors non.
- Vous avez mentionné que les béquilles seront supprimées, mais il y a une merveilleuse thèse - il n'y a rien de plus permanent que temporaire. Nous travaillons tous dans le développement de jeux, nous avons des délais, des producteurs, puis une nouvelle fonctionnalité et ainsi de suite. À quelle fréquence avez-vous vu une situation où vous nettoyiez des béquilles? Et les ont-ils amenés à zéro?- Probablement pas à zéro. Si le projet est en direct, vous aurez toujours des béquilles. Tout fonctionne si elles sont nettoyées systématiquement. C'est-à-dire Vous avez créé une fonctionnalité - immédiatement enregistrée.
- C'est-à-dire Faut-il construire un certain processus dans l'entreprise? Type de phase officielle de nettoyage des béquilles?- Oui, je crois que cela devrait être inclus dans la tâche. C'est-à-dire si vous avez besoin de refactoriser en cours de tâche - vous refactorisez. En gros, même le mot refactoring n'est pas - c'est à l'intérieur de la tâche.
- Arrivez-vous à le faire dans la pratique? Vous venez chez le producteur et dites sur la planification d'une nouvelle itération que nous avons besoin de deux semaines pour nettoyer, refactoriser, etc. Et il dit que la valeur commerciale est nulle, nous proposons maintenant x, puis vous le nettoierez plus tard dans la soirée après le travail. Comment être dans cette situation?- Nous réussissons. Le producteur est conscient qu'il y a certaines dettes que vous corrigez, mais en temps opportun. Ce n'est pas que vous ayez une nouvelle version, elle n'a pas une seule nouvelle fonctionnalité, mais voici une sorte de refactoring. Choisissez simplement le bon producteur.
"Avec l'expérience, la compréhension vient, le plus simple est le mieux." Mais les programmeurs novices essaient de créer des systèmes complexes, effrayants, grands et gigantesques. Question: comment les en empêcher, sauf pour un "non" dur?- Je pense que c'est un problème d'apprentissage. Il est nécessaire de montrer le plus tôt possible quelles solutions fonctionnent, lesquelles ne fonctionnent pas et pourquoi. Lorsque vous avez de l'expérience et que vous pouvez expliquer pourquoi vous n'avez pas besoin de le faire, vous pouvez simplement donner beaucoup d'exemples et cela fonctionne déjà bien. Pour montrer et surveiller constamment avec votre propre exemple afin que tout soit simple. Mettez des prototypes pour qu'ils réécrivent plus souvent - lorsque vous réécrivez souvent, vous n'avez pas envie d'écrire beaucoup et ils écrivent de plus en plus simplement.
- S'il y a déjà quelque chose de très compliqué qui est utilisé sur plusieurs projets, et cette complexité n'aide plus, mais interfère plutôt - est-il facile de passer à des solutions simples?- Mon avis est, recommencez. Idéalement, une équipe distincte, à partir de zéro. Vous récupérerez très probablement 80% des fonctionnalités très rapidement. Sur une bibliothèque nouvelle et propre. Et puis vous rattraperez.
- Par exemple, il existe un puissant sérialiseur et éditeur de logique de jeu, maintenant il est assez obsolète ...- Ce sont les mêmes outils incommodes. Prenez confortable. L'unité, par exemple.
- Dites-moi, quelle est votre planification dans le code, comment est-il détaillé? Le programmeur principal résout-il tous les problèmes mineurs, toutes les tâches?- Nous avons une telle anarchie, une structure assez plate, pas beaucoup de monde. Nous faisons confiance à tout le monde et distribuons simplement qui prendra le prototype et qui ne le fera pas. Il peut s'agir de toute personne arbitraire.
Plus d'entretiens avec Pixonic DevGAMM Talks