This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Si vous avez besoin d’interactions personnalisées de bas niveau avec des logiciels ou du matériel externes et que Lua ne suffit pas, le SDK Defold vous permet d’écrire des extensions du moteur en C, C++, C#, Objective-C, Java ou JavaScript, selon la plateforme cible. Les cas d’utilisation courants des extensions natives sont les suivants :
La prise en charge de C# est expérimentale et s’adresse aux extensions natives, pas aux composants script (script components) Defold. Elle utilise .NET 9 NativeAOT pour produire une bibliothèque statique ; ajoutez des fichiers source .cs au dossier src d’une extension et le service de build génère le fichier de projet. La prise en charge des cibles dépend des capacités actuelles de NativeAOT et du service de build. Consultez l’exemple officiel des langages pour les extensions natives pour connaître le flux de travail actuel et la configuration testée.
Defold vous permet de commencer à utiliser les extensions natives sans aucune configuration, grâce à une solution de build dans le cloud. Toute extension native développée et ajoutée à un projet de jeu, directement ou par l’intermédiaire d’un projet bibliothèque, fait partie du contenu ordinaire du projet. Il n’est pas nécessaire de compiler des versions spéciales du moteur et de les distribuer aux membres de l’équipe, car cela se fait automatiquement : tout membre de l’équipe qui compile et exécute le projet obtient un exécutable du moteur propre au projet, intégrant toutes les extensions natives.

Defold fournit gratuitement le serveur de build dans le cloud, sans aucune restriction d’utilisation. Le serveur est hébergé en Europe, et l’URL à laquelle le code natif est envoyé se configure dans la fenêtre des préférences de l’éditeur ou au moyen de l’option de ligne de commande --build-server de bob. Si vous souhaitez configurer votre propre serveur, suivez ces instructions.
Pour créer une nouvelle extension, créez un dossier à la racine du projet. Ce dossier contiendra tous les paramètres, le code source, les bibliothèques et les ressources associés à l’extension. Le service de build des extensions reconnaît la structure des dossiers et rassemble les fichiers source et les bibliothèques.
myextension/
│
├── ext.manifest
│
├── src/
│
├── include/
│
├── lib/
│ └──[platforms]
│
├── manifests/
│ └──[platforms]
│
└── res/
└──[platforms]
platform ou architecture-platform, en fonction des architectures prises en charge par vos bibliothèques.
Les plateformes prises en charge sont ios, android, osx, win32, linux, web.
Les paires arc-platform prises en charge sont arm64-ios, arm64_sim-ios, armv7-android, arm64-android, x86_64-android, arm64-osx, x86_64-osx, x86-win32, x86_64-win32, arm64-linux, x86_64-linux, wasm-web et wasm_pthread-web.
platform ou architecture-platform, comme les sous-dossiers de lib. Un sous-dossier common est également autorisé pour contenir les fichiers de ressources communs à toutes les plateformes.Le dossier facultatif manifests d’une extension contient des fichiers supplémentaires utilisés lors du build et de la création de bundles. Les fichiers devraient être placés dans des sous-dossiers nommés selon platform :
android - Ce dossier accepte un fichier de manifeste partiel à fusionner avec celui de l’application principale (comme décrit ici).
build.gradle avec des dépendances qui seront résolues par Gradle.ios - Ce dossier accepte un fichier de manifeste partiel à fusionner avec celui de l’application principale (comme décrit ici).
Podfile avec des dépendances qui seront résolues par Cocoapods.osx - Ce dossier accepte un fichier de manifeste partiel à fusionner avec celui de l’application principale (comme décrit ici).web - Ce dossier accepte un fichier de manifeste partiel à fusionner avec celui de l’application principale (comme décrit ici).Les extensions sont traitées comme toute autre ressource de votre projet et peuvent être partagées de la même manière. Si le dossier d’une extension native est ajouté comme dossier de bibliothèque, il peut être partagé et utilisé par d’autres comme dépendance de projet. Consultez le manuel des projets bibliothèques pour plus d’informations.
Créons une extension très simple. Nous commençons par créer un nouveau dossier myextension à la racine, puis nous ajoutons un fichier ext.manifest contenant le nom de l’extension « MyExtension ». Notez que ce nom est un symbole C++ et doit correspondre au premier argument de DM_DECLARE_EXTENSION (voir ci-dessous).

# C++ symbol in your extension
name: "MyExtension"
L’extension se compose d’un seul fichier C++, myextension.cpp, créé dans le dossier « src ».

Le fichier source de l’extension contient le code suivant :
// myextension.cpp
// Extension lib defines
#define LIB_NAME "MyExtension"
#define MODULE_NAME "myextension"
// include the Defold SDK
#include <dmsdk/sdk.h>
static int Reverse(lua_State* L)
{
// The number of expected items to be on the Lua stack
// once this struct goes out of scope
DM_LUA_STACK_CHECK(L, 1);
// Check and get parameter string from stack
char* str = (char*)luaL_checkstring(L, 1);
// Reverse the string
int len = strlen(str);
for(int i = 0; i < len / 2; i++) {
const char a = str[i];
const char b = str[len - i - 1];
str[i] = b;
str[len - i - 1] = a;
}
// Put the reverse string on the stack
lua_pushstring(L, str);
// Return 1 item
return 1;
}
// Functions exposed to Lua
static const luaL_reg Module_methods[] =
{
{"reverse", Reverse},
{0, 0}
};
static void LuaInit(lua_State* L)
{
int top = lua_gettop(L);
// Register lua names
luaL_register(L, MODULE_NAME, Module_methods);
lua_pop(L, 1);
assert(top == lua_gettop(L));
}
dmExtension::Result AppInitializeMyExtension(dmExtension::AppParams* params)
{
return dmExtension::RESULT_OK;
}
dmExtension::Result InitializeMyExtension(dmExtension::Params* params)
{
// Init Lua
LuaInit(params->m_L);
printf("Registered %s Extension\n", MODULE_NAME);
return dmExtension::RESULT_OK;
}
dmExtension::Result AppFinalizeMyExtension(dmExtension::AppParams* params)
{
return dmExtension::RESULT_OK;
}
dmExtension::Result FinalizeMyExtension(dmExtension::Params* params)
{
return dmExtension::RESULT_OK;
}
// Defold SDK uses a macro for setting up extension entry points:
//
// DM_DECLARE_EXTENSION(symbol, name, app_init, app_final, init, update, on_event, final)
// MyExtension is the C++ symbol that holds all relevant extension data.
// It must match the name field in the `ext.manifest`
DM_DECLARE_EXTENSION(MyExtension, LIB_NAME, AppInitializeMyExtension, AppFinalizeMyExtension, InitializeMyExtension, 0, 0, FinalizeMyExtension)
Notez la macro DM_DECLARE_EXTENSION, utilisée pour déclarer les différents points d’entrée dans le code de l’extension. Le premier argument symbol doit correspondre au nom indiqué dans ext.manifest. Dans cet exemple simple, aucun point d’entrée update ou on_event n’est nécessaire ; on passe donc 0 à la macro pour ces arguments.
Il suffit maintenant de compiler le projet (Project ▸ Build). Cela envoie l’extension au service de build des extensions, qui produit un moteur personnalisé intégrant la nouvelle extension. Si le service rencontre des erreurs, une boîte de dialogue affiche les erreurs de build.
Pour tester l’extension, créez un objet de jeu (game object) et ajoutez un composant script avec du code de test :
local s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
local reverse_s = myextension.reverse(s)
print(reverse_s) --> ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba
Et voilà ! Nous avons créé une extension native entièrement fonctionnelle.
Comme nous l’avons vu plus haut, la macro DM_DECLARE_EXTENSION sert à déclarer les différents points d’entrée dans le code de l’extension :
DM_DECLARE_EXTENSION(symbol, name, app_init, app_final, init, update, on_event, final)
Ces points d’entrée vous permettent d’exécuter du code à différents moments du cycle de vie d’une extension :
app_init de l’extensioninit de l’extension - Toutes les API Defold ont été initialisées. Il s’agit du moment recommandé dans le cycle de vie de l’extension pour créer les liaisons Lua vers le code de l’extension.init() des fichiers de script est appelée.update de l’extensionupdate() des fichiers de script est appelée.on_event de l’extensionfinal() des fichiers de script est appelée.final de l’extensionapp_final de l’extensionLes identifiants suivants sont définis par le service de build sur chaque plateforme correspondante :
DM_PLATFORM_WINDOWSDM_PLATFORM_OSXDM_PLATFORM_IOSDM_PLATFORM_ANDROIDDM_PLATFORM_LINUXDM_PLATFORM_HTML5Les journaux du serveur de build sont disponibles lorsque le projet utilise des extensions natives. Le journal du serveur de build (log.txt) est téléchargé avec le moteur personnalisé lors du build du projet. Il est stocké dans le fichier .internal/%platform%/build.zip et également extrait dans le dossier de build de votre projet.
Le portail de ressources Defold contient également plusieurs extensions natives.