-
Notifications
You must be signed in to change notification settings - Fork 3
Falcon Overview and Goals
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.
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.
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.
- Editable and static text fields:
- Center, left, justify, and right alignments
- Falcon HTML Formatting
- 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.
- ActionScript 3
- Anti-aliased shapes
- Advanced blend modes other than Normal and Additive.
- Filters
- Shape Morphs
- Stroke
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).
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.
Components of Falcon that contribute to high efficiency scene graph evaluation and rendering.
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.
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.
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.
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.
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
.
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.