Manuals
Manuals




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 API

Lua API는 하나만 있어야 하며, 그 구현도 하나만 있어야 합니다. 이렇게 하면 모든 플랫폼에서 같은 동작을 유지하기가 훨씬 쉬워집니다.

해당 플랫폼에서 익스텐션을 지원하면 안 되는 경우에는 Lua 모듈을 아예 등록하지 않는 것을 권장합니다. 이렇게 하면 nil 여부를 확인해서 지원 여부를 감지할 수 있습니다.

    if myextension ~= nil then
        myextension.do_something()
    end

폴더 구조

다음 폴더 구조는 익스텐션에서 자주 사용됩니다.

    /root
        /input
        /main                            -- 실제 예제 프로젝트의 모든 파일
            /...
        /myextension                     -- 익스텐션의 실제 루트 폴더
            ext.manifest
            /include                     -- 다른 익스텐션에서 사용하는 외부 include 파일
            /libs
                /<platform>              -- 지원되는 모든 플랫폼용 외부 라이브러리
            /src
                myextension.cpp          -- 익스텐션 Lua API 및 익스텐션 라이프사이클 함수
                                            Lua API 함수의 일반 구현도 포함합니다.
                myextension_private.h    -- 각 플랫폼이 구현할 내부 API(예: `myextension_Init` 등)
                myextension.mm           -- iOS/macOS에 네이티브 호출이 필요한 경우. iOS/macOS용 `myextension_Init` 등을 구현합니다.
                myextension_android.cpp  -- Android에 JNI 호출이 필요한 경우. Android용 `myextension_Init` 등을 구현합니다.
                /java
                    /<platform>          -- Android에 필요한 모든 Java 파일
            /res                         -- 플랫폼에 필요한 모든 리소스
            /external
                README.md                -- 외부 라이브러리를 빌드하거나 패키징하는 방법에 대한 참고/스크립트
        /bundleres                       -- 번들링해야 하는 리소스(game.project 및 [bundle_resources 설정]([physics scale setting](/ko/manuals/project-settings/#project)) 참조)
            /<platform>
        game.project
        game.appmanifest                 -- 추가 앱 설정 정보

myextension.mmmyextension_android.cpp는 해당 플랫폼에 특화된 네이티브 호출을 수행하는 경우에만 필요합니다.

플랫폼 폴더

특정 위치에서는 어플리케이션을 컴파일/번들링할 때 어떤 파일을 사용할지 알기 위해 플랫폼 아키텍처를 폴더 이름으로 사용합니다. 형식은 다음과 같습니다.

<architecture>-<platform>

현재 목록은 다음과 같습니다.

arm64-ios, armv7-ios, x86_64-ios, arm64-android, armv7-android, x86_64-linux, x86_64-osx, x86_64-win32, x86-win32

예를 들어 플랫폼별 라이브러리는 다음 위치에 넣습니다.

/libs
    /arm64-ios
                        /libFoo.a
    /arm64-android
                        /libFoo.a

네이티브 코드 작성

Defold 소스에서는 C++를 매우 제한적으로 사용하며, 대부분의 코드는 C와 매우 비슷합니다. 템플릿은 컴파일 시간과 실행 파일 크기에 비용을 발생시키기 때문에, 몇몇 컨테이너 클래스를 제외하면 거의 사용하지 않습니다.

C++ 버전

Defold 소스는 각 컴파일러의 기본 C++ 버전으로 빌드됩니다. Defold 소스 자체는 C++98보다 높은 C++ 버전을 사용하지 않습니다. 익스텐션을 빌드할 때 더 높은 버전을 사용할 수는 있지만, 더 높은 버전에는 ABI 변경이 함께 올 수 있습니다. 이로 인해 엔진에 포함된 익스텐션이나 Asset Portal의 익스텐션과 함께 하나의 익스텐션을 사용하는 것이 불가능해질 수 있습니다.

Defold 소스는 최신 C++ 기능이나 버전 사용을 피합니다. 주된 이유는 게임엔진을 만들 때 새 기능이 필요하지 않기 때문이지만, 최신 C++ 기능을 계속 파악하는 일은 시간이 많이 드는 작업이고, 그 기능들을 제대로 숙달하려면 많은 귀중한 시간이 필요하기 때문이기도 합니다.

또한 익스텐션 개발자에게는 Defold가 안정적인 ABI를 유지한다는 추가 이점도 있습니다. 최신 C++ 기능을 사용하면 플랫폼별 지원 차이 때문에 코드가 다른 플랫폼에서 컴파일되지 않을 수도 있다는 점도 짚어둘 만합니다.

C++ 예외 사용 안 함

Defold는 엔진에서 C++ 예외를 사용하지 않습니다. 게임엔진에서는 개발 중에 데이터가 대부분 미리 알려져 있으므로 일반적으로 예외를 피합니다. C++ 예외 지원을 제거하면 실행 파일 크기가 줄고 런타임 성능이 향상됩니다.

Standard Template Libraries - STL

Defold 엔진은 일부 알고리즘과 수학 관련 코드(std::sort, std::upper_bound 등)를 제외하면 STL 코드를 사용하지 않으므로, 익스텐션에서 STL을 사용할 수는 있습니다.

다시 말하지만, ABI 비호환성은 익스텐션을 다른 익스텐션이나 서드파티 라이브러리와 함께 사용할 때 장애가 될 수 있다는 점을 염두에 두세요.

(템플릿을 많이 사용하는) STL 라이브러리를 피하면 빌드 시간이 개선되고, 더 중요하게는 실행 파일 크기도 줄어듭니다.

문자열

Defold 엔진에서는 std::string 대신 const char*를 사용합니다. 서로 다른 C++ 버전이나 컴파일러 버전을 함께 사용할 때 std::string 사용은 ABI 불일치를 일으킬 수 있는 흔한 함정입니다. const char*와 몇 가지 헬퍼 함수를 사용하면 이를 피할 수 있습니다.

함수 숨기기

가능하다면 컴파일 단위 내부에서만 사용하는 함수에 static 키워드를 사용하세요. 이렇게 하면 컴파일러가 일부 최적화를 수행할 수 있으며, 성능을 개선하고 실행 파일 크기도 줄일 수 있습니다.

서드파티 라이브러리

사용할 서드파티 라이브러리를 선택할 때는 언어와 관계없이 다음을 고려하세요.

  • 기능 - 현재 가진 특정 문제를 해결합니까?
  • 성능 - 런타임에 성능 비용을 발생시킵니까?
  • 라이브러리 크기 - 최종 실행 파일이 얼마나 더 커집니까? 허용 가능한 수준입니까?
  • 종속성 - 추가 라이브러리가 필요합니까?
  • 지원 - 라이브러리의 상태는 어떻습니까? 열린 이슈가 많습니까? 아직 유지보수되고 있습니까?
  • 라이선스 - 이 프로젝트에서 사용해도 괜찮습니까?

오픈 소스 종속성

항상 종속성에 액세스할 수 있는지 확인하세요. 예를 들어 GitHub의 무언가에 의존한다면 해당 저장소가 삭제되거나, 갑자기 방향 또는 소유권이 바뀌는 것을 막을 방법은 없습니다. 저장소를 포크(fork)하고 upstream 프로젝트 대신 자신의 fork를 사용하면 이 위험을 완화할 수 있습니다.

라이브러리의 코드는 게임에 주입된다는 점을 기억하세요. 따라서 라이브러리가 해야 할 일만 수행하고 그 이상은 하지 않는지 확인해야 합니다!