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
Se devi interagire in modo personalizzato con software o hardware esterni a basso livello e Lua non è sufficiente, l’SDK di Defold permette di scrivere estensioni del motore in C, C++, C#, Objective-C, Java o JavaScript, a seconda della piattaforma di destinazione. Alcuni casi d’uso tipici delle estensioni native sono:
Il supporto a C# è sperimentale ed è destinato alle estensioni native, non ai componenti script di Defold. Usa .NET 9 NativeAOT per produrre una libreria statica; aggiungi i file sorgente .cs alla cartella src di un’estensione e il servizio di build genererà il file di progetto. Le piattaforme di destinazione supportate dipendono dalle capacità attuali di NativeAOT e del servizio di build. Consulta l’esempio ufficiale dei linguaggi per le estensioni native per il flusso di lavoro attuale e la configurazione verificata.
Defold permette di iniziare a usare le estensioni native senza alcuna configurazione, grazie a una soluzione di build nel cloud. Ogni estensione nativa sviluppata e aggiunta a un progetto di gioco, direttamente o tramite un progetto libreria, diventa parte del normale contenuto del progetto. Non occorre creare versioni speciali del motore e distribuirle ai membri del team: tutto questo viene gestito automaticamente. Ogni membro del team che crea una build ed esegue il progetto ottiene un eseguibile del motore specifico per quel progetto, con tutte le estensioni native integrate.

Defold mette a disposizione gratuitamente il server di build nel cloud, senza limitazioni d’uso. Il server è ospitato in Europa e l’URL a cui viene inviato il codice nativo si configura nella finestra delle preferenze dell’editor oppure tramite l’opzione a riga di comando --build-server di bob. Se desideri configurare un tuo server, segui queste istruzioni.
Per creare una nuova estensione, crea una cartella nella radice del progetto. Questa cartella conterrà tutte le impostazioni, il codice sorgente, le librerie e le risorse associate all’estensione. Il servizio di build delle estensioni riconosce la struttura delle cartelle e raccoglie tutti i file sorgente e le librerie.
myextension/
│
├── ext.manifest
│
├── src/
│
├── include/
│
├── lib/
│ └──[platforms]
│
├── manifests/
│ └──[platforms]
│
└── res/
└──[platforms]
platform o architecture-platform, a seconda delle architetture supportate dalle librerie.
Le piattaforme supportate sono ios, android, osx, win32, linux, web.
Le coppie arc-platform supportate sono 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 e wasm_pthread-web.
platform o architecture-platform, come per le sottocartelle di lib. È consentita anche una sottocartella common, contenente i file delle risorse comuni a tutte le piattaforme.La cartella facoltativa manifests di un’estensione contiene file aggiuntivi usati nel processo di build e di creazione del bundle. I file vanno collocati in sottocartelle denominate secondo lo schema platform:
android - Questa cartella accetta un frammento di file manifest da unire a quello dell’applicazione principale (come descritto qui).
build.gradle con dipendenze da risolvere tramite Gradle.ios - Questa cartella accetta un frammento di file manifest da unire a quello dell’applicazione principale (come descritto qui).
Podfile con dipendenze da risolvere tramite Cocoapods.osx - Questa cartella accetta un frammento di file manifest da unire a quello dell’applicazione principale (come descritto qui).web - Questa cartella accetta un frammento di file manifest da unire a quello dell’applicazione principale (come descritto qui).Le estensioni vengono trattate come qualsiasi altro asset del progetto e possono essere condivise allo stesso modo. Se una cartella di estensione nativa viene aggiunta come cartella di libreria, può essere condivisa e usata da altri come dipendenza del progetto. Consulta il manuale dei progetti libreria per ulteriori informazioni.
Realizza un’estensione molto semplice. Per prima cosa, crea una nuova cartella myextension nella radice e aggiungi un file ext.manifest contenente il nome dell’estensione, “MyExtension”. Il nome è un simbolo C++ e deve corrispondere al primo argomento di DM_DECLARE_EXTENSION (vedi sotto).

# C++ symbol in your extension
name: "MyExtension"
L’estensione è composta da un singolo file C++, myextension.cpp, creato nella cartella “src”.

Il file sorgente dell’estensione contiene il seguente codice:
// 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)
Osserva la macro DM_DECLARE_EXTENSION, usata per dichiarare i vari punti di ingresso nel codice dell’estensione. Il primo argomento, symbol, deve corrispondere al nome specificato in ext.manifest. In questo semplice esempio non servono punti di ingresso update o on_event, quindi in quelle posizioni viene passato 0 alla macro.
Ora basta creare una build del progetto (Project ▸ Build). L’estensione verrà caricata sul servizio di build delle estensioni, che produrrà un motore personalizzato con la nuova estensione inclusa. Se il servizio rileva errori, verrà mostrata una finestra di dialogo con gli errori di build.
Per provare l’estensione, crea un oggetto di gioco (game object) e aggiungi un componente script con del codice di test:
local s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
local reverse_s = myextension.reverse(s)
print(reverse_s) --> ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba
Ecco fatto! Hai creato un’estensione nativa completamente funzionante.
Come visto sopra, la macro DM_DECLARE_EXTENSION serve a dichiarare i vari punti di ingresso nel codice dell’estensione:
DM_DECLARE_EXTENSION(symbol, name, app_init, app_final, init, update, on_event, final)
I punti di ingresso permettono di eseguire codice in vari momenti del ciclo di vita di un’estensione:
app_init dell’estensioneinit dell’estensione - Tutte le API di Defold sono state inizializzate. Questo è il momento consigliato nel ciclo di vita dell’estensione per creare i binding Lua al codice dell’estensione.init() dei file script.update dell’estensioneupdate() dei file script.on_event dell’estensionefinal() dei file script.final dell’estensioneapp_final dell’estensioneIl servizio di build definisce i seguenti identificatori sulle rispettive piattaforme:
DM_PLATFORM_WINDOWSDM_PLATFORM_OSXDM_PLATFORM_IOSDM_PLATFORM_ANDROIDDM_PLATFORM_LINUXDM_PLATFORM_HTML5I log del server di build sono disponibili quando il progetto usa estensioni native. Il log del server di build (log.txt) viene scaricato insieme al motore personalizzato quando viene creata una build del progetto. Viene conservato nel file .internal/%platform%/build.zip ed estratto anche nella cartella di build del progetto.
Anche l’Asset Portal di Defold contiene diverse estensioni native.