Skip to content

Instantly share code, notes, and snippets.

@azriel91
Last active October 25, 2018 07:33
Show Gist options
  • Select an option

  • Save azriel91/72388ee2d47c0b1cb52284ad33bab8a9 to your computer and use it in GitHub Desktop.

Select an option

Save azriel91/72388ee2d47c0b1cb52284ad33bab8a9 to your computer and use it in GitHub Desktop.
Object configuration animation problem

In Amethyst, "animation" does not simply mean visual animation; it means any sort of data that can morph over a certain input value such as time.

When using Amethyst, animation is designed to be done per Component, e.g. we can morph the SpriteRender, or alter the local Transform component. Therefore, if you structure your application's configuration with a different data hierarchy, you should process it into the Component type.

In Will's game configuration, Every object has a series of Sequences, each sequence has a Vec<ObjectFrame>.

Each ObjectFrame contains multiple parts:

  • Sprite
  • Body
  • Interactions
  • Potentially more, such as weapon position

These are intended to change frame by frame, in sync with each other.

The question arises, should we have ObjectFrame as a Component, which means we have a single Animation<ObjectFrame>, or should we create Components for each of these configuration parts?

A top level Animation<ObjectFrame> means, when we add separate configuration parts, we do not need to create separate Component types for each of these parts. Systems that use a configuration part will access it either via ReadStorage<'s, ObjectFrame>, or there must be an intermediate system that reads the ObjectFrames and writes the individual Components for all entities. Note that this design means animation is strictly Step interpolated, so each part is discreetly calculated.

Separate Components means writing separate Animation<_> types for each component, and processing the configuration into those types. Each of the animations are run at the same time to keep them in sync with each other (same time input value). Systems that use a configuration part will access it via ReadStorage<'s, Component>. This design allows separate components to have separate interpolation. However, if Components are all going to be Step interpolated, then this introduces a lot of additional effort for which the value is not applicable.

The following table compares the development implications for the two design choices:

Item Frame Component Animation Multi Component Animation
Effort - Addition Lower Higher - process config into Component
Performance No duplication of interpolation Duplicates interpolation
Performance Bottleneck with splitter System -
Performance Poor data locality for systems Good data locality (read component)
System Data Unclear if no splitter system Clear
Compilation Extra(?) if no splitter system Generation of animation component types

There may be more that I haven't thought of right now.

Animation primitives are Copy + Serializable, which means we cannot simply pass references to the active ObjectFrame or component. This means we may have to generate a HashMap<u64, _>, where _ is either &ObjectFrame or &Component, or Handles to each, in order to not clone() the data in memory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment