Developer Guide (Version 1.12)

Slices and Dynamic Slices

The Component Entity System is currently in preview and is undergoing active development. It will replace the legacy Legacy Entity System.

A slice is a collection of configured entities that is stored as a single unit in a reusable asset. You can use slices to conveniently group entities and other slices for reuse. Slices are similar to prefabs but are part of the new Component Entity system. Slices can contain component entities, whereas prefabs cannot. Unlike prefabs, slices can be nested into a fully cascasding hierarchy. For example, a level, a house, a car, and an entire world are all slices that depend on (cascade) from a number of other slices.

You can generate a slice asset that contains any number of entities that you have placed and configured. These entities can have arbitrary relationships. For example, they can exist in a parent/child transform hierarchy, although this is not required.

After you have created the slice asset, you can use the editor to instantiate the slice asset in your worlds, either by right-clicking in the viewport and choosing Instantiate Slice, or by dragging a slice asset into the viewport directly from the Asset Browser. Just as with standard prefab systems, you can then modify the entities in your slice instance. You can optionally push the changes back to the slice asset, which will affect all instances of that slice asset, as well as any other slices cascading from it.

A slice can contain instances of other slices. Modifications of a slice instance within another slice causes the changes to be stored in the instance as overrides (in the form of a data differential or delta). The modifications stored can be changes such as entity additions, entity removals, or component property changes.

Anatomy of a Slice

The following diagram illustrates an example slice A, which contains references to two other slices B and C. Slice A has two instances each of B and C:

        Anatomy of an example slice

Each instance contains a data patch, which may be empty if no changes or overrides are present. If the instantiation of slice B in slice A has been modified in comparison with the source asset B, the data patch contains the differences. When slice A is instantiated again, it contains instances of slice B, but with the modifications applied. Any nonoverridden fields propagate through the hierarchy. If you change a property value in the slice B asset on disk, the instance of B contained in slice A will reflect that change — if the property for that instance has not already been overridden, as reflected in the instance's data patch.

In addition to references to other slices, slices can contain zero or more entities. These entities are original to this slice and are not acquired through referenced slice instances. A slice does not have to contain references to other slices. A slice that contains only original entities (as represented by the bottom box in the diagram) and no references to other slices is called a leaf slice.

Working with Dynamic Slices

Slices are a powerful tool for organizing entity data in your worlds. In the editor, you can choose to cascade slices and organize entity data in any desired granularity and still receive the benefits of data sharing and inheritance throughout the hierarchy. A level-based game, for example, implements each level as its own slice asset that contains instances of many other slices. These slices can potentially cascade many levels deep. You can even choose to create slices from other slices and inherit only the elements that you want.

Standard slice assets (.slice files) rely on the editor and cannot be instantiated at run time. However, Lumberyard provides a mechanism for designating any .slice asset that you've built as a dynamic slice. When you designate a slice as a dynamic slice, the Asset Processor processes and optimizes the slice for you, producing a .dynamicslice file asset. A dynamic slice is simply the run-time version of its source slice, containing only run-time components; the editor-dependent components have been converted to their run-time counterparts. Furthermore, dynamic slices are flattened and no longer maintain a data hierarchy, as doing so would increase memory footprint and reduce instantiation performance.

In the level-based game example previously mentioned, you could designate your giant level slice as a dynamic slice. When your game loads the level, it does so by instantiating the resulting .dynamicslice file.

You can choose to generate dynamic slices at whatever granularity is appropriate for your game. Because slices are loaded entirely asynchronously, they are a good choice for streaming strategies. For example, a driving game might represent each city block as a separate slice and choose to load them predictively based on player driving behavior.

To generate a dynamic slice

Right-click any .slice asset in the Asset Browser, and click Set Dynamic Flag.

        Set the dynamic slice in the Asset Browser.

The Asset Processor processes the source .slice file and generates a .dynamicslice file. The new .dynamicslice file appears in the Asset Browser as its own asset:

        A newly created dynamic slice appears in the Asset Browser.

To remove the dynamic slice

Right-click the source .slice file and choose Unset Dynamic Flag.

The Asset Processor deletes the .dynamicslice file from the asset cache for you.

Instantiating Dynamic Slices

You can instantiate dynamic slices from your own components. To do so, reflect a DynamicSlice asset reference. You can populate the reference in the editor in the usual way, such as dragging a .dynamicslice asset from the Asset Browser onto your component’s reflected asset property. You can then use the following EBus call to instantiate the referenced dynamic slice at a desired location in the world.

// Asset reference member, which must be reflected. AZ::Data::Asset<AZ::DynamicPrefabAsset> m_sliceAsset; // Create an instance of the dynamic slice. AZ::Transform location = ...; EBUS_EVENT(AzFramework::GameEntityContextRequestBus, InstantiateDynamicSlice, m_sliceAsset, location);

Lumberyard includes a spawner component that is a good example of this behavior. You can use the spawner component directly or as an example from which to build your own.

        Assigning a .dynamicslice asset to the spawner

You can see the source code for the spawner component at the file location dev\Code\Engine\LmbrCentral\source\Scripting\SpawnerComponent.cpp in the folder in which you installed Lumberyard.

For information on creating an AZ::Module, see Creating an AZ Module. For more information about working with slices, see Working with Slices.