Sauvegarder l'état du jeu roguelike?

11

Je travaille sur un roguelike de base en utilisant HTML5 et jQuery, et j'ai rencontré un problème.

Dans l'état actuel du jeu, le système enregistre uniquement l'état du jeu chaque fois que l'utilisateur se déplace entre les étages - pour minimiser les frais généraux. Le danger est que, si l'utilisateur a des ennuis, il peut simplement fermer la fenêtre et retourner à son jeu au début de l'étage actuel. Cela réduit considérablement la difficulté du jeu (et va presque à l'encontre du but d'un roguelike) - mais il est déraisonnable de sauvegarder l'état du jeu à chaque mouvement ou attaque d'un seul joueur.

J'ai cherché des moyens de sauvegarder l'état du jeu à la fermeture de la fenêtre du navigateur, mais je n'en suis pas satisfait. Ma question est la suivante: en supposant que "sauvegarder un état de jeu" signifie une demande ajax / post modérément lourde, comment puis-je contrecarrer ce comportement de triche? Existe-t-il une méthodologie connue pour quantifier les modifications incrémentielles / procédurales d'une carte 2D, au lieu d'enregistrer la totalité de l'état de la carte? Veuillez noter que je ne demande pas «le moyen le plus efficace» - je recherche des méthodologies existantes pour rectifier mon inexpérience.

CodeMoose
la source
Question de programmation JavaScript très générique et générale. J'ai voté contre, mais j'ai repensé car c'est assez intéressant si vous considérez comment vous le feriez si vous ne pouviez pas déclencher un événement de déchargement.
Tim Holt le
Peut-être que je vais reformuler pour résoudre ce problème directement =)
CodeMoose
@TimHolt - modifié selon votre suggestion
CodeMoose

Réponses:

8

La solution évidente consiste à envoyer chaque commande de joueur au serveur au fur et à mesure de sa création et à ce que le serveur les enregistre; de cette façon, si le jeu est abandonné pour une raison quelconque, les commandes enregistrées peuvent être rejouées pour restaurer le jeu au point où il s'est arrêté.

Bien sûr, lorsqu'une sauvegarde correcte est effectuée, l'ancien journal des commandes peut être jeté (bien que vous puissiez également le sauvegarder pour autoriser la relecture d'anciens jeux; si vous le faites, vous souhaiterez peut-être inclure des horodatages dans le journal pour une relecture en temps réel ). Vous pouvez également vouloir effectuer automatiquement une sauvegarde complète après que n commandes ont été effectuées depuis la dernière sauvegarde (où, par exemple, n = 1000) pour éviter des replays trop longs si le joueur reste au même niveau trop longtemps avant de fermer ou de planter le jeu. .

Si votre jeu comporte des nombres aléatoires (et, étant un roguelike, il le fait probablement), vous devrez également vous assurer qu'ils peuvent être recréés correctement lors d'une relecture. Une solution consiste à inclure chaque nombre aléatoire dans le journal de relecture; une autre consiste à utiliser un générateur de nombres pseudo-aléatoires déterministes et à sauvegarder la graine lorsque le jeu est enregistré.

Notez que toutes ces méthodes peuvent être exploitées en altérant le client, mais c'est vraiment inévitable chaque fois que vous avez une logique de jeu sur le client. Comme alternative à la triche, vous pouvez exécuter le jeu réel sur le serveur et demander au client d'envoyer toutes les commandes des joueurs au serveur et de recevoir les mises à jour d'affichage. Pour un roguelike, cela peut être faisable. De toute évidence, cela résoudrait également votre problème d'enregistrement d'état (bien que vous souhaitiez toujours implémenter une forme de journalisation des commandes sur le serveur, à la fois pour la fonctionnalité de relecture et pour permettre la récupération après des pannes de serveur). L'inconvénient est que cela rendrait le jeu hors ligne impossible (à moins, bien sûr, que vous ne rendiez également le code côté serveur disponible pour que les joueurs puissent l'exécuter localement s'ils le souhaitent).

Ilmari Karonen
la source
1
AFAIK tous les RGN sont pseudo-aléatoires. Vous avez besoin d' un matériel spécialisé pour obtenir des valeurs aléatoires véritablement (non gérées).
bobobobo
1
@bobobobo il y a un pseudo-aléatoire (prédéfini) et il y a des nombres aléatoires sécurisés cryptographiquement (non amorcés) dans la plate-forme .Net. Il peut / peut ne pas être aléatoire au niveau du matériel, mais il est suffisamment proche pour ne pas pouvoir simplement stocker une graine.
Rangoric
2

Voir /programming/3888902/javascript-detect-browser-close-tab-close-browser pour une question plus générique de la même question.

Pensez également à enregistrer le jeu complet lors des changements de sol et des deltas incrémentiels à chaque coup. Ensuite, vous pouvez rejouer le jeu jusqu'au dernier coup.

En supposant qu'il existe une certaine utilisation de générateurs de nombres aléatoires, vous pouvez générer et redéfinir le générateur de nombres aléatoires au début de chaque nouvel étage, puis l'enregistrer avec l'étage. Ensuite, vous pouvez réensemencer à la charge et vous devriez pouvoir rejouer les mouvements avec la même séquence jusqu'au dernier.

Tim Holt
la source
Merci Tim - une fois que je suis dans l'état d'esprit du développeur de jeu, il est vraiment facile de regrouper tout ce qui le touche dans le développement de jeu. Accessoires pour fournir une réponse de toute façon.
CodeMoose
Pas de soucis - voir aussi mon commentaire révisé sur la question :)
Tim Holt
J'aurais aussi dit des deltas incrémentiels à chaque mouvement .
bobobobo
2

Approches, non pas des sauvegardes incrémentielles, mais de la recherche de temps pour une sauvegarde complète:

  • onunload, comme mentionné précédemment. J'ai trouvé que c'était fiable (mais en utilisant localStorage, pas en réseau, ce qui peut changer les choses).
  • Enregistrez lorsque votre fenêtre perd le focus.
  • Enregistrer périodiquement: lorsque la dernière sauvegarde n'a pas eu lieu en n minutes et que l'utilisateur n'a effectué aucune entrée en m secondes.
Kevin Reid
la source