API communes JS
Les classes et fonctions globales utilisables par les quatre types de scripts. Les tableaux sont groupés par thème ; pour les ctx / wrapper propres à chaque type, voir Types de scripts JS ; pour les extensions propres à Yanyang, voir Extensions Yanyang.
Conventions de notation
- Le préfixe
static= appel direct au nom de la classe (Resources.id(...)) ; sans lui, il faut d’abord obtenir une instance (en général via la valeur de retour d’une autre fonction). - Les annotations de types suivent l’écriture Java :
str: Stringaccepte une chaîne Java (les chaînes JS sont converties automatiquement) ; un retourString?signifie « peut valoir null » ;String...désigne un nombre variable d’arguments chaîne. - Les entrées marquées Obsolète sont des interfaces de compatibilité de l’ère NTE — ne les utilisez plus dans les nouveaux scripts ; celles marquées Yanyang sont des extensions propres à cette branche.
Ressources et fichiers
Identifier (chemin de ressource)
Minecraft localise ses ressources au moyen d’Identifier de la forme espace_de_noms:chemin. Depuis JCM v2.3, la plupart des emplacements qui attendent un Identifier acceptent aussi une simple chaîne : forme complète "mtr:asd.png", ou chemin relatif au répertoire du script courant avec le préfixe ./ (équivalent d’idr()).
| Fonction | Description |
|---|---|
static Resources.id(idStr: String): Identifier | crée un Identifier à partir d’une chaîne |
static Resources.idr(relPath: String): Identifier | résout relativement au répertoire du script courant ; à n’utiliser qu’en phase d’analyse (en phase d’exécution, la notion de « script courant » n’existe plus) |
static Resources.id(id: Identifier, suffix: String): Identifier | ajoute un suffixe à un Identifier existant — notez la base avec idr() pendant l’analyse, puis composez le chemin en exécution |
Resources (lecture dans le pack de ressources)
Lire une ressource sur disque est bien plus lent qu’une opération en mémoire : ce qui peut être lu pendant la phase d’analyse n’a pas à être relu à chaque frame dans render().
| Fonction | Description |
|---|---|
static Resources.read(id): DataReader? | lit un fichier du pack de ressources et retourne un DataReader ; null si le fichier n’existe pas |
static Resources.exist(id): boolean | le fichier existe-t-il |
static Resources.getSystemFont(name: String): Font | retourne une police AWT. Polices intégrées : Noto Serif (sérif CJK), Noto Sans SemiBold, Noto Sans CJK TC Medium ; accepte aussi Serif / SansSerif / Monospaced (selon les polices installées sur la machine du joueur) |
static Resources.hasSystemFont(name: String): boolean | la famille de police existe-t-elle sur le système (sans traitement spécial des polices intégrées) |
static Resources.getFontRenderContext(): FontRenderContext | le contexte utilisé pour les métriques de texte AWT |
static Resources.ensureStrFonts(text, primaryFont, fallbackFonts...): AttributedString | assemble le texte avec la police principale + une chaîne de polices de repli, en basculant automatiquement quand un glyphe manque — l’outil anti « carrés de tofu » pour la composition multilingue |
static Resources.getAddonVersion(modId: String): String | retourne la version du mod : "mtr" / "jcm" / "mtrscripting" (les scripts véhicule / décoration / ascenseur consultent mtrscripting, les PIDS jcm) |
| Obsolète | Description |
|---|---|
Resources.readString(id) / readBufferedImage(id) / readFont(id) | remplacez uniformément par read() + DataReader |
Resources.manager() / Resources.mgr() | le framework inter-versions de MTR 4 ne l’expose pas : retourne toujours null ; les fonctions qui en ont besoin acceptent null |
Resources.getMTRVersion() et autres fonctions de version NTE | remplacez par getAddonVersion() ; les fonctions de la série NTE retournent toujours les anciennes valeurs, uniquement par compatibilité |
Files (fichiers locaux)
L’activité est confinée à .minecraft : lecture + écriture + suppression limitées à .minecraft/data/mtrscripting (le répertoire de données des scripts), lecture ouverte à tout .minecraft. Les chemins se transmettent en plusieurs arguments, sans barres obliques : Files.read("config", "mtr.json").
| Fonction | Description |
|---|---|
static Files.read(path: String...): DataReader? | lit un fichier sous .minecraft ; null s’il n’existe pas |
static Files.readData(path: String...): DataReader? | comme ci-dessus, mais relatif à data/mtrscripting |
static Files.saveData(content: String | BufferedImage, path: String...): void | enregistre du texte ou une image ; le répertoire parent est créé automatiquement |
static Files.deleteData(path: String...): void | supprime le fichier |
static Files.hasData(path: String...): boolean | le fichier / répertoire existe-t-il |
Mathématiques et transformations
Vector3f (vecteur tridimensionnel)
Coordonnées (x, y, z). L’implémentation JCM travaille en double en interne, reçoit et restitue des float à l’extérieur ; toutes les méthodes de calcul retournent l’objet lui-même pour permettre les appels chaînés :
new Vector3f(x, y, z) (constructible aussi depuis Vector / Position de la TSC) · x() y() z() · copy() · normalize() · add(x,y,z) / add(v) · sub(v) · mul(x,y,z) / mul(n) · rotX(rad) / rotY(rad) / rotZ(rad) (radians) · cross(v) · distance(v) · distanceSq(v) · rawBlockPos(). Constantes Vector3f.ZERO / XP / YP / ZP — en lecture seule, ne les modifiez pas.
Matrices (pile de transformations)
Le rendu exige souvent « dessiner ce passage, puis revenir à la transformation précédente ». Matrices est une pile de transformations ; push et pop s’emploient par paires :
new Matrices() (matrice identité au départ) · translate(x,y,z) · rotateX/Y/Z(rad) (radians) · rotateX/Y/ZDegrees(deg) (degrés) · pushPose() (enregistre l’état courant) · popPose() (restaure le dernier enregistrement) · popPushPose() (restaure puis enregistre).
Rendu
Le script tourne sur un thread d’arrière-plan, le rendu a lieu sur le thread principal — le dessin suit donc le modèle des appels de dessin (draw calls) : dans render(), vous soumettez « comment dessiner » au RenderManager ; JCM mémorise ce lot d’instructions et continue de le dessiner tel quel jusqu’à votre prochaine exécution. L’ancien lot est effacé après chaque exécution du script — pour un affichage continu, soumettez-le à nouveau à chaque tour ; mais rien à craindre si une exécution lente fait sauter des frames : JCM continue de rejouer le lot précédent jusqu’à ce que vous en livriez un nouveau.
RenderManager
Obtenu via le ctx.getRenderManager() de chaque type ; il embarque une « transformation de base » (eyecandy = position du bloc + décalage et rotation GUI ; véhicule = par voiture… — détails par type sur la page Types de scripts) et toutes les soumissions se dessinent relativement à elle :
| Fonction | Description |
|---|---|
drawModel(model: Model, matrices?: Matrices) | soumet un modèle ; transformation additionnelle facultative |
drawModel(model, matrices?, light: int) | comme ci-dessus, avec éclairage personnalisé (valeur de MinecraftClient.lightAt) |
drawModel(holder: DynamicModelHolder, matrices?: Matrices) | soumet directement un détenteur de modèle dynamique — l’intervalle « le transfert ne complète qu’à la frame suivante » est géré en interne, évitant le scintillement |
draw(call: DrawCall) | soumet un appel de dessin brut (QuadDrawCall, etc.) |
QuadDrawCall (quadrilatère)
Dessine une face quadrilatère, avec texture, UV, teinte et éclairage au choix — l’usage typique est d’y plaquer une texture dynamique pour simuler un écran :
static QuadDrawCall.create() (accepte un paramètre de commentaire) · quad(c1, c2, c3, c4) ou corner1..4(pos) (quatre Vector3f) · renderType(str) · color(rgb) · texture(id) · uv(u1,v1,u2,v2) (0–1) · matrices(m).
Valeurs de renderType : EXTERIOR (livrée extérieure du véhicule, éclairée selon sa position, par défaut), EXTERIOR_TRANSLUCENT, INTERIOR (habitacle, pleine luminosité avec teinte par face), INTERIOR_TRANSLUCENT, LIGHT (pleine luminosité sans ombrage, adapté aux LCD), LIGHT_TRANSLUCENT. Côté modèles existe en outre ALWAYS_ON_LIGHT.
Modèles
Sont pris en charge WaveFront OBJ et Metasequoia (.mqo) ; le .bbmodel de Blockbench n’est pas pris en charge. Les OBJ exportés par Blender / Blockbench exigent l’inversement de l’axe V (flipV = true, la valeur par défaut) ; ceux exportés par Metasequoia exigent un false explicite.
| Classe | L’essentiel |
|---|---|
ModelManager | loadModel(id, flipV=true): RawModel, loadModelParts(id, flipV=true): Map<String, RawModel> (découpe par groupes d’objets), upload(rawModel): Model (téléversement vers le GPU ; phase d’analyse uniquement — en phase d’exécution, passez par DynamicModelHolder) |
RawModel | conteneur de données de sommets : append(mesh|model), applyTranslation(x,y,z), applyRotation(dir, angleDeg), applyScale(x,y,z), applyMirror(x,y,z), applyUVMirror(u,v), setAllRenderType(str), copy(), replaceTexture(fileName, id), replaceAllTexture(id) |
Model | téléversé sur le GPU : les sommets ne se modifient plus, mais replaceTexture(...) / replaceAllTexture(...) / copyForMaterialChanges() / close() restent disponibles |
RawMeshBuilder | modélisation par code : après new RawMeshBuilder(faceSize, renderType, textureId), vertex(pos) → normal(x,y,z) → uv(u,v) → endVertex() (color(r,g,b,a) en option), finalisez avec getMesh() ou asRawModel() |
DynamicModelHolder | téléversement en phase d’exécution : uploadLater(rawModel) (téléverse sur le thread de rendu à la frame suivante), getUploadedModel() (peut être l’ancien modèle ou null — préférez remettre le détenteur directement à drawModel), close() |
Pour les transformations simples en phase d’exécution (translation / rotation / mise à l’échelle), passez des Matrices à drawModel au lieu de modifier les sommets puis de re-téléverser à chaque frame — cette dernière voie est plus lente de plusieurs ordres de grandeur.
Textures dynamiques
GraphicsTexture
Une texture virtuelle à résolution fixe + un canevas Java AWT, téléversée au jeu pour affichage une fois dessinée — c’est elle qui porte les écrans intérieurs et extérieurs des véhicules comme les panonceaux LED :
| Membre | Description |
|---|---|
new GraphicsTexture(width, height) | création. Créez dans create, et stockez dans state, le contenu propre à chaque écran / chaque véhicule |
.identifier | l’Identifier de cette texture — remettez-le à QuadDrawCall.texture() ou utilisez-le en remplacement de texture de modèle |
.bufferedImage / .graphics | le canevas AWT BufferedImage et son Graphics2D (seul l’anticrénelage du texte est activé par défaut) |
.fullAA() / .noAA() | anticrénelage complet / entièrement désactivé (noAA est courant sur les écrans à matrice de points) |
.upload() | téléverse l’image entière vers le GPU. Le coût n’est pas négligeable — réduisez la cadence avec RateLimit (par ex. 10 Hz) et ne mettez plus à jour au loin |
.upload(x, y, width, height) | ne téléverse qu’une sous-zone, l’ancien contenu est conservé. Forme 2 : upload(dstX, dstY, srcX, srcY, w, h) ; accepte aussi une BufferedImage externe : upload(img, dstX, dstY, srcX, srcY, w, h) |
.close() | libère la mémoire du GPU. Ce qui est créé dans create doit être fermé dans dispose, sans quoi la mémoire fuit |
Yanyang .uploadRawABGR(bytes, dstX, dstY, w, h, lut) | écrit directement dans la texture un tableau d’octets en ordre BGRA, puis ne téléverse que ce rectangle — le canal économe en bande passante pour les mises à jour pixel par pixel à haute fréquence, voir Extensions Yanyang |
Côté AWT, on utilise couramment : Color.decode / new Color, graphics.setColor / setFont / setStroke, drawRect / fillRect / drawRoundRect / fillRoundRect, drawImage / drawString, Font.deriveFont, GradientPaint, AffineTransform, setClip, AlphaComposite ; importez le tout avec l’importPackage(java.awt) de Rhino. Pour un guide, consultez la JavaDoc de Graphics2D.
Le contenu d’une texture fraîchement créée n’est pas garanti propre (de la mémoire réutilisée peut afficher du bruit visuel) — faites un premier upload() après création pour imposer votre propre contenu.
Pour les besoins multi-écrans des véhicules, tournez-vous plutôt vers le DisplayHelper intégré (include(Resources.id("mtrsteamloco:scripts/display_helper.js"))) : une grande texture découpée en emplacements, des modèles générés automatiquement selon la configuration — voir la page Types de scripts.
Sons
SoundManager
Obtenu via le ctx.getSoundManager() de chaque type ; la position de référence dépend du type :
playLocalSound(id, volume, pitch, category="MASTER") (sans spatialisation, pour les annonces) · playSound(id, pos, volume, pitch, category="MASTER") (positionnée dans le monde, relativement à la position de référence) · play(soundInstance) / stop(soundInstance) (instances contrôlables).
TickableSoundInstance
Un effet sonore ponctuel, une fois joué, ne se contrôle plus ; pour régler le volume en cours de lecture ou interrompre, employez des instances contrôlables (annonces embarquées complexes, sons de moteur, musiques en boucle) :
static create(id, category) · setSoundVolume(v) / setSoundPitch(v) (1.0 est la référence) · setRepeatable(b) · setLoopDelay(tick) · setRelative(b) (volume constant en suivant le joueur) · setPos(v) (une boucle doit mettre à jour sa position frame par frame elle-même) · isPlaying(). La lecture passe par play() / play(delayTick) / play(ctx), avec abort() pour couper une instance en cours (retravaillé dans l’amont v2.3.0-prerelease.3). Une instance en boucle doit impérativement être arrêtée (stop) dans dispose.
Déprécié : setLoopable(b) — remplacé par setRepeatable(b) dans la refonte v2.3.0-prerelease.3 ; les scripts existants continuent de fonctionner.
Catégories de sons : MASTER BLOCKS MUSIC RECORDS WEATHER HOSTILE NEUTRAL PLAYERS AMBIENT VOICE.
Réseau et arrière-plan
Networking
static Networking.fetch(url, requestOption?): NetworkResponse<DataReader>. RequestOption est un simple objet JS : method (GET par défaut), connectTimeout / readTimeout (millisecondes), headers (objet), body (chaîne, Content-Length ajouté automatiquement).
NetworkResponse : getResponseCode() · success() (vrai dès qu’une réponse est parvenue — pour un succès métier, jugez avec ok(), c’est-à-dire 200–299) · getData() (null en cas d’échec) · exception() · getHeaders().
Les requêtes partent par défaut avec User-Agent: Joban Client Mod (https://jcm.joban.org), impossible à modifier par les voies normales (sauf si le joueur relâche les restrictions de scripts). Passez les requêtes réseau sur un thread d’arrière-plan (voir ci-dessous).
BackgroundWorker
static BackgroundWorker.submit(task) confie une tâche lambda à un exécuteur d’arrière-plan monothread — n’en abusez pas, les autres scripts y recourent aussi ; interceptez vous-même par try/catch les exceptions levées dans la tâche. Au rechargement du pack de ressources, la file d’attente est purgée et les tâches en cours interrompues ; un blocage finit par se résorber de lui-même.
BackgroundWorker.submit(() => {
let resp = Networking.fetch("https://example.com/data.json");
if (resp.ok()) {
let str = resp.getData().asString();
// après traitement, écrire dans state ; lu dans render
}
});
Console
print(...) et console.log(...) sont équivalents (héritage NTE, à utiliser librement). L’API Console s’aligne sur les usages du Web, sans les méthodes de type table / profile :
console.log / warn / error / debug(...) (debug ne sort qu’en mode debug) · console.count(label="default") / countReset(label) (compteurs indépendants par étiquette) · console.time(label) / timeLog(label) / timeEnd(label) (chronomètres indépendants par étiquette). L’interpolation par substituants n’est pas prise en charge — les template literals suffisent.
Données MTR
MTR.ClientConfig (préférences du joueur)
isChatAnnouncementEnabled() · isTtsAnnouncementEnabled() · shouldHideTranslucentParts() · getLanguageDisplay() (NORMAL / CJK_ONLY / NON_CJK_ONLY) · getDynamicTextureResolution() (0–8) · getVehicleOscillationMultiplier() (multipliez par 10 pour un pourcentage) · getDefaultRail3D() · isCustomFontEnabled().
MTR.Data (données connues du client)
MTR 4 ne synchronise que les données proches — ne rien trouver au loin n’a rien d’étonnant, et bien des fonctions retournent null :
| Groupe | Fonctions |
|---|---|
| Stations / dépôts | findStation(pos) · getStation(id) · getKnownStations() ; findDepot(pos) · getDepot(id) · getKnownDepots() |
| Lignes | getRoute(id) · getKnownRoutes() · getKnownRoutesPassingPlatform(platformId) |
| Véhicules | getVehicle(vehicleId) · getPlayerMountedVehicle() · getKnownVehicles() · isPlayerMounted(id) · getVehicleMountDetail(): MountDetail (ridingCarIndex(): int, pos(): Vector3f relative au centre de la voiture — amont v2.3.0-prerelease.3) |
| Ascenseurs | getLift(id) · getPlayerMountedLift() · getKnownLifts() · getLiftFloors(tscLift): List<Floor> (les étages d’un ascenseur TSC — amont v2.3.0-prerelease.3) |
| Rails | getRailFromPath(pathData) · getKnownRails() · isRailBlocked(hexId) · getKnownBlockedRails() · getBlockedSignalColors(hexId) · getConnectedRails(pathData, front, back, excludeSelf = false) / getConnectedRails(pos) (les rails connectés à une extrémité de chemin / à la position d’un nœud de rail — amont v2.3.0-prerelease.3) |
| Quais / voies de garage | getPlatform(id) · getKnownPlatforms() · findNearbyPlatforms(pos, radius) ; getSiding(id) · getKnownSidings() · findNearbySidings(pos, radius) |
| Arrivées | getArrivals(platformId | platformIds[]): ArrivalEntries — le même objet que pids.arrivals() des scripts PIDS |
MTRClientData est une référence directe à la classe de données interne de MTR — un dernier recours : aucune promesse de stabilité, le contenu peut changer d’une version à l’autre.
Environnement Minecraft
MinecraftClient
worldIsRaining() · worldIsThundering() · worldIsRainingAt(pos) · worldDayTime() · blockLightAt(pos) · skyLightAt(pos) · lightAt(pos) (valeur empaquetée pour le rendu) · lightLevelAt(pos) · renderDistance() · localPlayer() · gamePaused() (la simulation TSC ne s’arrête pas avec la pause !) · narrate(msg) · displayMessage(msg, actionBar) (accepte aussi VanillaText) · spawnParticleInWorld(id, pos, velocity, alwaysSpawn=false) · getScoreboardScore(objective, player) · getWorldPlayers() · getCurrentWorldId() · getCameraMode() · getRedstoneLevel(pos) · getWorldBlockState(pos, stateName).
VanillaText (texte enrichi vanilla)
Construit les composants de texte vanilla du chat / de la barre d’action : literal(str) · translatable(key, ...) · append(other) · withBold() · withItalic() · withFont(id) · withColor(rgb | name) · clickToCopyText(str) · clickToOpenURL(url) · withHoverText(str | VanillaText) · getString() (retourne le résultat localisé).
VoxelShape (contours de bloc)
Pour les collisions / contours personnalisés des décorations : empty() · fullCube() · create(minX, minY, minZ, maxX, maxY, maxZ, facing?) (l’unité 16 = un bloc) · combine(other) ; à utiliser avec ctx.setOutlineShape(...) / ctx.setCollisionShape(...).
ItemStack / PlayerEntity
ItemStack : itemId() · translationId() · empty() · count(). PlayerEntity (en général issu de MinecraftClient.localPlayer() ou des événements) : uuid() · pos() / blockPos() / smoothPos() / velocity() · pitch() / yaw() / bodyYaw() · playerName() / displayName() · hasPermissionLevel(level) (information côté client, à ne pas prendre au sérieux) · mainHandItem() / offHandItem() / activeItem() / isHoldingItem(id) · isSneaking() / isSprinting() / isSwimming() / isCreative() / isSpectator().
Classes utilitaires
DataReader (décodage unifié)
Resources.read, Files.read et Networking.fetch le retournent tous — le décodeur d’une séquence d’octets :
asString(): String? (UTF-8) · asBufferedImage(): BufferedImage? · asFont(): Font? (TTF/OTF ; l’implémentation dépose un fichier dans le répertoire temporaire — en cas de disque saturé, nettoyez les résidus préfixés +~JF) · asByteArray(): byte[] · openInputStream(callback) (ferme le flux automatiquement) · asInputStream() (à fermer vous-même). Un échec de décodage retourne null et signale l’erreur dans la console.
Autres utilitaires
| Classe | L’essentiel |
|---|---|
Timing | elapsed() (secondes de jeu écoulées, y compris en pause) · delta() (secondes depuis le dernier render — la base pour cadrer les animations sur le framerate) · currentTimeMillis() · nanoTime() |
TextUtil | découpe le format de nommage 中文|English||附加 de MTR : getCjkParts / getNonCjkParts / getExtraParts / getNonExtraParts / getNonCjkAndExtraParts / isCjk / cycleString(src[, tick]) |
StateTracker | suivi des transitions d’état (pour éviter « redéclencher à chaque frame dès que la condition est remplie ») : setState(value): boolean (vrai uniquement en cas de changement) · stateNow() / stateLast() / stateNowDuration() / stateNowFirst() · changedTo(v) / changedFromTo(old, v) ; une instance par objet, à conserver dans state |
CycleTracker | carrousel cadencé dans le temps : new CycleTracker(["route", 5, "next", 5]) + tick() · stateNow() / stateLast() / stateNowDuration() / stateNowFirst() |
RateLimit | bridage de cadence : new RateLimit(intervalSec) + if (rl.shouldUpdate()) { ... } ; resetCoolDown() fait arriver l’échéance immédiatement |
Java | aide à l’interopérabilité Java : Java.newArray(class, length | dims), Java.toArray(class, list) — certaines méthodes AWT exigent de vrais tableaux Java |
Fonctionnalités des scripts
include (inclusion entre scripts)
include(Resources.id("mtrsteamloco:scripts/display_helper.js")); // chemin absolu
include("./util/common.js"); // relatif au script courant
Charge et exécute un autre fichier JS pendant la phase d’analyse (accepte un chemin relatif sous forme de chaîne, ou un Identifier).
Références croisées entre entrées de script
Une entrée de script qu’aucun contenu du même pack ne référence est refusée au chargement par défaut (pour prévenir un scriptId oublié) ; ajoutez "forceLoad": true à l’entrée pour la charger de force — utile pour partager une entrée de script entre packs, ou pour qu’une entrée MTR 3 emprunte une déclaration partagée MTR 4 ; attention à l’ordre de chargement des packs (le déclarant doit être chargé en premier).
Classes de compatibilité ANTE
SoundHelper (lecture de sons façon ANTE), TickableSound, GlobalRegister, ComponentUtil (utilitaires de composants de texte vanilla) et le asJavaArray(list, class) global sont disponibles depuis v2.3, avec des signatures identiques à ANTE, pour faciliter la migration du contenu ANTE.
Ensuite : Types de scripts JS — les API dédiées aux véhicules / décorations / ascenseurs / PIDS ; Extensions Yanyang — les capacités que cette branche ajoute par-dessus JS.