Débutant Erlang

jrebillat
Débutant Erlang

Bonjour.
Je cherche à faire un serveur de jeu (un truc galactique genre Elite II - en 2D - mais en multijoueur).
Il est composé
- d'un client (javascript dans le browser du joueur)
- d'un serveur général (apache/PHP)
- d'un serveur de jeu qui n'interagit qu'avec le serveur général par sockets et qui gère les événements du jeu - y compris la BdD.

J'étudie en ce moment la possibilité de faire le serveur de jeu en Erlang, car tel que je le conçoit, il est basé sur des notions d'échange de messages.

Or, débutant dans ce langage, j'ai du mal à voir comment traduire certains concepts de mon architecture - ou comment adapter l'architecture, d'ailleurs.

Prenons un point précis sur lequel j'ai besoin d'aide :

- Chaque joueur incarne un personnage.
- Ce personnage est dans un vaisseau particulier
- Ce vaisseau est d'un type générique mais dérivant de concepts plus élevés (ex: Véhicule->Véhicule Spatial->Cargo), mais avec des ajouts uniques (détecteurs, moteurs, etc...) qui eux aussi sont de type générique, etc...

La question (j'y arrive enfin) est :
Comment au mieux peut-on, en Erlang, gérer cette notion de type générique "dérivé" avec des attributs particuliers ?

En Java je fais des classes abstraites que je dérive sur plusieurs niveaux et mes objets les instancient. Mais en Erlang je sèche un peu :cry:

fredericmazue

Que voilà une question intéressante :D

Quote:

Je cherche à faire un serveur de jeu (un truc galactique genre Elite II - en 2D - mais en multijoueur).

Ah Elite... :) ça me rappelle l'époque de mon Amstrad 6128 et d'Elite I. J'avais réussi à aller au bout... :) Mais bon la nostalgie m'égare. :D

Quote:

- d'un client (javascript dans le browser du joueur)

Ok.
Quote:

- d'un serveur général (apache/PHP)

Pourquoi cela ? Pourquoi pas Erlang tout de suite ? :)
Quote:

- d'un serveur de jeu qui n'interagit qu'avec le serveur général par sockets et qui gère les événements du jeu - y compris la BdD.

Ok. Oh ok... quoique...
Deux serveurs Erlang, c'est bien ça que tu voulais dire n'est-ce pas ? ;)

Quote:

J'étudie en ce moment la possibilité de faire le serveur de jeu en Erlang, car tel que je le conçoit, il est basé sur des notions d'échange de messages.

Et en effet Erlang semble un choix excellent :)

Quote:

Or, débutant dans ce langage, j'ai du mal à voir comment traduire certains concepts de mon architecture - ou comment adapter l'architecture, d'ailleurs.

C'est assez normal. Si Erlang est un langage facile en tant que tel, pour mener un gros projet en Erlang il est impératif de penser en Erlang.
Erlang est un langage fonctionnel concurrent orienté processus.
Java ou Php, par exemple, sont des langages impératifs orienté objets.
Il y a une nette fracture entre ces deux mondes. Et si Erlang est facile, "penser" en Erlang doit s'acquérir. Et ça ce n'est pas nécessairement facile, ça demande même une phase d'apprentissage non négligeable. D'abord en raison de l'environnement qui ne ressemble à aucun autre. Et ensuite parce qu'il faut apprendre à se débarrasser des habitudes de programmation, inconscientes, ancrées dans le geek rompu à la programmation objet que tu es :)

Quote:

- Chaque joueur incarne un personnage.

Ok.
Quote:

- Ce personnage est dans un vaisseau particulier
- Ce vaisseau est d'un type générique mais dérivant de concepts plus élevés (ex: Véhicule->Véhicule Spatial->Cargo), mais avec des ajouts uniques (détecteurs, moteurs, etc...) qui eux aussi sont de type générique, etc...

Je sens pointer ici une habitude de réflexion/conception orientée objet et donc un manque de "pensée Erlang".

Quote:

La question (j'y arrive enfin) est :
Comment au mieux peut-on, en Erlang, gérer cette notion de type générique "dérivé" avec des attributs particuliers ?
En Java je fais des classes abstraites que je dérive sur plusieurs niveaux et mes objets les instancient. Mais en Erlang je sèche un peu

Tout est dit: "En Java". En Java c'est ok. Pas en Erlang.
De même qu'en Erlang les desing pattern, pour puissants qu'ils soient en orienté-objet, sont à oublier.
Je vais dire une chose, mais en fait je ne devrais pas le dire. Il est possible de définir ce qui ressemble à des interfaces "Java" en définissant des behaviour en Erlang. MAIS même si je l'ai dit, il faudrait l'oublier au moins pendant la phase d'apprentissage du langage.
Il faut commencer à apprendre à penser en Erlang. Puis je suggérer que ton projet pour intéressant qu'il soit est ambitieux et qu'il est peut être pertinent de te familiariser plus avec le langage lui même d'abord ?
Pour penser en Erlang, il faut avoir un point fondamental chevillé à l'esprit: ** Erlang est orienté processus **
Java est orienté objet, donc tu penses en objets: classes abstraites, spécialisation, etc. parfait, rien en redire.

En Erlang tu *DOIS* penser processus. Erlang modélise le modèle réel concurrent tel qu'il est. Prend une voiture. En Java la classe Voiture a un moteur et des essuies-glaces.
En Erlang le processus superviseur voiture supervise le processus moteur et le processus essuie-glace. Tous ces processus sont liés entre eux et forment un graphe de processus: la voiture, MAIS moteur et essuie-glace tournent indépendamment. Tu vois la différence d'approche ? Donc ton vaisseau tu dois le penser comme un graphe de processus. Tu as cargo avec simplement un processus moteur ? Tu veux en faire un vaisseau de combat ? Alors tu crées un processus canon laser, qui s'intègre dans le graphe de processus du vaisseau.

En Erlang *TOUT* est processus. Par exemple quand tu lis un fichier, qu'est-ce que ce fichier dans le système Erlang, ce n'est pas une instance de classe, ce n'est pas un descripteur, c'est un processus :)
Donc avant tout il faut te familiariser avec cette idée, et avant tout penser en termes de processus. Avant même en fait penser à définir des behaviours. Si ça se trouve, on peut implémenter ton jeu sans définir la moindre behaviour personnelle. Je n'en serais pas surpris :)

Pour conclure, probablement, il n'est pas pertinent d'adapter ton architecture, mais de la repenser.
Imagine le monde de ton jeu comme un monde réel, donc totalement concurrent, et pense ton architecture en fonction de ça, parce qu'Erlang est fait pour ça, et c'est en l'approchant comme ça que tu vas profiter de sa puissance et de son expressivité. Sinon, la programmation Erlang ne sera qu'une suite de contorsions douloureuses.

jrebillat

fredericmazue wrote:

Ah Elite... :) ça me rappelle l'époque de mon Amstrad 6128 et d'Elite I.

Je ne connais que le II, mais j'ai aussi la nostalgie...

Quote:

Quote:

- d'un serveur général (apache/PHP)

Pourquoi cela ? Pourquoi pas Erlang tout de suite ? :)

Parce que ce système s'intégre dans un serveur de domaine avec plusieurs sous-domaines, gestion d'accès et de droits, etc...
Pour le moment, je trouve plus raisonnable de garder Apache comme frontal sur mon serveur.
Mais en effet, si tu connais un moyen de traiter un serveur en Erlang comme un Tomcat au travers d'un "Mod_jk", je prends !

Quote:

il faut apprendre à se débarrasser des habitudes de programmation, inconscientes, ancrées dans le geek rompu à la programmation objet que tu es :)

J'ai posé ma question justement dans cette optique.

Quote:

Il faut commencer à apprendre à penser en Erlang. Puis je suggérer que ton projet pour intéressant qu'il soit est ambitieux et qu'il est peut être pertinent de te familiariser plus avec le langage lui même d'abord ?

C'est évident. Si j'arrive à faire tourner le jeu d'ici un an je serais content !
Justement, je veux tout d'abord valider (ou comme je le comprends bien, dans ce cas invalider mes concepts). Donc j'ai préféré décrire la cible plutôt que m'enferrer dans des points de détail qui n'ont peut-être (cela semble bien le cas) pas lieu d'être.
Par exemple si j'avais demandé "Comment dériver une classe en Erlang" la réponse n'aurait pas été aussi intéressante...

Quote:

Pour conclure, probablement, il n'est pas pertinent d'adapter ton architecture, mais de la repenser.

Je l'avais un peu anticipé dans mon message ;)

Quote:

Imagine le monde de ton jeu comme un monde réel, donc totalement concurrent, et pense ton architecture en fonction de ça.

Ok.
Donc je résume :
- En "orienté-objet", il faut définir des éléments statiques (les objets) sur lesquels on peut agir avec des méthodes.
- En Erlang nous avons des processus concurrents qui tournent indépendemment et qui s'échangent des stimuli.

Hummm... Le monde Erlang me semble vraiment ultra-libéral... :roll:

fredericmazue

Quote:
Mais en effet, si tu connais un moyen de traiter un serveur en Erlang comme un Tomcat au travers d'un "Mod_jk", je prends !

Si j'ai bien compris la question, je crois que ça n'existe pas.
Quote:
Par exemple si j'avais demandé "Comment dériver une classe en Erlang" la réponse n'aurait pas été aussi intéressante...

Quote:

Par exemple si j'avais demandé "Comment dériver une classe en Erlang" la réponse n'aurait pas été aussi intéressante...

Je suis heureux que la réponse soit intéressante. C'était facile, la question était très bien posée :)

Quote:
- En "orienté-objet", il faut définir des éléments statiques (les objets) sur lesquels on peut agir avec des méthodes.

Oui.
Quote:
- En Erlang nous avons des processus concurrents qui tournent indépendemment et qui s'échangent des stimuli.

OUI!
Tiens la programmation d'un jeu de la vie en Erlang est un excellent exercice d'apprentissage.
Chaque cellule est... devine quoi ?... un processus bien sûr ;)
Quote:
Hummm... Le monde Erlang me semble vraiment ultra-libéral...

Et il l'est!
Et tant de liberté peut désarçonner quand on est habitué à une ligne toute tracée comme en Java :)
Une sorte de vide existentiel quoi :D
fredericmazue

Quote:
- En Erlang nous avons des processus concurrents qui tournent indépendemment et qui s'échangent des stimuli.

Et il y a un stimuli particulier dont il faut être bien conscient qui s'appelle la propagation des erreurs. (Erreur pas nécessairement au sens péjoratif du terme).
Quand un processus se crashe, tous les processus du graphe le ressentent, et par défaut décèdent aussi, sauf si dans le lot, il y a un superviseur, dont le rôle est d'intercepter le stimuli et de prendre la décision en conséquence, par exemple relancer le proc

Exemple, une centrale à énergie dans ton jeu se crashe, est détruit par l'ennemi, etc. Automatiquement tous les vaisseaux, peut être des milliers, qui étaient alimentés par elle explosent. A moins qu'un superviseur à centrales d'énergies ne soit là, et que s'il dispose d'une autre centrale, il la connecte aux vaisseaux, mais s'il n'y en a plus, alors crash.
20 lignes de codes à peine pour coder ça. Erlang, c'est fou :)