dimanche 23 janvier 2011

Itinéraires

Le nouveau système d'itinéraires est en grande partie implémentée. Il est maintenant possible de donner une liste d'ordres à son train, et de l'observer allant d'une gare à une autre. Il est également possible d'arrêter et de redémarrer son train en route.

Ce sera évidemment bien plus joli avec des noms de gares plutôt que des numéros.

samedi 22 janvier 2011

La GUI se met à jour

Mon observer (nommé RWData) fonctionne comme prévu. J'en ai profité pour revoir un petit peu les interfaces de propriétés. Pour les trains, donc, nous avons la vitesse courante, qui se met à jour au fur et à mesure, et la boite qui contiendra bientôt l'itinéraire.

Des nouvelles d'Infinity

Comme mentionné dans un post précédent, je surveille de près le projet Infinity, l'ambitieux projet de MMORPG spatial amateur (ou plutôt semi-pro, comme on le verra dans la suite du post). Hier, son concepteur a publié sa rétrospective pour 2010, et a notamment annoncé un changement majeur sur la conduite du projet: maintenant secondé par un développeur pro, il a monté une entreprise, I-novae studios, et se concentre sur la vente du moteur de jeu.

Ceci a bien entendu causé quelques changements dans ses priorités, et il semble que beaucoup de temps ait été passé sur les bug fix, le port vers d'autres architectures, l'intégration à .NET, et bien évidemment l'effort marketing. Le jeu Infinity en lui-même n'est pas abandonné, mais mis de côté en attendant que la vente du moteur permette au studio de recruter une véritable équipe de développement.

La communauté est très divisée par ces nouvelles. Tout en admettant que la vente du moteur est la chose à faire pour lever des fonds, l'inévitable recul de la date de publication du jeu Infinity est difficilement vécue par ceux qui espéraient que le silence de ces derniers mois débouche sur une béta jouable.

Tous les fans d'Infinity (et j'en suis!) devront donc continuer de prendre leur mal en patience, et d'espérer un rapide succès commercial du moteur. Plus personnellement, j'espère tout de même que nous aurons au moins quelques vidéos à se mettre sous la dent.

20 000 lignes

Voilà, c'est atteint, le projet fait maintenant très exactement 20032 lignes de code, avec l'ajout hier soir d'une implémentation générique d'un observer (on dit vraiment "patron de conception" pour design pattern???). Je vous en causerai plus avant après nettoyage du code.

Mais, pour en revenir à nos lignes, je pense être plutôt dans une pente descendante: avec l'implémentation de piglet et la simplification annoncée du système d'itinéraires, c'est beaucoup de code qui va jarreter. Les systèmes de contrôle de version étant faits pour ça, j'ai la ferme intention d'oblitérer de vastes quantités de code.

mercredi 19 janvier 2011

Openrailz v0.2 sur Sourceforge

À la demande générale, j'ai publié sur Sourceforge la dernière version du code et des ressources d'OpenRailz dans un beau paquet. Pour Windows, malheureusement, il va falloir être un peu plus patients, et attendre que je trouve la motivation de porter le code.

Pour ceux qui veulent tenter la compilation sous Linux, la difficulté va surtout dépendre de la disponibilités des bons paquets pour votre distribution préférée. Le fichier INSTALL explique comment compiler avec une Debian Squeeze, la seule subtilité étant qu'il faudra compiler soit-même wxWidgets 2.9 (pour l'antialiasing). Pour la compilation en elle-même, un bête omake dans le répertoire principal fera l'affaire, mais il sera plus efficace de suivre d'un peu plus près la documentation, et d'utiliser les en-têtes précompilées ainsi que la compilation en parallèle.

Les ressources sont fournies avec le code, et sont dans le répertoire "data". L'exécutable cherchant par défaut les données dans le répertoire courant, le mieux est de se placer dans le répertoire principal, et lancer OpenRailz en tapant ./debug/bin/openrailz.

C'est là que tout se corse: je n'ai pu tester OpenRailz qu'avec ma carte vidéo, une Radeon HD 4870, en utilisant les drivers propriétaires, et j'ai peu de doutes que bien d'autres cartes ne supportent pas les shaders de la manière dont je les ai écrits. C'est vraiment au petit bonheur la chance. Les fichiers de shaders sont dans le répertoire data/shader, et sont lus au runtime, donc vous pouvez tripatouiller un peu pour tenter de résoudre d'éventuels problèmes.

Si, par le plus grand des hasards, OpenRailz se décidait à démarrer proprement, vous pourrez alors vous amuser un petit peu avec les circuits.

  • La navigation se fait en maintenant le bouton droit pour l'orientation, et le bouton central pour les déplacements

  • Ajoutez une gare, en sélectionnant l'icône "Build station", et en maintenant le bouton gauche à partir d'un endroit du terrain pour orienter le bâtiment

  • Ajoutez quelques autres gares (backspace pour effacer la gare courante)

  • Passez en mode rails avec l'icône "Track layout". Les waypoints des gares apparaissent, en rouge car ils ne peuvent pas être manipulés

  • Sélectionnez-en un, il devient doré. Puis cliquez et maintenez pour créer un autre waypoint. Une fois le bouton lâché, un rail apparaît si un chemin peut-être calculé. Re-cliquez et glissez pour réorienter un waypoint (manipulable, en vert) existant

  • Le train courant est situé dans la première gare que vous avez créée. Passez en mode sélection avec l'icône "Selection tool", et cliquez sur une autre gare. S'il existe un chemin, le train va s'y déplacer!

dimanche 16 janvier 2011

Et maintenant?

Malgré quelques bugs, cette démo de déplacement des trains est une avancée majeure et valide le modèle d'entités graphiques (le bien nommé piglet), le modèle de rails, et le pathfinder. La pose de rails, malheureusement, reste très ardue, mais ce sous-système est suffisamment générique pour être facilement amélioré plus tard, ce qui le rend non prioritaire.

Je peux donc travailler sur l'amélioration du réalisme (accélérations et décélérations), l'interface (simplifier mon modèle d'itinéraires), et enfin m'attaquer à des améliorations de gameplay. Je pense notamment à enfin intégrer l'aspect passagers, avec des gares qui se remplissent de passagers désireux de voyager. L'aspect financier, avec le coût des gares, des rails et des trains, viendra plus tard.

Mais peut-être avant tout ça faut il d'abord trouver enfin un modèle raisonnable pour les callbacks (fonctions de rappel, me dit Wikipedia (!)) entre le moteur et la GUI. L'approche monolithique consistant à faire dériver chaque élément de la GUI d'une interface qui fait tout (sélections de trains et de gares, changements de vitesse, itinéraires, passagers dans les gares, etc) est trop limitée: non seulement cette interface mammouth couplerait tous les composants, mais cela veut dire que des centaines de fois par seconde, chaque train va envoyer sa nouvelle vitesse, chaque gare va envoyer son nouveau nombre de passagers, et bien d'autres événements vont être générés et envoyés à des boites de dialogue qui vont pour la plupart les ignorer.

Inspiré par une approche que j'ai vue au boulot (chut!), je vais tenter quelque chose de plus découplé: permettre à chaque composant de la GUI de s'enregistrer auprès d'un événement donné, en lui passant une fonction de callback, et gérer l'enregistrement dynamiquement au fur et à mesure des besoins de l'utilisateur. Ansi, l'utilisateur cliquant sur une gare, la boite de propriétés de la gare enregistre un callback directement sur un objet représentant le nombre de passagers. Lorsque ce nombre change, la boite de propriétés en est informée, et affiche la nouvelle valeur. Lorsque la gare est dé-sélectionnée, la boite de propriétés se dés-enregistre. Ainsi, pas d'interface monolithique, pas de couplage entre des événements indépendants, et, je l'espère, moins de code à gérer.

samedi 15 janvier 2011

Openrailz tech demo 3 - La vidéo


Openrailz tech demo 3

Il a fallu franchement se battre avec les formats, mais enfin, la vidéo est là. L'on remarquera que le train à tendance à défier les lois de la physique avec ses demi-tours sur l'aile et ses démarrages et freinages au quart de tour, mais l'on a bien les fonctionnalités de base.

I've got the power!

Enfin, j'ai les trains bougeant de gare en gare!

Certes, c'est un petit peu bizarre par moments, les "demi-tours" dans les gares sont un poil irréalistes... Mais enfin, l'on peut contrôler le déplacement des trains à la souris, et voir le pathfinder en marche. Je vous poste une vidéo bientôt.

1000ème commit

Alors j'allais quand même sortir une jolie capture d'écran pour cette occasion! Voici donc un train en gare. La plus grande partie de la logique est implémentée, il ne reste plus qu'à ajouter quelques contrôles pour pouvoir indiquer au train où aller, et l'on devrait enfin pouvoir commencer à bouger.

dimanche 9 janvier 2011

Tests unitaires

Mais comment ai-je pu coder pendant des années sans tests unitaires? Ce truc, c'est LA pratique qui a augmenté mon rendement, m'a permis de mieux dormir la nuit, et m'a sauvé la vie (professionnelle, tout du moins) plus d'une fois.

Il y a quelques années, j'avais eu entre les mains un bouquin sur le développement orienté tests (le TTD, "Test Driven Development"), et j'avais douté leur déclaration qu'une fois touché aux tests unitaires, on ne pouvait plus s'en passer. Eh bien, ils avaient raison. Une fois utilisés correctement, les avantages sont tels qu'il devient évident que l'on ne peut vivre sans.

Cependant, utilisés à mauvais escient, ils peuvent faire plus de mal que de bien. Il y a donc quelques règles à garder à l'esprit quand on se lance à écrire du code.

  • Les tests unitaires influencent le design. Il est rare qu'un bout de code quelconque, une fois atteint une complexité minimale, puisse être testé tel quel. Lorsque l'on sait que l'on va devoir tester le code, l'on tend à diminuer les effets de bord, à découpler ses routines, à écrire des interfaces afin de pouvoir "moquer" ses objets. Ça tombe bien, ce sont le genre d'habitudes qui améliorent la qualité du code!

  • Corollaire du point précédent: il est généralement difficile d'ajouter des tests unitaires à un projet existant. Le projet dépend probablement de fichiers de configuration non moqués, force les logs vers un fichier, cause à la base de données, n'est pas séparé par bibliothèques indépendantes, dépend d'une GUI, dépend de l'horloge, écrit ses résultats dans un fichier Excel, etc. Demander tout à coup aux développeurs de "tester toute la codebase mais sans y toucher" est voué à l'échec. Pour approcher un gros projet non testé, il va falloir doucement, au fur et à mesure des nouvelles fonctionnalités ou des corrections de dysfonctionnements, tenter d'abstraire et de découpler pour pouvoir tester le changement. Au fur et à mesure que le code évolue, le nombre de tests augmente, et la qualité du produit avec.

  • Il existe un point où la loi des rendements décroissants entre en ligne. À moins de coder pour la NASA ou autre cas où la qualité doit être absolue, l'abus de tests unitaires rend le code plus difficile à changer (car il risque de casser une batterie de tests). Le développeur peu scrupuleux (et, croyez le ou non, il y en a!), plutôt que de plonger dans les abîmes de la perplexité, se laisse aller à sa paresse naturelle et désactive les tests urticants. Avant peu, les 3/4 des tests ont été éliminés, et ne testent plus rien du tout (point bonus aux développeurs qui désactivent les tests en commentant l'intérieur de chaque routine, afin que leur forfait n'apparaisse pas dans les statistiques de chaque build).

  • À contrario, l'utilité des tests augmente exponentiellement avec leur nombre. Quelques tests sur les fonctionnalités de base ne vont probablement jamais casser, et quand bien même un bug se serait glissé dans le code, il aurait été rapidement trouvé. Tandis qu'une batterie de tests sur les fonctionnalités centrales mais plus complexes vont trouver beaucoup plus de régressions. C'est pour cela qu'il peut être difficile de convaincre certains développeurs: n'ayant rien vu venir après avoir coder leur petite dizaine de tests, ils n'en voient pas l'intérêt. Il faut persévérer!


Le test, c'est comme le chocolat: un incomparable sentiment de plénitude lorsque la dose est bonne.

mercredi 5 janvier 2011

En voiture Simone

Je ne peux plus reculer, il n'y a plus d'échappatoire possible: la prochaine étape est vraiment de faire bouger les trains entre les gares. Pas mal de plomberie, et quelques soucis à résoudre (par exemple, je ne suis toujours pas sûr de la manière de faire faire demi-tour à mes trains...), avec je l'espère un résultat enfin visible bientôt!

samedi 1 janvier 2011

Bonne année 2011!

En plus, cette année est un nombre premier, que demander de plus.

Bisous à toutes et à tous!