Menu
Lumberyard
Developer Guide (Version 1.11)

Using Gems to Add C++ Code to a Lumberyard Game

To add C++ code or assets to your Lumberyard game, use a gem. This document shows you how to create a gem and the various techniques that you can use to add code to it.

Creating and Configuring Gems

Creating a gem is straightforward. To create or enable a gem for your game project, follow the steps in the Gems section of the Amazon Lumberyard User Guide. The gem that you create or enable is located in the \dev\Gems\<gem name> directory. The gem's directory structure is similar to the following example. Your gem might not have all the directories listed.

Copy
\3rdParty \Assets \Code \Include \Source \Tests \External

3rdParty – Contains third-party definition files that are specific to the gem.

Assets – Contains assets to include in the game project that are specific to the gem.

Code\Include – An additional header include path to add to a game project that uses the gem.

Code\Source – Contains the source code for the gem.

Code\Tests – Contains unit testing source code for projects that are built in a test configuration.

External – Contains external libraries on which the gem depends that are specific to the gem.

Code Directory Contents

The \dev\Gems\<gem name>\Code subdirectory has the following items that Lumberyard creates by default:

Item Location
An empty EBus include file that is named after the gem. \Include\<gem name>\<gem name>Bus.h
The AZ module for the gem \Source\<gem name>Module.cpp
The default systems component files

\Source\<gem name>SystemComponent.h

\Source\<gem name>SystemComponent.cpp

Standard precompiled header files

\Source\StdAfx.h

\Source\StdAfx.cpp

Skeleton unit test source file \Tests\<gem name>Test.cpp

Lumberyard also creates certain Waf–related files in the \dev\Gems\<gem name>\Code subdirectory. These files specify the source code content and how the gem is defined and built.

Item Location
Manifest file for the Waf build of the gem <gem name>.waf_files
Manifest file that lists additional files to for test configuration builds (for example, Tests/<gem name>Test.cpp) <gem name>_tests.waf_files
Waf build script file that defines the gem wscript

The manifest file that manages the source code uses the Lumberyard Waf waf_files schema to define the source files, their Microsoft Visual Studio filter, and uber file grouping. The default <gem name>.waf_files that Project Configurator generates looks like the following:

Copy
{ "none": { "Source": [ "Source/StdAfx.cpp", "Source/StdAfx.h" ] }, "auto": { "Include": [ "Include/<gem name>/<gem name>Bus.h" ], "Source": [ "Source/<gem name>Module.cpp", "Source/<gem name>SystemComponent.cpp", "Source/<gem name>SystemComponent.h" ] } }

The .waf_files file contains the following three levels of indentation:

  • The first level contains the uber file mapping for uber file–enabled builds.

    • none specifies files to be excluded from the uber file. Precompiled headers must be listed here.

    • auto specifies files that are automatically combined into modules that are optimized for compile time by Waf.

    • You can also specify a fixed uber file name (for example, my_gem_uber_0.cpp) at this level to specially group a set of files. All of the files in the grouping are combined into my_gem_uber_0.cpp. This technique is useful to restrict which files are combined, like platform-specific code.

  • The second level represents the Visual Studio filters that determine how the files are organized in the Visual Studio solution that Waf generates.

    • A special value called Root represents the root node of the project explorer in Microsoft Visual Studio (that is, the file is not placed in any subdirectory).

  • The third level contains paths to the source files relative to the location of the waf_files file itself.

Updating Gem Code

To update code in your gem, add a third-party library, new source code files, system components, or dependencies on other gems or Lumberyard modules.

Adding an External Third-Party Library to a Gem

A gem can use any Lumberyard third-party library, including its own private third-party library. To register a private third-party library for a gem, create a third-party configuration file in the \3rdParty directory of the gem.

When you set the configuration file to an external third-party library, the library can be added as a gem dependency through Waf's dependency mechanisms.

Waf uses two conventions to add dependencies to third-party libraries: uselib and use. The convention uselib is a wscript keyword that configures a module to link to a library's include path, library path, and library. If a gem uses uselib to consume its gem-specific library, then that library is available to the gem only for compiling and linking.

The convention use is similar to the uselib keyword, except that the library's dependencies are recursively propagated to the module that adds the dependency. If a gem uses use to consume its gem-specific library, then the library can be used recursively. This means that if the gem is enabled, the gem–specific third-party library is also available to the game project or dependent gems.

Adding New Source C++ Files to Gems

To add source code (for example, C++ or Qt) to a gem, use the Lumberyard Waf build system. Place internal source files (that is, files not meant to be exposed outside of the gem) under the \Code\Source directory. Place header files that can be included in projects or other gems in the \Code\Include\<gem name>\ directory. Place additional unit tests in the \Code\Tests directory.

To add code files to a gem

  1. Add the files to the target location. For consistency, we recommend that you place the source files somewhere in the \Code directory.

  2. Add the source files to the Waf manifest waf_files file. Following the format described earlier, add the source file paths to either the <gem name>.waf_files file and/or the <gem name>_test.waf_files file.

  3. From a command prompt window, run lmbr_waf configure to configure Waf and regenerate the Microsoft Visual Studio solution.

Adding System Components

New gems come with a default system component called <gem name>SystemComponent. You can modify this system component according to your requirements. To communicate with the system component, you can define as many EBuses as required. If you want to add additional components, you must add the component descriptor to the AZ module for the gem ( \Code\Source\<gem name>Module.cpp). For more information, see System Components and Creating System Components.

Adding Dependencies to a Gem

In addition to adding dependencies to gem-specific third-party libraries, your gem can specify dependencies on Lumberyard Engine modules, other gems, or third-party libraries for Lumberyard.

Adding a Dependency on a Lumberyard Module

Any gem can be configured to depend on any of the following Lumberyard framework modules:

  • AzCore

  • AzFramework

  • AzGameFramework

  • AzQtComponents

  • AzToolsFramework

  • GridMate

  • GridMateForTools

To declare a dependency on one of these Lumberyard modules, use the Waf use mechanism. The following example wscript file specifies a dependency on AzFramework.

Copy
def build(bld): bld.DefineGem( # Add custom build options here includes = [bld.Path('Code/CryEngine/CryAction'), use = ['AzFramework'], )

Adding a Dependency on Another Gem

You can configure a gem to depend on another gem by modifying the gem.json file that is in the gem's directory. The following example shows how the Camera Framework gem that is included with Lumberyard declares a dependency on the Camera Gem. This gems.json file is located in the \dev\Gems\CameraFramework\ directory.

Copy
{ "Dependencies": [ { "Uuid": "f910686b6725452fbfc4671f95f733c6", "VersionConstraints": [ "~>0.1" ], "_comment": "Camera" } ], "GemFormatVersion": 3, "Uuid": "54f2763fe191432fa681ce4a354eedf5", "Name": "CameraFramework", "Version": "0.1.0", "LinkType": "Dynamic", "DisplayName": "Camera Framework [PREVIEW]", "Tags": ["Camera", "Framework"], "Summary": "The Camera Framework Gem includes the camera rig component which drives an entity through camera behaviors. Behaviors are provided in the Starting Point Camera Gem.", "IconPath": "preview.png" }

The Camera Framework Gem specifies the Camera Gem in the Dependencies section. The Dependencies section also has a VersionConstraints section that you can use to specify versioning requirements.

Adding a Dependency on a Third-Party Library for Lumberyard

You can define a gem that uses a third-party library for Lumberyard that another module is also using. To do so, use the Waf uselib mechanism to add the dependency to the gem, as in the following example wscript file.

Copy
def build(bld): bld.DefineGem( # Add custom build options here includes = [bld.Path('Code/CryEngine/CryAction'), use = ['AzFramework'], uselib = ['AWS_CPP_SDK'] )

Note

You can also specify use, but use this technique with caution. The recursive nature of use can lead to linker errors, especially duplicate symbol errors.