Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Consistent Game Development

across all Platforms
The Road to 

Starling 2.0
or:
How to turn a framework inside out

(whil...
Starling 1.x
• (quite) backwards-compatible since 2012
• Rock solid, but lots of small quirks
• Difficult to add new feature...
Starling 2.0
• A major rework is required!
• Rethink complete architecture
• Clean up inconsistencies
• But: keep all basi...
Meticulous Planning
Custom Batching
Clean Up APIs
Dynamic Lighting
Flexible Meshes
Release: Q1 2016
Simplify!
Easier to ex...
Kick-off
• Started development on July 24th, 2015
• All work done on a new branch (private)!
• That way, I could still fix ...
Start small
• It’s tempting to start with the big components.
• That way, you’ll end up with 

too many changes at once
• ...
Start small
• Instead, work bottom-up:

small components first, 

big components later
• Underlying building blocks

becom...
VertexData
• Stores information about each vertex:

position, texture coordinates, color
• Old class was very rigid





•...
VertexData
// format string defines per-vertex contents
vertexData = new VertexData("position:float2, color:bytes4");
vert...
Painter
• RenderSupport → Painter
• Wraps many Context3D methods
• Passed to all “render” methods
• Universally accessible...
Painter
override public function render(painter:Painter):void
{
}
Building Block #2:
painter.pushState(); // save a curren...
Effect
• Each Stage3D draw call requires a lot of set-up:
• shaders and buffers
• program constants
• context loss restorati...
Effect
// create effect
var effect:MeshEffect = new MeshEffect();
Building Block #3:
// configure effect
effect.mvpMatrix3D...
Effect
Effect position:float2
FilterEffect position:float2, texCoords:float2
MeshEffect position:float2, texCoords:float2, col...
Mesh & MeshBatch
• Basic “tangible” object in Starling 1: Quad
• Arguably the most important 2D object …
• … but shouldn’t...
// create geometry
var vertexData:VertexData = new VertexData();
vertexData.setPoint(0, "position", 0, 0);
vertexData.setP...
Run into Dead Ends
• Original idea: IMeshBatch interface
• Custom Rendering: write “batchers”
implementing this interface
...
MeshStyles
• The more flexible solution after the 

IMeshBatch dead-end
• Can be attached to any mesh

(composition instea...
// example: ColorOffsetStyle (tutorial)
var image:Image = new Image(texture);
var style:ColorOffsetStyle = new ColorOffset...
Follow ideas along the road
• “Sprite.flatten()” needed to be re-implemented
• When starting to work on that, I realized t...
Render Cache
• Starling keeps track of changes in the display tree
• Unmodified meshes can be drawn from cache
• Fewer mat...
Render Cache
Hide complexities
• no more “clipRect” 

→ instead, optimized masking with Quads
• TextField

→ supporting different font t...
Fix things 

you always hated
• Changed prefix of all member variables

mVariable → _variable
• … with the help of a small...
Fix things 

you always hated
• Now enforcing “premultipliedAlpha”
• via Fragment Shader
• Simplified a lot of areas
• Fix...
Fix things 

even if you’re hated for it ;)
• old TextField class had format settings 

directly on instance
• Hard to re-...
Admit when 

you’ve been stupid
• PixelSnapping 

prevents blurriness when object is not pixel-aligned
• I never came up w...
Write extensive 

commit messages
• When refactoring code, you often run into things
you know were important, but not: why...
• e.g. “February 2016”
• and keep it!
• Special hint: 

exploit Leap Years!
Promise a release date
Pro Tip:
One more thing …
• New (experimental) extension:

Cross-Texture-Batching
• Batches up to 4 textures in one draw call
• Ava...
That's it, folks!
Thanks for
watching!
Mail: daniel@gamua.com
Twitter: @PrimaryFeather
Upcoming SlideShare
Loading in …5
×

The Road to Starling 2

1,893 views

Published on

My presentation from the Flash Online Conference #13, showing how Starling 2 was created and explaining some of its new features.

Published in: Software
  • Be the first to comment

  • Be the first to like this

The Road to Starling 2

  1. 1. Consistent Game Development
 across all Platforms The Road to 
 Starling 2.0 or: How to turn a framework inside out
 (while staying sane) Daniel Sperl
  2. 2. Starling 1.x • (quite) backwards-compatible since 2012 • Rock solid, but lots of small quirks • Difficult to add new features 
 without major API changes • Underlying render architecture at its limit
  3. 3. Starling 2.0 • A major rework is required! • Rethink complete architecture • Clean up inconsistencies • But: keep all basic concepts intact
 (it’s still Starling, after all)
  4. 4. Meticulous Planning Custom Batching Clean Up APIs Dynamic Lighting Flexible Meshes Release: Q1 2016 Simplify! Easier to extend State Stack Scale9-Textures FilterChain Pro
 cra
 sti
 nate! Re
 lea
 se! Rough
  5. 5. Kick-off • Started development on July 24th, 2015 • All work done on a new branch (private)! • That way, I could still fix bugs in Starling 1.7
  6. 6. Start small • It’s tempting to start with the big components. • That way, you’ll end up with 
 too many changes at once • One class leads to the next! • Can you even compile?! • Hard to pinpoint problems Pro Tip:
  7. 7. Start small • Instead, work bottom-up:
 small components first, 
 big components later • Underlying building blocks
 become ready for your 
 rough plan • Work in baby steps: Each 
 commit must leave Starling 
 running! Pro Tip:
  8. 8. VertexData • Stores information about each vertex:
 position, texture coordinates, color • Old class was very rigid
 
 
 • Wanted: arbitrary per-vertex data • Important: fast (!) and easy to use Building Block #1: vertexData = new VertexData(); vertexData.setPosition(0, 50, 20); vertexData.setTexCoords(0, 1.0, 0.5); vertexData.setColor(0, 0xff00ff);
  9. 9. VertexData // format string defines per-vertex contents vertexData = new VertexData("position:float2, color:bytes4"); vertexData.setPoint(0, "position", 320, 480); vertexData.setColor(0, "color", 0xff00ff); // default format contains position, texCoords and color vertexData = new VertexData(); vertexData.setPoint(0, "position", 320, 480); vertexData.setPoint(0, "texCoords", 1.0, 0.5); vertexData.setColor(0, "color", 0xff00ff); Building Block #1:
  10. 10. Painter • RenderSupport → Painter • Wraps many Context3D methods • Passed to all “render” methods • Universally accessible (Starling.painter) • Keeps a stack of state changes Building Block #2:
  11. 11. Painter override public function render(painter:Painter):void { } Building Block #2: painter.pushState(); // save a current state on the stack painter.popState(); // restore previous state } painter.state.renderTarget = renderTexture; painter.state.alpha = 0.5; painter.state.transformModelviewMatrix(matrix); painter.prepareToDraw(); // apply all settings at context drawSomething(); // insert Stage3D rendering code here
  12. 12. Effect • Each Stage3D draw call requires a lot of set-up: • shaders and buffers • program constants • context loss restoration • The “Effect” class encapsulates all of this • Plus, it supports inheritance! Building Block #3:
  13. 13. Effect // create effect var effect:MeshEffect = new MeshEffect(); Building Block #3: // configure effect effect.mvpMatrix3D = painter.state.mvpMatrix3D; effect.texture = getHeroTexture(); effect.color = 0xf0f0f0; // upload vertex data effect.uploadIndexData(indexData); effect.uploadVertexData(vertexData); // draw! effect.render(0, numTriangles);
  14. 14. Effect Effect position:float2 FilterEffect position:float2, texCoords:float2 MeshEffect position:float2, texCoords:float2, color:bytes4 LightEffect position:float2, texCoords:float2, color:bytes4, normalTexCoords:float2 Building Block #3:
  15. 15. Mesh & MeshBatch • Basic “tangible” object in Starling 1: Quad • Arguably the most important 2D object … • … but shouldn’t be the only one. • New: Mesh allows arbitrary shapes • New: MeshBatch to batch meshes together Building Block #4: Mesh Quad Image MeshBatch
  16. 16. // create geometry var vertexData:VertexData = new VertexData(); vertexData.setPoint(0, "position", 0, 0); vertexData.setPoint(1, "position", 10, 0); vertexData.setPoint(2, "position", 0, 10); var indexData:IndexData = new IndexData(); indexData.addTriangle(0, 1, 2); // create Mesh var mesh:Mesh = new Mesh(vertexData, indexData); addChild(mesh); Mesh & MeshBatch Building Block #4:
  17. 17. Run into Dead Ends • Original idea: IMeshBatch interface • Custom Rendering: write “batchers” implementing this interface • Turned out to be too rigid: 
 uses inheritance → can’t apply to existing classes • Turned out to be too slow: 
 performance issue with AOT (fixed with AIR 21) • You’ll find more dead ends when browsing through the GitHub history ;-) Pro Tip:
  18. 18. MeshStyles • The more flexible solution after the 
 IMeshBatch dead-end • Can be attached to any mesh
 (composition instead of inheritance) • Allows customization of both 
 rendering and batching Building Block #5:
  19. 19. // example: ColorOffsetStyle (tutorial) var image:Image = new Image(texture); var style:ColorOffsetStyle = new ColorOffsetStyle(); style.redOffset = 0.5; image.style = style; MeshStyles Building Block #5: // example: LightStyle (extension) var normalMap:Texture = Texture.fromBitmap(…); var image:Image = new Image(texture); var style:LightStyle = new LightStyle(normalMap); style.light = new Light(); image.style = style;
  20. 20. Follow ideas along the road • “Sprite.flatten()” needed to be re-implemented • When starting to work on that, I realized that an automatic render-cache would be feasible • I gave it a try, and it worked out great! Pro Tip:
  21. 21. Render Cache • Starling keeps track of changes in the display tree • Unmodified meshes can be drawn from cache • Fewer matrix operations, method calls, loops • Only ByteArray.copy → upload → draw • Great for menus, business apps, etc. 
 (anything with often static content)
  22. 22. Render Cache
  23. 23. Hide complexities • no more “clipRect” 
 → instead, optimized masking with Quads • TextField
 → supporting different font types through
 ITextCompositor • Texture class 
 → many internal classes inheriting “Texture” Pro Tip:
  24. 24. Fix things 
 you always hated • Changed prefix of all member variables
 mVariable → _variable • … with the help of a small Ruby script:
 http://tinyurl.com/convert-members • Done very late in development 
 → easy “cherry-picking” between branches Pro Tip:
  25. 25. Fix things 
 you always hated • Now enforcing “premultipliedAlpha” • via Fragment Shader • Simplified a lot of areas • Fixed inconsistencies when switching 
 between ATF and PNG textures Pro Tip:
  26. 26. Fix things 
 even if you’re hated for it ;) • old TextField class had format settings 
 directly on instance • Hard to re-use format or pass around • new: TextFormat class, just like in Flash • … but sucks less! • Everybody upgrading to Starling 2 will have to change a LOT of code because of this. Pro Tip:
  27. 27. Admit when 
 you’ve been stupid • PixelSnapping 
 prevents blurriness when object is not pixel-aligned • I never came up with a good solution! • Now that it finally happened, and it’s just a few
 lines of code (see: MatrixUtil.snapToPixels) Pro Tip:
  28. 28. Write extensive 
 commit messages • When refactoring code, you often run into things you know were important, but not: why?! • Via “git blame”, you find the responsible commit • Clutters up the code less than inline comments Pro Tip:
  29. 29. • e.g. “February 2016” • and keep it! • Special hint: 
 exploit Leap Years! Promise a release date Pro Tip:
  30. 30. One more thing … • New (experimental) extension:
 Cross-Texture-Batching • Batches up to 4 textures in one draw call • Available here:
 http://wiki.starling-framework.org/extensions/cross-texture-batching // usage: Mesh.defaultStyle = MultiTextureStyle;
  31. 31. That's it, folks! Thanks for watching! Mail: daniel@gamua.com Twitter: @PrimaryFeather

×