J'ai conçu des jeux multijoueurs avant, mais je voulais maintenant créer une architecture MMORPG pour l'apprentissage / le défi. Je veux aller aussi loin que simuler des centaines (ou quelques milliers de milliers) de joueurs simultanés sur un seul serveur.
Jusqu'à présent, si bon, je suis confronté à un problème pour trouver un bon moyen de mettre à jour tous les objets de jeu. sur le serveur aussi souvent et aussi vite que possible. P>
par des objets de jeu, je veux dire tous les joueurs, les mobs, les balles. P>
Le problème est que tous les joueurs, les mobs, les balles sont stockées dans des collections sur la mémoire latérale du serveur pour un traitement plus rapide et de l'itération de tous pour vérifier les collisions, mettre à jour la santé, le mouvement de mise à jour, etc ... prend beaucoup trop longtemps. P>
Permet de dire que j'ai 1000 Les joueurs et il y a 10000 mobs dans le monde entier et tous les joueurs et créatures sont responsables de la création de 5 autres objets de jeu (plus non moins) tels que des balles. p>
qui donnerait (1000 + 10000) * 5 = 55000 objets de jeu dans une collection. P>
Itération de tous les objets, pour les mettre à jour, prendre pour toujours (quelques minutes de couples) sur un Dual-Core HT i5 avec 4 Go de RAM. C'est faux. P>
Lors de l'itération, le code ressemble à ceci (pseudo): p> comme une optimisation, je pense à diviser mes objets de jeu Dans différentes zones et collections, mais cela ne corrigerait pas le problème où je dois mettre à jour tous les objets plusieurs fois par secondes. P> Comment puis-je procéder pour mettre à jour tous les objets de jeu sur le côté serveur? J'ai fait des recherches lourdes pour trouver des modèles de conception de jeux intéressants mais pas de résultats jusqu'à présent. : ( P> Merci d'avance! P> P>
3 Réponses :
La boucle plus de 55 000 objets ne devrait pas être trop lente. Évidemment, vous faites trop de choses trop souvent sur ces objets et que vous faites probablement des choses qui ne devraient pas toujours être faites. p>
Par exemple, s'il n'y a pas de joueurs autour d'une foule, devrait-il vraiment être calculé? (Si un arbre tombe dans une forêt et il n'y a personne autour, cela fait-il vraiment un son?) p>
En outre, beaucoup d'objets peuvent ne pas avoir besoin d'être mis à jour à chaque boucle. Les joueurs par exemple pourraient être laissés au client pour calculer et seulement être "vérifié" une fois toutes les 1-2 secondes. Dumping Toute la collision du joueur au client rendrait la charge de travail de votre serveur beaucoup plus facile à gérer. Mêmes choses pour la balle du joueur ou Raycast. En retour, cela rend également le jeu beaucoup plus de liquide pour les joueurs. P>
fait des mobs lorsque la suite d'un chemin doit être testé pour collision ou que les nœuds du chemin peuvent être suffisants? P>
Tester tous les objets contre tous les autres objets est terrible. Est-ce que toutes les mobs doivent être testés vs tous les autres mobs ou que seuls un type ou une faction spécifique doivent être testés? Pouvez-vous diviser votre monde en une zone plus petite qui ne ferait que tester des mobs contre des objets aussi? P>
Il y a un travail énorme fait dans le code du serveur MMO pour le faire fonctionner correctement. Les optimisations effectuées sont parfois insensées, mais aussi longtemps que cela fonctionne. P>
Vous êtes intelligent, je savais que quelqu'un allait parler de la «chute de l'arbre de la forêt». Le fait est que je considère toujours si des mobs, même si ce n'est pas dans la portée visuelle de tous les joueurs, se déplacerait toujours, construisant nid ou migration. Mais encore une fois, je pourrais probablement simplement mettre en œuvre la logique différemment.
@Armz Très bien ... Mais pouvez-vous simplifier leur boucle, leur mouvement, leur collision s'ils ne sont pas près d'un joueur? S'ils vont à une position, vous ne pouviez que interpoler entre deux points. Aucune collision, pas d'animation, pas de rayoncast, aucune ligne de vue ... beaucoup de choses peuvent être faites pour faciliter la charge de travail.
Absolument, je trouverai un moyen de mettre en œuvre la logique hors visualisation. Merci!
Votre code est en cours d'exécution, non seulement parce qu'il vérifie tous les objets N, mais parce qu'il vérifie toutes les interactions possibles d'objets, ce qui prend des calculs N ^ 2 = 3 025Â 000 dans votre échantillon.
un moyen de réduire ce nombre de chèques consisterait à mettre l'objet dans votre monde de jeu dans une grille, de sorte que les objets qui ne soient pas dans les mêmes cellules ou alignées ne puissent pas interagir les uns avec les autres. p>
aussi, votre actuel Code vérifie chaque fois chaque interaction, vous pouvez facilement résoudre ce problème en démarrant la boucle de i dans votre cycle interne: p>
Je vais enquêter sur l'idée de la grille lors de la division du monde dans différentes zones et sous-zones. Merci!
Je changerais complètement la conception et implémenteriez une conception de base d'événement. Cela présente de nombreux avantages, l'une est évidente que vous n'aurez besoin que de mettre à jour les objets en cours d'interaction. Comme vous aurez toujours la majorité des objets de jeu dans un jeu MMO étant inactif, ou pas du tout. P>
Il n'y a aucune raison pour que vous puissiez calculer des objets qui ne sont visibles sur aucun écran de joueurs. Ce serait fou et nécessiterait une ferme de serveur que vous ne pouvez probablement pas vous permettre. Au lieu de cela, vous pouvez essayer de prédire le mouvement. Ou stockez une liste de tous les objets qui ne sont actuellement pas interagisés et les mettent à jour moins fréquemment. p>
Si un joueur ne peut pas voir un objet, vous pouvez téléporter l'appareil sur de grandes distances au lieu de le voyager en douceur. Déplacement essentiellement l'unité sur d'énormes distances dans la zone confinée que l'objet est autorisé à bouger. Il semble que l'objet se déplace librement même lorsque l'objet n'est pas visible pour les joueurs. Cela serait généralement déclenché comme un événement lorsqu'un nouveau joueur entre ou quitte une zone. P>
Vous pouvez y parvenir simplement en calculant simplement l'heure depuis la dernière mise à jour et prédisez jusqu'où l'objet aurait voyagé, comme s'il était visible au joueur. Ceci est particulièrement utile pour les objets ou les PNJ qui a un itinéraire défini, car il rend les calculs beaucoup plus simples. P>
Merci pour la réponse, je penserai certainement à un moyen de mettre en œuvre une logique de commandes basées sur des événements ainsi que de diviser mon monde dans des zones / sous-zones à l'intérieur d'une grille.
Oui, vous auriez certainement besoin de combiner cela avec un système de zone. :)
J'irais avec une conception basée sur l'événement qui ne nécessite qu'un objet à mettre à jour si nécessaire.
Pour le cas du code de contrôle de la plage, vous devez utiliser un arbre quadruple ( en.wikipedia.org/wiki/ Quad_tree ) (ou similaire) Structure. Ça va l'empêcher de toujours être n ^ 2.
Notez que même si l'approche n'est pas correcte, je voudrais mentionner que vous n'utilisez pas 2 cœurs dans cette boucle, aucune multithreading impliquée, vous gaspillez 50% de votre pouvoir de processeur.
Bien sûr @ Fire-Dragon-Dol, mais cela ne résoudrait pas le problème fondamental, au mieux, il faudrait 4-5 minutes, au lieu de 8.
@eandresson: Oui, c'est évident. Je voulais juste souligner que vous ne pouvez pas vous attendre à une bonne utilisation du processeur si votre code ne se soucie pas de cela.
Merci pour la réponse Fire-Dragon-Dol. J'avais effectivement envisagé de tirer parti de multi-noyau lors d'une phase d'optimisation.