Skip to content

Falcon Overview and Goals

seoul-engine-public edited this page Sep 12, 2022 · 1 revision

What is Falcon?

Falcon is a .swf rendering and layout engine for game engines, developed by Demiurge Studios. It is similar in purpose to Iggy, Scaleform, and uniSWF.

Why Falcon?

Libraries such as Iggy and Scaleform, in pursuit of implementing a complete and correct SWF runtime, are expensive. Falcon was born from an observation that Demiurge Studios used only a small fraction of the capabilities of SWF for its game projects. As a result, we can make assumptions that Iggy and Scaleform cannot make, and therefore improve efficiency.

Finally, as of 2022, both Scaleform and apparently Iggy are end-of-life.

How is Falcon different?

The SWF runtime in Falcon does not play most SWFs. Instead, it plays SWFs that contain a limited feature set, sufficient for using SWF to build game UI, and it does so very efficiently, making use of assumptions and simplifications that are otherwise not possible in a feature complete SWF runtime.

If you're used to creating SWF content in (e.g.) Adobe Animate for use in game UI built on Scaleform or Iggy, then your workflow creating content for Falcon should remain essentially unchanged.

For engineers and anyone with experience authoring ActionScript 3, the experience is entirely different (in short: Seoul Engine does not use ActionScript 3). See A note on ActionScript for details.

Falcon Features

Supported

  • Editable and static text fields:
  • Mask layers
  • Shapes:
    • Straight and curved edges
    • Bitmap fill
    • Linear and radial gradient fill
    • Solid fill
  • TrueType fonts:
    • Anti-aliasing, outline, drop shadow via SDF rendering.
    • Gradient fill (top and bottom colors).
    • Text Effects
  • 9-slice scaling, including on shapes with bitmap fill (this is an extension over standard SWF runtimes).
  • Normal and Additive blend modes.

Not Supported

  • ActionScript 3
  • Anti-aliased shapes
  • Advanced blend modes other than Normal and Additive.
  • Filters
  • Shape Morphs
  • Stroke

A note on ActionScript

The lack of an ActionScript 3 VM in Falcon is the most notable departure from a standard SWF runtime like Iggy or Scaleform. All coding of UI behavior is done in C# (using SlimCS).

Falcon Minimal Actions

A limited subset of ActionScript 3.0 is supported, to support common authoring patterns. These include:

  • this.dispatchEvent(evt:Event)
  • this.dispatchEvent(evt:Event, bubble:Boolean)
  • this.gotoAndStop(label:String)
  • this.gotoAndStop(frame:Number)
  • this.gotoAndPlay(label:String)
  • this.gotoAndPlay(frame:Number)
  • this.stop()
  • this.play()
  • this.visible = false
  • this.visible = true

NOTE: The labeling above is deliberate. This limited set of actions are only supported when invoked on this.

For more information, extraction of ActionScript on the timeline is implemented in FalconCookerAVM2.cs.

Falcon Optimization Techniques

Components of Falcon that contribute to high efficiency scene graph evaluation and rendering.

Once only tesselation and gradient generation

SWF shapes are described as polygons, which are tesselated into triangles for rendering. In a fully compliant runtime, re-tesselation can occur at runtime to support (e.g.) shape morphs or smooth curves at arbitrary scales.

Falcon drops support for shape morphs and exploits this to tesselate once per shape. Similarly, gradient textures are computed once per gradient material.

Occlusion Culling

All textures in Seoul Engine include a conservative occlusion rectangle. This rectangle is the largest rectangle that can be fit to fully opaque pixels of the texture.

At runtime, Falcon uses this occlusion rectangle to avoid drawing subtrees of the scene graph that are completely occluded by large, opaque shapes.

For more information, see FalconRenderOcclusionOptimizer.cpp.

Dynamic Texture Atlas

In Falcon, both font glyphs and small bitmaps are stored in a single, dynamically managed texture atlas. This increases the size of batches by reducing render state changes. Also, text is rendered with SDFs (see also for example pixi-sdf-text), which reduces the pressure on the texture atlas from rendering text, allowing more to be used for small bitmaps.

For more information on the texture atlas, see FalconTextureCache.cpp and FalconTexturePacker.cpp.

For more information on SDF rendering, see MakeGlyphBitmapSDF and FalconTypes.cpp.

Batch Optimizer

By default, nodes in the Falcon graph are drawn back-to-front, to maintain Painter's algorithm ordering from the original SWF data. To increase batch sizes, Falcon applies a batch optimization pass that re-orders draw commands into larger batches, whenever that re-order would not violate the necessary ordering of draws to achieve correct rendering.

For more information, see FalconRenderBatchOptimizer.cpp.

One Simple Shader

Falcon uses tiers of pixel shaders, each which support the features of the lower tier. The most expensive shader supports SDF rendering with a color multiply and add. The Falcon rendering backend attempts to balance the size of batches (to decrease render state changes) against the screen space of a render operation (to avoid needlessly using the most expensive pixel shader on large areas of the screen).

For more information see the Falcon Shader Effect and CheckForStateChange.

Equivalent Draw Batching

Draw calls which use the same render states are merged into larger vertex and index buffers and fewer draw calls. This is facilitated by both the usage of a single large Dynamic Texture Atlas and One Simple Shader.