Table of Contents

Engine Plugins

Engine plugins are the best way to get your custom code into the engine, such that it is accessible by the editor and also ezPlayer.

Contrary to using a plugin, you could also build your own application, which may link to static libraries that contain your code. However, that approach means that your code cannot be loaded into the editor process and therefore you won't be able to leverage those tools to their full extent. We strongly advise against that.

Creating a Plugin

The easiest way to create a custom plugin is to use the C++ Project Generation. This will create a template project for you, set up the CMake files for your build and configure the plugin selection.

Creating a Plugin Manually

In case you want more control, you can also set up your game plugin manually. The Sample Game Plugin is a good reference for how to do that. To just create a plugin, at all, you only need very little setup.

The only files you need to look at are:

  • CMakeLists.txt
  • SampleGamePluginDLL.h
  • SampleGamePlugin.cpp

Build System Setup

The file CMakeLists.txt is only of interest here in case you want to reuse the EZ build infrastructure to generate your library. If you use ezEngine as a Submodule then you probably have your own CMake scripts. Either way, you need to add a project that generates a DLL.

DLL Symbol Import/Export

The file SampleGamePluginDLL.h only contains #defines for DLL import/export macros.

// Configure the DLL Import/Export Define
#if EZ_ENABLED(EZ_COMPILE_ENGINE_AS_DLL)
#  ifdef BUILDSYSTEM_BUILDING_SAMPLEGAMEPLUGIN_LIB
#    define EZ_SAMPLEGAMEPLUGIN_DLL EZ_DECL_EXPORT
#  else
#    define EZ_SAMPLEGAMEPLUGIN_DLL EZ_DECL_IMPORT
#  endif
#else
#  define EZ_SAMPLEGAMEPLUGIN_DLL
#endif

If your plugin will be entirely on its own, you don't even need this. However, if you want to use multiple plugins and some of them should contain shared code, then others need to be able to link against the shared libraries and access classes and functions from that library. By tagging classes with these macros you can export symbols from a DLL and thus make those things available to other code. For examples how to use this, just search the sample plugin.

Plugin Callbacks

EZ provides additional hooks for initialization when a plugin gets loaded or unloaded. You can find these in SampleGamePlugin.cpp:

EZ_PLUGIN_ON_LOADED()
{
  // you could do something here, though this is rare
}

EZ_PLUGIN_ON_UNLOADED()
{
  // you could do something here, though this is rare
}

These callbacks are optional, though in some cases you may want to register and unregister things here. However, it is way more common to rather use the startup system instead.

Loading a Plugin

If you want to load a plugin from code, you would use ezPlugin::LoadPlugin() and provide only the name (no path) of your plugin. Make sure that the DLL is stored in the same directory as all other DLLs and EXEs.

The more convenient way to load your game plugin, though, is to enable it in the project settings. Then it will be automatically loaded by every application.

Add Custom Code

Once you have your basic plugin set up and can load it into your project, you can start adding custom code. The easiest way to get started is to write a custom component. Once you need control over higher level game logic, you can add your own game state. And if you need to initialize and shut down certain systems, you should utilize the startup system.

Utility Plugins

If you want to write a plugin that provides some functionality for shared access, like some integration of a third-party library, the process is exactly the same. The only difference is, that such libraries would never contain a game state.

Also, have a look at singletons if your plugin is supposed to provide an implementation of some abstract interface.

Statically Linking Plugins

On platforms where you need to statically link all libraries, some of the automatisms used to load and configure the engine may not work correctly, because the linker optimizes away code that it deems unreferenced.

See the StaticLinkUtil for how to fix this.

See Also