Technical Documentation

[Warning] The documentation is under construction, with content being added and grammar/spelling still being checked.

This guide is being developed and maintained by Project Workbench to document the team’s technical development process as a reference to other developers. Project Workbench used Lumberyard to create a Twitch-integrated game called Krossis (watch the trailer). The document is purely our understanding and interpretation of Lumberyard and does not represent the views of Amazon. This is not an extensive documentation of the game engine. Please refer to the official documentation of Amazon Lumberyard and Twitch for further information.

Version: The most recent release of Lumberyard at the time of writing this documentation is 1.13.0.0.

LumberJam: To learn about LumberJam and LumberJam resources, LumberJam.

The documentation fits into two places of flow for developers. While learning, it is expected that developers are going through Amazon’s official documentationGetting Started Guide YouTube series, and their tutorials (although mostly deprecated). If a developer has experience with Unity, we highly recommended they read our Unity to Lumberyard documentation, although it should be helpful to other developers as well. This technical documentation is to be used as a reference while developing, meaning that this document acts as a supplement to the official documentation as well as sample projects available in the engine. If the problem you are tackling cannot be solved after going over any of these resources, Amazon’s GameDev forums is a good place to ask your question.

Below is a general workflow of resources to refer to during your development process. Along with this, each section has specific resources listed out at the end of the sections.

Flow of the documentation.

Contents

Contents

Introduction

Amazon Lumberyard is a AAA game engine developed by Amazon that is based on Crytek’s CryEngine. Lumberyard’s source code is freely available under a proprietary license on GitHub. Lumberyard offers a variety of unique features including tight integration with Amazon Web Services, and native Twitch integration that supports live streaming and audience participation. Lumberyard comes packed with a free version of Audiokinetic’s Wwise for audio solutions as well as plugins for Allegorithmic’s texturing software, Substance, and the real-time character animation SDK, Emotion FX. The software is currently in beta and supports building games for PC (Microsoft Windows), consoles (PlayStation 4, Xbox One), mobile (iOS, Android), as well as for VR (Oculus Rift, HTC Vive).

Resources

Contents

Installation and Setup

Lumberyard is available as an installer for the Windows platform only. You can find the system requirements here. The setup comes with three modules:

  1. The Setup Assistant that lets you configure your installation.
  2. The Project Configurator that lets you create and configure projects, enable/disable gems, as well as select the project you want to work on in the Editor.
  3. The Editor where you actually create your game.

The game engine offers two types of installation options – Express and CustomExpress Install only does the basic installation that allows you to open up the Editor and work on and run the sample projects provided with the engine. Custom Install on the other hand allows you to do more with the engine by letting you select your installation options as per your needs. For any kind of development outside on a project of your own, you will need to follow this option. We will be walking through the custom installation process below.

Uninstalling Visual Studio

Lumberyard uses Visual Studio to build and run the engine and game code. You would need to install a compatible version of the IDE (details below). One of the major problems we faced during the installation process was having incompatible versions of Visual Studio installed alongside the one that Lumberyard wanted. We ran into errors despite having all the required software and SDKs, so we decided that the best solution was to get rid of incompatible versions of Visual Studio. Usually these errors would not appear in the engine compilation process, but rather during the project creation process. in the Project Configurator. We found that, in general, if your project creation fails, it is likely an issue related to Visual Studio.

  1. Uninstall all previous versions of Visual Studio along with the redistributables.
  2. Click on the start menu search bar and type “add remove”. Select Add or Remove Programs.

    Add or remove programs setting
  3. In the window that opens up, scroll down to “M” and delete all versions of Microsoft Visual Studio along with the Redistributables. Please ensure that you don’t delete the Visual Studio Installer before uninstalling the application itself. Your computer might need to restart during the process.

    Visual Studio redistributables

Uninstalling Wwise

Audiokinetic Wwise (Wave Works Interactive Sound Engine) is the only software that Lumberyard supports to add sounds to your game project. Lumberyard comes packed with a free version of Wwise that you can use out of the box. If you have a license for a later version of Wwise available and want to use that, you can skip this step and refer to Lumberyard’s documentation on using your version of Wwise instead. However, we found that our installation had some incompatibilities. We found this issue to be a general trend. Lumberyard requires installing specific versions of software in specific ways. While there might be existing solutions to these problems, for the sake of simplicity, we decided to uninstall conflicting software and reinstall them through Lumberyard’s Setup Assistant.

  1. Click on the start menu search bar again and search for “wwise”. If you see the Wwise Launcher, right click and select Run as Administrator. If you don’t have Wwise installed on your computer, skip to the next step.
  2. In the Wwise launcher, look for the current installation in the tabs on the top and uninstall all versions of Wwise.
  3. Go to Add or Remove Programs again, look for the Wwise launcher, and uninstall it.

Installing Lumberyard along with its dependencies

This step will walk you through the steps required to actually install and build the engine.

  1. Open up the Lumberyard Setup Assistant.
  2. Click on the first three check boxes. The tabs on the left will turn red to signify missing software and/or SDKs.

    Lumberyard Setup Assistant getting started
  3. Follow the instructions on individual tabs and install all the required SDKs and software.
    1. For Visual Studio, sign in to your Microsoft account when prompted (CMU students can use there Andrew accounts for a student license) and download Visual Studio Community 2015 with Update 3 or the version specified by the latest installation of Lumberyard. When you open the installer, click on Custom and check the following before installing:
      Programming Languages -> Visual C++ -> Common Tools for Visual C++ 2011
      Programming Languages -> Visual C++ -> Microsoft Foundation Classes for C++
    2. In the “Install software” tab on the Lumberyard Setup Assistant, also install the Audiokinetic Wwise LTX Authoring Tool that’s listed under “Optional Software”.
  4. Before you proceed, make sure your system locale is set to English (United States).
    1. Navigate to: Control Panel -> Clock, Language, and Region -> Region
    2. Click on the Administrative tab.
    3. Change the system locale settings to English (United States).
    4. You might need to restart your computer after this.
  5. Open the Command Prompt by searching for “cmd” in the search bar.
    1. Navigate to the dev folder in your Lumberyard installation director. Typically you can do this through this command:
      > cd C:\Amazon\Lumberyard\1.12.0.1\dev
    2. Run the following two configuration commands:
      > lmbr_waf configure
      > lmbr_waf build_win_x64_vs2015_profile -p game
    3. Important Note: In general, every time you add/remove gems from a project you create, or make any changes to the C++ code, you will have to run the above two commands. These commands will only work for the project that is set as default in the Project Configurator. You will have to repeat the steps for another project by first setting it as default in the Configurator and then running these commands. It is also required that your Lumberyard Editor is not open. The commands will fail with unhelpful error messages if your Editor window is open.
  6. Finally, ensure your setup was done correctly by opening up the Lumberyard Project Configurator and creating a new project.

First Time Launch

Lumberyard comes prepackaged with a few sample projects that act as a great reference for developers to get started with creating their own games using the engine. Starter Game and Samples Project each contain sample levels and the Getting Started Guide video tutorial series goes hand-in-hand with these samples. Since Lumberyard currently doesn’t have any publicly available “Asset Store” of any sort, these projects also serve as a great asset-rich resources that you can use.

Source Control with Perforce

Regardless of the game being developed, developers use version control to track changes, keep a backup of history, as well as having the ability to revert their changes. Lumberyard supports, and in fact encourages developers to utilize version control with their projects. Lumberyard development is integrated with Perforce, which is apparent on opening the Lumberyard Editor. Developers not connected to a Perforce workspace or having disabled the Perforce Lumberyard plugin will be warned about lock-files. If another version control is planning on being used rather than Perforce, the Perforce plugin can be disabled by selecting the P4 text on the bottom toolbar and selecting disable (You can find a small grey button next to “Pending Jobs” on the bottom tool bar in the Editor).

Perforce plugin button

Although Lumberyard supports other version controls, such as Git, it is left up to the developer to generate the appropriate ignore files, determine what should be included, and manually add files through an outside interface. Lumberyard’s Perforce Plugin on the other hand provides an interface that makes development more smoothly integrated with version control. In order for the engine to recognize the Perforce server, the settings (same location as the disable mentioned above) can be changed per-user. In addition to setting the Perforce settings, the project folder must be in the Perforce workspace for the Perforce Plugin to natively recognize the project as part of Perforce as well as having the capability of adding, checking out, and determining lock files. This causes issues if Lumberyard was installed in the default location of C:\Amazon and the Perforce workspace isn’t located there. In addition, if a Perforce directory structure is formatted for an organization, rather than for the specific Lumberyard install, the folder hierarchy can be too long to build the engine because of Windows file name limit. The Lumberyard install is packaged with a set of .p4ignores, a file which lists files to ignore from adding to a Perforce server (similar to a .gitignore), structured throughout various folders.

In order to address some of the concerns mentioned above, a tutorial video was created for Project Workbench team members to setup Lumberyard. Developers can use this instructional video in helping all team members once the initial install of Lumberyard is added onto a Perforce server.

Video demonstrating how to setup Lumberyard in the correct folder structure for Perforce version control.

Contents

The Engine

As mentioned above, Amazon offers Lumberyard’s source code on GitHub for free. This allows a lot of flexibility to developers to make changes to the engine for their requirements as they see fit. Understanding how to make changes to the engine required a prior knowledge of how and where things are present in the engine itself. Below we introduce you with some core concept that you need to know before you get started with development.

Gems

Gems are like packages of assets and code that can be included in projects. Each project is itself a game gem, which can hold assets specific to that game. Gems created in the Project Configurator can be included in multiple projects, which makes transferring assets and code between projects easy and quick. After a Gem is added to a project (or the default project is switched) the project must be configured in the command line to include the gem, and when code changes within the gem, the game must be compiled to include the new changes (this requires the Editor to be closed). Gems are, by default, created with an event bus, however the event bus doesn’t need to be used and can be removed.

Engine programming vs Scripting

Developing in Lumberyard can be divided into two main parts – engine programming, and scripting. While Lumberyard is primarily written in C++, it exposes all of the systems and components to game developers through it’s scripting language, Lua. If you’re looking to leverage the features, components, and systems Lumberyard offers out of the box, you shouldn’t need to worry about what goes on at the engine side, and all your work can be contained within the scripting language. However, there can be many reasons that a developer might need to delve on the engine side of things:

  1. If you want to add a feature to an existing system or component, you’d need to make changes directly to the engine. For example, shaders are something that exist at the engine level. To add or modify a shader, you would need to do it in the engine itself.
  2. If you want to expose your own data structure for passing around data while scripting, this is something that would need to be added to the engine in the form of a gem.
  3. Adding a new system, component, or functionality that you want to expose to Lua would also require engine programming in C++.

While it’s possible to also code an entire game project just in C++ or just in Lua, they both offer some advantages and disadvantages, it’s up to the developer to make those decisions as per their requirements. The programming section below discusses this further.

Legacy vs Updated Systems and Components

Lumberyard at its conception is a fork of Crytek’s CryEngine. Since the time it was launched in beta and up till now, every subsequent version released has replaced CryEngine’s systems and components with Lumberyard’s own. Lumberyard will remain in beta until there still exist legacy systems and components (the one inherited from CryEngine) within the engine.

In the current version of Lumberyard, the engine, Lua scripting, and documentation are going through large overhauls to remove deprecated features and add in new functionality in preparation for the full release. Anything marked with “Cry” or associated with the CryEngine is subject to be removed. The tutorials found on the Amazon Game Developer tutorial page are for the most part out of date, with developers extrapolating how the technology has changed. While its good practice to avoid using Legacy features so your project can stand for longer over future releases, some systems are not in a state to be replaced yet with the updated or “in-preview” mode. PhysX, for example, is not at a stage yet where it can replace the legacy physics engine.

Contents

Game Projects

Lumberyard projects act as the folder repository for all files involved with the project. The Project Configurator considers each folder a “Game Gem”. A project can be associated with multiple Gems, and each Gem can add/remove functionality and ease scripting interfaces. To switch between projects, the Editor must be closed and the Project Configurator open, where you can enable/disable gems and switch projects by setting it as the default. When a project is created, the folder can be found under the “dev” directory of the Lumberyard installation. Transferring a project requires all its associated gems to be transferred with it. Enabling/disabling gems also requires a reconfiguration and rebuild of the game.

Project Hierarchy

While there is no mandated hierarchy that needs to be followed for user-imported assets, there is a vaguely defined structure, exemplified below with the folder structure of a sample project that comes with Lumberyard. Exceptions to this rule are the audio files and folders. The Wwise project, sound banks, and the XML files for the audio that needs to be imported into the game currently have hard-coded paths in the engine. Lumberyard only looks for audio files to be present at certain locations, ignoring any other user-defined location.

Starter Game Project Hierarchy

Game Levels

Every new level in a game project is stored in its own directory under the main project directory. Level directories contain information about the terrain, time of day, and where all the entities in the level are placed. You can also enable automatic backups in your project, the cache for which is stored inside the level directories. Levels are directly associated with a project, and when browsing for opening a level, developers are restricted to the levels within the project, and the developer can’t browse outside the project folder.

Slices

Slices in Lumberyard refer to saving level entities (and their components) as a separate file of data to be reused in the same or a different level. Saving an entity as a slice includes saving the children of the entity and their relative transforms, so the object can be duplicated multiple times. Modifying attributes of an entity in a slice can be then saved to the slice file, which will propagate the changes to all the other entities which are instances of that slice. It is good practice to save objects which are replicas of one another as a slice, because it makes adding/removing to all those objects easier in the future. Lumberyard allows for nested slices, meaning, children of a slice entity can also be slices themselves. This multi-layered slicing is useful in cases of modifying specific entities within a slice. Another benefit to slices are that they can be edited and saved without saving the level, which allows for collaboration on the same level without worrying about conflicting one another’s work.

Multi-layered slices, however, have a shortcoming of that the child slices become detached, acting as an independent instance. This meant that each child could not be independently modified, and would require the modification of the parent slice. This might cause some problems while collaborating, and so a workaround is to keep the slices detached, especially if they need to be edited simultaneously. Another issue we encountered with slices, which may not directly be the result of slices but rather caching/perforce, was slices not being shared properly. The work-around is generally having users with an inconsistent copy of the slice replace it with itself (almost acting like a “refresh”).

Resources

Creating Builds

To be able to create a build of a project, the computer needs to be able to compile the Lumberyard engine which requires the Setup Assistant to have the first 5 options selected in the Get Started tab. In addition to these options, there will be additional required 3rd party libraries and SDKs to install once those options have been selected.

Setup Assistant Options for Creating a Build

There is a 5 step process, each with sub-steps, for a successful build to be made. It is recommended to create a project pak and shader pak batch files specific to the project by duplicating the already available files for samples project and changing the project name. Within those files, to see errors/success after running the file add a pause after the echo for fail or success, otherwise the command window opened by the batch file will close on complete (regardless of process outcome). To create a smaller build, the project named files in the Bin64vcXXX.Release that aren’t the project being built can be deleted. There may be a way to minimize the build more, however be careful of what is deleted because it may corrupt the project build. The documentation doesn’t mention the step to export the level to the build, prior to running the project batch file; in the level editor, in the games tab, the level must be exported to the engine. If the level isn’t exported, when the build is run the level will be empty, without entities; the level will still have the level properties like terrain and time of day. Another pinch point can be with the time of day settings, since running the game in the editor doesn’t simulate the time of day where a build does. See the Environment section for a more detailed solution, but the simple fix is ensuring the current time is within the start and end times. Finally, once a build is created it may not run at full-screen or the correct resolution for the application being deployed to; to change this for all future builds modify the system_PLATFORM.cfg file to have the correct r_width, r_height, and for full-screen set r_fullscreen to 1. To modify an already created build or so future builds don’t carry the same settings, there is an associated system_PLATFORM.cfg file located in the build folder that can be changed.

As a demonstration for the build files, the Workbench Project build files as well as a readme are bundled into a zip, BuildProject. An additional file was created, named BuildWorkbenchProject, to help complete the steps outlined within the Amazon documentation; use the readme to edit the files for a different project.

Level not exported to engine.

Resources

Contents

The Editor

Lumberyard’s Editor provides developers with different tools and editors to build a project. Some of the basic steps include creating a new level and adding new entities with different components to the level. Different tools and editors can help developers solve different problems. Lumberyard uses Lua as the scripting language which comes with an in-built editor. There are various components available including AI, animation, audio, camera, environment, network, physics, rendering, scripting, shape, UI, VR, and many more.

Maneuvering The Perspective Window

To navigate within the Editor is simple. It is very similar to a First-Person Shooting game.

Input Device Key Function
Keyboard W Strafe forward
Keyboard S Strafe back
Keyboard A Strafe left
Keyboard D Strafe right
Mouse Left Select/Marquee select
Mouse Middle + Direction Pan direction
Mouse Right + Direction Look direction
Mouse Scroll wheel Zoom in and out
Basic navigation controls in the Editor

 

 Key Description
Q Toggle the camera or terrain collision
Z Focus the camera to the selected object in the viewport
F3 Toggle the wireframe view
Alt + Middle mouse button Rotate around the selected object
Alt + right click Zoom in and out
Ctrl + Tab Cycle the viewport perspective
Ctrl + F1 (or F2, F3, …,F12) Save the viewport location
Shift + F1 (or F2, F3, …, F12) Move to the saved viewport location
Shift + Space Show or hide helpers
Useful keyboard shortcuts for navigation

 

Resources

Editor Basics

The image below gives a brief overview of how the Lumberyard Editor is laid out. We will discuss the individual parts of the Editor.

Lumberyard Entity

Main Menu & Editor Toolbar

The Main Menu contains the standard functionalities and settings of any application. Through the main menu, you can edit the current level or project that is open, change the layout of the Editor, and access any tools and editors available in the interface.

The Editor Toolbar contains the most commonly used tools and editors within Lumberyard. For example, select, move, rotate and move entity functions, open layer, material and animation editor, and flow graph.

Perspective Viewport

In the Perspective Viewport, you can view and edit entities you want and lso control the viewpoint by navigating within the level. The Viewport further includes a header and a control bar.

Lumberyard Editor Perspective Viewport

The header at the top provides different mounts of information for three modes that you can switch between by clicking. You can toggle display help (Shift+Space) to show or hide helper objects, and also search for any entity within the level by typing it in the search bar.

The perspective control bar at the bottom lets you edit the position of selected entities and also lets you modify the speed of navigating within the Viewport. Some other functions include:

  1. Switching on the lock selection button (key B) can prevent you from inadvertently selecting something else in a level.
  2. Switching on the lock scale button (key D) can prevent you from changing the ratio of the entity’s length, width and height. You can still scale it up and down.
  3. The AI/Physics button lets you simulate the two systems without actually starting the game. This is very helpful in unit debugging before testing out the systems as a whole.
  4. Switching on the No Sync Player button (key H) can detach the player entity from the camera. The No Sync Player function can be useful with AI or Physics enabled, when you don’t want to activate triggers while navigating through a level.
  5. Goto position (key I) helps you view a certain position.
  6. While Mute Audio button (key J) should mute all sounds in the level, this feature doesn’t work as expected and is unable to mute all audio at all times.
  7. The VR Preview button (K) previews your game project in virtual reality mode when a virtual reality gem is enabled.
Perspective Viewport toolbar

Rollup Bar

The rollup bar is a legacy feature but contains some important and useful functionalities. There are 5 tabs in rollup bar:

  1. Objects – contains options for various brushes, entities, volumes, prefabs and more.
  2. Terrain – contains tools for sculpting and painting terrain, adding vegetation and creating rivers and roads.
  3. Modelling – helps edit meshes that support the mesh editing.
  4. Display – contains options for rendering settings, 3D display settings, and hide settings for various types of objects and entities in Lumberyard.
  5. Layers – helps arranging the layers.
RollupBar

Entity Inspector

The entity inspector displays all the components of a selected entity and allows developers to add/delete/enable/disable/edit these components. The “Start Active” option is how to disable an entity on start, and to enable the entity in play requires a scripting event. The search bar allows filtering for certain components, however because Lua scripts are attached to Lua components, scripts cannot be searched for directly. The Entity names can be changed here, however the ID is static and cannot be modified by the developer (the ID has been hidden in version 1.13). The green icon to the left of name is the icon which is displayed in the Perspective Viewport, and is able to be customized. There is a pin icon to the right of the name (v1.13) which opens an inspector window for that entity that won’t change after selecting another entity.

Entity Inspector (1.12 image)

Entity Outliner

The Entity Outliner contains the entity hierarchy of the level. Entities can be renamed and reparented from the outliner. The entities can be parented and which will be seen visually as a drop-down. Enity slices will have their name highlighted in dark blue, and the children of the slice will be highlighted in a slightly lighter blue. The eye icon to the right of on an entity denotes whether it is visible while editing, it has no effect on visibility during playing the game (see above “Start Active”). The lock icon to the right of the eye determines whether the entity can be clicked within the Perspective Viewport or deleted from the Entity Outliner, however does not stop the entity from being edited from within the Entity Inspector. Both the eye and lock icons have hierarchical functionality, meaning hiding a parent entity will hide that entity along with the children. Entities can be filtered through the search bar and the filter icon. The search filters by name of entity as well as named components, however as mentioned above Lua script names cannot be searched for.

Entity Outliner

Asset Browser

The asset browser displays all the assets present both in the project folder as well as the ones present engine-wide. Assets can be selected from the browser and dragged into the Perspective Viewport, but not into the Entity Outliner. Modifying files located in the Editor, Engine, or Gems folder will modify the file for the current project as well as any other project using that file. Files located in the project named file are only accessible in the specific project. Files can be filtered and searched for, and the arrow keys also work for navigating files (with down expanding a folder and up jumping to the parent). The Asset Browser also provides a preview of a selected file, in the case of a mesh it will display the mesh, however it will not preview materials (see Material Editor). Files cannot be moved/deleted from the Asset Browser, rather with a right-click can be accessed from the file explorer where they can be moved/deleted.

Asset Browser

Contents

Programming

Lua vs. C++

In getting comfortable with Lumberyard it required investigating the programming languages available to developers. The engine’s scripting language is Lua, and is available from the Editor. However, the other language available to developers is C++, which is embedded in the Lumberyard Gem system and engine code. Lua scripting has functionality exposed to it through the C++ code. Any game should be able to be developed with either or both languages, based on development needs.

Lua scripting is included within the Lumberyard Editor. Being an interpretive language, it’s great for prototyping and iteration, more so because it doesn’t need to be recompiled every time a change is made, and can be loaded in real time. It is easier to share with other developers because it only has one source file within a specific project. Lua is where the majority of your game logic should be located, because the engine shouldn’t be aware of your specific project. Developing in Lua is ideal for a small team, with a rapid turnaround time. The downfalls of Lua is that not everything is fully exposed or well documented at this time, especially because systems and documentation are being deprecated in every subsequent release. The language also isn’t as powerful/optimized as C++ so can cause performance issues in cases where C++ wouldn’t.

 C++ isn’t included in Lumberyard’s Express Install and requires the option of compiling the game code to be checked and the engine recompiled. However, the language is the industry standard because it is so performant and can be well optimized. C++ source code can’t be created from the Editor, it requires you to create Gems and enable them through the Project Configurator. The C++ classes have access to all the engine code, since it is coupled with the source code, which can cause problems when game logic is entwined with the engine. However, one thing to keep in mind during programming with C++ is that Lumberyard currently does not have native support for hot reloading of C++ code. The way it is integrated into Lumberyard isn’t set for quick iteration, it requires the game code to be recompiled for each gem. This can also slow your team members down if the binaries aren’t shared and your team member needs to recompile the code/game as well. Mistakes made in your C++ won’t be determined until compilation, which isn’t ideal for rapid changes. While there are external tools available (both paid and unpaid) for hot reloading of C++ code, the integration is something the developers will have to take the burden of.

The option of using both is viable, such as using Lua scripts to contain all game logic and C++ to expose user-defined data structures and functionalities, and to optimize any Lua bottlenecks. In either case, a program creates a “component” (not identical, but similar to Lumberyard defined components) which can be attached with an entity in game. For Lua, the entity object which will be using the script must first be assigned a Lua Script Component and the script required attached to the component. For C++, the game needs to be compiled and the Gem activated for the project, which can then be associated with an entity.

Resources

Event Bus / Gameplay Bus

The gameplay bus is the main way of communicating between scripts and entities through Lua. Entities cannot be found with a specific Lua script attached to them, so to communicate to the Lua script the script must know the EntityId that the Lua script is attached to. With the EntityId, messages can be sent through the Event Bus. The gameplay bus is the most generic Event Bus (EBus) to pass information around your game, however to have more specific events create EBus events in a C++ gem. In the case, the “Compile game code” option isn’t selected in the Setup Assistant, EBuses can’t be created so the gameplay bus is the only option.

Our experience with creating C++ EBuses is limited because at the time of learning Lumberyard there were limited resources available for creating these. In addition, there wasn’t a clear explanation of why these EBus events were necessary, which after creating a game we realized that Lua is more error prone to using the generic gameplay bus rather having contexts for each type of event.

For any event bus you are required to have an identifier, which for the gameplay bus is the gameplay notification id. The gameplay notification id requires three parameters: an EntityId (sending/receiving entity), a string with the event name, and the type of parameter to be passed. Prior to version 1.12 the parameter type wasn’t needed, in version 1.13 the typeid() function assisted in finding the id of a parameter; however, the parameter type doesn’t seem to influence the actual values that can be send or received the bus (it seems like a needless parameter in the current version). For a script to receive an event from another script/entity all 3 parameters must match (including the EntityId), otherwise the event will be sent to the wrong place or not recognized properly.

Resources

Serialization/Reflection

The reflection function will expose a C++ struct/class to the editor and/or Lua. Our knowledge of serialization is slightly superficial, and was mainly used to create structs for more compact Lua code. This can include variables and functions coded in C++ to be reused in Lua. The “Compile game code” option must be selected in the Setup Assistant to be able to create classes on the C++ side.

Suggested File Structure

To add a new class into the engine, the code can either be placed into the “Gems” folder of the project or in a engine gem. Within the “Code” folder, create a folder named “Components” which is where class files will be located. Each class category component needs a “.cpp” and “.h” file (for best practice). The class/struct are located within the “.h” file. Each class/struct needs an “AZ_TYPE_INFO” and “AZ_CLASS_ALLOCATOR” to serialize/reflect, however the class/struct doesn’t need its own “Reflect” function. The “.cpp” file has the “GetUuid” and “Reflect” functions, see Starter Game/other Gems for examples.

The other files to edit are: [gem_name].waf_files located in the “Code” directory and [gem_name]SystemComponent.cpp. In the waf file, create a components array with the header and cpp files of the created files.
"Components": [

"Components/[file].cpp",
"Components/[file].h",

],

In the System Component file, include the header files of the newly created classes. In the “Reflect” function, call the reflect function of the classes passing in the serialize context and/or behavior contexts.

Serialize and Edit Context

The serialize and edit context are required to expose parameters to the inspector in the engine. For the serialize context, use the function call “Field” to serialize class parameters. The edit context is more complicated/customizable, see the Lumberyard documentation for more details.

Behavior Context

The behavior context is how functions and parameters are exposed to Lua scripting. Functions can include constructors with different number of parameters, however cannot include the same number of constructor arguments. We have found, however, constructors don’t always work within the Lua Editor and reassigning the parameters after calling the constructor is needed.

Resources

Lua Scripting

Outlined is the structure of Lua script, which connects to a single EBus, the Tick Bus. Lua is fairly relaxed with regards to syntax, so it is recommended to have a style when creating a project and stay consistent. Amazon outlines the structure and format of a Lua script, with the links listed below, however examples can be more useful which can be found within StarterGame and SamplesProject. StarterGame shows how code can be integrated into a game project, where SamplesProject provides smaller, specific examples for a lot of functionality.

local required = require("scripts.path.to.file");
local ScriptName =
{
-- variables exposed to the editor
Properties =
{
},
-- table holding the connected event buses
Handlers =
{
},
}
-- called when the entity is spawned or game is started
function ScriptName:OnActivate()
-- connecting to an event bus, passing self as the object of reference
self.Handlers.Tick = TickBus.Connect(self);
end
-- called when the entity is deleted or game is ended/quit
function ScriptName:OnDeactivate()
end
-- called each tick (frame) when connected to the Tick Bus
function ScriptName:OnTick(deltaTime, scriptPointTime)
end

-- to expose the script to the editor
return ScriptName;

Occasionally, after creating a new script, the script won’t be available to select in the Lua Script component from the editor. This can happen because there is a syntax error in the script, or Lumberyard didn’t process/recognize the file. If the problem is due to the latter, to solve the issue, either duplicate the script through copy/pasting in the window explorer or close and reopen the editor. It is recommended that once you have the basic structure of the script, as outlined above, save the script and add it to the Lua component. This will not only stop the script from not showing up, but also be easier to debug since an error message will appear on the Lua component if there is one.

Resources

Lua Editor

The Lua Editor is a built-into Lumberyard but can also be docked to the start bar of your OS. It is opened in a new window, which can cause issues when left open and switching projects. We had run into the problem that if the Lua Editor was left open when the editor closed or crashes, the editor wouldn’t open again unless the Lua Editor was closed.

The Lua Editor is Lumberyard’s default editor, and recommended to program Lua scripts in because of the built-in functionality. The editor has debugging functionality, like most IDEs, but also has the panel labeled “Class Reference”. When the Lua Editor is connected to the Lumberyard Editor, the target is set to the Project Configurator, the Class Reference has classes, EBuses, and globals exposed to the Lua script for that specific project. Because of the lack of online documentation about Lua scripting, the Class Reference panel was invaluable in finding functions and understanding the expected parameters.

Lua Editor – Target Options

 

Lua Editor – Class Reference with target set to none

 

Lua Editor – Class Reference with target set to Project Configurator

The Lua Editor is also is in beta so it has its flaws. The Lua Editor was sometimes not able to detect the Project Configurator as the target which removed most functionality of the editor, and made it a glorified text editor. The autocomplete functionality of the editor has weird behavior when the cursor is not at the end of the word to autocomplete, it will insert the remaining characters at the cursor rather than the end of the word.

Lumberyard Systems

Lumberyard, being a AAA game engine, offers an extensive suite of systems in its engine for game developers. Below, we’ll go over some of the core systems of the engine. For a brief introduction of all the available systems, have a look at this page from Lumberyard’s User Guide.

Contents

Entity Component System

Lumberyard uses a component entity system that provides a modular interface for the construction of game elements. Entities are the main objects in the game level and components act as functionalities/behaviors attached to the entities. To add a component to an entity, find the component in the component drop-down menu in the inspector. Components are manipulated from a menu drop down on the entity, and can also be manipulated using typical keyboard shortcuts (copy – Ctrl+c, Paste – Ctrl+v, delete – Delete). They can also be organized by dragging them up/down in the inspector.

Entity in Entity Inspector.

Transformation

Every entity has a transformation component which determines the position, rotation, and scale of the entity. Entities transforms can be altered in the perspective viewport with the mouse, in the transformation component on the entity, as well as at the bottom of the perspective viewport (the x, y, z positions). The transformation component on the entity allows the number to be changed through typing and scrolling the wheel but doesn’t allow dragging the mouse left/right. The component sometimes encounters floating-point errors after the level is saved or the entity is saved as a slice, this is manifested in numbers looking like 179.9999 rather than being 180.

The transformation bus can be connected and and manipulated through code. In Lua, the transform bus can return the transformation matrix of the entity, which requires knowledge of the matrix to be able to use properly. The World TM contains position, rotation, scale, and other information encoded with it. To obtain the right vector of an entity GetColumn(0) of the matrix, GetColumn(1) corresponds to the forward, and the cross of the right and forward gives the up vector; these are really commonly used in game programming.

One of the major issues we encountered was that scaling and rotation in the transformation component don’t always work as expected. Rotating a scaled entity through Lua leads to unpredictable behavior where the rotation angle isn’t equal to the angle input into the rotation function. For example if an entity is scaled and then a script attempts to rotate the entity 90 degrees, the resultant angle is somewhere in between the original angle and 90 but not correlated to the scale of the object. Another effect observed with scaling and rotation, is when an entity was scaled and rotated (in a specific order), the entity obtained a shear, which shouldn’t happen regardless of ordering.

Camera

The camera system in Lumberyard has 2 main components, the camera component which is the view of the game and the camera rig component which helps the camera track/look-at behavior. When a camera component isn’t present in the level, the game will default to using the editor’s camera at its last transform. Once a camera is added into the level, when the game is played Lumberyard will default to the first camera added. To set priority of cameras or change which camera is being used is done through code.

Lumberyard Camera Components.

To change a view of a camera, it can be moved like any other object but it can also be moved as if it was the editor camera. By selecting “Be this camera” the camera being moved in the perspective viewport is the camera entity. This allows for developers to precisely place the camera in a location and know the exact view without running the game. When “Be this camera” is selected, the Viewport Camera Selector menu also pops-up, typically on the left panel, which is how to switch back to the editor camera. With more than one camera in the scene, the menu also allows for quickly selecting another camera as well as finding unexpected cameras that weren’t suppose to be present.

Viewport Camera Selector

Contents

Environment

Terrain

To make terrains in Lumberyard, you will need to use the Terrain Editor, a tool that allows you to create and edit a terrain, and generate or import a height map. By default, terrains in Lumberyard come with a beautifully generated ocean. The downside of this is that the ocean can eat up a lot of the game’s performance.  For this reason, the ocean can be removed from the scene or scaled down as per needs. To remove ocean, in the Terrain Editor, click on Modify – Remove Ocean. This change is permanent so be sure to remove the ocean only if not needed again at all. The terrain editor allows importing or exporting of a basic texture to cover the entire terrain. Under the Tools menu, there’s a function called “export/import megaterrain texture” that offers this functionality. This, of course, is very low resolution. Developers can later paint vegetation, roads, or grass in detail on top of the terrain through Tools – Other – Terrain Texture Layers. Objects painted through the terrain editor are not the same as level entities, the objects can have colliders which are added through the terrain tool, but cannot have components added to them nor can they be selected from the Entity Outliner. For assigning materials to roads or other painted objects, it works similarly to normal entities in that within the Material Editor the material must be assigned; the material cannot be dragged/double-clicked to assign.

Terrain Editor

Lighting

Lighting in Lumberyard can be roughly divided into three parts. Lights, Time of Day, and Environment Probes. Lights in general, be it a spotlight, a point light, or a directional light, can all be found under Tools – RollupBar(LEGACY) – Create – Objects – Entity – Lights. Lights can additionally be added as Components via the Entity Inspector. Time of Day is a tool that includes multiple functions such as light direction, standard fog, sun simulation, etc., and an Environment Probes is a general light source that helps balance contrast, provides default illumination, and controls fog density and visibility. The Time of Day lighting will update while changing values, however the light displayed will always be for the current time set. The time of the scene is in the Time of Day Tasks inspector, located between the 2 graphs. The start/end time allows lighting to progress between those time, as if time was actually passing, creating a dynamic lit level. If the start/end times don’t include the current time when the game is built or when the Time of Day is simulated (through the play button in the Time of Day Editor) the time will default to the start time. However, playing the game through the editor won’t cause this affect so it can be confusing when the lighting isn’t correct in the build.

Time of Day Attributes

 

Environment Proble

There are three types of basic light sources which can be created within Lumberyard:

  1. Point lights
  2. Area lights
  3. Projector lights

A point light has the ability to give off light equally, in all directions from a single source. An area light has a deeper light source than a point light, and thus can be used to light larger areas. For projecting larger pools of light onto different surfaces, the Projector Light is the most suitable. All three of these lights can be added as Components to Entities or Child Entities from the Entity Inspector.

The three Light Components

Once a light has been added as a Component, there are many values which can be changed in the Entity Inspector to create a specific lighting solution depending on the needs of the project.

Projector Light in Entity Inspector

Fog

In Lumberyard, there are two different fog systems – the Standard Fog System, which can be found under Tools – Other – Time of the Day, and Volumetric Fog System, which can be applied to level by adding the Fog Volume component to an entity through the Entity Inspector. The engine then notifies that Fog Volume is missing another component in order to work properly, so by clicking Add Required component, and choosing Box Shape, this new volumetric fog entity now has a volume. Volumetric fog has more options such as Ramp, Density Noise and Fall off settings options. While the volumetric fog is more detailed and dynamic, it also influences the performance greatly. Standard Fog System on the other hand provides a rather decent fog visual, but is static and not affected by any other entity or lights in the level.

Standard Fog
Volumetric Fog

Resources

Contents

Model/Materials

Importing

Importing assets in Lumberyard is fairly straightforward. By dragging an FBX file directly to Viewport, a window will pop up to specify which folder you want to import the model to. Copying files directly to the desired folder and then looking it up in the Asset Browser will also do the job. This works the same way for importing material and textures.

Importing Assets

Material Editor

Lumberyard handles all materials through the Material Editor, which can be accessed through Tools – Material Editor, or by simply pressing “M” on the keyboard. The Material Editor is the only window to display materials, so materials cannot be previewed in the Asset Browser. Select the material that needs to be edited through the hierarchical menu on the left, and the options will pop up. To edit the material of an asset that is currently placed in the Viewport, click the eyedropper shaped tool on the upper menu section, and select the asset in Viewport. The material will be selected in Material Editor:

Edit materials

To create a new material, click the file icon on the upper menu section and choose the desired save location.

Create material

Resources

Contents

Animation (EMotionFX)

Lumberyard uses EMotionFX as the animation editor.

Exporting FBX from Maya and Importing in Lumberyard

Lumberyard’s asset pipeline to import FBX models can sometimes be a little complicated. Lumberyard expects assets to be imported in a specific way, and fails or causes weird issues otherwise. To export models from Maya, both the mesh and the skeleton should be selected along with unchecking the Animation and Bake animation box. Additionally, to export only animations, only select the skeleton and check the Animation and Bake animation box before exporting. Finally, these files can then be places in an appropriate folder within a project in Lumberyard.

To make characters move around the level with their animations, Lumberyard uses Motion Extraction. For this purpose, an extra joint needs to be added in the rig of the character in Maya to be the root node (shown in picture below). If this is not done, animations in Lumberyard get messed up with the character facing the wrong direction and it’s animation rolling.

 

In order to import the character (Actor in Lumberyard) and animations into the EmotionFX, click the “file” button and then select “Add Actor” to choose a character FBX for creating a new Actor.

Animation Control

Character Entity

Actor

In Lumberyard, a character entity needs an Actor component. Actor component is necessary if we want an animated character in the game. The actor assets should be rigged, otherwise it can’t be recognised by the component.

Actor Component

 

Anim Graph

If we want to add controllable animations to the character, we should add the Anim Graph component to the character entity. This entity should have Actor component.

Anim Graph Component

 

There are two things we should add to the Anim Graph component: Anim graph and Motion set. Anim graph is a graph that contains all the animation transition logic. Motion set is a set that contains all the motions needed in the anim graph. These two things can be edited in the animation editor.

Simple Motion

If we only want one animation for the character, we should add the Simple Motion component to it. There are several functions we can use in this component to help us add different features to the animation. There can be only one Simple Motion component for one entity.

Simple Motion Component

Animation Editor

AnimGraph

The AnimGraph holds information about the different animations of the actor as well as the relationships between these animations. The AnimGraph component has a Graph property that lets you select the animation graph that was created in the Animation Editor.

Anim Graph’

To activate the anim graph, we have to double click the anim graph name, and remember, motionset should be selected.

select anim graph

Motion Sets

Motion Sets hold a group of animations which can be added in the AnimGraph for that particular Actor. In the example below, there are three animations: char_idle_gold, cahr_run_gold and char_walk_gold in MotionSet0.

Motion Sets

Motion Extraction

Actors in Lumberyard move with root motion. For example, if we want the actor to run forward in the level, the actor will move forward only if the animation root is moving forward (but not stepping on the spot). To set up root motion, models in Maya should be set up to move the root forward in the animation. Additionally, we need to set the Motion Extraction in the attributes window of the AnimGraph by selecting the root node as the motion extraction node.

Motion Extraction Settings

Parameters

Parameters can trigger certain animations. In this example, there are two parameters – walk, and run. Their types are checkbox. Changing a parameter can cause the change of state of current animation. There are different value types of a parameter, for example, floatslider, intslider, checkbox, vector2, vector3 and so on.

Parameters in the Animation Editor

State Machines and Blend Trees

With state machine, we can conclude several animations into a group and abstract them as a single state. With blend trees, we can blend several animations together and set the connections of the output with parameters.

State machine and blend trees can be created in the animation editor on an animation graph.

Creating a State Machine

 

Simple state machine set up

 

Creating a Blend Tree

There are four types of options we can use inside a blend tree. The most important things in blending tree are the target motions. They are the material for blending. For example in idleBlend, there are two motions are waiting for blending: idle and idle_aim.

Motion Nodes in blend trees

Inside a blend tree, there should also be a Blend Two node to make the blending happen.

Creating a Blend Two node

 

A Blend Two node

Also, a parameter node together with a parameter is needed to control blending. The weight lay on two motions would be controlled by this parameter.

Parameter Node

Last but not least, a smoothing node can help smooth the blending.

Smoothing Node

All of the elements can be organised in this way:

A simple blend tree organization

In this blend tree, the weight on the two motions is influenced by the aimParameter. If the parameter value is 1.0, the weight on idle aim is 1.0 while the weight on idle is 0.0. If the parameter value is 0.0, vise versa.

Parameter value 1

 

Parameter Value 0

 

Parameter Value between 0.0 and 1.0

PoseMask

A PoseMask node can be added inside a blend tree. It is a blend node, used for set different layers to a certain pose. For example, if we want to keep the root motion of running while keeping the body animation of jumping, we can add a PoseMask as per the followed picture:

PoseMask set up

Pose 0 is Jump animation, pose 1 is run animation.

PoseMask Setings

Adding root node to mask 1 to keep the root motion in run animation.

Scripting Interface

Scripts controlling animations should be attached to the entity that has the Actor and AnimGraph components attached to it. In scripting, animations can be called by changing values of parameters that in turn changes animation state based on the state machine set up. In the animation graph, each animation can be set up to be triggered by certain parameters, thus, having access to control these parameters means being able to trigger animations.

For example, if we want to change the speed parameter in the AnimGraph:

self.speedParam = AnimGraphComponentRequestBus.Event.FindParameterIndex(self.entityId, "Speed");

and if we want to assign a value to it:

AnimGraphComponentRequestBus.Event.SetParameterFloat(self.entityId, self.speedParam, 1.0);

Resources

Contents

Input

Component

Lumberyard uses a unique system to get input data from a variety of controllers, including mouse and keyboard, and bind it to an event through its Input component. The component in turn references a .inputbinding file that actually defines the list of valid inputs that can then be referenced from a script to describe the behavior of every input. The Input component should be attached to the same entity as the script which is going to call the input event.

Input Component

Input Binding

The .inputbinding file contains an Input Event Group. There can be multiple events in the group. Each event has its own event name and generators. Each event can have multiple generators, which means a certain event can be controlled by one or more inputs. The .inputbinding file can be added and edited in the Asset Editor. If the Asset Editor panel isn’t wide enough the plus/delete/clear buttons can be hidden, simply expand the panel if there are missing buttons of the right.

Asset editor for input bindings

Scripting Interface

There are two ways to script the input:

1. Input Bus

Lumberyard doesn’t check input within an update loop, rather input events are subscribed to. When an input event occurs, the input notification bus is notified and any script listening for those event receives callbacks such as OnPressed, OnHeld, and OnReleased.

The script should be attached to the entity which has the input component. In scripting, the input component is connected with the scripts through the Event Name and the event value multiplier. The value is related to the input and is updated every frame. Using the values and the event name helps detect user input event that can be used to the trigger a reaction.

self.forwardBackInputBusId = InputEventNotificationId("NavForwardBack");
self.forwardBackInputBus = InputEventNotificationBus.Connect(self, self.forwardBackInputBusId);

There are three input functions: OnPressed(float); OnHeld(float); OnReleased(float); These functions can help us read the input events. In each events, we can check the value of the CurrentBusId and implement related reactions.

if (InputEventNotificationBus.GetCurrentBusId() == self.forwardBackInputBusId) then
-- do something
end

 

2.Gameplay Notification Bus

Another way to listen for input events is to use the StartingPointInput Gem, which provides Lua scripts that convert input bus events into gameplay bus events (held, pressed, and released scripts). Then in the script that recognizes input, rather than connecting to the input bus it connects to the gameplay bus. The reason to do this is that it allows for controls to be disabled by disabling the StartingPointInput script rather than updating a script, as well as helps with quick recognition of what input a entity is listening to. The downside to this method is that there is an additional string for the gameplay event that has the possibility of being mistyped.

self.ForwardBackId = GameplayNotificationId(self.entityId, "NavForwardBack", "float");
self.ForwardBack = GameplayNotificationBus.Connect(self.entityId, self.forwardBackId);

function script1:OnEventBegin(value)
-- do something
end
function script1:OnEventUpdating(value)
-- do something
end
function script1:OnEventEnd(value)
-- do something
end

This functionality is contained within the StartingPointInputGem, however can easily be scripted.

function script2:OnPressed(floatValue)
GameplayNotificationBus.Event.OnEventBegin(GameplayNotificationId(self.entityId, "NavForwardBack", "float"), floatValue)
end
function script2:OnHeld(floatValue)
GameplayNotificationBus.Event.OnEventUpdating(GameplayNotificationId(self.entityId, "NavForwardBack", "float"), floatValue)
end
function script2:OnReleased(floatValue)
GameplayNotificationBus.Event.OnEventEnd(GameplayNotificationId(self.entityId, "NavForwardBack", "float"), floatValue)
end

Resources

Contents

Physics

Physics include the movement and collision of objects, which typically require 2 components: a physics component and a collider. Lumberyard is in the transition between CryPhysics and PhysX, because the project was started with version 1.12 our experience mainly involves the legacy system. The simulation of physics can happen in 2 ways, while the game is running as well as simulating it through the Perspective Viewport toolbar, see Perspective Viewport for more information.

Legacy Physics System

Lumberyard’s physics system offers simulation of physical systems, including static and dynamic physical entities, triggers and collisions, ragdoll, and more advanced systems such as hair, particles, wind, and water. The AI/Phyiscs button in the bottom bar of the Perspective Viewport is a useful tool to simulate the two systems without needing to enter into the game mode.

Static Physics

The static physics component is applied to bodies that have logically “infinite mass”. That means that while they can other entities can have physics interactions with them, they are stationary and immovable themselves. Usually, things like a wall would have a static physics component since while they let other entities collide with it, they don’t move themselves.

Static Physics Component

Rigid Body Physics

Rigid Body Physics is usually added to non-living entities that you want to be able to interact with the physics system and also respond to it. Any living entity should generally have Character Physics rather than Rigid Body Physics, and an entity can only have one of these components, but not both. Rigid Bodies are generally dynamic, in the sense that they can apply or react to forces and collisions.

Rigidbody Physics Component

Colliders

In addition to Static or Rigid Body Physics components, entities require some kind of collider also attached to them. While the physics components are responsible for simulating physics, colliders actually record collisions that in turn invoke corresponding physics simulations. A collider can be Primitive (which requires a Shape component for the primitive shape you want your collider to be as), or Mesh (takes the shape of the required Mesh component attached to the entity).

Primitive shape colliders are associated with a shape, and the shapes are attached at the center of the entity. Shapes dimensions can be scaled however not not offset from the entity’s pivot. All shapes don’t work with the primitive collider component, only the primitives so not the polygon prism shape, compound shape or spline.

Shape Components
Primitive Collider Component with box shape

 

There is a visual bug associated with shape colliders and scaling. If an entity’s transform is scaled then the shape will be scaled with the largest scaled axis, ie if the entity is scaled Vec3(2,1,1) then the box will appear with dimensions Vec3(2,2,2). However, the primitive collider isn’t actually of size Vec3(2,2,2) rather still the original size of Vec3(1,1,1). The image below demonstrates this, the left entity is scaled by 2 in the x dimension but has the same collider size as the right entity.

Shape Collider Bug

 

For a mesh collider to act as an active component on an entity, there must be a mesh component attached to the entity and that mesh must have physics proxy associated with it. Where primitive colliders show the shape, although sometimes inaccurate, the mesh collider don’t show any visual information in the level editor. This can be particularly deceiving when an entity is scaled to know the collider has an accurate shape, as well as determining whether the mesh’s physics proxy is exists and will work as a collider.

Mesh Collider Component

Physics Proxies

Any mesh, not rigged actor, that will use a mesh collider needs physics proxies generated for the asset. These are geometries that are needed for collision detection. Opening up any mesh from the Asset Browser lets you add a Physics Proxy modifier to it that can then be used by any physics components attached on an entity of the same mesh. Physics will not work if the mesh does not have a proxy added to it. While adding proxies was a painless procedure in v1.12, v1.13 caused an irreparable issue in our copies of the engine where updating a mesh after adding the proxy would fail without a good explanation. The workaround to this was to copy the fbx asset to v1.12, build the mesh with the proxy (updating the assetinfo), and finally copying the fbx asset, assetinfo and material file that were generated in v1.12 back to the project in v1.13.

CryPhysics Proxy on mesh asset

Character Physics

Character Physics allows adding physical behavior to character entities. This is mainly used on game characters like players on enemies. It’s different from the rigid body physics system since these entities can actually be “moved physically” in correspondence with the AI and Animation systems. Without a character physics component, the entity’s animations won’t be able to move the entity in the level. One of the main drawbacks of Character Physics is that the collider fields in the component are vaguely defined, and since the collider is not visible to us at all, setting the values becomes a painful trial-and-error task.

Character Physics component allows masking out of different types of physical entities that the character itself can interact with.

Character Physics component

 

The entity pictured below has a character physics component attached to it. Like a mesh collider, there is no visual information in the level editor to tell the shape or size of the collider. This is more concerning than a mesh collider, because the character physics component allows for the player dimensions to be specified but there is no feedback of what the changes are doing until play mode/simulation.

Character Physics Entity

Ragdoll Physics

Ragdoll physics doesn’t work with the new FBX workflow.

PhysX

Lumberyard offered physics for games through its legacy physics system until version 1.12. In the latest version (1.13), PhysX was released in preview mode that would in the future replace the legacy system. However, at it’s current state, PhysX doesn’t offer all the features of the legacy system, such as interaction with Character Physics, and both the physics systems don’t interact with each other. This makes it hard to either entirely switch to PhysX or to use both simultaneously. PhysX still needs to mature until it can be adapted in place of the legacy physics system, however, you can use the resources provided below to learn more about PhysX.

 

Resources

Contents

UI

UI Components

To include UI in a level, a UI file must be loaded through a entity component. The UI canvas isn’t necessarily loaded in at run-time, and the loading of the canvas and enabling of the canvas can be controlled through script. The 3 available components to attach to level entities are: UI Canvas Asset Ref, UI Canvas Proxy Ref, and UI Canvas on Mesh. The UI Canvas Asset Ref is the component which contains the pointer to the canvas, as well as whether the canvas is loaded on awake. The canvas is able to directly communicate with the entity its attached to, without having an additional entity pointer. In scripting this entity is associated with loading and getting. The UI Canvas Proxy Ref has a pointer to the entity holding the canvas, and because it is a pointer modifying either canvas will modify the other — the canvases are shallow copies. The UI Canvas on Mesh does what expected, it places the the UI on a mesh which can be modified directly on the mesh.

UI Components to attach to level entities.

UI Editor

Lumberyard’s UI system can’t be edited within the level, but rather through a separate panel, the UI Editor. The UI Editor can be docked within the editor, however like other windows cannot overlay the perspective window. The two options for opening the editor are circled in white below. 

How to open the UI Editor from the Level Editor.

The UI Editor automatically creates an empty canvas, and to edit your canvas it must be loaded from a save file. Entities are referred to elements within the canvas. There are a list of preset elements which can be selected from the Slice Library, these elements include sliders, images, etc. To edit the properties of the canvas, simply deselect all entities (click within the hierarchy), and to edit elements select one as you would within the level.

The UI Editor with a canvas opened.

Tools

The UI Editor consists of the following:

  1. Toolbar – Commonly used tools and settings
  2. Hierarchy pane – List of UI elements that you create
  3. UI canvas tab bar – Tabbed display of open canvases
  4. Viewport – Display of the UI elements on the current UI canvas
  5. Properties pane – Component properties for the selected element
  6. Animation Editor – Tool for animating UI elements
Preset slice elements to add to a canvas.

 

The UI Inspector isn’t the same inspector as the Entity Inspector, and has a customized Transform component for 2D elements. The elements can be anchored within the canvas/parent and the grid has a quick select of the typical anchors desired, but also percentages to the right for customization. The Pivot grid selection is for where the pivot of the specific element selected is, and can also be numerically customized.

Canvas inspector for a text element. Transformation is required on all canvas elements.

The UI can be previewed with real-time UI effects without playing a specific level, since the information is local to the canvas and not the level. To preview the UI, select the preview button which will put the canvas into an intractable, non-editable state.

Preview mode of a canvas.

To import a font [NICOLE]

Scripting Interface

The UI in Lumberyard is incorporated in 2 parts, one part being attached to an entity in the perspective view and the other part is integrated into the UI editor. The UI editor component can’t directly communicate with any entity located in the level. Within the UI Editor, entities can only attach UI-specific components, which includes a Lua Script component. There is a separate reference documentation for Lua UI Scripting included within Lumberyard’s documentation, see resources. 

Available UI components for canvas entities.

If the script has a property of entity, that entity cannot be selected from level and is restricted to entities within the same canvas. To communicate with entities in the level, see below. This does also mean that canvases can be reused in multiple levels and projects without worrying about broken connections.

To send/receive messages from entities in the level, the level entities need a reference to the canvas and either the name in the hierarchy of that element or use of the Gameplay Bus. For level entities to reference a canvas, a component either need a reference to the entity holding the canvas or a component of proxy. Entities in the level and elements in the canvas can both reference the entity id of the canvas, through their own function calls. A common issue with communicating between the level and elements on the canvas is getting the EntityId of canvas entity. The level elements can get the canvas EntityId OnActivate, however this does depend on the order of components added into level, typically it is better practice to wait for first tick to call the function or listen to OnCanvasEntityLoaded (however the problem with waiting for this is in the case the canvas loads prior the function will never be called). The canvas element cannot get the EntityId of the canvas OnActivate, the function will not return an error but will return an invalid EntityId, the only option is to get the canvas EntityId on the first tick.

To have UI appear in the level and not be an overlay, the canvas must be set as a render texture. Render textures must have an assigned render target, which is a string that connects the canvas to a material. The render target in the canvas must match a material with the diffuse texture set to the same string, however if the canvas will be used in multiple instances different materials are required each with a variation on the render target string. For example, a render target: “$uicanvas” can have a diffuse materials: “$uicanvasLit”, “$uicanvasTest”, etc (no special characters or numbers can be part of the string).

UI Canvas Properties

 

Resources

Contents

Audio

Lumberyard comes prepackaged with Wwise for audio solution. Currently, integration with Wwise is the only way to import audio into your projects. All sounds are created, modified, and linked to different types of parameters in Wwise. Lumberyard offers an Audio Translation Layer (ATL) to integrate workflow between Wwise and Lumberyard. Watch this helpful tutorial to learn more about importing audio through Wwise and setting up Ambient Audio. Lumberyard’s Starter Game comes with a pre-created Wwise project and audio triggers already imported into the game project that can be used to get started.

Lumberyard currently only supports audio integration using Wwise. 

Audio Controls Editor

Audio Controls Editor is where audio triggers can be added/edited the Wwise project into Lumberyard.

Components

Audio Proxy

The Audio Proxy component is a required dependency if you want to add multiple audio components to an entity. It acts as a proxy audio object wrapped in a component. For example, if you have an audio trigger component and an audio RTPC component on the same entity, they communicate to the same audio object using this audio proxy component.

Audio Listener

Audio Listener is a component that is needed for 3D sound. Usually the rotation entity and position entity are for the main camera.

Audio Trigger

The Audio Trigger component provides basic play and stop features. We need Audio Trigger on an entity if we want to trigger audio with a script.

Script interface

Here is an example of playing audio by executing a trigger in script:

AudioTriggerComponentRequestBus.Event.ExecuteTrigger(self.entityId, "Play_KrossisCombatAreaMusic");

Resources

Contents

Shaders

Lumberyard supports writing custom shaders. Lumberyard follows Physically Based Rendering (PBR) techniques and is almost fully deferred. It uses forward only for translucent materials or for hair/skin. Lumberyard runs DirectX for graphics and uses a shader language similar to Cg/HLSL. Shader files are of three main types:

*.cfi [dev\Engine\Shaders\HWScripts\CryFX] – include files
*.cfx [dev\Engine\Shaders\HWScripts\CryFX] – shader files containing shader params
*.ext [dev\Engine\Shaders] – shader generation params for shader

Shader params are similar to having constants declared in the shader that affect the shading process. Properties such as alpha composition, opacity, etc, are shader parameters. Shader generation param, on the other hand, are values that define the overall working of the shader. Parameters such as whether the shading should be simple or advanced fall under shader generation parameters. A lot of the times, some shader parameters will only be exposed according to the shader parameters that are set.

Setup

Setting up a custom shader in Lumberyard is not very hard. Run-time compilation of shaders makes it easy to immediately see the changes made in a shader in the game, and hot reloading of shaders is also supported.
Setting up a custom shader:

  1. You’ll need a .ext and .cfx file for your shader
  2. dev\Editor\Materials\ShaderList.xml
    Add your shader to the list:
    <Shader name=”MyTestShader” />
  3. Copy:
    MyTestShader.ext -> dev\Engine\Shaders
    MyTestShader.cfx -> dev\Engine\Shaders\HWScripts\CryFX
  4. In Lumberyard, restart Tools->Material Editor
  5. In the Material Editor, create a new material and under Material Settings, attach your shader from the drop down menu under Material Settings->Shader.

For hot reloading of shaders, open dev\system_windows_pc.cfd (or another config file according to OS) and append to the file:
sys_PakPriority=0 (to ensure shaders load from file system instead of pak files)
r_ShadersEditing=1 (to enable shader recompilation at runtime)
To reload shaders in a game executable, go to the console at dev\ and type:
> r_reloadshaders 1

Resources

Contents

Twitch Integration

Twitch integration is built into the Lumberyard engine with ChatPlay, JoinIn, and the developer APIs. The current Lua Scripting reference, linked below, is not as detailed as the other aspects of the Twitch, and thus methods parameters and language can be confusing. For example, the reference guide uses the parameter channel for some method inputs, but does not explain what a channel is, and where people familiar with Twitch may believe it is the channel name, it is not related. The tutorials don’t overview Lua Scripting for Twitch, but rather Flow Graph, a visual scripting system that is being deprecated. The real strength with the Twitch integration in the current version is from the visual scripting, Flow Graph, which makes connecting to Twitch and other Twitch operations smooth. To contain all scripting in one language, preferably not a visual scripting like Flow Graph, developers can use the Flow Graph scripting system as a test of functionality. By slowly removing layers/nodes of the visual scripting and implementing them into Lua, the Lua script can be unit tested.

To develop for Twitch, developers need to connect the game to the Twitch application, through the Twitch developer dashboard, which will provide a clientID. To use ChatPlay the chatPlay_ClientID must be set to the clientID value provided in the game.cfg, see register reference.

Another discrepancy with Lumberyard’s Lua Twitch documentation is with regards to setting a keyword which is recognized in the chat. In Flow Graph, documentation and engine source code, the phrasing used for recognizing a word in the Twitch chat is keyword. Within the engine code and Flow Graph, the phrasing for methods is ‘RegisterKeyword’ however the Lua script is lacking this register. The Lua reference has a notification callback for keyword match and other functions calling out to a set keyword. The miscommunication in the reference, is the method function ‘AddOption’ is the way to add a keyword. Once the keyword is added, it isn’t set to be recognized by default, it is added in a disable state; which, is why the options either need to be enabled individual or all options can be enabled simultaneously.

Twitch Bots

While Lumberyard provides their ChatPlay feature to integrate Twitch with the engine, Twitch also provides their own IRC for anyone to be able to connect to channels and chat rooms. Bots are a useful way of automating certain tasks that a broadcaster might find important and helpful, such as chat moderation, immediate feedback loop, and custom chat commands. Some commonly available Twitch bots are Nightbot, Phantombot, and Moobot.

Twitch bots are nothing but pieces of code that you, as the broadcaster, can start during streaming (or even when you are offline for connecting to chat rooms). Bots can be written in any language. In most cases, socket programming is used to connect to the IRC channel. IRC is set up as a TCP connection. All messages that are sent or received are done so in the bytes format. All bytes are appended with “\r\n” to denote the end of the message.

Authentication

IRC works very similar to how ChatPlay is set up. To connect your bot to your channel, or any other channel, you’ll need to get an oauth token linked to the Twitch account that you want to link the bot with. To connect to a channel through IRC, the bot needs to be authenticated. This can be done through sending the following messages:

  1. NICK <your bot’s Twitch account username>
  2. PASS <the oauth token>
  3. JOIN #<name of the channel you want to connect to>

Ping

IRC clients need to keep their connection alive. Every 5 minutes or so, the Twitch servers send a ping to test whether the connection is still active or have been terminated. Bots need to listen for this ping and reply with a “PONG :tmi.twitch.tv”.

Sending/Receiving Messages

Twtich IRC uses “PRIVMSG” to send and receive messages. This is true for communication over a chat channel, a chat room, or even whispers. Some example commands:

  1. Sending a message to a channel:
    > PRIVMSG #<channel> :<message>
  2. Sending a message to a chat room:
    > PRIVMSG #chatrooms:<channel ID>:<room UUID> :<message>
  3. Sending a whisper:
    > PRIVMSG #<channel> :/w <recepient> <message>

Moderation and Other Chat Commands

Broadcasters can grant “mod” permissions to specific users. Every broadcaster is by default a moderator of its own channel. When a bot with a moderator status joins a chat, it can regulate the chat in the channel to a certain extent. These actions include:

  1. Slow mode (/slow or /slowoff):
  2. R9K mode (/r9kbeta or /r9kbetaoff)
  3. Emote mode (/emoteonly or /emoteonlyoff)
  4. Ban user (/ban or /unban)
  5. Clear Chat (/clear)

Capabilities

Twitch allows requesting for capabilities that allow a broadcaster or a moderator of the chat to get more information about the viewers.

  1. Membership (CAP REQ :twitch.tv/membership)
    Get information about when someone joins or departs from a channel, gains or loses moderator status, or list the existing chatters in a channel.
  2. Tags (CAP REQ :twitch.tv/tags)
    Get user state related tag information with several commands.
  3. Commands (CAP REQ :twitch.tv/commands)
    Enables several Twitch-specific commands.

Due to caching, events are not sent to a channel immediately; instead, they are batched up and sent every 10 seconds.

Limits

Normal Twitch accounts are associated with some limits that they need to follow. You are, however, allowed to register your bot with Twitch. Known or verified bot have a slightly more liberal set of limits. Currently, bots can be registered using this form. For the official set of limits, check out the Twitch docs.

Resources

Contents

AI

Navigation

Navigation Area

In Lumberyard, we should set up the navigation area first to make sure in this certain area AI can move around. This can be setup in RollupBar window.

Navigation component

This window can help us to define where is walkable where is not. This area is a 3-dimensioned area which is a little bit different from Unity.

The default choice is the area walkable, we can also select “exclusion” to exclude the area we don’t want. The final navigation area will be like this:

Navigation area

The blue frame means walkable, the red frame means not walkable.

In Lumberyard 1.13, Navarea can also be added through a component: Navigation Area.

This component needs a polygon shape to define the navarea shape

Agent

AI needs a Navigation component. In which we can define some details of the agent.

Navigation component

AI also needs a Character Physics component to make it navigate using animations.

Script

In scripts, we need the navigationComponentNotificationBus to handle the navigation events. Here is an example:

function NavigationExample: OnActivate()
-- Tell the navigation component to start navigating.
self.navHandler = NavigationComponentNotificationBus.Connect(self, self.entityId)
-- Navigate to the first way point in the array
NavigationComponentRequestBus.Event.FindPathToEntity(self.entityId, self.Properties.wayPoint[0])
end

There are two functions it provides:

function NavigationExample:OnTraversalStarted(requestId)
end

function NavigationExample:OnTraversalComplete(requestId)
end

And we can use

NavigationComponentRequestBus.Event.FindPathToEntity(self.entityId,wayPoint);

to navigate the agent to a destination

In this way, we can add different way points to make the patrolling navigation happen.

Example code can be accessed here:  NavigationExample

State Machine

Example code ai_control.lua can be accessed here: AI_Example

This is an example of how to change between two states according to certain checks and how to make reactions after state changing.

Resources

Resources

Contents

Documentation

Amazon Documentation

C++ References

Tutorials

Lua References

Amazon Documentation

C++ References

  1. [Legacy] Empty Component
  2. [Legacy] Recommendations of where to start

Multiplayer Programming in Amazon Lumberyard

This book was written by an Amazon Lumberyard developer, and is currently the only book about programming in Lumberyard.

  1. Github
Sidebar