Charger
Framework NonIA

Page principale NonIA

Développement

Jalons de développement
Suggestion de changements de l'API

Programmation de l'IA

Documentation API
Introduction
Fichier info.nut
Fichier main.nut
Principes de base
Détermination de chemin routier
Détermination de chemin ferroviaire
Sauver / Charger des données
Choses à savoir
Squirrel
Page principale
Erreurs courantes
Listes
Traiter les erreurs OTTD
Tramways
Bibliothèques de l'IA
Forum
FAQ du forum
Comportement de l'IA

IAs

TestAI
WrightAI
Convoy
Voir le forum
Voir BaNaNaS
Tous les articles de la catégorie NonIA

Contents

Sauvegarde

Si vous créez une fonction Save() dans votre IA, vous pouvez stocker certaines données dans la sauvegarde d'un jeu. La fonction doit renvoyer une table avec l'information que vous voulez stocker. Vous ne pouvez enregistrer que:

Les instances de classes ne peuvent pas être sauvegardées. Notez bien que cela comprend AIList; donc si vous voulez sauvegarder une AIList, vous devez la convertir en un tableau ou une table pour cela, et faire la conversion inverse au chargement.

Dès que les utilisateurs sauvegardent leur partie, la fonction Save() de votre IA est appelée. Cela a lieu alors que votre IA est encore active, en train de faire ce pour quoi elle est prévue. Par exemple, au milieu d'une détermination de chemin, ou peut-être alors que vous modifiez un tableau interne. Le point à prendre en compte est que votre IA ne le remarquera pas, en plus du fait que le Save() est appelé pendant un moment. Quand vous faites un retour de cette fonction, votre IA continuera comme si rien n'était arrivé. Attention: si vous changez une variable que vous stockez aussi, et voulez absolument éviter tout effet de bord, faites-le juste après un Sleep(). Les chances pour qu'un ordonnanceur équilibré de Squirrel prenne effet juste après un Sleep() sont très faibles, donc vous devriez y être assez à l'abri.

Note: Aucune autre information n'est sauvegardée; ainsi, par exemple, tous les événements en cours sont perdus dès que le jeu est chargé. Pour éviter cela, vous pouvez stocker vous-mêmes tous les événements (convertis en types autorisés) dans la sauvegarde. Cependant, le jeu continuera normalement après l'appel de la fonction Save(), donc vous devez aussi traiter ces événements.

Chargement

Si une sauvegarde avec une IA est chargée, OpenTTD essaye ce qui suit. Dès qu'une étape réussit, la séquence est stoppée:

Tout d'abord, le constructeur de votre IA est appelé, puis ensuite votre fonction Load(). Si une IA n'a sauvegardé aucune donnée, la fonction Load() ne sera pas appelée.

Quelles données sauvegarder?

Bien entendu, les données que vous sauvegardez exactement ne dépendent que de vous, mais en règle générale, vous n'avez pas besoin de sauvegarder tout ce qui peut être aisément détecté en regardant de nouveau la carte. Vous pouvez donc stocker une carte des liens entre aire de poids lourds et industrie, mais stocker uniquement une liste de gares est inutile.

Ce que vous ne pouvez pas faire dans vos fonctions Save() et Load()

Les deux fonctions Save() et Load() sont appelées depuis le processus principal. Cela veut dire qu'il n'est pas possible d'exécuter une commande qui construit / supprime / modifie quelque chose dans le jeu. Vous pouvez exécuter certaines fonctions de l'API, mais uniquement celles qui récupèrent des données. Essayez de minimiser le code dans Save() et Load(), car l'utilisateur doit attendre la fin de ces fonctions chaque fois qu'il sauvegarde ou charge une partie.

Gérer les versions de sauvegarde

Quand une partie est sauvegardée, le nom et la version de chaque IA est enregistré. Quand OpenTTD charge une partie, il tente de trouver une version de la même IA qui peut charger l'état du jeu depuis la version de l'IA utilisée dans la sauvegarde. Cela se fait en déclarant MinVersionToLoad() dans votre info.nut et en lui faisant renvoyer la version minimale de votre IA depuis laquelle il peut charger les données.

De plus, il y a un argument version à Load() qui indique à la fonction de chargement quelle version de votre IA a été utilisée pour sauvegarder l'état du jeu.

Exemple de code Save() / Load()

/* info.nut */
class testai extends AIInfo
{
  /* ... */

  function GetVersion() { return 3; }

  /* Accepte de charger les parties sauvées par une version >= 2 de cette IA */
  function MinVersionToLoad() { return 2; } 

  /* ... */
}
/* main.nut */
class testai extends AIController
{
  constructor()
  {
    counter = 0;
  }

  counter = null;
};

function testai::Save()
{
  local table = {counter_value = this.counter};
  return table;
}

function testai::Load(version, data)
{
  if (data.rawin("counter_value")) {
    this.counter = data.rawget("counter_value");
  }
}

function testai::Start()
{
  while(true) {
    AILog.Info("Tic " + this.counter);
    this.Sleep(70);
    this.counter++;
  }
}

Identifiants de sauvegardes

Comme divers NewGFX peuvent modifier plusieurs des types d'ID utilisés dans le jeu, voici une liste des types d'ID auxquels vous pouvez vous fier comme étant constants quand la sauvegarde est chargée.

Type d'ID Signification Stocké dans les sauvegardes Codé en dur dans les IAs Note
BridgeID Type de pont (ex.: tubulaire) [0] Non Utilisez la fonction AIBridge::* pour trouver le type de pont adéquat.
CargoID Type de cargaison [0] Non Vous pouvez filtrer la AICargoList en utilisant AICargo::CargoClass (ex. CC_PASSENGERS) ou AICargo::TownEffect (ex. TE_PASSENGERS) pour obtenir le cargoID des passagers
EngineID Type de locomotive [0] Non Utilisez les fonctions AIEngine::* pour trouver l'engineID qui correspond à vos besoins.
GroupID Groupe de véhicule Oui ---

IndustryID Industrie spécifique quelque part sur la carte. Oui ---

IndustryType Type d'industrie, par ex. mine de charbon [0] Non Utilisez AIIndustryList_CargoAccepting et AIIndustryList_CargoProducing pour trouver les paires correspondantes.
SignID Un signe quelque part sur la carte. Oui ---

StationID Une station spécifique quelque part sur la carte. Oui ---

SubsidyID Subvention Oui (mais est réutilisé quand la subvention expire) ---

TileIndex Une case quelque part sur la carte. Oui ---

TownID Une ville quelque part sur la carte. Oui ---

VehicleID Véhicule Oui ---

WaypointID Point de passage Quelquefois --- En mettant à jour des sauvegardes d'avant la r16909, donc en effet de 0.7.x à 1.0.x ou ultérieur, les IDs changeront s'il y a des gares dans le jeu.

[0] Il peut être prudent de les stocker, mais ils peuvent changer quand la configuration des NewGRF change. Normalement, les utilisateurs ne devraient pas les modifier; donc, si votre IA plante à cause d'un de ces changements, blâmez l'utilisateur. Notez que la configuration NewGRF peut aussi changer en cours de partie, et dans ce cas, vous ne pouvez rien faire si un de ces IDs change (vous pouvez recalculer les IDs chaque fois que vous les utilisez, mais ce n'est guère pratique).