mardi 27 novembre 2012

Ces jeux qui m'ont marqué - A IV Network$

Prononcez A4 Networks, il s'agit d'une simulation économique dans laquelle vous prenez la direction d'une société de transports et d'investissements. Chaque carte représente une ville en 3D isométrique, dans laquelle vous pouvez ajouter des lignes de train et de bus et construire ou acheter des immeubles, golfs et autres. Chaque carte propose un défi particulier, comme de redresser le réseau de métro de Londres, ou de construire les îles Caïman à partir de zéro.

En tant qu'aficionado des jeux de gestion ferroviaire, je ne pouvais m'en passer et me jetais dessus quasiment dès sa sortie. Au final, c'est malheureusement un mauvais jeu, ce qui ne m'a pas empêcher d'y passer des heures. Et ses qualités tant ses défauts rendent son étude tout à fait intéressante. Voyons donc d'abord là où les développeurs se sont complètement plantés.

La simulation ferroviaire est ratée

Contrairement par exemple à Transport Tycoon, où les trains sont gérés via des signaux, et qui permettaient d'atteindre une complexité étonnante, les trains dans A4 Networks sont gérés par horaires: chaque train sait l'heure à laquelle il doit quitter la gare. C'est proprement ingérable, puisqu'il est très difficile de savoir si oui ou non deux trains vont se tamponner à un aiguillage, et impossible à forcer un train a prendre un côté plutôt qu'un autre dans une route à deux voies. Assez rapidement, l'on se retrouve à faire d'abord des lignes simples en point à point, et lorsque l'on commence à vouloir placer plus d'un train par ligne, à faire des lignes circulaires, sans aucun aiguillage.

L'alternance jour/nuit est gérée, mais elle est trop rapide par rapport à la vitesse des trains, ce qui rend impossible la gestion du rush hour. L'on tente donc d'avoir une densité de trains importante, en espérant qu'ils arrivent en gare au bon moment.

Le transport des marchandises est également sans queue ni tête: les trains de marchandises se remplissent à une gare, et se vident à la suivante, mais si par exemple une usine n'a pas eu le temps de se réapprovisionner, le train repart à vide, et se met à ramener les marchandises vers l'usine! Il faut manuellement aller inverser sa direction pour repartir dans le bon sens.

La simulation économique est ratée

Le jeu est très difficile à prendre en main, car les transports rapportent extrêmement peu par rapport à leurs coûts (ce qui est réaliste, ceci dit), jusqu'au moment où l'on se rend compte que par un curieux effet, le prix des immeubles s'écroule à chaque début d'année, vous permettant d'acheter quantité de bâtiments en solde, et de les revendre à 2 ou 3 fois le prix quelques mois plus tard. Une fois compris, ensuite, que l'impôt sur les bénéfices vous mettra vite sur la paille, et qu'il faut donc toujours investir tout son cash, la stratégie gagnante devient triviale: acheter le plus possible de bâtiments, les revendre juste avant le point de chute, et tout racheter. Ne vendre (et donc générer du cash) que pour construire autre chose, par exemple vos lignes de train. Au bout de quelques années, vous dépasserez les 2 milliards de cash, moment où l'entier 32 bits contenant votre argent durement gagné se retrouve tout d'un coup très négatif, vous forçant à une faillite prématurée. Dommage, non?

Évoquons à peine le mode bourse, qui fonctionne en dépit du bon sens. Certains scénarios demandent à obtenir une participation majoritaire dans plusieurs compagnies, mais il est parfaitement impossible de savoir quel est le pourcentage d'actions que l'on possède. En revanche, il est possible de se faire racheter, et donc de perdre au milieu du jeu sans pouvoir rien faire. La seule solution que j'ai trouvée est d'acheter ses propres actions dès qu'il y en a de disponibles.

Une antiquité à sa naissance

Graphiquement, ce n'est pas tout à fait ça. Alors qu'il est sorti plusieurs années après Transport Tycoon, la où TT proposait des animations et un scrolling de terrain fluide, A4 redessine péniblement la carte, carré par carré, à chaque recentrage, et les trains sautent de section de voie en section de voie. Alors certes, les cartes sont grandes, mais c'est très décevant.

Quel dommage!

Alors que beaucoup d'efforts et d'argent a été mis en œuvre pour la vidéo d'introduction avec James Coburn, l'on se dit que peut-être les designers auraient dû réduire leurs prétentions et sortir quelque chose qui marche. Parce que des points positifs, il y en a!

Une très grande liberté dans la pose des rails

Avec 3 niveaux en dessous du sol et 7 au dessus, l'on peut mettre les voies dans tous les sens: métros souterrains et aériens, croisements multiples, c'est un vrai plaisir.

Une ambiance particulière

L'alternance jour/nuit avec les dernières lumières dans vos gares, la musique d'ambiance pour chaque saison, et, paradoxalement, la sensation de vide qui vient du manque d'animations (les seules choses qui bougent sont vos propres véhicules), rend une atmosphère hors du temps, un peu bizarre, et très propice aux longues séances de jeu.

D'avoir proposé des scénarios basées sur de vraies villes est également un plus: l'on peut bidouiller le métro de Paris, développer New York ou Vienne.

Le nombre de bâtiments différents est également très important, et permet des villes variées. L'on pourra ainsi développer un quartier entier en s'assurant qu'il est bien desservi en transports, y installer quelques commerces, puis des bâtiments plus importants.

Une approche économique sérieuse

Quand bien même la simulation est défectueuse, l'idée de départ était bonne. Les rapports sont complets, le bilan de fin d'année est remarquable, et l'on gagne vraiment à les étudier en détail.

Face au mastodonte qu'est OpenTTD, la référence en gestion de transports, et, à mon humble avis, la référence tout court en matière de jeux libres, beaucoup de jeux font aujourd'hui pâle figure. A4 Network$ aurait pu connaître plus de succès sans ses nombreux bugs, mais il apparaît aujourd'hui bien plus dépassé que de nombreux jeux d'époque. Notons que la série des A-Train à laquelle appartient A4 continue de s'étendre, le dernier né de la série, A-Train 9, est sorti en 2010, dans la discrétion la plus absolue.

samedi 24 novembre 2012

Ces jeux qui m'ont marqué - Railroad Tycoon

L'ancêtre des jeux de train! Railroad tycoon, sorti en 1990 et qui tournait comme une bête sur mon 386 portable monochrome (eh oui, ça existait!) et tenait à l'aise sur une disquette, proposait au joueur de devenir un magnat du rail aux États-Unis, au Royaume-Uni, ou en Europe.

Le joueur peut donc installer ses rails et ses stations à travers la carte pour relier les villes et les industries et tenter d'optimiser son réseau pour maximiser les profits, en bon capitaliste qui se respecte. Au fur et à mesure du temps, de nouvelles locomotives plus performantes voient le jour, tandis que de nombreux compétiteurs installent eux-mêmes leurs réseaux.

Les contrôles sont fins, et il est possible de donner des ordres complexes à ses trains, comme par exemple de zapper les petites stations.

Le jeu est bourré d'humour, avec des titres de journaux délirants qui apparaissent régulièrement, les commentaires de fin d'année (mes actionnaires étaient apparemment "outrés" de mes résultats) ou encore la fin du jeu, où l'on obtient une certaine retraite en fonction de l'argent récolté (si l'on finit dans le noir, l'on se voit notifié une reconversion en ramoneur!).

Une autre très bonne idée est d'avoir fourni de vraies zones du monde pour jouer: il est très plaisant de créer sa ligne Paris-Lyon, ou encore de creuser sont tunnel sous la manche.

Le jeu est maintenant disponible gratuitement en abandonware, il tourne très bien sous DosBox. Une fois passé la première impression (c'est quand même assez moche), les vieilles sensations sont de retour.

mercredi 14 novembre 2012

Où l'on reparle des heuristiques

J'ai eu l'occasion récemment de me remettre aux heuristiques des fonctions Postgresql, que j'avais mentionnées dans un post précédent

Voyons le problème: l'on a un certain nombre de valeurs que l'on veut rechercher dans une grande table. On insère donc ces valeurs dans une table temporaire, et l'on fait une jointure. En fonction du nombre de valeurs dans la table temporaire, le planificateur de tâches va soit utiliser l'index, soit ordonner la table temporaire et faire un merge join. Sauf que depuis l'application, l'on prépare le plan à la première exécution, et l'on a donc aucune certitude sur le plan choisi. Pire, souvent les premières requêtes chargent un grand nombre de valeurs, et optimisent donc le plan pour ce cas, alors qu'ensuite le système se stabilise sur de toutes petites recherches, qui prennent donc beaucoup plus de temps.

create table data(i integer not null);
insert into data select generate_series(1, 1000000);
create index data_idx on data(i);

create temp table search(i integer not null);
insert into search select generate_series(1, 1000);
analyze search;
select d.i
from data d
join search s on d.i = s.i
truncate search;
insert into search select generate_series(1, 1);
analyze search;
select d.i
from data d
join search s on d.i = s.i

L'on pourrait empêcher la préparation du plan, ce qui oblige l'application à différencier entre les requêtes que l'on peut préparer et les autres. Mais il y a aussi une solution: doucement orienter le planificateur de requêtes vers le plan le plus efficace en moyenne, à l'aide d'une fonction et de hints bien choisis.

create or replace function get_search() 
returns table(i integer) 
rows 1 
volatile as
$$
 select * from search;
$$ language sql;

truncate search;
insert into search select generate_series(1, 100000);
analyze search;
select d.i
from data d
join get_search() s on d.i = s.i

L'on aura beau mettre autant de lignes que l'on veut dans la table search, le plan passera toujours par l'index de la grande table:

dimanche 4 novembre 2012

Postgresql - Arguments nommés

Je ne m'en étais même pas rendu compte: Postgresql 9.2 permet maintenant d'utiliser des paramètres nommés au sein de ses fonctions, en place des paramètres positionnels. C'est à dire qu'avant, il fallait écrire:

create function myadd(int, int) returns int as
$$
 select $1 + $2;
$$ language sql;

Mais maintenant, l'on peut écrire:

create function myadd(x int, y int) returns int as
$$
 select x + y;
$$ language sql;

Ce qui est quand même nettement plus lisible, non?