Sur cette page
Docs Extensions de jeu

Mods de jeu

Un schéma n’est pas forcément une IA qui joue à votre place : ce peut aussi être un ensemble de règles. Vous jouez vous-même dans la fenêtre du jeu ; le mod prépare le début de partie, fait apparaître les monstres, distribue les récompenses, vous présente boutons et cartes de choix à l’écran et décide de l’issue. Héritez de openwar3.Mod : un fichier, un gameplay complet.

Les schémas d’IA sont de deux sortes : kind: bot est une IA qui joue à votre place ; kind: mod est un ensemble de règles — vous jouez vous-même dans la fenêtre du jeu, et le mod vous lance les défis : comment la partie est préparée, quand les monstres apparaissent (selon le temps ou les événements), quelles récompenses sont données, quels boutons et cartes de choix s’affichent à l’écran, quand la partie est gagnée.

Un mod n’utilise que des capacités existantes : Interface et entrées (boutons et cartes cliquables, raccourcis clavier, clics au sol), le canevas (panneaux, barres de progression, tracés), le canal JASS (faire apparaître des unités, modifier des caractéristiques, donner des objets) et le flux d’événements (morts, montées de niveau, sorts lancés, chat).

Deux exemples

À choisir dans Farsight, sous « Schémas d’IA » → « Intégrés » :

ModPrincipeCapacités utilisées
Roguelike de héros builtin/hero-roguelikeVous n’avez qu’un paladin, et les monstres arrivent par vagues de tous les côtés ; à chaque niveau gagné, choisissez un bonus parmi trois au centre de l’écran (le jeu est en pause pendant le choix) ; tenez 10 vagues pour gagner ; si le héros meurt, c’est perdug.ui.choice (cartes cliquables + pause), événements hero.levelup / killed / spell.cast, -help dans le chat, JASS pour modifier les caractéristiques du héros et donner des objets
Défense sans fin builtin/endless-defenseLes monstres partent du point de départ opposé et foncent vers votre bâtiment principal en suivant une ligne rouge tracée au sol ; chaque vague repoussée rapporte de l’or ; cliquez sur le bouton à l’écran ou appuyez sur F7 pour appeler la vague suivante plus tôt, avec une récompense ×1.5 ; appuyez sur F8 puis faites un clic gauche au sol pour poser une tour de garde gratuite (clic droit pour annuler)g.ui.button, g.ui.hotkey, g.ui.mouse (capture des clics au sol), panneau / barre de progression / tracé du canevas, JASS pour faire apparaître les monstres et ajouter de l’or

Chacun des deux exemples fait environ 150 lignes ; le code se trouve dans brains/examples/mod_hero_roguelike.py et brains/examples/mod_endless_defense.py.

python tools/play.py --bot brains/examples/mod_hero_roguelike.py --inst 9     # lance une partie, le mod prend la main, vous jouez dans la fenêtre du jeu

Écrire un mod

from openwar3 import Mod

class Survive(Mod):
    name = "survive"

    def on_start(self, g):
        super().on_start(g)                        # vérifie qu'on est en solo + neutralise l'ordinateur adverse
        self.foe = self.wave_player(g)             # un emplacement libre devient le « joueur des vagues » : allié de personne, sans IA d'ordinateur
        self.every(30, self.wave)                  # une vague toutes les 30 secondes de jeu (rien ne s'écoule pendant la pause)
        g.ui.hotkey("F7", lambda g, ev: self.wave(g))

    def wave(self, g):
        self.spawn_ring(g, self.foe, "ugho", 6, self.home(g), 1400, attack_to=self.home(g))

    def on_event(self, g, ev):
        if ev.kind == "unit.died" and ev.type == "htow":
            self.finish("loss", "L'hôtel de ville est tombé")

Par rapport à Bot, Mod ajoute :

Méthode / attributDescription
on_start / on_tick / on_event / on_endComme pour Bot ; si vous surchargez on_start / on_tick, appelez d’abord super()
every(secondes, fn, first=) / after(secondes, fn)Minuteurs qui suivent le temps de jeu ; le callback est fn(g)
finish(result, reason)Termine la partie ('win' / 'loss' / 'unknown') : l’exécuteur s’arrête au tick suivant, un panneau de résultat est dessiné au centre de l’écran, et le bilan du schéma est enregistré d’après ce résultat
wave_player(g)Le premier emplacement de joueur libre, à utiliser comme joueur des vagues
spawn_ring(g, joueur, unité, nombre, centre, rayon, attack_to=)Fait apparaître des unités sur un cercle, sans à-coups même par dizaines à chaque vague ; renvoie les handles JASS
alive_of(g, joueur) / attack_move_all(g, joueur, point)Les unités vivantes d’un joueur / toutes en attaque-déplacement vers un point (appelez-la toutes les quelques secondes pour que les monstres vous poursuivent)
home(g) / hud(g, titre, lignes)Position de notre bâtiment principal / panneau d’informations en haut à droite
neutralize_ai = TrueNeutralise l’ordinateur adverse en début de partie : ses unités sont mises en pause toutes les 5 secondes, son or et son bois remis à zéro. Une carte de mêlée a toujours un ordinateur ; quand le mod fixe ses propres règles, il ne doit pas venir perturber la partie
single_player_only = TrueRefuse de s’exécuter s’il y a d’autres joueurs humains (le JASS qui modifie le monde les désynchroniserait)
linger_s = 6Une fois l’issue décidée, nombre de secondes passées sur l’écran de résultat avant de terminer

finish() fonctionne aussi sur Bot : un Bot ordinaire peut lui aussi annoncer lui-même la fin de la partie.

En faire un schéma et le partager

Écrivez "kind": "mod" dans scheme.json, et définissez une sous-classe de Mod dans le fichier d’entrée :

{"id": "survive", "name": "Tenir 10 vagues", "kind": "mod", "entry": "survive.py", "class": "Survive"}

Un mod n’est jamais en mode équitable (c’est l’arbitre qui pose les défis : il doit voir toute la carte et modifier le monde), et son issue n’est jamais jugée selon les règles de mêlée (c’est finish qui la signale) ; fair / judge dans le manifeste sont sans effet. Export en zip, import, confiance et bilan fonctionnent exactement comme pour les schémas de Bot : voir Schémas d’IA. Un mod, c’est aussi du code : avant la première exécution du mod de quelqu’un d’autre, il faut également confirmer votre confiance.

Mesures

2026-09-25, sur une instance de test :

  • Roguelike de héros : la première vague apparaît, le panneau en haut à droite se met à jour ; héros monté au niveau 3 → des cartes s’affichent au centre de l’écran et l’horloge du jeu s’arrête ; deux clics sur des cartes → deux bonus appliqués (force 22 → 27), l’horloge repart.
  • Défense sans fin : panneau, tracé au sol et bouton sont bien là ; F8 + clic au sol → une tour de défense apparaît à côté du bâtiment principal ; clic sur le bouton alors que la vague en cours n’est pas terminée → message « cette vague n’est pas encore terminée ».

Limites

  • Parties solo uniquement : faire apparaître des unités et modifier des caractéristiques passe par le canal JASS, ce qui désynchronise une partie multijoueur. C’est une conséquence du modèle lockstep ; un gameplay multijoueur devra attendre un canal de synchronisation (voir la feuille de route).
  • Le mod voit toute la carte — c’est lui qui pose les défis, ce n’est pas un joueur.
  • Dans une carte de mêlée, l’ordinateur adverse est seulement « neutralisé », pas retiré (le retirer déclencherait la victoire selon les règles de mêlée).