18/12/2009

Pitfalls of OOP par Tony Albrecht

A moins de vivre dans une cave (ou d’être un programmeur de jeu du Dimanche), il y a une grande vague de remise en cause des principes de la programmation orientée objet dans le contexte des moteur de jeu (au runtime hein, pas dans les outils).


Dernier exemple en date, cette présentation par Tony Albrecht (Sony) qui est littéralement en train de faire le tour du web en ce moment même :


http://research.scee.net/files/presentations/gcapaustrali...

 

Si vous êtes programmeur, rendez-vous service et prenez le temps de lire cette présentation: car même si vous n'êtes pas d'accord avec l'argument principal, vous comprendrez enfin pourquoi les codeurs moteurs passent leurs temps à raler :-)

10:50 Publié dans Code | Lien permanent | Commentaires (11)

13/10/2009

The Ready At Dawn Engine

Tiens, après Insomniac qui partage une partie de sa base de code (a.k.a Nocturnal), c'est au tour de Ready At Dawn qui, si j'en juge par le pitch à peine voilé, se verrait bien à la place d'Epic ^_^

 

Tired of PC engines shoe-horned into game consoles?


Tired of engine middleware forcing you to run around to other vendors and integrate even more middleware in order to get your game done?


Tired of sales hype and flashy demos that do not deliver in the real world?


Introducing the Ready At Dawn Engine.


The complete game development platform

 

[ RAD:E ]

 

En soi, évidemment, ce n'est pas un mal. Nombre de studios essaient de rentabiliser leurs couts R+D. De plus, il est probablement trop tard dans le cycle de développement pour démarer un moteur from scratch ^_^

 

shapeimage_7.png

13:37 Publié dans Code | Lien permanent | Commentaires (5)

01/10/2009

Data driven engines, data driven bugs...

La plupart des moteurs de jeu modernes sont dit “data driven” i.e la majorité de l’expérience de jeu est défini par les données, pas par le code.

 

 

Evidemment, c’est beaucoup plus facile à dire qu’à faire.

 

 

Déjà, ces données doivent provenir de quelque part, et emmener ces données dans le jeu est le rôle principal du pipeline. Il y a 3 façons de produire les données qui vont composer une asset : par production avec un outil « externe » (3DSMax, Maya…), par production avec un éditeur interne (en général, l’éditeur de jeu), ou enfin par production automatisé de type batch (génération des light map ou du mesh de navigation, etc etc).

 

 

Jusqu’ici, tout va bien.

 

 

Le hic, c’est que comme le moteur est data driven, beaucoup de bugs ou de problèmes sont data driven aussi. En d’autres termes, il est plus ou moins aisé de créer des cas pathologiques, des problèmes de performances ou encore de réels bugs complexes dus à l’interaction entre ces données.

 

 

Du coup, quand on a identifié un de ces problèmes, on a souvent besoin de pouvoir remonter à la donnée source qui a produit l’asset. C’est l’une des qualités premières d’un bon pipeline que de simplifier ce travail d’investigation.

 

 

Et évidemment, ce n’est pas si simple que ça, car il n’y a pas une relation unitaire entre une asset donnée et un fichier source.

 

 

Un fichier source peut par exemple générer plusieurs assets. Il est ainsi fréquent que les animateurs stockent leurs animations dans un seul fichier pour Motion Builder afin de simplifier leur travail. Du coup, un fichier source va permettre de générer N animations, ces N animations pouvant parfois être utilisé dans M banques d’animations.

 

 

Le problème inverse existe aussi : une asset peut parfaitement être le produit de l’interaction entre plusieurs données. Par exemple, une texture compressée est le produit d’une texture d’origine et d’un fichier de configuration de compression. La qualité d’un mesh de navigation résulte de l’interaction entre les éléments de collisions et les informations de design posés dans tout un niveau.

 

 

Ces considérations de dérivations (retrouver le ou les sources qui ont produits l’assets), de dépendances (lister toutes les assets qui dépendent les unes des autres) ou d’interactions (retrouver les assets qui peuvent influer sur la production ou le comportement d’une asset donnée) forment le cœur des problèmes « data driven ».

 

 

Il n’y a pas de solutions idéales, mais il y a des outils et des process qui peuvent aider à se dépatouiller.

 

 

- Etre à même de tracer l’origine d’une assets, les différentes dépendances directes ou indirectes pour cette asset, et l’historique des fichiers sources concernés.

 

 

- Pouvoir reconstituer facilement tout ce qui a participé à la création d’une asset à un instant T donnée, ce qui signifie de pouvoir retrouver toutes les sources ainsi que tout les process qui ont participé à la création de l’asset.

 

 

- Permettre de versionner les assets, en autorisant (ou pas, voir au cas par cas) la rétro compatibilité. Permettre aussi de synchroniser ces versions afin de « labelliser » un ensemble d’assets et de fichiers sources pour archivage et/ou récupération postérieure.

 

 

- Etablir des mécaniques permettant d’identifier « gracieusement » les données manquantes ou mal formées : assets par défaut ou de secours permettant au runtime de continuer à fonctionner malgré une erreur dans une donnée, log et emailing automatisé, machine de tests unitaires ou de tests de stress…

 

 

L’essentiel, c’est de garder le contrôle sur ce qui va constituer le corps du jeu. Personne n’a envie de se retrouver à rechercher en vain un fichier 3dsmax contenant la modélisation d’un personnage qui a été ajouté 6 mois plus tôt. De même, découvrir par hasard une dépendance caché entre deux types d’assets disjoints peut être fatal à la bonne humeur quand on a nettoyé l’une de ces assets ^_^

14:28 Publié dans Code | Lien permanent | Commentaires (18)

26/09/2009

Unsung heros - strings et autres chaines...

Avec un titre pareil, si je fais pas exploser mes stats… ;-)

 

 

Enfin, trêve de bavardage de comptoir, revenons aux choses séreuses ^_^

 

 

On dit souvent que le son est la cinquième roue du carrosse, mais il y a en fait un élément qui est encore moins apprécié des développeurs : le texte.

 

 

Si les jeux vidéos sont faits d’images, de textures, de modèle 3D et de sons, les textes sont pourtant une composante majeur des jeux vidéo. Les textes sont partout : dans nos UI, dans la scène, dans les tutoriaux, dans les diverses aides et indications, dans l’exposition à la situation, etc etc

 

 

D’un pur point de vue design, les raisons d’être du texte sont multiples. En premier lieu, la chaine de caractère constitue la matière première la plus accessible pour décrire ce qui ne peut pas être produit. On utilise l’écriture pour faire l’exposition aux personnages, poser les bases narratives, expliquer les mécaniques de jeu. C’est la façon la moins couteuse de parvenir à transmettre l’information, et c’est pour ça qu’il faut en règle générale savoir lire pour pouvoir jouer à un jeu.

 

 

Evidemment, ça va à l’encontre même de la nature du jeu, où la règle primordiale est « show, dont tell ».

 

 

Mais le rôle du texte ne s’arrête pas là. En production, le texte sert aussi à nommer les niveaux, les différents acteurs, les différents layers, les assets, les textures, les meshs, en fait tout ce qui va être manipulé par les artistes en général, et le level designer en particulier.

 

 

Le texte là sert de clef d’abstraction pour manipuler les assets du jeu. Elle permet la communication et l’édition effective du jeu. Ce qui signifie d’établir des nomenclatures précises et efficaces afin de permettre un datamining naturel.

 

 

Evidemment, tous ces textes doivent être numérique, accessible depuis les outils ou le moteur de jeu.

 

 

Dire que la chaine de caractère n’est pas populaire auprès des programmeurs, c’est un euphémisme. En fait, c’est probablement le type de donnée la plus communément utilisés tout en étant la plus détesté, voir la moins comprise.

 

 

La manipulation des chaines de caractères n’est jamais simple. En premier lieu, la chaine de caractère n’est pas de taille fixe. Quand elle sert d’identifiant, elle requiert donc un cout certain quand il faut comparer deux chaines de caractère. De même, de nombreux algorithmes n’existent que dans l’objectif de trier les chaines, les ranger par hash, permettre la comparaison rapide ou la recherche avançée dans les bases de données.

 

 

De même, les chaines peuvent être manipulées à l’aide des expressions régulières, expressions qui suffisent souvent à faire passer des sueurs froides dans le dos du programmeur qui doit les utiliser.

 

 

Mais il y a pire : la chaine de caractère est une bête protéiforme : ANSI et autres formats ISO sont communs. Afficher une chaine de caractère requiert l’usage d’une font, et il n’y a pas deux fontes qui exhibent les mêmes propriétés.

 

 

Allez, pour enfoncer le clou, le contenu d’une chaine de caractère est en général écrit dans une langue donnée, ce qui signifie qu’il faut prévoir de pouvoir les localiser, dans n’importe quelle langue, et avec des alphabets bien différents.

 

 

Bref, la chaine de caractère n’est ni populaire chez le programmeur moteur (les perfs nomdediou !), ni chez le programmeur gameplay (la nomenclature nomdediou !), ni chez le QA localisation (les kanas nomdediou !), ni chez le designer (show dont tell nomdediou !)...

 

 

Pourtant, c’est notre matière première, celle que l’on utilise tout les jours, et dans tout les jeux. Il est difficile d’imaginer devoir s’en passer. Un moteur moderne est un processeur de données, et la chaine de caractère est une donnée primordiale. Alors quand on passe beaucoup de temps à travailler nos pipes de rendus ou nos moteurs d’animations ou de physique, il ne faut pas oublier de garder à l’œil la vulgaire chaine de caractère… Avant de se faire mordre en crunch time…

14:36 Publié dans Code | Lien permanent | Commentaires (5)

04/09/2009

Circle Of Death

^_^

 

Cercle de la mort.jpg

12:55 Publié dans Code | Lien permanent | Commentaires (5)

12/08/2009

Tim Sweeney, The End Of The GPU

La dernière présentation de Tim Sweeney au Siggraph 2009 revient sur l’évolution des CPU/GPU, en particulier en ce qui concerne les problématiques de rendu. Ce que l’on sait : On va des architectures mixtes de plus en plus complexes qui font que la distinction CPU et GPU devient de moins en moins clair.

 

 

1.jpg

 

 

A priori, on sait aussi que l’on va revenir vers des architectures complètement software, like in the old days. Rien de surprenant à cela, puisque pour tirer parti de ces architectures, il va bien falloir mettre les mains dans le cambouis ^_^

 

 

Techniquement, cette évolution n’est pas un problème en soi. Au contraire.

 

2.jpg

 

Par contre, dans la pratique, il y a deux problèmes majeurs qui vont émerger.

 

 

D’une part, l’accessibilité à ces hardwares va définir leur succès. Peu importe combien ils sont puissant, plus ils seront difficiles à programmer, moins ils auront de succès.

 

4.jpg

 

Mais ça encore, c’est le marché qui régule au fond, et la machine qui a du succès sera celle qui se vendra le plus. En la matière, « it’s all about the games ».

 

 

Non, l’autre problème est un vrai problème de production i.e comment produire les monstres de données que ces monstres de calculs peuvent ingurgiter.

 

3.jpg

 

Dans la génération PS2, ce qui faisait la différence, c’était la qualité du pipeline. Aujourd’hui, même si le point précédent reste plus valide que jamais, la différence se fait sur la maximisation du hardware.

 

 

Mais à l’ avenir, on va vers un vrai problème de production : quels outils mettre en œuvre pour créer intelligemment toutes ces données…

13:00 Publié dans Code | Lien permanent | Commentaires (27)

07/08/2009

SIGGRAPH 2009: Beyond Programmable Shading

Je n'aurai pas le temps de poster quoi que ce soit ce week end, mais voici de quoi s'occuper d'ici à Lundi (enfin, pour les codeurs). Les notes du cours "Beyond Programmable Shading" du siggraph 2009 sont disponibles en lignes, avec en particulier quelques détails au sujets du moteur FrostByte de Dice (qui fait tourner Battlefield Bad Company et Battlefield 1943), ainsi que quelques notes sur le nouveau moteur d'ID (Rage):

 

There are strong indications that the future of interactive graphics programming is a more flexible model than today's OpenGL/Direct3D pipelines. Graphics developers need a basic understanding of how to combine emerging parallel programming techniques and more flexible graphics processors with the traditional interactive rendering pipeline.

 

The first half of the course introduces the trends and directions in this emerging field. Topics include: parallel graphics architectures, parallel programming models for graphics, and game-developer investigations of the use of these new capabilities in future rendering engines.

 

The second half of the course has leaders from graphics hardware vendors, game development, and academic research present case studies that show how general parallel computation is being combined with the traditional graphics pipeline to boost image quality and spur new graphics algorithm innovation.

 

Each case study discusses the mix of parallel programming constructs used, details of the graphics algorithm, and how the rendering pipeline and computation interact to achieve the technical goals.

 

The focus is on what currently can be done, how it is done, and near-future trends. Topics include volumetric and hair lighting, alternate rendering pipelines including ray tracing and micropolygon rendering, in-frame data structure construction, and complex image processing.

 

The course concludes with a panel, moderated by the creator of OpenGL Kurt Akeley, on the future of interactive graphics programming models.

 

[ Beyond Programmable Shading ]

18:40 Publié dans Code | Lien permanent | Commentaires (0)

03/08/2009

Unsung heroes: Performances

Pour une raison qui m’échappe, quand on parle des performances d’un jeu entre codeurs, on tombe très vite dans un certain nombre de travers qui vont du déni le plus farouche (ce n’est pas le plus important) au délire mystique façon secte (c’est fait comme ça parce que c’est comme ça qu’il faut faire) en passant par les égos les plus sensibles qui soit (mon code est toujours le meilleur).



Sigh, c’est à vous découragez de vouloir avoir une discussion adulte ^_^



Commençons par reprendre les faits. Pourquoi les performances des applications sont elles si importantes ?



1 - On recherche les performances pour réduire la latence gameplay :



- Nous programmons des jeux i.e des programmes qui interagissent avec un être humain.


- Pour que ces programmes soient efficaces, il faut que la boucle de feedback soit la plus rapide possible i.e il faut réduire la latence au strict minimum.


- La latence acceptable varie en fonction du design du jeu. Ce qui est acceptable pour un démineur ne l’est déjà plus pour un Tetris. Ce qui est acceptable pour un Tetris ne l’est plus pour un jeu de course. Et nombre de joueurs ne peuvent pas jouer à un FPS en dessous de 60 Hz.


- Pour ce faire, la latence « gameplay » est donc la première considération de la programmation orientée performance.



2 – On recherche les performances pour délivrer une expérience :



- Beaucoup de jeux (en particulier ceux qu'on appellent les AAA) recherchent à délivrer une expérience réaliste (voir surréaliste).


- Pour ce faire, on souhaite rendre les décors et les personnages les plus beaux possibles, avec un maximum de détails et d’animations diverses.


- On cherche aussi souvent à augmenter la diversité sans augmenter le surcout en production de données.


- Enfin, on cherche parfois à créer des expériences uniques qui ne peuvent pas être sans une couche software dédié.


- Dans tout ces cas là, la considération de performance est importante, puisqu’elle défini les limites techniques de l’expérience délivrable.



3 – Les considérations de performances ne sont souvent pas dissociables de la plateforme hardware.



- Nous programmons des jeux sur plateforme embarquée (oui, les consoles sont des plateformes embarqués).


- Ces consoles, même si elles ont une couche OS relativement fine, proposent toutes des services et des composants différents, et souvent en quantité limité.


- Pour maximiser les performances de nos applications, on souhaite exploiter chacune de ces ressources du mieux possible (mémoire, parallélisations, optimisation…).


- Dans ce cadre, il y a donc deux types de performances qui nous intéresse : la performance mémoire (ou comment utiliser le moins de mémoire possible), et les performances logicielles (ou comment maximiser son throughput i.e combien de choses peut on faire à la frame).



Quand on prend un point de vue très pragmatique, ça parait simple dit comme cela, alors pourquoi est-ce un sujet si controversé ?



Pour simplifier, il y a deux dérives fréquentes : l’excès de zèle, et le déni.



L’excès de zèle est une pratique commune qui revient à mettre les considérations de performances sur un pied d’estale et à dénigrer tout le reste (lisibilité, maintenance, simplicité). C’est un travers parce qu’il oublie que la performance est au service de l’application, et pas l’inverse.



C’est une attitude de programmeur cowboy qui conduit souvent à l’arrogance ^_^



Le déni lui provient en général d’une mauvaise interprétation de la fameuse phrase « premature optimization is the root of all evil ». Il semble qu’elle soit souvent comprise comme étant une excuse pour ne considérer les performances qu’en aval de l’exécution. S’il s’agit d’une attitude saine en règle général, il ne faut pas non plus que cela devienne une excuse pour renoncer à la pensée !



Puisque l’on connait nos plateformes, nos contraintes, et nos objectifs, c’est bel et bien en amont qu’il faut penser aux performances ! En fait, ce qu’il faut comprendre de la phrase, c’est ça : « premature optimization in the implementation is the root of all evil ».



Ce sont les optimisations incertaines dans l’implémentation qui posent problème, pas le fait de s’être creuser la tête pour choisir les bons algorithmes et les bonnes structures de données dès le départ !



Programmer pour les performances, c’est savoir se poser des questions, et de préférences les bonnes questions, et ce dès le départ. Prenons quelques exemples, fournis par Mike Acton, directeur technique chez Insomniac.



Dans « Quicksort is not a concurrent algorithm », Mike reviens sur le grand cas d’école typique qui tout le monde apprend pendant ses études : le quick sort. Souvent, on passe beaucoup de temps à apprendre différents algorithmes de tri, et parfois on apprend même à les implémenter plus ou moins efficacement.



Du coup, comme on tri souvent pas mal de choses dans les moteurs de jeu, on pense naturellement à optimiser ces algorithmes là. Logique non ?



Pourtant, est ce que l’on se pose les bonnes questions ? Déjà, pourquoi est ce que l’on tri ces données ? Et c'est quoi qu'on tri au fait ? Qu’allons-nous faire de la liste une fois trier ? Ai-je vraiment besoin de construire la liste avant de faire ce que je veux faire avec ces données ? Et puis d'abord, est ce vraiment le tri qui fait bottleneck de toute façon ?

 

 

607502049_E5U3W-M.jpg
607500913_9g4QE-M.jpg
607502496_X86VV-M.jpg
607511303_ZFgZ4-M.jpg
607512040_rYeSX-M.jpg
607513958_4ycnr-M.jpg
607514302_iH8T6-M.jpg
607514643_eLhhh-M.jpg
607520763_iAUki-M.jpg
607517752_D6sDV-M.jpg
607518080_Gr9MT-M.jpg

 

[ La suite chez Mike Acton ]



Autre cas d’école, autre exemple analysé par Mike, implémentation d’un algorithme de détection de collision entre une sphère et un plan. Ca aussi, c’est du code très utilisé et balisé depuis des années dans les graphics gems.



Pour autant, ca ne nous dispose pas de savoir se poser les bonnes questions : combien de plans et de sphères ait je besoin de tester exactement ? Une, deux, mille ? Et comment se comporte mes données sur la plateforme cible ? Et dans combien de situation fait avoir à implémenter un comportement différent nécessitant une implémentation virtuelle? Est-ce que mes données sont triés, et si elles ne le sont pas, est ce que je ne gagnerai pas à ce qu’elle le soit avant ?

 

 

1.jpg
2.jpg
3.jpg
4.jpg
5.jpg
6.jpg
7.jpg
8.jpg

[ La suite chez Mike Acton ]



Programmer pour les performances pour plateforme embarquée nécessite donc un certain état d’esprit (et, il faut bien le reconnaitre, de solides connaissances au sujet de la plateforme et du compilateur). Mais il y a certains principes qui émergent toutefois, et que l’on peut garder à l’esprit quand on s’y essaye. Ce sont ce que Mike appelle les 3 mensonges :



Lie 1: Software is a platform



Something that often is being teached at schools. It comes around the idea that you shouldn't care about what hardware you are running. Software is not a platform, software is always running on hardware and even if it may be different hardware its hardware that we can understand and optimize for.



Lie 2: Code should be designed around a model of the world



In typical C++ and OOP code there is idea that you need to model your code around the real world.





The typical problem with code like this is that above all it doesn't scale. Today all code that is used during run-time needs to been designed with data layout in mind and for multicore.


...



Lie 3: Code is more important than data



I touched a bit about this in the above point as well. This is the big one. We spend way way too much time talking about code when it really doesn't matter. When doing time critical programming one can think of it as a complex DSP. We get data in, modify it and send out. We spend very little time on actually talking about how the data flows in an application. Data is what should be dictating all decisions in your application. If you don't know the data how will you know how it will perform? where the bottlenecks will be, etc. You have no idea.



If data is designed in a correct (and often simple way) you should only be able to write the code in one way.



 

[ Daniel Colin ]



Ce n’est pas que ces conseils soient définitifs ou absolus, ni qu'ils doivent s'appliquer partout pour tout, ils peuvent parfaitement être invalidés par les progrès techniques et logicielles. Mais pour l’heure, en ce qui concerne les plateformes embarquées actuelles, et à venir dans un futur proche, ce sont les meilleurs conseils qui soient.

 

Et dans tout les cas, il faut bien admettre que tout travail sérieux démarre au moment où l'on commence à se poser des questions, et c'est la qualité première en ingénierie, n'est ce pas ? ^_^

14:00 Publié dans Code | Lien permanent | Commentaires (21)

25/07/2009

Developing DOFUS 2.0 : Overcoming challenges in Flash/AS3

Je ne sais plus quand exactement, mais il me semble bien avoir écrit sur ce blog que Flash était une plateforme à part entière, et même qu'il s'agissait probablement de la plateforme la plus répandu au monde. Et quand on parle de dévelopement web, on ne peut que penser au succès d'Ankama avec Dofus ^_^

 

6539_dofus.jpg

 

La présentation « Developing DOFUS 2.0 : Overcoming challenges in Flash/AS3 MMOG development» donnée durant la gamelab 2009 par Samuel Lorétan est disponible en ligne sur son blog:

 

Cette année, j’ai participé à la conférence Gamelab, en Espagne, en donnant une conférence sur le thème « Developing DOFUS 2.0 : Overcoming challenges in Flash/AS3 MMOG development»  (» Développer DOFUS 2.0 : Dépasser les difficultés dans le développement de MMOG en Flash/AS3″).


Cette présentation portait sur deux des nombreux challenges que nous avons rencontré durant le développement de DOFUS 2.0 : le moteur d’animation (» Tiphon» ), et les outils.

 

[ Tynambule ]

 

J'en profite aussi pour signaler mon plaisir de voir de plus en plus de blog Français de qualité en matière de dev ^_^ J'avoue avoir l'impression de faire office de vieux de la vieille maintenant, mais il y a de plus en plus de bon blogs.

 

Je ferai un tour de la blogosphère dans un prochain post ;-)

13:35 Publié dans Code | Lien permanent | Commentaires (1)

10/07/2009

Google OS

Evidemment, tout le monde en parle. Moi, je pense qu'il faudra encore du temps avant que cela n'ait une quelconque signification pour notre industrie.

 

En tout cas, rien de résume mieux mon opinion que ce dessing, ainsi que l'article qui va avec:

 

google-microsoft-chrome-480.jpg

 

This is, for lack of a better term, Google's "Microsoft Moment". This is the point when the difference between their internal conception of the company starts to diverge just a bit too far from the public perception of the company, and even starts to diverge from reality. At this inflection point, the reasons for doing new things at Google start to change.

 

[ Anil Dash ]

23:57 Publié dans Code | Lien permanent | Commentaires (3)

04/07/2009

Paris AI Game Dev Conférence 2009

Les papiers de la dernière conférence Parisienne sur l'IA sont désormais en ligne (on m'a dit beaucoup de bien de la conférence)!

 



GAIC09w_AudienceTop.medium.jpg

13:00 Publié dans Code | Lien permanent | Commentaires (0)

03/07/2009

Apprendre à programmer pour l'Iphone

Hé bé, si avec un titre pareil je n'explose pas mes stats ^_^

 

Bref, pour ceux d'entre nous qui ont envie de faire de l'Iphone (et a en juger par la popularité de la plateforme dans le millieu, ils sont nombreux), l'université de Stanford a mis en ligne son semestre de cours de cette année:

 

businessmobilephonenet-iphone-software-update.jpg

13:36 Publié dans Code | Lien permanent | Commentaires (1) | Tags : code, iphone