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
Lua만으로는 충분하지 않은 낮은 수준에서 외부 소프트웨어나 하드웨어와 커스텀 상호작용이 필요한 경우, Defold SDK를 사용해 타겟 플랫폼에 따라 C, C++, Objective C, Java 또는 JavaScript로 엔진 익스텐션을 작성할 수 있습니다. 네이티브 익스텐션의 일반적인 사용 사례는 다음과 같습니다.
Defold는 클라우드 기반 빌드 솔루션으로 네이티브 익스텐션에 대한 zero setup 진입점을 제공합니다. 직접 또는 라이브러리 프로젝트를 통해 개발되어 게임 프로젝트에 추가된 모든 네이티브 익스텐션은 일반 프로젝트 컨텐츠의 일부가 됩니다. 엔진의 특수 버전을 빌드해서 팀원들에게 배포할 필요가 없습니다. 이 작업은 자동으로 처리되며, 프로젝트를 빌드하고 실행하는 모든 팀원은 모든 네이티브 익스텐션이 포함된 프로젝트별 엔진 실행 파일을 받게 됩니다.

Defold는 사용 제한 없이 클라우드 빌드 서버를 무료로 제공합니다. 서버는 유럽에서 호스팅되며, 네이티브 코드가 전송되는 URL은 Editor Preferences 창에서 설정하거나 bob의 --build-server 커맨드 라인 옵션으로 설정합니다. 자체 서버를 설정하려면 이 지침을 따르세요.
새 익스텐션을 만들려면 프로젝트 루트에 폴더를 만듭니다. 이 폴더에는 익스텐션과 관련된 모든 설정, 소스 코드, 라이브러리, 리소스가 들어갑니다. 익스텐션 빌더는 폴더 구조를 인식하고 모든 소스 파일과 라이브러리를 수집합니다.
myextension/
│
├── ext.manifest
│
├── src/
│
├── include/
│
├── lib/
│ └──[platforms]
│
├── manifests/
│ └──[platforms]
│
└── res/
└──[platforms]
platform 또는 architecture-platform 이름의 하위 폴더에 배치해야 합니다.
지원되는 플랫폼은 ios, android, osx, win32, linux, web입니다.
지원되는 arc-platform 쌍은 arm64-ios, x86_64-ios, armv7-android, arm64-android, arm64-osx, x86_64-osx, x86-win32, x86_64-win32, arm64-linux, x86_64-linux, wasm-web, wasm_pthread-web입니다.
platform 또는 architecture-platform 이름의 하위 폴더에 배치해야 합니다. 모든 플랫폼에 공통으로 사용되는 리소스 파일을 담는 common 하위 폴더도 허용됩니다.익스텐션의 선택적 manifests 폴더에는 빌드 및 번들링 과정에서 사용되는 추가 파일이 들어갑니다. 파일은 platform 이름의 하위 폴더에 배치해야 합니다.
android - 이 폴더에는 메인 어플리케이션에 병합될 메니페스트 스텁 파일을 넣을 수 있습니다(여기에 설명된 대로).
build.gradle 파일도 넣을 수 있습니다.ios - 이 폴더에는 메인 어플리케이션에 병합될 메니페스트 스텁 파일을 넣을 수 있습니다(여기에 설명된 대로).
Podfile 파일도 넣을 수 있습니다.osx - 이 폴더에는 메인 어플리케이션에 병합될 메니페스트 스텁 파일을 넣을 수 있습니다(여기에 설명된 대로).web - 이 폴더에는 메인 어플리케이션에 병합될 메니페스트 스텁 파일을 넣을 수 있습니다(여기에 설명된 대로).익스텐션은 프로젝트의 다른 에셋과 동일하게 취급되며 같은 방식으로 공유할 수 있습니다. 네이티브 익스텐션 폴더를 라이브러리 폴더로 추가하면 프로젝트 종속성으로 공유하고 다른 사람이 사용할 수 있습니다. 자세한 내용은 라이브러리 프로젝트 매뉴얼을 참조하세요.
아주 간단한 익스텐션을 만들어 보겠습니다. 먼저 myextension이라는 새 루트 폴더를 만들고 익스텐션 이름 “MyExtension“이 들어 있는 ext.manifest 파일을 추가합니다. 이 이름은 C++ 심볼이며 DM_DECLARE_EXTENSION의 첫 번째 인자와 일치해야 합니다(아래 참조).

# 익스텐션의 C++ 심볼
name: "MyExtension"
익스텐션은 “src” 폴더에 생성한 myextension.cpp라는 단일 C++ 파일로 구성됩니다.

익스텐션 소스 파일에는 다음 코드가 들어갑니다.
// myextension.cpp
// 익스텐션 lib 정의
#define LIB_NAME "MyExtension"
#define MODULE_NAME "myextension"
// Defold SDK 포함
#include <dmsdk/sdk.h>
static int Reverse(lua_State* L)
{
// 이 struct가 범위를 벗어났을 때
// Lua 스택에 있어야 하는 예상 아이템 수
DM_LUA_STACK_CHECK(L, 1);
// 스택에서 문자열 파라미터를 확인하고 가져오기
char* str = (char*)luaL_checkstring(L, 1);
// 문자열 뒤집기
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;
}
// 뒤집힌 문자열을 스택에 넣기
lua_pushstring(L, str);
// 아이템 1개 반환
return 1;
}
// Lua에 노출되는 함수
static const luaL_reg Module_methods[] =
{
{"reverse", Reverse},
{0, 0}
};
static void LuaInit(lua_State* L)
{
int top = lua_gettop(L);
// Lua 이름 등록
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)
{
// 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는 익스텐션 진입점을 설정하기 위해 매크로를 사용합니다.
//
// DM_DECLARE_EXTENSION(symbol, name, app_init, app_final, init, update, on_event, final)
// MyExtension은 관련된 모든 익스텐션 데이터를 보관하는 C++ 심볼입니다.
// `ext.manifest`의 name 필드와 일치해야 합니다.
DM_DECLARE_EXTENSION(MyExtension, LIB_NAME, AppInitializeMyExtension, AppFinalizeMyExtension, InitializeMyExtension, 0, 0, FinalizeMyExtension)
익스텐션 코드의 다양한 진입점을 선언하는 데 사용되는 DM_DECLARE_EXTENSION 매크로를 확인하세요. 첫 번째 인자 symbol은 ext.manifest에 지정된 이름과 일치해야 합니다. 이 간단한 예제에서는 “update” 또는 “on_event” 진입점이 필요하지 않으므로 매크로의 해당 위치에 0을 제공합니다.
이제 프로젝트를 빌드하기만 하면 됩니다(Project ▸ Build). 그러면 익스텐션이 익스텐션 빌더에 업로드되고, 빌더는 새 익스텐션이 포함된 커스텀 엔진을 생성합니다. 빌더에서 오류가 발생하면 빌드 오류가 포함된 대화 상자가 표시됩니다.
익스텐션을 테스트하려면 게임 오브젝트를 만들고 테스트 코드가 있는 스크립트 컴포넌트를 추가합니다.
local s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
local reverse_s = myextension.reverse(s)
print(reverse_s) --> ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba
이제 완료되었습니다. 완전히 동작하는 네이티브 익스텐션을 만들었습니다.
위에서 본 것처럼 DM_DECLARE_EXTENSION 매크로는 익스텐션 코드의 다양한 진입점을 선언하는 데 사용됩니다.
DM_DECLARE_EXTENSION(symbol, name, app_init, app_final, init, update, on_event, final)
진입점을 통해 익스텐션 라이프사이클의 여러 시점에서 코드를 실행할 수 있습니다.
app_initinit - 모든 Defold API가 초기화되었습니다. 익스텐션 코드에 대한 Lua 바인딩을 생성하기에 권장되는 익스텐션 라이프사이클 시점입니다.init() 함수가 호출됩니다.updateupdate() 함수가 호출됩니다.on_eventfinal() 함수가 호출됩니다.finalapp_final빌더는 각 플랫폼에서 다음 식별자를 정의합니다.
DM_PLATFORM_WINDOWSDM_PLATFORM_OSXDM_PLATFORM_IOSDM_PLATFORM_ANDROIDDM_PLATFORM_LINUXDM_PLATFORM_HTML5프로젝트에서 네이티브 익스텐션을 사용할 때 빌드 서버 로그를 확인할 수 있습니다. 빌드 서버 로그(log.txt)는 프로젝트를 빌드할 때 커스텀 엔진과 함께 다운로드되며, .internal/%platform%/build.zip 파일 안에 저장되고 프로젝트의 빌드 폴더에도 압축 해제됩니다.
Defold 에셋 포털에도 여러 네이티브 익스텐션이 있습니다.