Amazon GameDev Blog

Reflections on GDC 2016

by Eric Schenk | on | | Comments

With the release of Lumberyard Beta 1.1 and our participation in the Game Developers Conference, March was an important milestone for the Lumberyard team. This was the 30th year of GDC and the 18th I’ve attended. We’ve witnessed significant change in our industry over these years. Platforms and products have evolved. Game development has become a vast and complex business, moving from simply building and shipping products to also supporting live services. Gaming has become a lifestyle enjoyed by over two billion people around the world. What hasn’t changed at GDC is the sense of community and passion from everyone—from students to industry veterans. It was with respect for this passion that Amazon Lumberyard made its inaugural appearance at GDC.

Six weeks ago we launched Lumberyard and Amazon GameLift with the aim of giving developers a powerful game engine that is deeply integrated with AWS and Twitch. Our hope is that this technology will enable game makers to both create unparalleled experiences, and to connect to and engage with fans in a community around their games.

We kicked off GDC on March 14th with our first Lumberyard update: Lumberyard Beta 1.1. Our first update included 208 improvements, fixes, and features. Major features included significant workflow improvements, the introduction of mobile support, and extensions to the functionality of Twitch ChatPlay. An overview of Lumberyard Beta 1.1 is available here and you can download it here. The updates in this release are in addition to the new autoscaling features and region additions we announced for Amazon GameLift on March 10th. Autoscaling allows you to give GameLift simple rules to automatically decide when to use more virtual machines to support your game, and when to shut down machines to save you money. You can learn more about that update here. We will continue to release regular updates to Lumberyard and Amazon GameLift, so look forward to many more to come.

On March 15th, we hosted a Developer Day with talks by some of our team leads. These talented developers dove into Lumberyard with a special focus on our community-enabling features, and our approach to engine architecture and components.

Chris Byskal and Geoff Pare gave a walk-through of Amazon GameLift and autoscaling. During their talk they demonstrated autoscaling taking a test environment past 1,000,000 players. They have written up a blog describing the details here.

Bill Merrill and Rosen Baklov served up pizza slices, both metaphorical and real, in their talk about Lumberyard’s approach to engine modules, game systems, our new component entity system, and our “slices” composition system. Together slices and the component entity system allow you to create reusable templates for repeating elements in your game, place them in your world, and customize them individually. You can read Bill’s blog post about reworking Lumberyard’s entity framework here.

Hao Chen provided a deep look at rendering output for the latest High Dynamic Range (HDR) televisions using a demo created in Lumberyard. The graphics technology in Lumberyard is extremely powerful, and we got a hint of its capabilities with a look at a new character, Rin.

James Clarendon talked about building cloud-connected games using Lumberyard’s Cloud Canvas visual scripting tools for AWS services. Twitch’s developer relations maestro, Brooke van Dusen, gave us a data-driven glimpse inside what makes popular Twitch broadcasters successful.

In addition to Lumberyard demos, we shared our expo booth with Twitch, a Merch by Amazon T-shirt printer, and an AWS solutions desk. Twitch’s space highlighted the new Developer Success Program, which helps game makers leverage Twitch within and alongside their applications. Twitch Developer Success is a valuable resource for broadcasters and developers trying to build a community with their broadcasts.

We demonstrated ChatPlay, Lumberyard’s initial integration with Twitch. ChatPlay lets Twitch viewers interact with game logic by sending chat commands to the game. One of the most popular spaces in our booth was our VR ChatPlay demo, which let Twitch viewers use chat to decide the fate of participants. Read about Venture Beat’s Jordan Novet’s reaction here.

It wasn’t all Twitch on the show floor, though. Cloud enabled features were a big part of our presence, with a live demo of GameLift running a multiplayer game, and a Cloud Canvas sample game (Don’t Die) showing both the game and the behind-the-scenes flow graph. We also featured some of our new core engine capabilities, with demos of our new Component Entity system and mobile support. We rounded this off with previews of upcoming support for HDR TVs and VR.

GDC was the first opportunity for many developers to see Lumberyard in action and talk face-to-face with its developers. We heard a lot of feedback and feature requests, and we’re so grateful for the warm welcome we received from everyone. We appreciate the reception and enthusiasm we received at GDC, and everything we heard will inform the future of Lumberyard. Come get involved by letting us know what you want to see in the Lumberyard forums.

Code Archeology: Crafting Lumberyard

by Luis Sempe | on | in Lumberyard | | Comments

Grab your weathered fedoras, we’re doing some code archaeology.

Engines evolve over time. The more people involved and the more projects it produces, the more an engine gets filled with all kinds of code. Code that fixes game-specific problems, code that is cleverly optimized, ultra-verbose code, code that looks like it participated in an obfuscated code competition, great code, and orphaned code.

At Amazon we strive to be Earth’s most customer-centric company, and Lumberyard’s commitment to game development is no exception. As we advance the Lumberyard engine, we continually ask ourselves, “Is this the best code we can deliver to our customers?” If the answer is not a definite yes, then we know we have some work to do. The code we want to deliver should be readable, consistent, extensible, correct, performant, logical, peer reviewed, documented, modern, and useful. This means we study the code and identify areas we can improve without sacrificing or hindering existing functionality. So how do we make sense of it all? Just as it is in field archaeology, we dust off one piece at a time.

Let’s examine one code artifact we uncovered in our code spelunking: IEntityProxy.

What is an entity proxy?

An entity proxy is a special type of entity component. By themselves, they are not very different from other components, the primary difference is in how and when they are used by entities.

Entities can host any number of components. Entity proxies are a type of component that is managed separately from the other components for a few reasons. One reason is for quick access; normal components are not meant to be available for random access, but entity proxies are stored in a map, which allows us to grab them using a value from the EEntityProxy enum as the key. Another reason is to control their lifetime. Many entity proxies are fairly core-level engine components (rendering, physics, audio), and may have inter-dependencies. As a result, during shutdown, we need to be mindful of the order in which we release them to prevent getting into the situation in which a proxy has been released while we still needed it.

So what’s the problem?

We want Lumberyard to be a very modular, component-based engine that is easy and intuitive to extend. To this end, we determined that the IEntityProxy system represents a layer of complexity and tight coupling to engine systems that we could not efficiently maintain over time. For example, in its existing design, adding a new low level component would require the addition of a new value into the EEntityProxy enum in IEntityProxy.h, which is a low level interface. This addition would affect the serialization order for all other proxies. But more egregiously, it would cause any files that depend on IEntity to be compiled. Depending on the number of entities in the code, this could take a significant amount of valuable time.

In fact, the entity proxy system does have an extensibility feature. There is a slot reserved for a “user” entity proxy, so why not use that? One problem with this design is that it hinders our ability to reuse code, a lot of code becomes special case for “user” proxies, and we lose the ability to easily distinguish between different user proxies, if there were any, without adding another layer of information. Another big problem with it is the fact that there is only one slot for a user proxy.

We made the decision to fold IEntityProxy and replace it with a component based system in which any component can inherently be accessed in O(1), that is by design extensible with very little boilerplate code and that does not involve modifying any centralized header file.

This work would simplify the existing code base and bring it closer in line to the goal of having an entirely new component system and reduce the effort of porting existing engine components into Lumberyard components when the new framework became available.

Throughout our exploration, we found many interesting paths. Some were clear, others posed a challenge, and a few were fraught with peril. IGameObjectExtension is also a specialized type of component used as a mechanism to bring component support to CGameObjects. Down the IGameObjectExtension path there is a lot of code that we did not delve into in this journey. We marked our map and we’ll come back to it another day.

As we explored further, we found some functions that existed for convenience, depending on programmer preference. The following two examples are equivalent:

IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)pEntity->GetProxy(ENTITY_PROXY_RENDER); //  Matching lines: 54
IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)pEntity->GetRenderProxy(); // Matching lines: 29

We all have ways we prefer to read and write code, so finding multiple approaches to the same problem is not uncommon. We replaced these two functions with a single way to retrieve all components with the goal of having a very clear, concise framework.

Early on we decided that an enum based type identifier was not extensible enough. Instead, we opted to replace it with a type based identifier, which meant we could leverage templates to retrieve the component of the desired type.

IComponentRenderPtr renderComponent = m_pEntity->GetComponent<IComponentRender>();

In addition to the syntactical change, we reduced the number of functions used to get components to just this one and we took the opportunity to make component pointers managed using std::shared_ptr<>—in fact they already were, but they were not consistently used.

Having moved away from a centralized enum for component types, we were now able to specify their type directly within each component. This has the added benefit of reducing compilation times when new components are added since we no longer modify a central header file that was pulled in wherever we included entity code.

A minimal component now looks like this:

class ExampleComponent : public IComponent
{
   DECLARE_COMPONENT_TYPE("ExampleComponent", 0xB2B34F13F1A04686, 0xBB49697AAD456275);
public:
};
DECLARE_COMPONENT_POINTERS(ExampleComponent);

Components could now exist entirely within .cpp files! In fact, the unit tests we wrote for this system exist entirely in source files.

A few more vines to swing from

So far we felt we had done some pretty tangible improvements to the code, and as our journey continued deeper and deeper we found yet another opportunity in the shape of this pattern:

if (!GetRenderProxy())
    CreateProxy(ENTITY_PROXY_RENDER);

We understood the need for the creation of proxies, but we wanted to simplify it. We absorbed the burden of verifying if the component exists ourselves and provided this function:

IComponentRenderPtr renderComponent = m_pEntity->GetOrCreateComponent<IComponentRender>();

This is very similar to the way we already retrieved our components. Then, almost by accident, we stumbled across this little guy tucked away in two different precompiled headers on the game side code:

inline IEntityProxy* GetOrMakeProxy( IEntity *pEntity,EEntityProxy proxyType ) { ... }

As the name implies, this function will check if the entity already has a proxy of that type. If it does, it returns the proxy, which gives us O(1) access. If it doesn’t, it will create a proxy, register into the proxy map, and then return it.

This is pretty much the same thing we did. This was good, it felt like validation that what we were thinking was a good idea. We dug around a bit more to see how often it was used and where we would need to go and replace it.

Find all "GetOrMakeProxy"... ... Matching lines: 3

Three results. That’s the declaration in each of the precompiled headers and the one use case in a file called RadioChatterModule.cpp. We didn’t know GetOrMakeProxy existed for a while. It was buried in precompiled header for game code and not in the engine side so that fact alone limited its scope.

For Lumberyard we placed this utility function as a member of IEntity, which makes it accessible throughout the code base, both engine and game-side. This gave us the ability to take advantage of it in more places:

Find all "GetOrCreateComponent"... ...Matching lines: 138

We went from three calls to GetOrMakeProxy to over a hundred calls to GetOrCreateComponent. The achievement here is that we now have a consistent way to get and/or create proxies and slightly reduced the amount of code needed to use components. Of course we now had the ability to grep the code and quickly find all the places where components were being lazily created. Sometimes, it’s the little things that matter.

Cue the giant, unusually round boulders!

We tried to be careful archaeologists. We gently dusted off our work area, we skillfully disarmed the booby traps and documented our findings (it’s not science unless you write it down). So, what did we break?

Well…

We experienced difficulties with the lifetime and order of destruction of components. We learned that some components may reference other components in their destruction and so the order must be preserved. One mistake we made was to inadvertently reverse the order of destruction of components. This lead to components expecting other components to still exist at the time of their own destruction.

Another mistake we made was in communication. In the course of our changes we noticed the pattern used for determining entity event priority:

virtual ComponentEventPriority GetEventPriority( const int eventID ) const { return ENTITY_PROXY_LAST - const_cast<IEntityProxy*> (this)->GetType(); }

Noticing how the priority was always LAST – ProxyType, we thought we might as well just flip the event priority ordering and return the value of the priority:

So before:

enum EEntityProxy
{
    ENTITY_PROXY_RENDER,
    ...
    ...
    ENTITY_PROXY_USER,
    ENTITY_PROXY_LAST
};
virtual ComponentEventPriority GetEventPriority( const int eventID ) const { return ENTITY_PROXY_LAST - const_cast<IEntityProxy*> (this)->GetType(); }

While in the new implementation we would simply do:

struct IComponentAudio : public IComponent
{
    ...
    ComponentEventPriority GetEventPriority(const int eventID) const override { return EntityEventPriority::Audio; }
    ...
};

With the caveat that we reversed the enum ordering:

namespace EntityEventPriority
{
    enum
    {
        User = 1,
        ...
        ...
        Render,
        GameObjectExtension
    };
}

So in the previous implementation the audio proxy event priority would be:

return ENTITY_PROXY_LAST - ENTITY_PROXY_AUDIO; // 15 - 3 results in 12

In the present implementation it is:

return EntityEventPriority::Audio; //  the value of EntityEventPriority::Audio is 12

The entity event priority calculation was equivalent with the added benefit that the code was slightly more readable, and had one less subtraction operation. However, we did not propagate the explanation of these changes to Lumberyard users. There was a gap between our deployment of these changes and when other teams began the process of integrating their own work. This is when they encountered this change and had questions about what our intentions were. Once they saw our intentions were benign, they lowered their spears and invited us to feast with them. They introduced us to this wonderful beverage called beer in their native language.

In conclusion

“When you do things right, people won’t be sure you’ve done anything at all.” – Futurama, S3E20

We are crafting Lumberyard to be a powerful game engine that will allow game developers to make all kinds of games. We believe that in order to achieve this, we need to find opportunities to make the code scalable, readable and generally easy to use and maintain. Replacing IEntityProxy with a component based system brings us closer to this goal allowing developers to create new components without so much overhead.

For newcomers to Lumberyard, this is a bit of history and trivia. We hope you found the insight useful. For those familiar with Lumberyard’s origins, we hope this conveys some of our thoughts and vision for the future.

Extending the FBX Importer

by Ronald Koppers | on | in Lumberyard | | Comments

With the recent code drop of Lumberyard came our new FBX Importer, which gives developers the ability to export single meshes and materials. The FBX Importer has been one of the most consistently requested features for Lumberyard. We’re quite excited about how the interface works and looks and the overall direction it’s heading, but there’s also some pretty exciting technology behind it. Sorry artists, this one’s for the programmers.

The basics

Let’s take a quick look at the overall system. There are three major components involved with importing anything from an FBX file, which are:

  1. Builders/importers
  2. Internal Storage
  3. Exporters

Rather than take an FBX file and convert it straight into data that Lumberyard can consume, the process is broken down into two distinct phases. Builders and importers read data from one or more source files and use this to fill up the internal storage in the first phase. The internal storage contains a tree to describe a scene (SceneGraph) and a dictionary containing meta-data (SceneManifest). This storage is passed on to one or more exporters in the second phase. The exporters look at the content of the internal storage and generate one or more files ready to be used by Lumberyard.

The FBX Importer preview currently contains a builder for the FBX format (see FbxSceneBuilder), a json importer and exporter to read/write metadata and an exporter to generate mesh data in Lumberyards CGF format (see CgfExporter). Materials are also supported, but these don’t behave as true exporters since they produce more of an intermediate file.

Typical FBX Importer flow

This two-phase approach is used by both the editor and the resource compiler (RC). When opening an FBX file in the editor, the FBX file and meta-data (“.scenesettings”-files) are read and the editor uses the tree and meta-data in the internal storage to populate the UI. The user can edit the settings in the meta-data and, after confirming the changes, write it out to disk. The RC monitors for any changes to the FBX file or the meta-data so the previous action by the editor will trigger an RC task to build or update the Lumberyard CGF files. The RC task, in turn, will read the FBX file and meta-data. It looks through the meta-data and executes these using the data in the tree. The RC will continue to watch for changes, so when any .scenesettings of .fbx file change, those changes will be reflected in the editor and/or the game as well after a short delay; no need to reimport anything.

The history

From that dry piece of information above, it’s hopefully clear that the internal storage is pivotal in our plans for importing. It’s the central place all data goes to and gets read from. We even went so far as to create DataObject, a type-erased storage object so that you don’t have to bother with interfaces and including multiple libraries but can simply call DataObject::Create<Type>(argument); to have your own data in either the tree or the meta-data.

Why put so much effort into this instead of just exporting with the FBX? At the root is the problem that, quite frankly, we can never know what data is important to you. Maybe the names in an FBX file have special meanings or a certain hierarchy means something important. Perhaps there’s a set of assets in a legacy format that need to be imported or Lumberyard was extended with a game-specific format. Perhaps there’s another reason; we just can’t know.

When the development of the FBX Importer started, we wanted to provide core functionality to import data from an FBX file and export it to data Lumberyard could process. We were also aware of the customizations users would eventually require. When it came to a lot of our technical choices, the most important question we asked ourselves was: How will a user extend this?

At times, that can be a hard question. Picture, if you will, a meeting in a darkened room at the very early stages of development. It was just established that a dictionary was going to be used as our meta-data and has to store export instructions. The faces of the meeting attendees are dimly lit by the light of the teleconferencing television. A can of soda opens with a hiss.

Lower the house lights and raise the curtains

Developer A: The data stored in the SceneManifest will derive from a common mesh export group or rule interface.
Developer B: Sounds good, but how will a user extend this?
A: Well, they just implement their version of the interface.
B: Sure but what about data that is not directly mesh-related, like animation or something like an author name?
A: OK, well, in that case let’s have a very basic SceneManifest-entry interface with no functions so everything can be added and have the mesh group/rule interfaces inherit from that.
Developer C: Good! Solved. But how will the user extend the UI?
B: We could use our property grid to automatically build a UI for editing.
C: Cool, then the user would only need to add runtime type information [RTTI] and reflection.
C: Hmmmm, now that I think about it, why do we need both an interface and RTTI?
A: Well, no real need, but we would need to write some sort of type-erasing storage to get rid of the interface, which will take extra time.
B: But it will make it easier for the user to put any of their data in, no matter what it might be.
A: That’s right. That’s what we’ll do.

End scene

My Tony Award must be in the mail. Still, this is more or less what happened. What we initially thought was a straightforward solution turned into DataObject to keep code requirements to a minimum. Just a few optional hints will help automate tasks such as building a UI. The only reason we came to this conclusion was because the question “How will a user extend this?” was brought up several times.

The part that’s actually interesting

DataObjects are used to store any data in the tree or the meta-data. The only requirement is that RTTI is implemented for the class that will be stored in the DataObject, although a single line to use the AZ_RTTI macro is already enough to satisfy this requirement.

For all the data added by our team, we’ve added an additional layer of convenience in the form of common interfaces to all data classes. We base our functionality on the interface, not the concrete implementation. You have the choice to extend the interface instead of creating a new type, so you can use the functionality that’s already there.

That’s a lot of information, so let’s run through an example to see how all these pieces tie together. Let’s pretend there’s a world where technology exists to procedurally generate hats. In such a world, Lumberyard clearly has to be extended to support importing .hat files.

  • Let’s begin by creating a new class to store the .hat content called “HatData”; no need to inherit from an interface, just make sure there’s an AZ_RTTI(“HatData”, …) in there.
  • A new importer will be responsible for loading the .hat file into HatData and adding one or more DataObjects with the loaded data. Let’s call that a HatSceneBuilder which will call something like tree.AddChild(GetRoot(), “TopHat”, DataObject::Create<HatData>(data));.
  • Next, there should be an option to attach the hat to a mesh node. To configure this, a HatRule is created. Let’s avoid writing a custom UI for this, so inherit from the IRule interface and add it to the rule factory. After adding AZ_RTTI, reflection is added (which is a bit too much to discuss here, so will skip for now). Since the IRule interface is used and given that reflection has been set up, there’s nothing else that needs to be done. The editor will be aware of the rule and allows it to be added to a mesh group. It will be serialized to and from the meta-data.
  • Finally a RuntimeHat exporter is created that will use the new rule in the meta-data and the content of the tree to generate the .rthat file, the fictional file which Lumberyard will use once the procedural hat technology has been added to the engine.

 

Conclusion

This blog covered a basic overview of the mechanics behind the FBX Importer and gave a quick peek into our approach to making an easily extensible system. There are plenty more examples and details I’d love to discuss but I didn’t want to drag on and on.

Your feedback on the entire FBX Importer is very important to us. The current version is a preview of things to come, and we have no shortage of plans that will hopefully lead to some very exciting news in the (near) future. Your feedback will be instrumental for us to prioritize those plans and give us even more concrete examples and ideas on how to answer that important question: How will a user extend this? Send us your asset importing needs and ideas, no matter how crazy! OK, maybe draw the line at procedurally generated hats.

Ronald Koppers is a technomancer specialized in the teachings of Stroustrup. For over a decade Ronald has been reordering bytes in the most optimal order in over half a dozen engines and editors as well as extending them with new technologies. At Amazon he’s currently passionately working on the easiest way possible to transmogrify your work into Lumberyard.

Reworking Lumberyard’s Entity Framework

by Bill Merrill | on | in GameLift, Lumberyard | | Comments

Technology providers and studios have pumped an incredible resources into building technology that enables faster iteration, rapid feedback, early error detection, and enables team members of vastly different skills to work together to build high-quality gameplay.

As the engineer leading up some of our workflow efforts, I’ve had the joy of working with a team passionately focused on enhancing Lumberyard so that content creators can get creative as fast as possible. Today, I’ll share insight into Lumberyard’s new component entity system and its related workflows and some of the underlying technology. If you happen to be at GDC this week and didn’t catch our talk in the West Hall on Tuesday, just drop by the Lumberyard booth in the South Hall for juicy details and demos.

Something Everyone Uses

The entity system is a key construct in most engines and acts as the glue between engineers and content creators. Every team member interacts with the entity system in some way, so this was an obvious place for us to start our work to advance Lumberyard’s workflows and general usability. Prior to release, we worked with early customers using Lumberyard and leveraged our own veteran team’s experiences building games of many shapes and sizes. We captured mountains of feedback and set out to deliver something more familiar to designers and artists, and more flexible for engineers, to enable them to use Lumberyard’s vast feature set to build higher-quality content faster.

We built many fundamental engine systems comprising an ecosystem that has and will continue to drive major improvements in Lumberyard.

 

Component entity editor overview

 

Drag & drop entity creation & configuration

Component as Building Blocks

A component architecture intends to contain and hide complexity, and facilitate software growth and iteration. Components represent a game or engine’s features as bite-sized atomic pieces that work intuitively with minimal dependencies. There are many practical advantages of well-applied component entity architectures, including:

  • Providing a common structure that engineers and content-creators can discuss and reason about together, enabling rapid design and development
  • Promoting code re-use when compared to monolithic entity architectures, reducing maintenance costs
  • Making deleting legacy code easier (like it should be) so you can minimize technical debt, reduce compile times, etc
  • Allowing for entities to have predictable runtime performance cost – pay only for what you use
  • Acting as an construct for making a large, source-available technology suite like Lumberyard easy to customize and extend to your own game-specific needs

One tenet of the Lumberyard’s new entity system is to keep entity life-cycle as simple as possible. In our experience, especially on large game projects, we’ve found complex entity life-cycles to be a major source of bugs and unnecessary complexity that makes it harder for your team to quickly evolve game features.

Lumberyard entities have two states: active, and inactive. That’s it. Once an entity is active, all components on the entity have a guarantee that the entity’s overall component make-up will not change. This simple rule makes writing reliable components straightforward, which means fewer errors. The lines are very clear as to when specific actions are possible. Additionally, Lumberyard components have the ability to express dependencies, requirements, and incompatibilities, in the form of services. The engine topographically sorts components within an entity based on these dependencies, to provide further mechanisms for component authors to minimize complexity (and bugs!).

An example of component services in the MeshCollider component:

    static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
    {
         provided.push_back(AZ_CRC("ColliderService"));
    }
    static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
    {
        required.push_back(AZ_CRC("MeshService"));
    }

An example of simple activation and deactivation in the Mesh component:

    void MeshComponent::Activate()
    {
        MeshComponentRequests::Bus::Handler::BusConnect(m_entity->GetId());

        m_mesh.CreateMesh();
    }

    void MeshComponent::Deactivate()
    {
        MeshComponentRequests::Bus::Handler::BusDisconnect();

        m_mesh.DestroyMesh();
    }

Components that ship with the engine make diligent use of subscription-based, event-driven programming patterns. For example, entities and components do not implicitly receive per-frame tick messages. Instead, components use Lumberyard’s high-performance messaging system, called Ebuses, to communicate. Using the messaging system also minimizes dependencies between components, ensures they do not develop assumptions about how others operate internally, and avoids the need for brittle multi-stage initialization patterns.

    // Notify listeners that we've moved. This event bus supports any number of listeners.
    TransformNotificationBus::Event(GetEntityId(), &TransformNotificationBus::Events::OnTransformChanged, m_localTM, m_worldTM);

    // Listen for our parent's transform changes.
    TransformNotificationBus::Handler::BusConnect(m_parentId);

A Strong Foundation

We have also put a lot of thinking into Lumberyard’s aggressively-tested, generic, and high-performance serialization, reflection, and messaging systems. While we apply these throughout the engine, they’re used heavily by components. We want it to be trivial for component authors to express their class’s data makeup and editing behavior to others on the team who are likely to use their components. It’s necessary to have the ability to provide a simple and error-free editing experience for complex game or engine behaviors. Field ranges, validation functions, visibility filters, and many other attributes are available within the reflection markup to aid in building a robust component library. These features allow a sophisticated and robust editing experience with minimal code.

Undo/redo, cloning, saving/loading, a fully-cascading prefab system we call slices, and many other features rest on the shoulders of a high-performance object manipulation and serialization that interchangeably supports XML, JSON, and binary formats, and includes format-agnostic versioning. We continue to put large emphasis into squeezing every possible drop of performance out of these systems, especially given how fundamental they are to key elements of both the editor and runtime.

These are of course flexible and broadly applied elements of the core Lumberyard engine applied to more than just game entities. Given their versatility, we’re using them to power many of the engine’s features. You’ll see a lot happening in Lumberyard to ensure fundamental systems such as these are built well and stressed heavily.

An example of class reflection for serialization using AZ::Entity:

    serializeContext->Class<Entity>()->
      Version(2, &ConvertOldData)->
      Field("Id", &Entity::m_id)->
      Field("Name", &Entity::m_name)->
      Field("IsDependencyReady", &Entity::m_isDependencyReady)->
      Field("Components", &Entity::m_components);

An example of class reflection for editing using the Light Component (partial):

    ...
    DataElement("ComboBox", &LightConfiguration::m_lightType, "Type", "The type of light.")->
      Attribute("ChangeNotify", &LightConfiguration::LightTypeChanged)->
      EnumAttribute(LightType::Point, "Point"))->
      EnumAttribute(LightType::Area, "Area"))->
      EnumAttribute(LightType::Projector, "Projector"))->
      EnumAttribute(LightType::Probe, "Probe"))->
    DataElement(0, &LightConfiguration::m_onInitially, "On initially", "The light is initially turned on.")->
    ...

Cascading Prefabs, aka “Slices”

Lumberyard’s “Slices” are another key element of its entity foundation. Slices are a big topic and something we’re really excited about, so we’ll be doing a follow-up article where we can dive into the implementation, workflows, and further grand plans, but they’re definitely worth a mention here.

Slices are a cascading prefab system. Any number of entities with any arbitrary relationships and component configurations can be used to produce a slice asset; no hierarchy is required. Slices are assets, and can then be instantiated and optionally cascaded any number of levels. This allows you to finely tune and test entity setups with the ability to propagate enhancements and fixes throughout the slice hierarchy. A slice can contain any number of instances of other slices (aggregation), and any modifications (entities added/removed, components added/removed, fields changed), making them flexible for managing all entity data. For game entities in Lumberyard, everything is a slice, whether it’s a pre-configured AI squad or an entire level.

After instantiating a slice, it’s possible to modify it in any way and push the changes back to the underlying slice asset. You can change and push a single property change, or whole entities. This allows you to further refine and grow existing slices as you add behavior to the game.

Pushing instance changes to back to slice hierarchy

Entities & Components as a Generic Architecture

Compositional entity structures have been around for some time and applied in many ways.

We’re very actively addressing Lumberyard’s core engine DNA to make it extremely customizable and extensible. Game and system level components can be reflected to the engine from your own modules. All components are discovered by the engine through reflection and automatically become an integral part of Lumberyard. Your game components are available through all workflows and user interfaces, including the component palette.

System-level components augment the engine itself at a core level. Whether it’s your custom AI, game systems, or an entire physics integration, you can bring 3rd party or your proprietary technology and assets into the engine, or even contribute work back to share in the broader Lumberyard ecosystem. As we continue to aggressively modularize Lumberyard, it’ll be increasingly easier to disable elements of the engine you’re replacing or not using. Because Lumberyard modules integrate deeply with the build system, code in modules you don’t wish to include is completely stripped out of the build. You won’t even pay to compile the systems you don’t wish to use.

Intuitiveness Matters, Even For Experts

A technology or tool that isn’t intuitive creates a frustrating experience for new users. Often what defines an expert is someone who has invested enough time that they’ve mastered countless quirks and hidden “features.” Minimizing the time it takes to become an expert at using Lumberyard to build your projects is important, and we’re of course applying this philosophy in the design and implementation of Lumberyard’s component/entities.

We’re already working directly with game teams to ensure these workflows mature quickly. Intuitiveness, iteration times, early error detection, and performance are all getting tons of love to satisfy high-demand games in development right now, which accelerates our ability to get battle-tested and production-ready features to you in a state you can have confidence in.

There’s much more to talk about. Now that you’re a bit more familiar with some of Lumberyard’s new features, here are the topics we’ll be talking about in the coming weeks with much deeper technical detail:

  • Generic reflection and serialization—rapidly edit and robustly manage, well, anything
  • The nuts and bolts behind Ebuses—Lumberyard’s general-purpose high-performance messaging framework
  • Slices—Lumberyard’s fully cascading prefab system
  • Migrating legacy entity functionality to component entities

We’re excited to get your feedback on the next release of the new component entity system. If you have questions or great ideas for how you’d like to use this system, or would like to know more about its inner-workings, please don’t hesitate to let us know.

Grab Lumberyard, play with it, and tell us what you want to see next! Stay tuned for more juicy articles on how we’re constantly improving all aspects of Lumberyard.

Bill Merrill has been a professional software engineer in the game industry for 13 years, building experience in nearly all areas of game development and technology including pipelines, tools, gameplay systems, physics, networking, optimization, and especially AI and animation.

FBX Importer Preview

by David Chiapperino | on | in Lumberyard | | Comments

Since the launch of Amazon Lumberyard Beta in February, we’ve been talking to developers, reading emails, and listening to forum posts about features that developers want to see in the engine. One of the most popular requests has been for FBX support. Lumberyard Beta 1.1 introduces the new Lumberyard FBX Importer which allows developers a path to import geometry from their favorite content tools (like Maya, Max, and Blender). The new tool lays the foundation for making an art pipeline that is extensible, easy to use, and allows for fast iteration.

To see a brief overview of the FBX Importer, watch this video:

What can developers expect to see in the FBX Importer?

The FBX Importer enables you to import single-mesh and auto generating material files. We’ve also added support for import rules, so developers have the ability to edit settings such as orientation, translation, and scale and immediately see these changes updated in a level. Developers are also able to author and edit multiple configurations to an FBX. This means that if an artist has an FBX scene with a phonograph, table, and chair, each individual piece of furniture may be extracted as a separate mesh file (.cgf). For a full list of FBX Importer features, please check out the documentation here.

Customers value extensibility so they can more easily add and modify source code to suit their individual needs. Our engineers have written an abstraction layer that allows developers to more easily add support for custom and emerging data formats beyond FBX. For example, if you’re a studio that believes that .obj is the king of all data formats, the data abstraction layer will allow you to more easily extend the importer’s code to add the format type.

What’s next?

We’re just getting started with the FBX Importer, and we’re continuing to tune the tool, improve iteration speed, and add new features. We’ll be including support for importing groups of mesh nodes so artists will be able to be selective about the group nodes they wish to include from an FBX hierarchy. We’ve also heard developers’ requests for support for skins, skeletons, and animation, and we’ve added those items to our list as well.

We appreciate the community interest in the FBX Importer and we look forward to hearing your feedback on the forums!

For nearly 20 years, David Chiapperino has been bringing characters to life with teams of animators, and tech artists and engineers. He has worked on games, cinematics and interactive experiences with companies such as Disney, Respawn Entertainment, Universal, Mattel, and SCEA.

Using Autoscaling to Control Costs While Delivering Great Player Experiences

by Chris Dury | on | in GameLift | | Comments

Game developers with real-time multiplayer games tell us they want to spend less on infrastructure expenses while still providing great online experiences for their players. The challenge is that player demand can fluctuate each day, hour, or even minute. When server capacity is fixed, developers run the risk of having too much or too little capacity at any moment. With too much capacity, developers are wasting money, and with too little capacity, players have to wait to play and may quit the game.

Potential consequences of fixed game server capacity

Developers want to be able to rapidly adjust server capacity based on real-time changes in player demand. So we developed a new autoscaling feature for Amazon GameLift that automatically increases server capacity during demand spikes and decreases capacity during lulls. In a few simple clicks, game developers can set Amazon GameLift to automatically raise or lower capacity as player demand changes over time.

Potential results with GameLift autoscaling

In this blog post, we’ll walk through the process of creating autoscaling policies in Amazon GameLift and cover some pro tips to help you get started.

 

Step 1: Select an Active Fleet

To take advantage of Amazon GameLift autoscaling, we first need an active fleet. To learn more about how to set up a fleet, consult the Working with Fleets section of the Amazon GameLift Developer Guide. You can set up and test fleets for free as part of the Amazon GameLift free tier.

Below is a screenshot of an active fleet in the Amazon GameLift console.

 

Step 2: Select the Scaling Tab on the Fleet Detail Page

We begin configuring autoscaling policies by clicking on the Fleet ID of the fleet we want to configure. On the fleet’s detail page, we open the Scaling tab. Here we see a graph of the number of instances in our fleet, as well as controls we can use to change our scaling limits. This page helps inform our decisions on when and how to scale this fleet.

 

Scaling Limits define the number of instances we want in our fleet. There are three settings:

  • Minimum – a threshold to never let our fleet scale below
  • Maximum – a threshold to never let our fleet scale above
  • Desired – our desired number of instances based on our autoscaling policies

Instance Counts display the number of actual current instances. There are four states:

  • Active – total instances running in this fleet
  • Idle – active instances without active game sessions
  • Pending – instances provisioning but not yet active
  • Terminating – instances in the process of terminating

The screenshot above shows that we manually scaled this fleet to ten desired instances when we created the fleet. As shown at the bottom of the Scaling tab, there are no autoscaling policies currently in place.

 

Step 3: Add an Autoscaling Policy

We open the autoscaling policy tool by clicking on Add Policy. In this walkthrough, we want to create a “scale up” policy – one that detects an increase in player demand and automatically increases capacity.

 

Amazon GameLift autoscaling policies follow this pattern:

If a certain metric meets or crosses a certain threshold value for a certain length of time, then change fleet capacity a certain amount.

As you can see in the screenshot below, the autoscaling policy tool makes it easy to build a policy statement step by step.

 

To create our policy, we need to set each of these values:

If [Metric] are [Comparison operator] [Threshold] for [Evaluation period] minutes, then [Adjustment method] [Adjustment value] [Adjustment type].

 

Step 4: Choose a Metric

The first decision we need to make is which metric to use. Amazon GameLift collects data about fleets automatically and makes the following six metrics available to use with scaling policies:

  • Available Player Sessions – Number of player session slots currently available in active game sessions across the fleet
  • Idle Instances – Number of instances in the fleet that are not currently running a game session
  • Active Game Sessions – Number of active game sessions currently running
  • Current Player Sessions – Number of active or reserved player sessions in the fleet
  • Active Instances – Number of instances currently running a game session
  • Activating Game Sessions – Number of game sessions in the process of being created

We’ll use the Idle Instances metric. With this metric, we can control the number of instances that are available for new games and minimize the time players wait to join.

 

Step 5: Choose a Threshold

Next we need to set a threshold for our metric that will trigger GameLift to scale up capacity. Thresholds have three settings:

  • a comparison operator – either <, <=, > or >=
  • a threshold value
  • an evaluation period – the number of consecutive minutes that a metric must exceed the threshold value before GameLift will trigger the policy

We want GameLift to scale up when there are too few idle instances, so we’ll choose the <= (less than or equal to) operator and enter five instances for ten minutes. This means that if the number of idle instances remains less than or equal to five instances for at least ten consecutive minutes, the scaling adjustment (which we’ll define in the next step) will be triggered.

 

Step 6: Choose a Scaling Adjustment

Once we’ve set our threshold, we need to tell GameLift how to adjust capacity. There are three options:

  • Scale up or down by a certain number of instances
  • Scale up or down by a certain percentage of capacity
  • Set capacity to an exact value

In each case, GameLift will add or terminate instances in order to make the specified adjustment.

We want to add more instances, so we need to scale up by either a certain number of instances or a percentage of total capacity. For this walk-through, we’ll scale up by five instances each time this policy is triggered.

 

Step 7: Activate the Scaling Policy

The last step is to save the scaling policy by clicking the checkmark icon to the right of the policy. That’s it! Once you save the policy, Amazon GameLift will begin adjusting capacity using this policy in about ten minutes.

 

Step 8: Add a Scale Down Policy

Now we need a second policy to scale down our fleet when fewer players are online, which will save us money.

We’ll repeat the process we used for our Scale Up policy to create a Scale Down policy. In this policy, we want GameLift to scale down by five instances if the number of idle instances is greater than or equal to fifteen for more than fifteen minutes.

Our two policies are shown in the screenshot below.

 

We can monitor the effects of our autoscaling policies using the graphs at the top of the Scaling tab. We can change, delete, or add new policies as needed to optimize our autoscaling approach based on actual player demand patterns.

 

Tips

Here are some pro tips to consider when setting your own autoscaling policies.

Set minimum and maximum instance values for fleets. Fleet maximums and minimums are important safeguards for autoscaling. It’s possible to set an autoscaling rule that scales your fleet all the way down to zero instances. If this happens, it can take ten or more minutes before a new instance is active, during which any players who want to join your game are left waiting. You may also want to set a fleet maximum that puts a fixed limit on the amount you’re willing to spend or prevents an autoscaling policy from scaling up too much. Keep in mind that fleet capacity is also constrained by on-demand instance availability and your account limits. You can find more information about account limits and requesting limit increases on the AWS Service Limits page.

Use game session protection for production fleets. The game session protection feature ensures that when your autoscaling policy triggers a scale down adjustment, Amazon GameLift will not terminate any instances that are hosting active game sessions. If there are no unprotected instances, GameLift will wait until all players leave the games on a protected instance before terminating the instance. This prevents players from being arbitrarily dropped during gameplay.

Keep in mind that autoscaling policies have ten minute cooldown periods. GameLift will wait ten minutes after a policy triggers an action before evaluating policies again. This allows enough time for GameLift to add or remove instances and begin collecting metrics from the resulting fleet.

Don’t create conflicting policies. Amazon GameLift doesn’t restrict the policies you can create. It is possible to create policies that conflict with each other, potentially creating an infinite loop of scaling up and down. You can also create rules that overlap, such as with multiple scale up policies, that can either exaggerate or nullify their effects.

We’re looking forward to hearing your ideas and feedback on GameLift autoscaling. Please join the conversation in the GameDev Forums.

– Chris

Chris Dury is a Director at Amazon Web Services. He’s responsible for Amazon GameLift and other cloud services for game developers and is currently playing SMITE and Clash Royale.

 

Now Available – Lumberyard Beta 1.1

by J.C. Connors | on | in Lumberyard | | Comments

Today, less than five weeks after the launch of Lumberyard, we are pleased to release Lumberyard Beta 1.1. This update includes 208 improvements, fixes and features; and is available for immediate download here. With Lumberyard Beta 1.1, we are releasing several significant workflow improvements, introducing mobile support, and extending the functionality of Twitch ChatPlay. The updates in this release are in addition to the new autoscaling features and region additions we announced for Amazon GameLift on March 10.

Workflow Improvements

Lumberyard Beta 1.1 includes three major new systems that directly accelerate your team’s workflows on the way to high-quality.

Component Entity System – One of the areas we are focused on with Lumberyard is making the engine extensible by developers without changing engine code. Our new Component Entity system is built to enable easy engine extension with new components. Content creators can drag-and-drop and combine those components into new game objects. They can then make reusable assemblies of Component Entities, which we call “Slices.” Slices can be composed of other nested Slices. Slices can contain scene elements and game logic written in Flow Graph, Lua, or C++. Individual properties of Slices can be overridden, or shared among all copies of a Slice. This approach allows you to lay out generic copies of a Slice in a scene, and then quickly make changes to specific copies.  For example, if you have a Slice that includes a row of street lamps, you could also include broken light bulbs on a select set of those street lamps. Furthermore, changes to the base model can quickly be shared with all copies. The Lumberyard Editor includes rapid drag-and-drop workflows for creating Components and Slices.

Component Palette

Component Palette

Substance Integration – We are actively incorporating the most popular third-party packages into Lumberyard and we are excited to announce that Allegorithmic’s comprehensive texture and material authoring software, Substance, is now integrated with Lumberyard. Substance enables artists to procedurally create materials using a visual, node-based system, so they can build beautiful worlds faster than traditional hand-painted methods.  You can use Lumberyard’s Substance Editor to import Substance files from Substance Designer, or generate and export static textures for materials. Additionally, you can use Lumberyard to modify Substance material properties in real-time.  For example, you could use the Flow Graph to cause materials in your world to rust and age over time, or enable players to customize the world with new colors and textures.

Substance Integration

Substance Integration

FBX Importer – Another workflow improvement we are previewing is a built-from-the-ground-up FBX Importer, which allows users to import 3D meshes and materials in a few simple steps. A new FBX Importer was one of the top requests from our developers who are using a variety of 3D authoring tools including Blender. Also, since many developers rely on their own proprietary asset formats (typically to support in-house tools or unique game features), we’ve built the FBX Importer to be extensible and support custom data formats.

FBX Importer

FBX Importer

Additional workflow improvements in Lumberyard Beta 1.1 include:

  • Six new Gems designed to help you get prototyping faster, including pre-built code and components for game cameras, movement, and game input.
  • A preview of the Cloud Canvas Resource Manager, which enables your engineers to set up specific AWS resources and deployments for your game features right from within the Lumberyard Editor.

And to make installation easier, we’ve introduced a new Lumberyard Installer, which automatically downloads the Lumberyard package, so you can get set up faster than by downloading a single large .zip file. We’ve also made the .zip version available for developers who prefer that format.

Initial Mobile Support

Lumberyard Beta 1.1 introduces mobile support. In this release, we include support for iOS devices with an A8 or better processor and the Android-based Nvidia Shield. Lumberyard Beta 1.1 uses Apple’s Metal API and leverages their GMEM fast memory to enable you to create high-fidelity iOS visuals. By using Metal and GMEM, Lumberyard enables your game to directly access and push more data to the Apple GPU hardware, so your game can use the latest rendering techniques (e.g. post effects such as depth of field, glow, flares, and color grading). Supporting mobile developers building 3D and connected games is a priority for us and we will continue to expand device support in coming releases.

Lumberyard on iOS

Lumberyard on iOS

New Twitch ChatPlay Features

Our customers have given us a number of suggestions for Twitch ChatPlay, which helps you build gameplay that interacts in real-time with Twitch viewers. Developers have told us that one of the most fun ways to engage fans on Twitch is by enabling viewers to vote on game modes and outcomes. To help developers create vote-based gameplay, we’ve added ChatPlay options that enable you to tally votes and query the results, so you can create more complex voting interactions. For example, you could ask your spectators to vote on who they think the best player was in a match, and then arm those players with different weapons in the inverse order of strength in the next match (so the worst player may end up with a nuclear plasma torpedo, versus the best player’s chicken bat).

ChatPlay Flow Graph

Sample ChatPlay Flow Graph

More Soon

We thank the Lumberyard community for sending suggestions and feedback to our forums and lumberyard-feedback@amazon.com. The team loves hearing what you have to say about our tools and workflows. Keep it coming! And if you’re going to be at GDC, we have a Dev Day scheduled on Tuesday, March 15, so you can meet some of our team and dive deeper into our newest release.

You can download Lumberyard Beta 1.1. here. For details on everything new in the Lumberyard Beta 1.1 release, check out the release notes here.

We have a steady cadence of Lumberyard and Amazon GameLift updates coming soon, including more workflow improvements and ways to help you connect to AWS and Twitch. We’re excited to get your feedback – see you on the forums, or swing by our booth (Main Hall #1224) if you’re in town for GDC.

Amazon GameLift Adds New Regions and Autoscaling Features

by J.C. Connors | on | | Comments

Today, Amazon GameLift expands to two new AWS regions in addition to the currently available Northern Virginia and Oregon regions. Developers can now deploy game servers for their session-based, multiplayer games throughout North America, Europe, and Asia Pacific.

  • New region names are: eu-west-1 (Ireland) and ap-northeast-1 (Tokyo)
  • Endpoints are: gamelift.eu-west-1.amazonaws.com and gamelift.ap-northeast-1.amazonaws.com.

Additionally, Amazon GameLift’s new autoscaling feature lets developers set up Amazon GameLift to dynamically manage server fleet capacity. With this feature, capacity can closely follow the game’s demand curve, so developers can keep costs down while still ensuring that players can get connected fast.

  • Autoscaling uses a set of policies, created by the game developer, that tell Amazon GameLift when to change capacity and by how much. Scaling policies are based on a set of metrics, such as server utilization, game session counts, and player counts. For example, a policy might say: “if the number of idle instances exceeds 20 for longer than 15 minutes, scale down by 10 instances”.  Fleet size can also be constrained with minimum and maximum capacity limits.
  •  Metrics available for autoscaling include:
    • Idle instances
    • Available player sessions
    • Current player sessions
    • Active game sessions
    • Activating game sessions
    • Active instances
  • Game session protection ensures that an instance with active game sessions will not be terminated until all players disconnect. Developers can apply this protection to an entire fleet or to individual game sessions.
  • The Amazon GameLift console offers tools to help create and apply autoscaling policies and set the game session protection option. Developers can also complete these actions using the AWS CLI or AWS SDKs.

Thanks to all of you who have sent feedback to us in both the GameDev forums and by sending email to lumberyard-feedback@amazon.com. The Amazon GameLift and Lumberyard teams love hearing what you have to say, so keep it coming! We’ll continue to lean on customer feedback as we update Amazon GameLift to make it easier to deploy, operate, and scale your session-based multiplayer games.

If you’ll be at GDC next week and want to meet the Amazon GameLift team, please swing by the Lumberyard booth in the Main Hall #1224, or visit our Amazon GameLift Dev Day talk on Tuesday, March 15, at 10-11am.

GDC 2016!

by J.C. Connors | on | | Comments

The Amazon GameDev team is excited to showcase Amazon Lumberyard and Amazon GameLift at this year’s GDC. We’ve been hearing positive and helpful feedback since our launch last month and will be discussing new features and improvements based on that feedback. Our booth is located in the Main Hall #1224, and we are eager to meet and talk to you.

We are also hosting a Lumberyard Track for Developer Day on Tuesday, March 15, 10:00 am to 5:00 pm, Room 2000 in the West Hall. Below is the full schedule and descriptions of our sessions. We designed these sessions to help game developers of all levels learn about our tools and services. We hope to see you there!

 


 

GDC DEVELOPER DAY SCHEDULE:

10:00 am – 11:00 am

Amazon Lumberyard and Amazon GameLift – Building Blocks to Create Great Games and Build Communities

Eric Schenk, General Manager, Lumberyard

Chris Dury, Director, Amazon Web Services

This session introduces the tools and services that will help you build on the shoulders of Amazon commerce, AWS, and Twitch, and make and deliver experiences that garner vibrant communities of passionate fans. We will provide an insider view into game technologies we’re building at Amazon, show examples of game innovations with Twitch and AWS, and introduce the features of Lumberyard and Amazon GameLift. Beginner/Intermediate

Eric Schenk has developed game technology and led game technology teams for the last 20 years. He is responsible for building client and server technology that enables game developers to build great games and content that leverage cloud services. Chris Dury is responsible for building and growing cloud services for game developers, including Amazon GameLift.

 

11:20 am – 12:20 pm

HDR Rendering in Lumberyard

Hao Chen, Senior Principal Software Engineer, Lumberyard

Take an in-depth look at the HDR rendering pipeline of Amazon Lumberyard. This session will provide an overview about Lumberyard’s rendering pipeline and emerging HDR standards. It will also deep dive into an HDR demo, highlighting content production, lighting, material and post processing techniques that work together to deliver spectacular visuals on the next generation HDR TVs. Beginner/Intermediate.

Hao Chen has led graphics R&D and game engine development for nearly 20 years at a number of game companies, including Bungie, Microsoft, and SingleTrac.

 

12:20 pm – 1:20 pm (Lunch Provided)

Scale Session-based Multiplayer Games with Amazon GameLift

Chris Byskal, Sr. Software Development Manager, Amazon GameLift

Geoff Pare, Principal Engineer, Amazon Web Services

In this session, Amazon engineers will introduce Amazon GameLift core concepts, complete a step-by-step walkthrough of deploying a multiplayer game to the cloud, and demonstrate rapidly scaling a game based on player demand. Intermediate/Advanced.

Chris Byskal has software development experience spanning the video game and distributed computing fields. His specialties include character animation, gameplay, game engine tooling and high-availability, fault tolerant, distributed systems. Geoff Pare has spent the last 10 years at Amazon building and operating distributed systems. Geoff specializes in infrastructure management at scale, and Amazon GameLift combines his love of gaming with cloud computing. 

 

1:20 pm – 2:20 pm

Built for Broadcasting

The coming era of game design for interactive live video communities

Brooke Van Dusen, Director of Game Developer Success, Twitch

While it’s tough to argue the influence game broadcasters have had on the success of many of today’s new releases, how does one create a game that’s worth broadcasting? More generally, what does it actually mean to build a game for a live video and chat community?  This session will look at the live video ecosystem, exploring the different ways broadcasters have integrated game systems as a part of their everyday communities and how developers are taking cues from these implementations to design new and unique games for video platforms. Beginner/Intermediate.

Brooke Van Dusen is Twitch’s Director of Game Developer Success, where he works with game studios interested in leveraging the Twitch platform as a central part of their growth and engagement strategies. 

 

 

2:40 pm – 3:40 pm

Game Architecture and Component Systems in Lumberyard

Bill Merrill, Sr. Engineer, Lumberyard

Rosen Baklov, Principal Engineer, Lumberyard

As the complexity of building games increases, game developers look to their technology to simplify complex problems and maximize productivity. To provide a solid foundation for the future, we have evolved our approach to engine modules, game systems, and game object components and entities. This talk provides an overview of how we have combined hierarchical data management, modern workflows, advanced asset management, messaging and reflection to enable developers to easily extend and customize Lumberyard. Intermediate/Advanced.

Bill Merrill has been a professional software engineer for the game industry building experience in nearly all areas of game development and technology including pipelines, tools, gameplay systems, physics, networking, optimization, and especially AI and animation. Rosen Baklov is a principle engineer at Amazon. Rosen is the architect of many large systems shared across  game teams, and he’s especially excited to advance Lumberyard’s core systems, pipeline, networking and physics.

 

4:00 pm – 5:00 pm

Building Cloud-Connected Games using Lumberyard’s Cloud Canvas

James Clarendon, Sr.  Software Development Manager, Lumberyard

It’s no longer enough to build a game that has cutting-edge graphics or Hollywood production values.  Customers are looking for games that allow them to connect with friends and community, but game developers are often at a loss as to how to get started building features to fulfill that need. Amazon Lumberyard’s Cloud Canvas empowers developers to leverage services such as databases, data storage, and methods to execute game logic within Amazon Web Services (AWS) without needing to configure or maintain servers.  Cloud Canvas makes these resources accessible to non-engineers and helps content creators incorporate cloud-connected features directly into their game via the Lumberyard visual scripting system. We will provide an overview of the features of Cloud Canvas, including cloud resource management, the designer interface, and a deep dive on how to build your own unique cloud-connected features. Intermediate/Advanced.

James Clarendon has worked as an engineer, designer, and creative lead on titles such as Star Wars: The Force Unleashed II, Ghostbusters: The Video Game, Thief: Deadly Shadows, and Deus Ex: Invisible War. He aspires to bridge the gap between design and engineering to enable easy access to the cloud for game designers.


For more information on our Developer Day, please visit the GDC 2016 Conference page.

New, more compact, Lumberyard install

by Eric Schenk | on | | Comments

As J.C. mentioned in his Lumberyard Blog post last week, we have been enthusiastically reading your feedback. One of the top requests we’ve heard is for a smaller, more manageable download. Today we are releasing an updated and more compact Lumberyard release. You can download it here. We have trimmed away some fat, and removed a couple of things that are only needed in rare circumstances. The result is a new, more compact release weighing in at 5.7 GB. The full release is still available on our previous version’s download page here. If you want to rebuild our code generation tool, AzCodeGenerator, you will need the full release, which includes a modified version of the Clang. In future releases we will make it possible to get the code and binaries needed to rebuild AZCodeGenerator independently. In the meantime, those of you who have been having trouble fetching the original release may find the new package easier to download. If you are one of those customers who could not get Lumberyard, please try this and let us know how it works for you. We are also working on a more robust solution with a small initial download. In the meantime, we wanted to get something into your hands as quickly as possible.

As always, there is more to come. Please keep the feedback coming! We are listening.