Guide pour les auteurs de mods tiers, lisible par un humain et par un
assistant de code (voir llms.txt : un fichier unique à coller dans
un LLM). Tout ce qui est écrit ici est tiré du code de crates/modding et des mods
livrés ; ce qui ne l'est pas est marqué [À VÉRIFIER]. La référence historique
et détaillée reste Mods TypeScript.
Plan
| Document | Contenu |
|---|---|
| Ce fichier | Démarrage rapide : dossier, main.ts, hello HUD, installation, export |
| Concepts : comment fonctionne un mod | Cycle de vie, threads et budgets, événements, permissions, erreurs, déterminisme, interdits |
| Référence de l'API des mods (version 2) | Référence par espace de noms, vérifiée contre le SDK |
| Livre de recettes | 17 recettes complètes (jugement, vitesse, HUD, hit bar, modificateur, touche, notes/filtre, stage, stockage, skin, script de map, classement, onglet, source de téléchargement, pont, import de skin) |
llms.txt |
Contexte compact pour assistant IA + modèle de prompt |
LACUNES.md |
Ce que l'API ne permet pas (encore), ou qui surprend |
Les deux autres genres de scripts : skins (skin.ts, defineSkin)
et scripts de map (defineChart).
Démarrage rapide
1. Le dossier
Un mod est un dossier contenant main.ts (ou index.ts) ; il n'y a pas de
manifeste JSON, la seule déclaration est l'appel defineMod.
mon-mod/
main.ts point d'entrée obligatoire
lib/format.ts modules relatifs importés par main.ts (jamais hors du dossier)
fonts/Title.ttf polices déclarées dans `fonts` (.ttf/.otf)
images/star.png images PNG (hud.image, stage.sprite)
Un dossier sans main.ts (comme mods/sdk) est ignoré ; un nom qui commence par
. aussi. Le nom du dossier n'est pas l'id : l'id vient de defineMod.
2. Un hello HUD (moins de 40 lignes)
/// <reference path="../sdk/modding.d.ts" />
export default defineMod({
id: "hello-hud", // a-z, 0-9, ., -, _ ; 1 à 64 caractères ; stable
name: "Hello HUD",
version: "1.0.0", // semver
apiVersion: 2, // doit valoir la version de l'API du jeu
author: "Moi",
description: "Le combo en gros, et la précision dessous.",
setup() {
ctx.on("game.songStart", () => {
hud.group({
id: "panel",
flow: { direction: "column", align: "end", gap: 0.004 },
layout: { x: 0.98, y: 0.5, anchor: "topRight" },
});
// `bind` : la surcouche met la valeur à jour toute seule, sans repasser par le script.
hud.text({ id: "combo", parent: "panel", text: "", bind: { kind: "combo" }, style: { size: 0.06 } });
hud.text({ id: "acc", parent: "panel", text: "", bind: { kind: "accuracy", decimals: 2 }, style: { size: 0.03 } });
});
ctx.on("game.songEnd", () => hud.clear());
log.info("Hello HUD chargé");
},
});
Les longueurs (size, width, gap…) sont des fractions de la hauteur de
l'écran ; x/y des fractions du parent (l'écran au premier niveau).
3. Où le mettre
Deux racines, lues dans cet ordre (Créer un mod) :
mods\à côté deprism.exe(en développement : le dossiermods/du dépôt) ;- le dossier des mods du joueur :
%LOCALAPPDATA%\Prism\PrismNG\data\mods(C:\Users\<utilisateur>\AppData\Local\Prism\PrismNG\data\mods). La variablePRISM_MODS_DIRremplace uniquement cette racine de données.
Copy-Item -Recurse mon-mod "$env:LOCALAPPDATA\Prism\PrismNG\data\mods\"
La page Mods (libellés de l’interface en anglais par défaut : Open folder, Reload, Install…, Export, Uninstall) : Open folder ouvre cette racine ; Reload relit
tous les mods sans redémarrer le jeu. Le mod apparaît dans la liste, ses messages
(log.info/log.warn) et ses erreurs sous lui. Si deux dossiers déclarent le même
id, le premier chargé gagne et un message l'indique.
4. Activer, désactiver, désinstaller
- Chaque mod a un interrupteur (clavier : Espace) sur la page Mods ; le choix
est conservé (
Settings.disabledMods) sans désinstaller le mod ni effacer son stockage. Un changement fait pendant une partie attend le retour au menu. - Désinstaller supprime le dossier (
<dossier des mods>/<id>) ; le stockage du mod est conservé pour une réinstallation. Pour un mod demods\à côté de l'exe : le dossier est supprimé s'il est accessible en écriture, sinon une erreur nomme le chemin. Retirer un mod, c'est supprimer son dossier. - Installer, exporter, désinstaller et recharger sont refusés pendant une partie.
5. Partager : exporter un .pvmod
Page Mods → Export : une archive ZIP <id>-<version>.pvmod. Pour
l'installer : bouton Install…, ou glisser-déposer le fichier sur la fenêtre.
Règles (Règles d'un paquet) : fichiers .ts, .ttf, .otf,
.png, .json (données), .md, .txt ; 64 Mio au plus, 1024 entrées, 256
fichiers ; main.ts ou index.ts à la racine ; entrées cachées et node_modules
ignorées ; liens symboliques et entrées chiffrées refusés. Réinstaller un mod de
même id le remplace (mise à jour, réinstallation ou retour en arrière).
Vérifier ses types
Le jeu transpile sans vérifier les types : seule l'exécution (budgets, validations Rust) vous reprend. Pour les types, avec le TypeScript de l'interface :
node apps/web/node_modules/typescript/bin/tsc --noEmit --strict --target es2022 --lib es2022 --module esnext --moduleResolution bundler mods/mon-mod/main.ts
Les déclarations sont mods/sdk/modding.d.ts ; la ligne
/// <reference path="../sdk/modding.d.ts" /> suffit (elle n'a aucun effet à
l'exécution). Hors du dépôt, copiez le fichier et adaptez le chemin.
mods/sdk/modding.ts (modèles typés et raccourcis d’écoute comme onJudgement) est optionnel : un mod
qui l'utilise le copie dans son dossier.
Vérifier cette documentation
node scripts/check-modding-docs.mjs # symboles et recettes vérifiés contre le SDK
node scripts/check-modding-docs.mjs --strict # + échoue si un type du SDK n'est cité nulle part
node scripts/check-modding-docs.mjs --sdk chemin/modding.d.ts # contre un autre SDK
Le script échoue si un symbole documenté a disparu du SDK, s'il manque une
fonction ou un événement dans Référence de l'API des mods (version 2), ou si une recette
ts ne passe plus tsc --strict (TypeScript est cherché avec --tsc, $TSC ou
apps/web/node_modules). Après un changement d'API :
cargo run -p modding --example write_sdk, puis ce script.
Fonctions récentes
- Classement local (
leaderboard.query,leaderboard.best), onglets de sélection (tabs.register,tabs.extend) et import de skins (skinImport.*, permissionskinImport) : dans le SDK d'integration, documentés dans Référence de l'API des mods (version 2). - Sources et miroirs de téléchargement (
downloads.register,downloads.registerBridge, permissionnetwork) : documentés ici d'après la branchefeature/mod-download-sources; ils n'existent dansmods/sdk/modding.d.tsqu'une fois cette branche fusionnée dansintegration. Avant cela, le script de vérification se lance avec--sdk <d.ts de la branche>.
Ce qui manque encore est dans LACUNES.md.