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                            -- All the files for the actual example project
            /...
        /myextension                     -- The actual root folder of the extension
            ext.manifest
            /include                     -- External includes, used by other extensions
            /libs
                /<platform>              -- External libraries for all supported platforms
            /src
                myextension.cpp          -- The extension Lua api and the extension life cycle functions
                                            Also contains generic implementations of your Lua api functions.
                myextension_private.h    -- Your internal api that each platform will implement (I.e. `myextension_Init` etc)
                myextension.mm           -- If native calls are needed for iOS/macOS. Implements `myextension_Init` etc for iOS/macOS
                myextension_android.cpp  -- If JNI calls are needed for Android. Implements `myextension_Init` etc for Android
                /java
                    /<platform>          -- Any java files needed for Android
            /res                         -- Any resources needed for a platform
            /external
                README.md                -- Notes/scripts on how to build or package any external libraries
        /bundleres                       -- Resources that should be bundles for (see game.project and the [bundle_resources setting]([physics scale setting](/ru/manuals/project-settings/#project))
            /<platform>
        game.project
        game.appmanifest                 -- Any extra app configuration info

Обратите внимание, что myextension.mm и myextension_android.cpp нужны только при использовании нативных вызовов для соответствующих платформ.

Папки платформ

В некоторых случаях архитектура платформы используется в качестве имени папки, чтобы определить, какие файлы использовать при компиляции/упаковке приложения. Формат:

<architecture>-<platform>

Текущий список:

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

Например, для платформоспецифичных библиотек:

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

Написание нативного кода

В исходном коде Defold C++ используется очень ограниченно и преимущественно в C-стиле. Шаблоны почти не используются (за исключением некоторых контейнерных классов), так как они увеличивают время компиляции и размер исполняемого файла.

Версия C++

При сборке основного движка мы используем C++11, но в Windows — C++14. Сборки для консолей сейчас обычно требуют C++14 или новее.

Для нативных расширений мы не используем фиксированную версию C++, а полагаемся на версию по умолчанию в наборе инструментов платформы.

Исходный код Defold избегает использования последних возможностей или версий C++. В основном потому, что при разработке игрового движка нет необходимости в новых возможностях, а также потому, что отслеживание последних изменений в C++ — это трудоёмкая задача, а для полного освоения этих возможностей потребуется много драгоценного времени.

Дополнительным плюсом является поддержание стабильного ABI, что важно для разработчиков расширений. Использование новейших возможностей C++ также может затруднить сборку под разные платформы из-за различий в поддержке.

Без исключений C++

Defold не использует исключения в движке. Исключения, как правило, не применяются в игровых движках, так как большинство данных известно на этапе разработки. Отключение поддержки исключений C++ уменьшает размер исполняемого файла и повышает производительность.

Стандартная библиотека шаблонов (STL)

В движке Defold не используется STL, за исключением некоторых алгоритмов и математических функций (std::sort, std::upper_bound и т.д.). Однако, при необходимости, вы можете использовать STL в расширении.

Следует помнить, что несовместимости ABI могут помешать использованию расширений совместно с другими расширениями или сторонними библиотеками.

Избегание STL (из-за его обширного использования шаблонов) помогает ускорить сборку и уменьшить размер исполняемого файла.

Строки

В Defold используется const char* вместо std::string. Использование std::string часто вызывает проблемы ABI при смешивании разных версий C++ или компиляторов. Применение const char* и вспомогательных функций позволяет избежать этих проблем.

Скрытие функций

Если возможно, используйте ключевое слово static для функций, локальных для единицы трансляции. Это позволяет компилятору выполнять оптимизации, улучшает производительность и уменьшает размер исполняемого файла.

Сторонние библиотеки

При выборе сторонней библиотеки (вне зависимости от языка), учитывайте:

  • Функциональность — решает ли она поставленную задачу?
  • Производительность — влияет ли она на работу во время выполнения?
  • Размер — насколько увеличится итоговый размер исполняемого файла?
  • Зависимости — требуется ли что-то дополнительно?
  • Поддержка — актуальность, наличие открытых проблем, активность разработки.
  • Лицензия — позволяет ли она использовать библиотеку в рамках проекта?

Зависимости с открытым исходным кодом

Убедитесь, что у вас есть доступ к зависимостям. Например, если вы полагаетесь на библиотеку из GitHub, ничто не мешает её удалению или смене владельца/направления. Чтобы снизить риск, рекомендуется создать форк и использовать его вместо оригинала.

Помните, код из этой библиотеки будет встроен в вашу игру. Убедитесь, что библиотека делает именно то, что вы от неё ожидаете — и ничего лишнего.