17-06-2018, 06:15 PM
(Modification du message : 17-06-2018, 06:23 PM par niahoo.
Raison de la modification: fôtes
)
J'ai exactement ce projet dans les cartons, notamment le multi basé sur le commerce !
Par contre, je ne pense pas que coder un système orienté objet avec un process = un objet (ou agent) soit une bonne idée. À mon avis ça complique pas mal et ça bouffe de la ressource.
Je vois plutôt un process par ville (en théorie, ensuite s'il faut séparer la partie défense militaire, la partie climatique ou la partie connectée au marchés/transports intercités, c'est à un autre niveau du problème).
Ensuite tu auras un truc genre Entity/Component/Systems, en gros ta ville c'est ton state (ou, bien sûr, une sous-partie du state pour pouvroir stocker des timestamp ou autre joyeusetés en dehors), ou un ensemble modulaire de states. Ce state contient des entités, les agents (du coup des Struct !), que sont les villageois, bâtiments, et d'autres propriétés comme les ressources, etc.
Enfin, ton système c'est le code du process : il a une task queue, et il est capable d'ajouter lui-même des tâches dans sa queue. Par exemple, toutes les X secondes tu rajoutes le "system" (au sens ECS) qui consiste à calculer la population courante, calculer combien de bouffe il leur faut pour la période, tenter de consommer cette bouffe depuis les inventaires de la cité et buter du villageois en proportion si y a pas assez.
Si on prend l'implémentation de Banished, le nombre de woodcutters est fixe, déterminé par le joueur. On peut donc lancer X tâches de woodcutter qui vont checker l'inventaire, voir s'il faut du firewood, pécho des logs, les amener, les couper, etc.
Et puis se remettre sur la liste des tâches dès qu'on a fini 1 simple batch. ça fait beaucoup de boucles donc il vaut mieux favoriser les batchs plus longs avec un meilleur rendement.
Comme ça, tu peux faire tourner ce process à l'infini, tout en lui envoyant des messages pour le mettre à jour de la part du joueur. Et tu as un objet unique sur lequel poser tes listeners pour mettre à jour les clients.
Si le code est pas trop compliqué, et que tu sais que ta ville est occupée (tous les villageois sont occupés, ou bien il n'y a pas encore de ressources nécessaire avant X secondes pour les autres tâches), ton process va être gentiment idle, tu peux donc l'éteindre après l'avoir sauvegardé. Comme ça tu peux en faire tourner pas mal. Avec de faibles ressources, tu peux même avoir plein plein de villes sur le même serveur si par exemple tu as un moyen depuis la base de données de prioriser équitablement les villes à mettre à jour, et que tu les charge/update/save puis les éteint de force tour à tour. Bon, ça fait beaucoup d'IO avec la base.
Enfin, ça te permet de recoder la logique du jeu en Rust ou en C quand tu veux de la perf, via une NIF erlang, ou en Lua ou en JS, sans devoir toucher au code qui gère la relation avec HTTP, puisque tu gardera le process, il se contentera juste de faire le passe-plat à une implémentation externe : envoyer les tasks, récupérer des events et le nouveau state (entier, ou juste des updates).
--------------
Voilà, après effectivement sur un jeu pas multi, ou alors si tu as peu de villageois mais qu'ils sont particulièrement détaillés : skills avec niveaux, relations, état de santé, stuff/gemmage/enchant/talents/glyphes ou autre, l'idée des Agents n'est pas mauvaise en soi, mais c'est plus compliqué. Partir directement sur du multi me semble audacieux.
Je peux aussi développer là dessus si tu le souhaites, mais pour un city builder, bof.
Par contre, je ne pense pas que coder un système orienté objet avec un process = un objet (ou agent) soit une bonne idée. À mon avis ça complique pas mal et ça bouffe de la ressource.
Je vois plutôt un process par ville (en théorie, ensuite s'il faut séparer la partie défense militaire, la partie climatique ou la partie connectée au marchés/transports intercités, c'est à un autre niveau du problème).
Ensuite tu auras un truc genre Entity/Component/Systems, en gros ta ville c'est ton state (ou, bien sûr, une sous-partie du state pour pouvroir stocker des timestamp ou autre joyeusetés en dehors), ou un ensemble modulaire de states. Ce state contient des entités, les agents (du coup des Struct !), que sont les villageois, bâtiments, et d'autres propriétés comme les ressources, etc.
Enfin, ton système c'est le code du process : il a une task queue, et il est capable d'ajouter lui-même des tâches dans sa queue. Par exemple, toutes les X secondes tu rajoutes le "system" (au sens ECS) qui consiste à calculer la population courante, calculer combien de bouffe il leur faut pour la période, tenter de consommer cette bouffe depuis les inventaires de la cité et buter du villageois en proportion si y a pas assez.
Si on prend l'implémentation de Banished, le nombre de woodcutters est fixe, déterminé par le joueur. On peut donc lancer X tâches de woodcutter qui vont checker l'inventaire, voir s'il faut du firewood, pécho des logs, les amener, les couper, etc.
Et puis se remettre sur la liste des tâches dès qu'on a fini 1 simple batch. ça fait beaucoup de boucles donc il vaut mieux favoriser les batchs plus longs avec un meilleur rendement.
Comme ça, tu peux faire tourner ce process à l'infini, tout en lui envoyant des messages pour le mettre à jour de la part du joueur. Et tu as un objet unique sur lequel poser tes listeners pour mettre à jour les clients.
Si le code est pas trop compliqué, et que tu sais que ta ville est occupée (tous les villageois sont occupés, ou bien il n'y a pas encore de ressources nécessaire avant X secondes pour les autres tâches), ton process va être gentiment idle, tu peux donc l'éteindre après l'avoir sauvegardé. Comme ça tu peux en faire tourner pas mal. Avec de faibles ressources, tu peux même avoir plein plein de villes sur le même serveur si par exemple tu as un moyen depuis la base de données de prioriser équitablement les villes à mettre à jour, et que tu les charge/update/save puis les éteint de force tour à tour. Bon, ça fait beaucoup d'IO avec la base.
Enfin, ça te permet de recoder la logique du jeu en Rust ou en C quand tu veux de la perf, via une NIF erlang, ou en Lua ou en JS, sans devoir toucher au code qui gère la relation avec HTTP, puisque tu gardera le process, il se contentera juste de faire le passe-plat à une implémentation externe : envoyer les tasks, récupérer des events et le nouveau state (entier, ou juste des updates).
--------------
Voilà, après effectivement sur un jeu pas multi, ou alors si tu as peu de villageois mais qu'ils sont particulièrement détaillés : skills avec niveaux, relations, état de santé, stuff/gemmage/enchant/talents/glyphes ou autre, l'idée des Agents n'est pas mauvaise en soi, mais c'est plus compliqué. Partir directement sur du multi me semble audacieux.
Je peux aussi développer là dessus si tu le souhaites, mais pour un city builder, bof.