Game Development 11 min read

Bone Animation Implementation in the Candy Game Engine

To add robust bone animation to the Candy game engine, the team selected DragonBone assets, built a custom Flutter runtime that parses editor data into a unified skeletal format, flattens the bone hierarchy into Z‑ordered slots, uses TweenSequence for transform tweens, achieves smooth performance up to about one thousand bones, and plans future Lottie support and interactive animation orchestration.

Xianyu Technology
Xianyu Technology
Xianyu Technology
Bone Animation Implementation in the Candy Game Engine

Bone animation is a technique that controls skeletal parameters to create multi‑frame animations, offering flexibility and smoothness compared to GIFs or sprite sheets. It is widely used in games and interactive applications, and the Candy engine needs robust support for it.

Tool selection : After evaluating Flutter‑compatible Flare (rejected due to unfamiliar .flr format) and the front‑end oriented Egret engine with DragonBone tools, the team chose DragonBone‑based assets and implemented a custom runtime for Flutter.

Basic concepts (Armature, Bone, Slot, DisplayData) are introduced, explaining how bones form a hierarchical tree and slots act as image containers.

Rendering strategy : To avoid parent‑child draw order issues, the bone tree is flattened into a Z‑ordered list of slots, each represented as a GameObject. Absolute positions are computed from relative bone transforms.

Architecture consists of three layers:

Parser layer – converts various editor outputs (e.g., DragonBone) into a unified skeletal data format.

Data layer – stores armature, bone, slot, display and animation data.

Render layer – treats each armature as a GameObject; slots become child GameObjects, and TransformComponents receive absolute coordinates for SpriteComponent rendering.

Animation implementation : Each bone’s animation is a combination of translation, rotation, scale, and opacity tweens. Flutter’s TweenSequence is used, where each TweenSequenceItem<Transform2> defines a tween and its weight (frame count). The following code parses a transform animation:

///Transform2 为自己定义的一个数据结构,只要重载了相应的运算符,一样可以被Animation所使用
TweenSequenceItem
_parseTransformAnimation(
    TransformFrame cur,
    TransformFrame next, {
    int duration,
}) {
  final Animatable
tween = Tween
(
    begin: cur.transForm,
    end: next.transForm,
  );
  if ((cur.duration != null && cur.duration > 0) ||
      (duration != null && duration > 0)) {
    return TweenSequenceItem
(
        tween: tween,
        weight: duration == null ? cur.duration?.toDouble() : duration.toDouble(),
    );
  }
  return null;
}

Performance tests on iPhone Xs show that rendering up to ~1000 bones maintains smooth frame rates, while exceeding 3000 bones leads to noticeable lag, which is acceptable for most in‑app mini‑games.

Future work includes extending support to Lottie animations and building a full interactive animation orchestration system that combines multiple animations with user‑driven logic.

Flutterperformancebone animationGame EngineTweenSequence
Xianyu Technology
Written by

Xianyu Technology

Official account of the Xianyu technology team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.