Aller au contenu

Mods WebAssembly (C/C++)

Pour du code plus lourd ou si vous préférez le C et le C++, écrivez votre mod en WebAssembly. Votre code est compilé en un seul fichier .wasm de quelques kilo-octets, qui tourne à l’identique sur Windows et macOS, sans signature ni compilation par plateforme.

  • wasi-sdk (clang pour WebAssembly) ;
  • du SDK NeoPiano : l’en-tête NeoPianoModAPI/Wasm/neo_mod.h et le script Scripts/build_wasm_mod.sh.
  • RépertoireMods/
    • RépertoireChordSpheres/
      • ChordSpheres.uplugin
      • RépertoireCode/
        • ChordSpheres.wasm produit par la compilation
      • RépertoireSource/
        • ChordSpheres.cpp non chargé par NeoPiano
ChordSpheres.uplugin
{
"FileVersion": 3,
"FriendlyName": "Chord Spheres",
"Version": 1,
"VersionName": "1.0.0",
"CanContainContent": false,
"NeoModApiVersion": 5,
"NeoModScripts": ["Code/ChordSpheres.wasm"],
"NeoModCapabilities": []
}

Le module exporte des fonctions que NeoPiano appelle, et importe les fonctions de l’API neo. Les signatures sont vérifiées au chargement.

Source/ChordSpheres.cpp
#include "neo_mod.h"
NEO_EXPORT void neo_mod_init() {
NEO_LOG_LITERAL("Chord Spheres prêt");
}
NEO_EXPORT void neo_on_note_on(int note, float velocity) {
// Une sphère au-dessus de la touche, du bleu (doux) au rouge (fort).
neo_spawn_note_mesh(note, velocity, 0.3f, 1.0f - velocity, 1.5f);
}
NEO_EXPORT void neo_on_note_off(int note) {}
NEO_EXPORT void neo_on_tick(float dt) {}
Export Appelé
neo_mod_init() une fois, au démarrage du mod
neo_on_note_on(int note, float velocity) à chaque note jouée (vélocité de 0 à 1)
neo_on_note_off(int note) au relâchement d’une note
neo_on_tick(float dt) à chaque image
neo_on_ui, neo_on_setting événements d’interface et de réglages (voir plus bas)
  1. Installez wasi-sdk.

  2. Compilez votre source avec le script du SDK, Scripts/build_wasm_mod.sh (ses options sont décrites en tête du script), et placez le .wasm obtenu dans Code/.

  3. Rechargez les mods dans NeoPiano.

Le script compile sans bibliothèque standard ni WASI (-nostdlib), sans exceptions ni RTTI, et retire les symboles. Les classes, les templates et std::array fonctionnent ; ce qui dépend d’un système (fichiers, horloge, printf) n’est pas disponible : passez par l’API neo.

Les fonctions d’interface (neo.ui.*), de réglages et de stockage prennent leurs arguments en JSON (pointeur et longueur dans la mémoire du module). Les événements arrivent par deux exports : le module fournit neo_alloc pour que NeoPiano y écrive le JSON de l’événement, puis appelle neo_on_ui ou neo_on_setting.

{ "id": "ping", "event": "click", "value": null }
Limite Valeur
Mémoire linéaire 2 Mio
Pile 64 Kio
Taille du module 4 Mo
Temps par appel 20 ms (250 ms pour neo_mod_init)

Toute adresse passée à l’API est vérifiée : un accès hors de la mémoire du module provoque un trap et le mod est désactivé. Les imports en dehors de l’API neo sont refusés au chargement.

Documentation synchronisée avec NeoPiano · commit cbf48cc · 17 octobre 2026