Kepler. Documentation · Scripts 325 fonctions disponibles actuellement English

Célestes et ressources

Vos planètes et vos lunes, ce qu'elles produisent, ce qu'on y a construit. C'est la famille la plus employée : presque tout script commence par savoir où il est et ce qu'il a.

Ce que la version 13 a changé, et ce que vous n'avez pas à faire

En version 13 du jeu, plusieurs pages ont changé de nature. Les lectures qui les utilisaient échouent chez tout le monde, et leur message ne dit pas la vraie cause :

  • page=fetchResources et page=fetchTechs rendent désormais la page de jeu entière au lieu du JSON attendu. La lecture accuse alors votre identifiant de céleste (« invalid planet id ») alors qu'il est bon.
  • la page du commissaire-priseur ne porte plus la variable que la lecture groupée y cherchait, d'où « failed to get resources json », qui laisse croire à un JSON absent.
  • l'adresse des curseurs de production a changé de casse, et le serveur répond « An error has occured! ».

Cinq fonctions de cette page ont été réparées. Elles essaient d'abord la voie normale, et prennent une voie de secours quand elle ne répond pas. C'est transparent : vous les appelez comme avant, elles rendent le même nombre de valeurs qu'avant. Le jour où la voie normale répondra de nouveau, le secours ne servira plus, sans que vous ayez une ligne à changer.

FonctionCe que fait le secoursCe qu'il coûte en plus
GetResourcesrelit les ressources à la nouvelle adresse1 requête
GetResourcesDetailsla même1 requête
GetAllResourcespasse par la page d'empire, planètes puis lunes2 requêtes
GetTechsrecompose le relevé par cinq lectures qui, elles, répondent5 requêtes, environ 1,5 s contre 0,3 s
GetResourceSettingsrelit les curseurs sur la page en minuscules1 requête

Ces coûts s'ajoutent à l'essai perdu sur la voie normale, puisque c'est son échec qui déclenche le secours.

Sur un céleste, la même réparation

Ninja propose partout une seconde écriture, sur le céleste : resources, err = celestial.GetResources(). Elle passe par la même réparation que la fonction : même secours, même coût, même résultat, et elle attend comme elle la fin du mode manuel. Les deux écritures se valent.

c = GetCachedCelestial("1:2:3")

res, err = c.GetResources()          // ✓ passe par le secours
res, err = GetResources(c.GetID())   // ✓ la même lecture

Cela vaut pour GetResources, GetResourcesDetails et GetTechs sur une planète comme sur une lune, pour GetResourceSettings et GetResourcesProductions sur une planète, et pour Phalanx sur une lune. Jusqu'à la version 1.82.322 comprise, ces méthodes-là échouaient en version 13 : si un de vos scripts les a remplacées par les fonctions, il n'a rien à changer.

Trois précisions :

  • GetTechs() rend une seule structure. Sur une planète, c'est le relevé entier de GetTechs2, formes de vie comprises ; sur une lune, celui de GetTechs.
  • planet.GetResourceSettings() déclenchait dix tentatives avec attente croissante avant d'abandonner. Mesuré le 02/09/2026 sur un compte réel : 4 min 14 s pendant lesquelles le compte était retenu, sans worker, sans écran, sans navigateur intégré. Comme la fonction, elle renonce désormais au réessai : son premier échec tombe en trois cents millisecondes, et elle lit ensuite la bonne page.
  • planet.GetResourcesProductions() lisait les curseurs par ce même chemin et calculait ensuite sur des curseurs à zéro. Elle lit à présent les bons, et une lecture qui échoue lui fait rendre une erreur plutôt qu'un chiffre faux.

Savoir où l'on est

FonctionRend
GetUniverseName()1 : une chaîneLe nom de l'univers.
GetServerNumber()1 : un entierLe numéro du serveur : s152-en donne 152.
GetLang()1 : une chaîneLe code de langue du serveur, fr, en…
IsLoggedIn()1 : un booléenDit si la session est ouverte.
Printf("%s s%d-%s", GetUniverseName(), GetServerNumber(), GetLang())

Sans session, ces quatre-là rendent la valeur nulle : chaîne vide, zéro, faux. Ce sont les seules de la page à ne rien écrire au journal dans ce cas, parce que cette valeur nulle dit déjà tout ce qu'il y a à dire.

GetLang et GetServerNumber sont propres à Kepler. Ninja les connaît, mais comme méthodes de son objet interne IVMBot, pas comme fonctions offertes à vos scripts.

Savoir qui l'on est

FonctionRend
CharacterClass()1 : un entierLa classe : NO_CLASS, COLLECTOR, GENERAL ou DISCOVERER.
IsCollector()1 : un booléenRaccourci sur la classe.
IsGeneral()1 : un booléenLe même.
IsDiscoverer()1 : un booléenLe même.
HasCommander()1 : un booléenL'officier est-il engagé.
HasAdmiral()1 : un booléenLe même.
HasEngineer()1 : un booléenLe même.
HasGeologist()1 : un booléenLe même.
HasTechnocrat()1 : un booléenLe même.
IsVacationModeEnabled()1 : un booléenLe compte est-il en mode vacances.
IsPioneers()1 : un booléenLe compte passe-t-il par le lobby « pioneers ».

Ces onze-là changent les chiffres de tout le reste. Un Collector porte plus, un Général vole plus vite, un Géologue produit un dixième de plus, un Amiral ajoute des emplacements de flotte et d'expédition, un Technocrate coupe un quart de chaque recherche. Un script qui calcule une charge, une durée de vol ou un ordre de construction sans les lire se trompe d'autant, et rien dans sa sortie ne le dira.

if IsCollector() {
	Print("charge majorée, vitesse de transporteur majorée")
}
if !HasAdmiral() {
	Print("moins d'emplacements de flotte que vous ne croyez")
}
if IsVacationModeEnabled() {
	LogWarn("mode vacances : rien ne partira, ce n'est pas une panne du script")
	return
}

Tout se lit au cache, sans une requête au jeu. Ces valeurs arrivent avec chaque page complète que le robot charge de toute façon. Les appeler dans une boucle ne coûte donc rien, et n'attend pas son tour dans la file.

IsVacationModeEnabled mérite un mot. Rien ne vole et rien ne se construit tant que le mode vacances est actif. Un script qui l'ignore lit chaque refus du jeu comme une panne de son propre code, et peut insister des heures.

IsPioneers n'est pas une classe, malgré le voisinage : c'est un autre lobby de Gameforge, celui par lequel passent certains serveurs. Le compte y joue de la même façon.

Mettre le compte en vacances

FonctionRend
SetVacationMode()1 : une erreurGèle le compte. Quarante-huit heures au minimum.

Rien ne l'annule avant deux jours - ni vous, ni le support, ni nous. C'est le jeu qui l'impose. C'est aussi la seule fonction de toute cette API dont un appel de trop ne se rattrape pas : une flotte se rappelle, un worker se rallume, une campagne se relance ; un mode vacances, non.

Elle refuse par défaut. Il faut avoir coché « autoriser un script à mettre le compte en vacances » dans les paramètres du robot, onglet « Généralités ». Case décochée, la fonction ne touche pas au jeu et rend une erreur qui nomme la case : un script recopié d'un forum se heurte donc au refus, pas au gel.

err = SetVacationMode()
if err != nil {
	LogWarn("vacances refusées : " + err.Error())
}

La case est relue à chaque appel. La décocher reprend effet tout de suite, sans rien redémarrer.

Les planètes et les lunes

FonctionRend
GetPlanets()1 : une listeToutes vos planètes.
GetMoons()1 : une listeToutes vos lunes.
GetPlanet(quoi)2 : la planète et une erreurUne planète précise.
GetMoon(quoi)2 : la lune et une erreurUne lune précise.
GetCelestial(quoi)2 : le céleste et une erreurUne planète ou une lune précise, l'une ou l'autre.
GetCelestials()2 : la liste et une erreurToutes vos planètes et lunes ensemble.
GetCachedCelestial(quoi)1 : un célesteLe céleste tel que le robot le connaît déjà.
GetCachedCelestials()1 : une listeToutes vos planètes et lunes, telles que le robot les connaît déjà.
GetCachedPlanets()1 : une listeVos planètes, prises dans le même cache.
GetCachedMoons()1 : une listeVos lunes, prises dans le même cache.
planetes = GetPlanets()               // UNE cible : la liste
Print(len(planetes), "planetes")

p, err = GetPlanet("1:2:3")           // DEUX cibles, la doc annonce l'erreur
if err != nil { LogError(err) }

GetPlanets et GetMoons rendent une seule valeur. Écrites planetes, err = GetPlanets(), elles laisseraient err non défini, avec les conséquences décrites au second piège.

Ce qui coûte une requête et ce qui n'en coûte pas. GetPlanets, GetMoons, GetPlanet, GetMoon, GetCelestial et GetCelestials relisent tous la même page d'aperçu du jeu, à chaque appel - GetCelestial comme GetCelestials n'y échappent pas, malgré un nom qui ressemble à GetCachedCelestial. GetCachedCelestial, GetCachedCelestials, GetCachedPlanets et GetCachedMoons ne demandent rien : elles répondent depuis ce que le robot a déjà en mémoire. Dans une boucle, préférez toujours une forme Cached.

Comment désigner un céleste. Un céleste se désigne par un identifiant (un nombre) ou par une coordonnée, "1:2:3" ou "M:1:2:3". Le préfixe P, M ou D est optionnel et vaut planète par défaut. Toutes les fonctions de cette page qui prennent un céleste acceptent ces formes. coord, err = ParseCoord("M:1:2:3") fait cette lecture pour vous, sans requête : elle rend une erreur si le préfixe n'est ni P, ni M, ni D.

Un nombre n'est pas vérifié. Les relevés (ressources, bâtiments, chantiers, curseurs) l'envoient tel quel au jeu, sans le chercher dans le cache. C'est voulu : cela vous permet de ranger un identifiant avec Put et de le relire au démarrage suivant, avant même que la liste des célestes soit chargée. En contrepartie, un numéro faux n'est refusé que par le jeu, pas par le robot. GetCachedCelestial, GetFields et GetDiameter, elles, passent par le cache.

Céleste introuvable : GetCachedCelestial rend nil. La méthode que vous enchaînez dessus échouera alors franchement, et le script s'arrêtera. C'est voulu : mieux vaut cela qu'un identifiant inventé qui partirait dans un ordre de flotte.

Choisir la base la plus proche

FonctionRend
GetSortedCelestials(destination)1 : une listeVos célestes, du plus proche au plus loin.
GetSortedPlanets(destination)1 : une listeVos planètes seules.
GetSortedMoons(destination)1 : une listeVos lunes seules.
base = GetSortedPlanets("4:212:9")[0]     // la plus proche de la cible
Print("on part de", base.GetName())

À distance égale, les lunes passent avant les planètes. Une lune porte la coordonnée de sa planète, donc sa distance : c'est ce qui produit à la fois l'ordre M1, P1, M2, P2 quand les distances diffèrent, et « toutes les lunes puis toutes les planètes » quand elles sont égales.

La destination doit être une coordonnée, écrite "4:212:9", ou un objet qui en porte une, un céleste par exemple. Un simple identifiant de céleste n'est pas accepté : la fonction rend alors une liste vide et note l'échec au journal.

Ces trois lectures travaillent sur le cache. Elles ne coûtent aucune requête, et rendent une liste vide sans session.

Les ressources

FonctionRend
GetResources(céleste)2 : les ressources et une erreurMétal, cristal, deutérium, énergie, matière noire, population, nourriture.
GetResourcesDetails(céleste)2 : le détail et une erreurLes mêmes, avec la capacité de stockage et la production.
GetAllResources()2 : une table et une erreurLes ressources de tous les célestes d'un coup.
r, err = GetResources("1:2:3")
if err != nil { LogError(err); return }
Print(r.Metal, r.Crystal, r.Deuterium)

d, err = GetResourcesDetails("1:2:3")
Print("metal", d.Metal.Available, "sur", d.Metal.StorageCapacity)
Print("production", d.Metal.CurrentProduction, "par heure")

La production est horaire. La page de version 13 la sert à la seconde ; elle est convertie avant de vous parvenir, pour coller à ce que le jeu affiche. C'est la production réelle, officiers, objets et formes de vie compris.

Sur un serveur en version 13, le détail est partiel. La voie de secours remplit ce que la nouvelle page donne, et rien de plus. Restent donc à zéro, sans que ce zéro soit un fait de jeu :

  • Energy.CurrentProduction et Energy.Consumption, alors que Energy.Available est juste,
  • Food.StorageCapacity, Food.Overproduction et le reste du bloc nourriture,
  • tout Population sauf Available,
  • Darkmatter.Purchased et Darkmatter.Found.

GetAllResources rend une table dont la clé est l'identifiant du céleste.

toutes, err = GetAllResources()
if err != nil {
	LogWarn("relevé groupé indisponible, on repasse céleste par céleste")
} else {
	for p in GetPlanets() {
		Print(p.GetName(), toutes[p.GetID()].Metal)
	}
}

Prévoyez son échec. Elle refuse volontairement de rendre un relevé incomplet : une moitié muette, vos planètes sans vos lunes, vous ferait conclure que vous n'avez pas de lune. Elle rend alors une erreur, et c'est à votre script de retomber sur GetResources, céleste par céleste.

Ce contrôle compare le relevé à la liste des célestes que la session connaît. Tant que cette liste est vide, juste après le démarrage, il ne peut pas jouer.

L'empire en une requête

FonctionRend
GetEmpire(type)2 : une liste et une erreurTout d'une nature de célestes : ressources, mines, installations, défenses, vaisseaux.
// DEUX cibles. Écrit « for c in GetEmpire(PLANET_TYPE) », la boucle tournerait
// deux fois : une sur la liste, une sur l'erreur. C'est le premier piège.
empire, err = GetEmpire(PLANET_TYPE)
if err != nil { LogError(err); return }
for c in empire {
	Print(c.Name, c.Coordinate, c.Resources.Metal, c.Supplies.MetalMine)
}

Le type se donne avec PLANET_TYPE ou MOON_TYPE. DEBRIS_TYPE n'a pas de sens ici et ressort en erreur.

Les champs qu'on lit d'une entrée : Name, ID, Type, Coordinate, Diameter, Fields, Temperature, Resources, Supplies (les mines et entrepôts), Facilities, Defenses, Ships et Researches.

C'est la lecture la plus économique du lot : une requête par nature de céleste, là où un relevé unitaire en demanderait quatre par planète. Elle vous coûte aussi moins d'activité : un relevé céleste par céleste inscrit une activité sur chacun d'eux, que vos voisins lisent dans la galaxie.

Gardez un repli. Cette page est optionnelle dans le jeu, et sa forme a déjà changé d'une version à l'autre.

Ce qu'il y a sur un céleste

FonctionRend
GetResourcesBuildings(céleste)2 : les niveaux et une erreurLes neuf : mines, centrale, réacteur à fusion, satellites, entrepôts.
GetFacilities(céleste)2 : les niveaux et une erreurLes onze : usines, chantier, labo, dépôt, silo, terraformeur, dock, base lunaire, phalange, porte de saut.
GetShips(céleste)2 : les vaisseaux et une erreurCe qui est posé là, pas ce qui vole.
GetDefense(céleste)2 : les défenses et une erreurMissiles compris.
GetTechs(céleste)6 : bâtiments, installations, vaisseaux, défenses, recherches, une erreurTout le relevé d'un coup.
GetTechs2(céleste)8 : les six ci-dessus, plus les bâtiments et les recherches de forme de vieLe relevé entier d'un céleste.
GetResearch()1 : vos recherchesElles appartiennent au compte, pas au céleste : aucun argument.
// SIX cibles. C'est la fonction de la page qui en demande le plus.
bat, inst, vais, def, rech, err = GetTechs("1:2:3")
if err != nil { LogError(err); return }
Print(bat.MetalMine, inst.RoboticsFactory, vais.LargeCargo, rech.Astrophysics)

Ces quatre relevés répondent en version 13, et une cinquième lecture avec eux, GetResearch, qui appartient au compte et non au céleste. C'est sur ces cinq que s'appuie le secours de GetTechs. GetResearch ne rend qu'une valeur, sans erreur : une lecture qui échoue rend des recherches vides et le dit au journal.

GetTechs n'est plus la lecture la moins chère. Tant que le secours sert, elle coûte six requêtes, l'essai perdu compris, là où les quatre relevés séparés en coûtent quatre. Elle rend en plus les recherches, que ces quatre-là ne donnent pas. Si vous n'avez besoin que des mines, appelez GetResourcesBuildings.

Les quatre relevés savent répondre par identifiant, ce qui permet de boucler sur les tableaux de constantes.

bat, err = GetResourcesBuildings("1:2:3")
Print("mine de metal", bat.ByID(METALMINE))

Attention en bouclant sur BuildingsArr, qui compte vingt-trois entrées : ByID d'un relevé de bâtiments ne connaît que les neuf bâtiments de ressources, et celui des installations que les onze installations. Les trois entrepôts protégés, SHIELDEDMETALDEN, UNDERGROUNDCRYSTALDEN et SEABEDDEUTERIUMDEN, ressortent donc toujours à zéro par ce chemin.

GetTechs2 rend le relevé ENTIER, formes de vie comprises, en un seul appel :

// HUIT cibles, et l'erreur en dernier comme chez Ninja.
bat, inst, vais, def, rech, lfBat, lfRech, err = GetTechs2("1:2:3")
if err != nil { LogError(err); return }
Print(bat.MetalMine, inst.RoboticsFactory, rech.Astrophysics)

Elle coûte sept requêtes tant que le secours sert, contre cinq pour GetTechs : les deux lectures de forme de vie s'ajoutent. Un appel au lieu de cinq côté script, et une seule transaction - le céleste ne change pas d'état au milieu du relevé, ce qu'une jointure écrite à la main ne peut pas garantir.

L'exemple de la référence de Ninja est faux sur cette fonction. Il affecte huit cibles sans erreur là où sa propre déclaration met l'erreur en huitième position. C'est la déclaration qui fait foi ici.

Les chantiers en cours

FonctionRend
GetProduction(céleste)3 : la file, les secondes restantes, une erreurVaisseaux et défenses au chantier spatial.
ConstructionsBeingBuilt(céleste)4 : bâtiment, secondes, recherche, secondesLe bâtiment et la recherche en cours.
file, restant, err = GetProduction("1:2:3")
for q in file {
	Print(q.ID, "x", q.Nbr)
}
Print("file vide dans", restant, "secondes")
// QUATRE valeurs, et AUCUNE erreur. Une cinquième cible resterait non définie.
bID, bSec, rID, rSec = ConstructionsBeingBuilt("1:2:3")
if bID != 0 {
	Print("en construction :", bID, "encore", bSec, "s")
}

Les trois décomptes sont en secondes, mais pas pour la même raison. GetProduction rend celui que le jeu écrit lui-même, en secondes. ConstructionsBeingBuilt convertit : la bibliothèque de jeu porte ses deux décomptes en nanosecondes, et sans cette conversion dix minutes de chantier se liraient 600 000 000 000.

Zéro se lit « rien en construction », et c'est aussi ce que rend un échec. ConstructionsBeingBuilt n'a pas de valeur de retour où loger une erreur : page illisible ou session fermée, elle rend quatre zéros, comme un céleste au repos. Le seul moyen de les distinguer est le journal, où l'échec est noté. Un script qui relance un chantier sans le vérifier peut donc en lancer un de trop.

ConstructionsBeingBuiltLf, pour les formes de vie, n'existe pas encore.

Les curseurs de production

FonctionRend
GetResourceSettings(planète)2 : les réglages et une erreurLes sept curseurs de rendement.
reg, err = GetResourceSettings("1:2:3")
if err != nil { LogError(err); return }
Print(reg.MetalMine, reg.CrystalMine, reg.DeuteriumSynthesizer)
Print(reg.SolarPlant, reg.FusionReactor, reg.SolarSatellite, reg.Crawler)

Planètes seulement. Une lune n'a pas de mines à régler, et vous n'obtiendrez qu'une erreur en lui en demandant.

Un curseur absent ressort à zéro. Une planète sans satellite ni foreuse n'en a que cinq sur sept, et la structure rendue n'a pas de place pour dire « absent ». Ne concluez donc pas d'un zéro que le bâtiment est bridé.

En revanche, une page dont aucun curseur ne serait lisible est refusée franchement, par une erreur. Vous ne lirez jamais « tout à 0 % » sur une planète réglée à cent.

Il n'y a pas de réglage en écriture : SetResourceSettings n'existe pas encore.

La fiche d'un céleste

FonctionRend
GetFields(céleste)1 : les champs, Built et Total
GetDiameter(céleste)1 : un entierLe diamètre, en kilomètres.
ch = GetFields("1:2:3")
Print("libres :", ch.Total - ch.Built)
Print("rayon :", GetDiameter("1:2:3") / 2)

Ces deux-là lisent le cache, sans requête. Elles ne bougent pas d'une session à l'autre, sauf champs gagnés par un terraformeur.

Une seule valeur chacune, et c'est ce qui permet de les mettre dans un calcul : GetDiameter(c) / 2 donne bien la moitié du diamètre. Une fonction qui rendrait deux valeurs, elle, y donnerait zéro sans la moindre erreur. C'est le défaut que ces deux-là avaient avant réparation, et c'est ici qu'il faisait le plus de dégâts.

Ces deux fonctions globales sont propres à Kepler. Ninja ne connaît que les méthodes du céleste, c.GetFields() et c.GetDiameter(), qui marchent aussi et rendent la même chose.

Lancer et annuler un chantier

FonctionRend
Build(céleste, quoi, nombre)1 : une erreurBâtiment, technologie, vaisseau ou défense.
BuildBuilding(céleste, bâtiment)1 : une erreurRefuse ce qui n'est pas un bâtiment.
BuildTechnology(céleste, technologie)1 : une erreurRefuse ce qui n'est pas une technologie.
TearDown(céleste, bâtiment)1 : une erreurDémolit un niveau.
CancelBuilding(céleste)1 : une erreurAnnule le chantier en cours.
CancelResearch(céleste)1 : une erreurAnnule la recherche en cours.

Le céleste s'écrit comme partout ailleurs : une coordonnée "1:2:3", une fiche rendue par GetCachedCelestial, ou un identifiant nu.

Le nombre ne compte que pour ce qui se compte. Zéro sur une mine ou une technologie demande le niveau suivant : c'est la convention de l'outil de référence, pas un cas particulier.

c = GetCachedCelestial("1:2:3")
err = Build(c.GetID(), LIGHTFIGHTER, 5)
if err != nil { LogError("chasseurs :", err) }
Build(c.GetID(), LIGHTLASER, 5)
BuildBuilding(c.GetID(), METALMINE)
BuildTechnology(c.GetID(), ENERGYTECHNOLOGY)
TearDown(c.GetID(), SOLARPLANT)
CancelBuilding(c.GetID())
CancelResearch(c.GetID())

À lire avant de s'en servir : votre script et le Brain visent le même chantier. Le jeu n'en accepte qu'un par céleste, donc le second arrivé est refusé — et lequel des deux arrive en second ne se décide pas, il se constate. Ce n'est pas un défaut du robot, c'est la règle du jeu.

Choisissez donc, céleste par céleste : votre script ou le Brain, jamais les deux. StopBrain() éteint le Brain partout ; pour ne le retirer que d'un céleste, videz sa file depuis le panneau.

Annuler ce qui n'existe pas ne rend AUCUNE erreur. Vérifié en jeu le 05/09/2026 : CancelBuilding et CancelResearch sur un céleste qui ne construit rien rendent nil, comme si le geste avait eu lieu. Ne vous fiez donc pas au retour pour savoir s'il y avait quelque chose à annuler ; lisez ConstructionsBeingBuilt avant, si la réponse vous importe.

Quand il y avait bien un chantier, le jeu rend TOUT. Mesuré en jeu le 05/09/2026 sur un vrai compte : la mine de métal lancée puis annulée dans la même minute a laissé le stock identique à l'unité près. C'est la démolition, TearDown, qui n'en rend que la moitié.

Et ne jugez pas une commande de vaisseaux sur la file de production. Sur un univers rapide, trois petits transporteurs sont finis avant que la lecture suivante n'arrive : la file paraît vide alors que la commande est passée. Comptez les vaisseaux, pas la file.

Les formes de vie

FonctionRend
GetLfBuildings(céleste)2 : les bâtiments et une erreurUne requête à chaque appel.
GetLfResearch(céleste)2 : les recherches et une erreurUne requête à chaque appel.
GetLfBonuses()2 : les bonus et une erreurRelit les bonus dans le jeu.
GetCachedLfBonuses()2 : les bonus et une erreurCe que le robot sait déjà. Aucune requête.
GetPlanetLifeformType(planète)1 : la forme de vieUne requête. Sans erreur : voir plus bas.
c = GetCachedCelestial("1:2:3")
b, err = GetLfBuildings(c.GetID())
if err != nil { LogError("formes de vie :", err) }

rech, err = GetLfResearch(c.GetID())
Print(rech, err)

bonus, err = GetCachedLfBonuses()
Print(bonus, err)

frais, err = GetLfBonuses()
Print(frais, err)

Les bonus changent vos calculs. Ils portent sur la production, la vitesse et le fret : un script qui chiffre un transport sans eux raisonne sur un parc qui n'existe plus. CalcCargo et la famille des vols en tiennent déjà compte pour vous ; c'est votre propre arithmétique qui a besoin de les lire.

Laquelle des deux fonctions de bonus prendre. GetCachedLfBonuses ne coûte rien et suffit dans une boucle : les bonus ne bougent qu'avec vos recherches. GetLfBonuses relit le jeu, ce qui n'a d'intérêt qu'après en avoir terminé une. Le cache d'un compte qui vient de se connecter est vide et rend une erreur, plutôt que des zéros qui se liraient comme une vérité.

Les recherches valent pour le compte entier, mais le jeu les range sur le céleste depuis lequel on les consulte : d'où l'argument, que l'outil de référence demande aussi.

Quand une lecture échoue

Deux régimes cohabitent sur cette page, et la colonne « Rend » vous dit lequel s'applique.

Les fonctions qui rendent une erreur vous la remettent : testez-la.

Les autres n'ont nulle part où la loger. Elles rendent la valeur nulle, liste vide, zéro, nil, ou quatre zéros pour ConstructionsBeingBuilt, et écrivent une ligne au journal du robot, page Journaux, au niveau Warn :

api de célestes : lecture impossible   script=ma-passe   fonction=GetPlanets   err=compte non connecté

Cette ligne ne va pas dans la console de votre script, seulement au journal. C'est le premier endroit à regarder quand un script se met à croire que vous n'avez plus de planètes.

Seules GetUniverseName, GetServerNumber, GetLang et IsLoggedIn se taisent : leur valeur nulle dit déjà « pas de session ».

Les formes de vie, au-delà des niveaux

FonctionRend
CancelLfBuilding(céleste)1 : une erreurAnnule le bâtiment de forme de vie en cours.
GetLfResearchDetails(céleste)2 : le détail et une erreurCoûts, durées et ce qui est ouvert.

La file des formes de vie est SÉPARÉE de celle des bâtiments ordinaires. Annuler l'une ne touche pas l'autre, et un céleste peut construire dans les deux à la fois : CancelBuilding et CancelLfBuilding ne se remplacent donc pas.

GetLfResearchDetails lit une page du jeu, là où GetLfResearch se contente des niveaux déjà connus. À ne pas mettre dans une boucle sur vingt célestes.

Les chapitres, et le choix d'une recherche de forme de vie

FonctionRend
GetChapter(chapitre)2 : le chapitre et une erreurSes tâches, et l'état de chacune.
ChapterCollectReward(tâche)1 : une erreurRamasse la récompense d'une tâche.
ChapterClaimAll(chapitre)1 : une erreurRamasse tout ce qui est ramassable.
SelectLfResearchSelect(planète, emplacement)1 : une erreurValide la recherche proposée.
SelectLfResearchRandom(planète, emplacement)1 : une erreurEn retire une autre au sort.
SelectLfResearchArtifacts(planète, emplacement, techno)1 : une erreurL'échange contre des artefacts.
FreeResetTree(planète, palier)1 : une erreurVide un palier entier. Gratuit, en nombre limité.
BuyResetTree(planète, palier)1 : une erreurLe même geste, contre de la matière noire.

Un chapitre rapporte sans rien risquer : il distribue des ressources et des objets contre des tâches déjà accomplies. Il n'y a donc aucune raison de ne pas les ramasser, sinon qu'il faut y penser tous les jours — ce qu'un script fait mieux qu'un joueur.

CronExec("@09h00", func() {
	err = ChapterClaimAll(4006)               // ← à vous : l'identifiant du chapitre
	if err != nil { LogError("chapitre :", err) }
})

ChapterClaimAll est propre à Kepler, et c'est un raccourci que l'outil de référence n'a pas : il oblige à boucler sur les tâches et à ramasser une par une. Le jeu sait le faire d'un seul appel, et vingt tâches ramassées à la main, ce sont vingt requêtes pour un geste qu'il compte comme un.

L'identifiant d'une tâche n'est pas celui de son chapitre. Les deux se ressemblent et ne s'échangent pas : ChapterCollectReward veut celui de la tâche, que GetChapter vous donne.

SelectLfResearchRandom coûte, et ne se défait pas : ce qui était proposé dans l'emplacement est perdu. Un script qui tire en boucle jusqu'à obtenir ce qu'il veut paiera chaque tour.

Les trois SelectLfResearch* veulent une planète : les recherches de forme de vie n'existent pas sur une lune, et une lune passée à leur place rend une erreur qui la nomme.

Les deux ResetTree vident un palier, et c'est la moitié qui manquait à la boucle : lire ce qui est proposé, le prendre s'il convient, tout remettre à zéro s'il ne convient pas, recommencer. SelectLfResearchRandom en approche, mais elle retire une case au sort — elle ne vide pas un palier.

p = GetCachedCelestial("1:2:3").GetID()

if GetPlanetLifeformType(p) != KAELESH {
	return                                    // ce script ne sait traiter que les Kaelesh
}

err = FreeResetTree(p, 1)                     // le palier 1, de nouveau vierge
if err != nil {
	LogError("plus de remise à zéro gratuite :", err)
	// err = BuyResetTree(p, 1)               // ← celle-ci coûte de la matière noire
}

Le palier va de 1 à 3, et rien d'autre ne se tente : un autre nombre est refusé avant que la moindre requête parte.

Le vidage ne se défait pas. Tout ce qui était choisi dans le palier est perdu, et les points dépensés avec. C'est bien ce qu'on lui demande, mais un script qui se trompe de palier ne peut rien rattraper.

Le jeu n'offre qu'un nombre limité de remises à zéro gratuites, et personne ne dit combien — ni la bibliothèque, ni l'outil de référence, ni Kepler. Il n'y a pas moyen de le savoir à l'avance : on essaie, et on lit l'erreur. C'est pour cela que l'exemple ci-dessus enchaîne sur la version payante plutôt que de compter les coups.

BuyResetTree dépense de la matière noire, qui s'achète avec de l'argent réel. Le robot, lui, n'en dépense jamais de sa propre initiative : cette fonction n'existe que parce qu'un script est un geste du joueur, qui écrit lui-même le nom de ce qu'il dépense.

Le prix ne se lit nulle part avant de payer, ni chez nous ni dans le jeu : on l'apprend en regardant sa réserve baisser. Mesuré une fois, le 22/09/2026, sur un palier 2 en univers v13 : 8 000. Rien ne dit que ce soit le même prix partout, ni qu'il ne monte pas avec le nombre de remises à zéro déjà faites — c'est une mesure, pas un tarif. Un script qui l'appelle en boucle vide une réserve qui s'achète avec de l'argent réel.

GetPlanetLifeformType rend un nombre, pas un nom : 0 aucune, 1 HUMANS, 2 ROCKTAL, 3 MECHAS, 4 KAELESH. Les constantes du même nom existent, et == KAELESH se compare bien. Print affichera le chiffre.

Elle ne rend pas d'erreur, comme l'outil de référence la déclare. Elle lit pourtant une page du jeu, qui peut échouer : elle rend alors 0, et l'échec part à la console du script et au journal — il n'est pas muet, il est ailleurs que dans le retour. Une lune rend 0 elle aussi, et là c'est la bonne réponse.

Elle coûte une page pleine, à chaque appel. Douze planètes relues à chaque tour de boucle, ce sont douze pages par tour pour une donnée qui ne change pratiquement jamais : lisez-la une fois, gardez-la.

Les curseurs de production, et le prix sur place

FonctionRend
NewResourceSettings(métal, cristal, deutérium, solaire, fusion, satellite, foreuse)1 : des réglagesCompose les sept curseurs.
SetResourceSettings(planète, réglages)1 : une erreurLes applique.
TechnologyDetails(céleste, quoi)2 : le détail et une erreurPrix, durée et niveau, sur ce céleste.

Les sept comptent, et c'est le piège. Le jeu applique le réglage ENTIER, pas la différence. Un script qui ne veut changer que la mine de métal doit donc relire les six autres et les reposer telles quelles — sans quoi il les met toutes à zéro, et la planète cesse de produire sans un mot.

c = GetCachedPlanets()[0]
avant, err = GetResourceSettings(c.GetID())
if err != nil { LogError(err); return }

// On ne change QUE le deutérium : les six autres sont recopiés.
apres = NewResourceSettings(avant.MetalMine, avant.CrystalMine, 100,
	avant.SolarPlant, avant.FusionReactor, avant.SolarSatellite, avant.Crawler)
err = SetResourceSettings(c.GetID(), apres)

Les curseurs vont de zéro à cent, par pas de dix : le jeu refuse les autres. Un curseur à zéro arrête la mine, il ne la met pas au minimum.

SetResourceSettings veut une planète : une lune ne produit rien, et une lune passée à sa place rend une erreur qui la nomme.

TechnologyDetails demande au jeu, là où GetPrice calcule. La différence tient à un mot : GetPrice chiffre un niveau qu'on lui donne, celle-ci demande ce qu'il en coûte ici, avec les installations, les bonus de forme de vie et les réductions de ce céleste-là. C'est une page du jeu — une requête par appel — et elle dit en plus si la démolition est ouverte, ce qu'aucun calcul ne sait.