Skip to content

fix: passer à ogamejs 4 et estimer les pertes sur les vagues réelles - #9

Merged
rolljee merged 1 commit into
masterfrom
fix/ogamejs-v4-and-moonbreak-losses
Aug 15, 2026
Merged

rolljee merged 1 commit into
masterfrom
fix/ogamejs-v4-and-moonbreak-losses

Conversation

@rolljee

@rolljee rolljee commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Trois correctifs de calcul, plus la montée en v4 de la lib. Version bumpée en 2.1.0 : aucune commande ne change, mais les chiffres que le bot affiche, si.

1. !ogc D payait le double sur un taux remis à l'échelle

4:3:2 est le même taux que 2:1.5:1. Dans ogamejs 3, parseRate(rate, 'deut') lisait les termes métal et cristal bruts, là où les branches métal et cristal divisent par le terme vendu. Donc :

commande avant après
!ogc M 60/40 4:3:2 1000000 correct inchangé
!ogc D 60/40 4:3:2 1000000 le double corrigé

Corrigé en amont dans ogamejs 4.0.1. Le bot passe donc en ogamejs ^4.0.2.

La v3 → v4 ne casse rien ici

Les deux seuls points d'appel passent tels quels, vérifié :

  • commerce.js — Ogame.Trader a exactement les mêmes clés et signatures.
  • create-link.js — ne lit que cost.metal et cost.crystal de Destroyable[1] et [15], que la v4 n'a pas renommés (seul cost.deut → cost.deuterium, non utilisé ici). Les valeurs sont identiques : 4000 pour le chasseur léger, 1000 pour la sonde.

Ce que la MIGRATION casse (entry.name, fret, deutCost, les signatures des calculateurs de mines) n'est utilisé nulle part dans le bot.

2. getLosses était aveugle au partage de la flotte

moonBreak construit sa probabilité sur le découpage en 6 vagues de chaque attaquant. getLosses faisait autre chose : il mettait toute l'attaque en commun en une seule taille de vague moyenne, nbrip / min(nbrip, nb_attaquants × 6).

Les deux moitiés du même calcul modélisaient donc des attaques différentes :

commande proba pertes avant pertes après
!mb 8944 1 100 78.96 % 22.04 26.74
!mb 8944 50 50 87.05 % 21.90 22.06

Même réponse pour deux attaques qui n'ont rien à voir. Réparties, les vagues sont plus petites, la lune tombe plus tôt, moins de vagues partent : ça doit coûter moins, pas pareil.

getLosses parcourt maintenant les vagues réelles — les 6 de chaque attaquant, chacune à sa taille, dans l'ordre de tir. Un attaquant de moins de 6 RIP complète avec des vagues vides, qui ne menacent pas la lune et ne coûtent rien.

Les chiffres auxquels les joueurs sont habitués bougent peu

cas avant après
!mb 3464 200 9.81 10.01
!mb 8944 100 27.66 27.78
!mb 8000 50 50 12.20 12.26

Les flottes déséquilibrées bougent beaucoup, ce qui était le but.

Une conséquence à assumer

Les pertes dépendent désormais de l'ordre des attaquants : !mb 8944 100 1 annonce 27.88 là où !mb 8944 1 100 annonce 26.74, parce que la flotte qui ouvre affronte une lune encore debout. La probabilité, elle, ne change pas. C'est réel — les attaquants passent l'un après l'autre.

Non modifié

La variance somme toujours les variances par vague, ce qui les suppose indépendantes alors qu'elles partagent la chaîne de survie, et la dispersion reste résumée par une gaussienne. Deux approximations du modèle d'origine, maintenant documentées comme telles dans le code. Les changer relève d'une décision sur les statistiques, pas sur l'attaque modélisée.

3. !ogc explique un taux inutilisable

Depuis ogamejs 4.0.2, un terme qui ne décrit pas un échange (0:1.5:1, 2::1, un terme négatif) lève au lieu de renvoyer Infinity. Sans garde-fou, index.js retomberait sur le message d'aide générique : l'utilisateur verrait la syntaxe des sept commandes sans savoir que c'est son taux qui cloche. commerce.js lève désormais une UserError qui le dit.

Tests

20 (contre 13) : le découpage en vagues, l'attaque déséquilibrée contre l'attaque répartie, l'attaquant qui ouvre, le taux remis à l'échelle, les cinq formes de taux inutilisable. Lint et tests verts en local.

Parité

Les chiffres sont identiques à ceux de ogame-ui après rolljee/ogame-ui#58, vérifié cas par cas.

🤖 Generated with Claude Code

Trois choses, toutes autour des calculs.

ogamejs 3 -> 4.0.2. La v3 lisait les termes métal et cristal bruts du
côté deutérium, là où les branches métal et cristal divisent par le terme
vendu: `!ogc D 60/40 4:3:2` payait le double de `!ogc D 60/40 2:1.5:1`
alors que c'est le même taux. Les deux points d'appel de la v3 passent
tels quels — `Ogame.Trader` n'a pas bougé, et `create-link.js` ne lit que
`cost.metal` et `cost.crystal`, que la v4 n'a pas renommés.

`getLosses` mettait la flotte en commun en une taille de vague moyenne
(`nbrip / nb_vague`) alors que la probabilité est construite sur le
découpage en 6 vagues de chaque attaquant. Les deux moitiés du même
calcul modélisaient donc des attaques différentes, et les pertes étaient
aveugles au partage: `!mb 8944 1 100` annonçait les mêmes 22.04 pertes
que `!mb 8944 50 50`, pour 79 % de réussite contre 87 %. Elle parcourt
maintenant les vagues réelles, chacune à sa taille, dans l'ordre de tir.
Les flottes égales bougent à peine (`!mb 3464 200` passe de 9.81 à
10.01), les flottes déséquilibrées beaucoup, ce qui était le but. Les
pertes dépendent désormais de l'ordre des attaquants, celui qui ouvre
affrontant une lune encore debout — la probabilité, elle, n'en dépend
pas.

`!ogc` explique enfin un taux inutilisable. ogamejs 4.0.2 lève sur
`0:1.5:1`, `2::1` ou un terme négatif au lieu de renvoyer Infinity;
sans ce contrôle index.js retomberait sur le message d'aide générique.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rolljee
rolljee merged commit 105d588 into master Aug 15, 2026
1 check passed
@rolljee
rolljee deleted the fix/ogamejs-v4-and-moonbreak-losses branch August 15, 2026 06:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant