Torque 2D MIT (Part 1)
by Melv May · 01/25/2013 (2:54 am) · 8 comments
The following is a (hopefully) interesting, quite technical but important blog. It’s also pretty long and I hit the size limit for blogs so I’m having to split this up into three parts so for those of you who are not technically minded or simply don’t wish to spend the next half hour consuming this then here’s a quick video which you’ll find in context further down inside the blog:
Welcome to the 2013 Torque 2D MIT

Additionally, for all the 2D stuff and systems, all the script-binding stuff in C++ has been moved to its own file like this “SceneObject_ScriptBinding.h” and “CompositeSprite_ScriptBinding.h” rather than it being embedded inside the implementation of the type.
So with the house-keeping out of the way there were more important things to attend to. Whilst I don’t recall the order or the reason why I was given a green-flag (maybe I just pushed real hard and/or there was a critical need) there were several new features that I created from scratch.
I recall integrating Box2D and realizing that I had to spend nearly a week (oh my, a whole week on something that should be trivial) encoding things like collision-shapes and joints and lots of other stuff to be persisted.
So the solution was simple. I took a concept that I developed from an internal prototype engine that I worked on in 2011 that used a persistence model similar to XAML. In this case it didn’t need to be as complex as that prototype system (that system was in C# and used .Net reflection) but it still needed to provide enough so that persisting Torque objects required near-zero effort for users of type instances and developers of the types themselves and absolutely allow the handling of “custom” state containing potentially complex data.
So to that end I (re)created TAML: Torque Application Mark-up Language. Well, that’s what it originally stood for, now I’m not sure if it is an acronym or not as it seems more like a friends name now. It’s why I tend to refer to it as Taml and not TAML.
So Taml itself is a strategy, not a format. It essentially performs analysis on a SimObject and has the ability to understand specific things about it such as Torque fields, its children and custom persistence features etc. It performs that analysis during a fast compilation step and can then write the results out as either XML or Binary formats. Taml can also write that out to other formats should anyone so choose and obviously only if the target format can encode the compiled data i.e. JSON, YAML etc. Adding new formats is easy as Taml produces the compilation independent of the format being used so you only have to deal with processing the format stream.
So Taml has a pretty simple usage but provides a lot of automatic features.
Taml also supports children objects such as SceneObject in a Scene or SimObjects in a SimSet. Essentially if the objects implement the simple interface class TamlChildren then your object will work. Both Scene and SimSet do this.
The basic layout for a Taml XML file is this:
If I were to type the following into a file then ask Taml to read it:
There’s also custom collections i.e. custom serialization which uses named collections like so:
A final point about Taml is that it only persists stuff that is not at the default although you can ask for everything if you so desire. This means that when you persist a new object that you have not changed, it will only save the declaration to create the type. In XML mode this appears as a single element with no attributes or children. This not only reduces the size of the Taml files but also makes reading them faster as the reader does not end up reasserting state that is already at its default.
It sounds silly but one thing that’s important to achieve is to get a good frame-rate when the engine is essentially doing “nothing”. You don’t want a few hundred FPS when rendering an empty screen. After all the work that happened it ended up at around 7000+ FPS on my system:

The new system itself is pretty good and it’s certainly fast. The 2D rendering pipeline is now based upon a scene render-request set-up where potentially visible objects get to push render requests out to a batch renderer. These are then processed (sorted if appropriate and many other things) and then each request is processed for rendering. This unifies and centralizes all the 2D rendering and provides a batching system to boot. It enables features like setting the global rendering mode i.e. wireframe etc in a central location.

It also enables useful things like render requests being sorted amongst other render requests from various other objects i.e. all the render requests get put into a render queue and can be sorted together independent of where they came from.
A concrete example of this is a composite-sprite which is very powerful (I’ll discuss that later) and can push render requests for the sprites it contains. Any render request can be placed anywhere in 2D space, have an age (serial-Id), have a scene-layer and a scene-layer-depth (layer sub-depth) etc. The sort mode from the old T2D is now revamped and you can not only sort on a per-layer basis but on a per-object basis but what does a sort on a per-object mean? Well imagine a composite-sprite that has a bunch of isometric tiles and it has positioned each tile appropriately but also each tile has a scene-layer-depth set. You can tell the composite-sprite to sort by scene-layer-depth and it will have all its sprites rendered in that order. The thing is, that’s okay for a set of sprites that work as some kind of complex background but what about other sprites moving “within” that scene-layer-depth, in this case I want other sprites to move within the iso-sprites and be occluded by them if appropriate. Well, you can tell the sprite to NOT sort (which is the default) but have its sprites sorted as part of the main layer-sort. If you were to then add separate sprites in the scene then they will get sorted alongside the sprites from within the composite-sprite. If you move the sprites then they move within the composite sprite (as a tile-layer in this example).
This sounds complex but it’s really simple and it’s controlled by two methods: one controls whether the object is batch-isolated i.e. it is batched, sorted and rendered in an isolated way or if it’s not isolated and is batched, sorted and rendered with the rest of the scene layer.
Essentially then, SceneObjects now don’t render themselves, it’s scene-render-requests that are the mechanism to render. It means that anything can submit such a request and not just SceneObjects. A SceneObject is convenient as it is owned by the Scene but it has no special capabilities or exclusive domination on scene rendering.
As before you can sort each scene layer individually. There are however new sort modes:
Here’s an example of a simple set-up using the particle system where I tell it to emit 1000 particles per second with each particle living for 2 seconds obviously resulting in approximately 2000 particles active at any one time:

With batching on I’m getting just over 1600 fps but with it off I get 160 fps so in this example, that's an order of magnitude.

The batcher provides a lot of detail here showing the current, minimum and maximum for various metrics like triangles rendered, maximum triangles rendered in any draw-call, how many draw calls, why draw-calls were flushed i.e. what state change caused them etc. You can just see at the top with batching on it shows 1<1> (1 draw call with a maximum of 1 ever). With batching off, it shows 1992 draw calls (oh my, no wonder that’s slow). Performing draw-calls like that on on iPad and you’re asking for trouble.
So with batching on (this is obviously the default), the batcher will consume the requests until such a time that it decides that something that has been requested cannot be pushed as part of the current draw-call. In that case then it flushes it (draws it) and continues. The sorting outlined above controls the order that these render requests are pushed to the batcher.
So for instance, in “Newest” sort, the scene layer is sorted appropriately resulting in the oldest items being pushed all the way to the newest ones in that order so that newests are rendered last i.e. are in-front.. The batcher will continue to consume/flush as appropriate trying its best to reduce the number of draw calls as it goes. Internally the batcher keeps track of the render state like blending, texture-handles etc. For instance, if all the render requests pushed when in “Newest” mode use the same texture, blending etc then it will result in a single draw call! That’s nice, I just told it to sort by age but I managed to get a single draw call.
Now obviously, the age of the render request (age of the SceneObject in most cases) does not relate to the most optimal way to draw but the batcher will do its best but in this mode, the batcher operates in what is termed a “strict order” mode i.e. the batcher can do whatever it likes to optimize the drawing but it cannot change the order. This makes sense because the sort mode explicit wants the draw order to be by the objects age and it has to assume that some of these object overlap otherwise why would sort by age have been selected?
This is what the “Batch” sort-mode is for. It’s for when you don’t care about the order i.e. you don’t want a “strict” order but you want the best batching performance. When this is selected, the sort order is done so that contiguous render requests allow the batcher to keep the draw calls to a minimum.
In one of my tests I had a texture that contained some isometric tiles and an animated gorilla (this was from 3-Step Studio). It set-up a composite sprite and added all the tiles using its isometric layout feature. I then added a bunch of Sprite scene-objects so that they were at the appropriate position so they were sorted such that they sat on the tiles. The test was to ensure that everything that was rendered was done with a single draw call and that was the case. It didn’t matter that the “tiles” (sprites) were controlled by a Composite-Sprite or that the gorillas were controlled by Sprite scene-objects set to play animations. What matters to the rendering pipeline was that the sort-mode was set to sort appropriate and that as these requests were pushed to the batcher, it didn’t stall and require a flush (draw). This means that the whole scene was rendered using a single draw call. The jerkyness of the video wasn't T2D it was that this video was taken on a laptop and not my main PC and the capture software doesn't run as good. This was super-smooth in reality.
For scenes like this I get well over 1000+fps. When I turn-off batching I get less than 200 fps. Excessive draw calls were a pain in legacy T2D but now that problem has gone. This above video works perfectly on an iPad and iPhone without any issues.
Before I finish on this subject I’d like to highlight a couple more interesting sort modes. The “Group” sort mode allows you to sort the objects by an assigned group name. This is exposed by anything that uses render requests such as the SceneObject or CompositeSprite (sub-sprites). It allows you to specify an arbitrary render name and the sorting will be done via this. This allows you to sort by (say) “Projectiles” or “Aliens” or some other logical grouping of your choice.
Finally I’d like to mention the Z-Axis which may interest a few folks. I almost decided that we should just have a continuous Z-Axis in 2D but that would almost make it a 3D engine! Besides, you would lose the nice features of controlling which discrete layers rendered etc.
Instead, I decided that what we needed was the ability to control the ordering within a layer. You could do this in legacy T2D however over the years stuff got modified and it resulted in the layer-depth getting coupled with the mounting order and resulted in a lot of expensive and messy code. I ripped out all that nonsense immediately. Now, you can specify scene-depth explicitly or leave it at its default of zero. This has nothing to do with age, mounting etc. This allows you to move objects back/forward relative to other objects in the same layer. This is a continuous value with no bounds i.e. you can use any floating-point value, positive or negative. There are helper methods that allow you to also move an object forward/backward/to-back/to-front within the layer and they manipulate the scene-layer-depth exclusively and it doesn’t affect any other state.
This is what the Z-Axis & Inverse-Z-Axis are all about. You can choose whether to sort by that or not. It’s essentially layer “depth”.
Whilst I’ve not added this feature, it was requested internally to have the ability to specify a secondary or sub-sort so you could (say) sort by Age then Z-Axis. Whilst I have not added that, it’s easy to do because this sorting is in one location within the code, no matter what uses it. Right now, if you sort by any mode and the two objects are equivalent then they are sub-sorted by the immutable age. This keeps the objects stable and stops them from jumping in their render order.
As a final thing, here’s the full metrics overlay which provides you with information on the most vital systems. All this information is available to be dumped out to disk as well:

Part 2 of this blog can be found here.
Part 3 of this blog can be found here.
Welcome to the 2013 Torque 2D MIT
Part 1
Reorganization
Let’s start small. When I originally wrote the T2D engine it was a seriously productive couple of weekends! That produced most of the backbone of it (the flesh and muscles took a fair bit longer) and it was then that I decided that I needed to differentiate my code from the surrounding TGE codebase so I decided to use a “t2d” prefix. This seemed natural as I had already created a bunch of “fx”-prefixed stuff for TGE. I wish I had not done that but it was a good idea at the time. I’ve rectified that decision and now you have nice clean type names like:- Scene
- SceneObject
- Sprite
- CompositeSprite
- Scroller

Additionally, for all the 2D stuff and systems, all the script-binding stuff in C++ has been moved to its own file like this “SceneObject_ScriptBinding.h” and “CompositeSprite_ScriptBinding.h” rather than it being embedded inside the implementation of the type.
So with the house-keeping out of the way there were more important things to attend to. Whilst I don’t recall the order or the reason why I was given a green-flag (maybe I just pushed real hard and/or there was a critical need) there were several new features that I created from scratch.
Persistence
One such feature is persistence. I absolutely loathed the fact that many types were coupled with the knowledge of how to write TorqueScript. Having a type write-out code as its persistence method is silly/crackers/bonkers/insane. Sure, it can be compiled into a DSO for a slight performance increase but in the end, considering how these things were typically used, that (potential) gain was outweighed by the sheer craziness of having to wire types to write-out their own code. I wasted so much time wiring types to write their state using dynamic fields, each with their own method of separating the state i.e. do I use space-separated and how to I encode more complex data? Then, when reading the type in, I had to wire-up a method that was called so it could then interpret and perform expensive string operations to separate the state and restore it. Developers using such fields had to understand the subtle encoding for such a field as well. No consistency. Not good.I recall integrating Box2D and realizing that I had to spend nearly a week (oh my, a whole week on something that should be trivial) encoding things like collision-shapes and joints and lots of other stuff to be persisted.
So the solution was simple. I took a concept that I developed from an internal prototype engine that I worked on in 2011 that used a persistence model similar to XAML. In this case it didn’t need to be as complex as that prototype system (that system was in C# and used .Net reflection) but it still needed to provide enough so that persisting Torque objects required near-zero effort for users of type instances and developers of the types themselves and absolutely allow the handling of “custom” state containing potentially complex data.
So to that end I (re)created TAML: Torque Application Mark-up Language. Well, that’s what it originally stood for, now I’m not sure if it is an acronym or not as it seems more like a friends name now. It’s why I tend to refer to it as Taml and not TAML.
So Taml itself is a strategy, not a format. It essentially performs analysis on a SimObject and has the ability to understand specific things about it such as Torque fields, its children and custom persistence features etc. It performs that analysis during a fast compilation step and can then write the results out as either XML or Binary formats. Taml can also write that out to other formats should anyone so choose and obviously only if the target format can encode the compiled data i.e. JSON, YAML etc. Adding new formats is easy as Taml produces the compilation independent of the format being used so you only have to deal with processing the format stream.
So Taml has a pretty simple usage but provides a lot of automatic features.
// Create a scene and add a scene object. %scene = new Scene(); %sceneObject = new SceneObject(); %scene.add( %sceneObject ); // Write it out. TamlWrite( “scene1.taml”, %scene );Here’s what it produces:
<Scene> <SceneObject/> </Scene>Here's how to read it in:
// Read it in. %newScene = TamlRead( “scene1.taml” );If you want to use the built-in binary format then:
TamlWrite( “scene1.baml”, %scene ); %newScene = TamlRead( “scene1.baml” );If you notice above, I don’t specify the format as the examples use the Taml automatic file-type detection (based upon the file extension which you are free to change) but you can be explicit i.e.
TamlWrite( “scene1.xml”, %scene, “xml” ); TamlWrite( “scene1.bin”, %scene, “binary” );If you add other formats you might be doing something like:
TamlWrite( “scene1.json”, %scene, “json” ); TamlWrite( “scene1.json”, %scene );The TamlWrite & TamlRead are just helper functions. Taml is a type that you can create directly from the scripts like this:
// Create a Taml instance. %taml = new Taml(); // Set the format to 'binary' explicitly. %taml.setFormat( “binary” ); // Use binary compression for the smallest possible file-size. %taml.setBinaryCompression( true ); // Compress the binary stream. // Write out the file. %taml.write( %scene, “scene1.bin”, ); // Read it back in. %binaryScene = %taml.read( “scene1.bin” ); // Set the format to 'xml' explicitly. %taml.setFormat( “xml” ); // Write out the file. %taml.write( %scene, “scene1.xml” ); // Read it back in. %xmlScene = %taml.read( “scene1.xml” ); // Delete out Taml instance. %taml.delete();Taml has a lot of features and I won’t go into all of them now. but some important ones are the ability to persist a “graph” of objects and keep the object relationships intact. For instance, if I persist a SimSet that contains hundreds of other SimObjects and some of those objects refer to each other then all those references will be persisted correctly, automatically.
Taml also supports children objects such as SceneObject in a Scene or SimObjects in a SimSet. Essentially if the objects implement the simple interface class TamlChildren then your object will work. Both Scene and SimSet do this.
The basic layout for a Taml XML file is this:
<TypeName
Type Field=”<FieldValue>”
Type Field=”<FieldValue>”>
<Child TypeName
Child Type Field=”<FieldValue>”
Child Type Field=”<FieldValue>”
</Child TypeName>
</TypeName>Elements are used to denote a type, attributes are a Torque-Field. Children can be any SimObject.If I were to type the following into a file then ask Taml to read it:
<SimSet> <ScriptObject Player=”Mich” Score=”10000”/> <ScriptObject Player=”Melv” Score=”9000”/> <ScriptObject Player=”Dave” Score=”8000”/> </SimSet>… then you’d have a SimSet that contains a bunch of ScriptObjects each containing two fields of “Player” and “Score”. Looks like Mich wins again dammit!
There’s also custom collections i.e. custom serialization which uses named collections like so:
<TypeName>
<TypeName.CollectionName>
<TypeAlias Field=””/>
</TypeName.CollectionName>
</Type>As a real example, let’s look at a SceneObject derived type “Sprite” persisting its collision shapes using this feature. In this case it uses the custom collection name of "CollisionShapes":<Sprite>
<Sprite.CollisionShapes>
<Circle Radius=”3” Sensor=”true” />
<Polygon Friction=”0.5” Density=”1” Restitution=”1”
Point0 = “0 0”
Point1 = “1 0”
Point2 = “0.5 1"/>
<Edge
Point0 = “1 0”
Point1=”2 0”/>
</Sprite.CollisionShapes>
</Sprite>So that’s a fair bit of detail but in the end, persisting types is now really easy and produces consistent results. You can read/write in an XML or BINARY format (binary even supports compression and encryption is easy to add). When it comes time to publish your game you can persist these as binary to make them smaller and obviously obfuscate them. With the automatic file-type detection you don’t need to modify your scripts to read the new types, Taml will do that automatically.A final point about Taml is that it only persists stuff that is not at the default although you can ask for everything if you so desire. This means that when you persist a new object that you have not changed, it will only save the declaration to create the type. In XML mode this appears as a single element with no attributes or children. This not only reduces the size of the Taml files but also makes reading them faster as the reader does not end up reasserting state that is already at its default.
Rendering Pipeline
So the rendering “pipeline” in the old Torque wasn’t so much of a pipeline but a set of curved, cross-connecting pipes with patches and taps all over the place. I wanted to fix this and as much as I wanted to completely rewrite the whole graphics infrastructure from the ground-up, that wasn’t going to get sanctioned easily. What I did manage to get done was rewriting all of the graphics pipeline that related to the 2D system. This was tasked as “Batch Rendering” but to facilitate that, it had to be a whole lot more.It sounds silly but one thing that’s important to achieve is to get a good frame-rate when the engine is essentially doing “nothing”. You don’t want a few hundred FPS when rendering an empty screen. After all the work that happened it ended up at around 7000+ FPS on my system:

The new system itself is pretty good and it’s certainly fast. The 2D rendering pipeline is now based upon a scene render-request set-up where potentially visible objects get to push render requests out to a batch renderer. These are then processed (sorted if appropriate and many other things) and then each request is processed for rendering. This unifies and centralizes all the 2D rendering and provides a batching system to boot. It enables features like setting the global rendering mode i.e. wireframe etc in a central location.

It also enables useful things like render requests being sorted amongst other render requests from various other objects i.e. all the render requests get put into a render queue and can be sorted together independent of where they came from.
A concrete example of this is a composite-sprite which is very powerful (I’ll discuss that later) and can push render requests for the sprites it contains. Any render request can be placed anywhere in 2D space, have an age (serial-Id), have a scene-layer and a scene-layer-depth (layer sub-depth) etc. The sort mode from the old T2D is now revamped and you can not only sort on a per-layer basis but on a per-object basis but what does a sort on a per-object mean? Well imagine a composite-sprite that has a bunch of isometric tiles and it has positioned each tile appropriately but also each tile has a scene-layer-depth set. You can tell the composite-sprite to sort by scene-layer-depth and it will have all its sprites rendered in that order. The thing is, that’s okay for a set of sprites that work as some kind of complex background but what about other sprites moving “within” that scene-layer-depth, in this case I want other sprites to move within the iso-sprites and be occluded by them if appropriate. Well, you can tell the sprite to NOT sort (which is the default) but have its sprites sorted as part of the main layer-sort. If you were to then add separate sprites in the scene then they will get sorted alongside the sprites from within the composite-sprite. If you move the sprites then they move within the composite sprite (as a tile-layer in this example).
This sounds complex but it’s really simple and it’s controlled by two methods: one controls whether the object is batch-isolated i.e. it is batched, sorted and rendered in an isolated way or if it’s not isolated and is batched, sorted and rendered with the rest of the scene layer.
Essentially then, SceneObjects now don’t render themselves, it’s scene-render-requests that are the mechanism to render. It means that anything can submit such a request and not just SceneObjects. A SceneObject is convenient as it is owned by the Scene but it has no special capabilities or exclusive domination on scene rendering.
As before you can sort each scene layer individually. There are however new sort modes:
- Off - No sorting.
- Newest - The newest render request (typically the age of the SceneObject) is rendered in front
- Oldest - The oldest render request (typically the age of the SceneObject) is rendered in front
- Batch - Sorted so that the absolute minimum number of draw-calls are required.
- Group - Sorted by each objects’ assigned render group name.
- X - Sort so that things further along the X-Axis are rendered in front
- Y - Sort so that things further along the Y-Axis are rendered in front
- Z - Sort so that things further along the Z-Axis are rendered in front
- -X - Sort so that things further along the X-Axis are rendered at the back
- -Y - Sort so that things further along the Y-Axis are rendered at the back
- -Z - Sort so that things further along the Z-Axis are rendered at the back
Here’s an example of a simple set-up using the particle system where I tell it to emit 1000 particles per second with each particle living for 2 seconds obviously resulting in approximately 2000 particles active at any one time:

With batching on I’m getting just over 1600 fps but with it off I get 160 fps so in this example, that's an order of magnitude.

The batcher provides a lot of detail here showing the current, minimum and maximum for various metrics like triangles rendered, maximum triangles rendered in any draw-call, how many draw calls, why draw-calls were flushed i.e. what state change caused them etc. You can just see at the top with batching on it shows 1<1> (1 draw call with a maximum of 1 ever). With batching off, it shows 1992 draw calls (oh my, no wonder that’s slow). Performing draw-calls like that on on iPad and you’re asking for trouble.
So with batching on (this is obviously the default), the batcher will consume the requests until such a time that it decides that something that has been requested cannot be pushed as part of the current draw-call. In that case then it flushes it (draws it) and continues. The sorting outlined above controls the order that these render requests are pushed to the batcher.
So for instance, in “Newest” sort, the scene layer is sorted appropriately resulting in the oldest items being pushed all the way to the newest ones in that order so that newests are rendered last i.e. are in-front.. The batcher will continue to consume/flush as appropriate trying its best to reduce the number of draw calls as it goes. Internally the batcher keeps track of the render state like blending, texture-handles etc. For instance, if all the render requests pushed when in “Newest” mode use the same texture, blending etc then it will result in a single draw call! That’s nice, I just told it to sort by age but I managed to get a single draw call.
Now obviously, the age of the render request (age of the SceneObject in most cases) does not relate to the most optimal way to draw but the batcher will do its best but in this mode, the batcher operates in what is termed a “strict order” mode i.e. the batcher can do whatever it likes to optimize the drawing but it cannot change the order. This makes sense because the sort mode explicit wants the draw order to be by the objects age and it has to assume that some of these object overlap otherwise why would sort by age have been selected?
This is what the “Batch” sort-mode is for. It’s for when you don’t care about the order i.e. you don’t want a “strict” order but you want the best batching performance. When this is selected, the sort order is done so that contiguous render requests allow the batcher to keep the draw calls to a minimum.
In one of my tests I had a texture that contained some isometric tiles and an animated gorilla (this was from 3-Step Studio). It set-up a composite sprite and added all the tiles using its isometric layout feature. I then added a bunch of Sprite scene-objects so that they were at the appropriate position so they were sorted such that they sat on the tiles. The test was to ensure that everything that was rendered was done with a single draw call and that was the case. It didn’t matter that the “tiles” (sprites) were controlled by a Composite-Sprite or that the gorillas were controlled by Sprite scene-objects set to play animations. What matters to the rendering pipeline was that the sort-mode was set to sort appropriate and that as these requests were pushed to the batcher, it didn’t stall and require a flush (draw). This means that the whole scene was rendered using a single draw call. The jerkyness of the video wasn't T2D it was that this video was taken on a laptop and not my main PC and the capture software doesn't run as good. This was super-smooth in reality.
For scenes like this I get well over 1000+fps. When I turn-off batching I get less than 200 fps. Excessive draw calls were a pain in legacy T2D but now that problem has gone. This above video works perfectly on an iPad and iPhone without any issues.
Before I finish on this subject I’d like to highlight a couple more interesting sort modes. The “Group” sort mode allows you to sort the objects by an assigned group name. This is exposed by anything that uses render requests such as the SceneObject or CompositeSprite (sub-sprites). It allows you to specify an arbitrary render name and the sorting will be done via this. This allows you to sort by (say) “Projectiles” or “Aliens” or some other logical grouping of your choice.
Finally I’d like to mention the Z-Axis which may interest a few folks. I almost decided that we should just have a continuous Z-Axis in 2D but that would almost make it a 3D engine! Besides, you would lose the nice features of controlling which discrete layers rendered etc.
Instead, I decided that what we needed was the ability to control the ordering within a layer. You could do this in legacy T2D however over the years stuff got modified and it resulted in the layer-depth getting coupled with the mounting order and resulted in a lot of expensive and messy code. I ripped out all that nonsense immediately. Now, you can specify scene-depth explicitly or leave it at its default of zero. This has nothing to do with age, mounting etc. This allows you to move objects back/forward relative to other objects in the same layer. This is a continuous value with no bounds i.e. you can use any floating-point value, positive or negative. There are helper methods that allow you to also move an object forward/backward/to-back/to-front within the layer and they manipulate the scene-layer-depth exclusively and it doesn’t affect any other state.
This is what the Z-Axis & Inverse-Z-Axis are all about. You can choose whether to sort by that or not. It’s essentially layer “depth”.
Whilst I’ve not added this feature, it was requested internally to have the ability to specify a secondary or sub-sort so you could (say) sort by Age then Z-Axis. Whilst I have not added that, it’s easy to do because this sorting is in one location within the code, no matter what uses it. Right now, if you sort by any mode and the two objects are equivalent then they are sub-sorted by the immutable age. This keeps the objects stable and stops them from jumping in their render order.
As a final thing, here’s the full metrics overlay which provides you with information on the most vital systems. All this information is available to be dumped out to disk as well:

Part 2 of this blog can be found here.
Part 3 of this blog can be found here.
About the author
#2
01/25/2013 (3:07 pm)
Great read. You identified several issues's and tackled them like a boss, and made it Torque 2D more simpler to work with.
#3
01/26/2013 (6:02 am)
Love this kind of stuff! Can't wait to start working with this.
#4
I have a question about using one draw call in the example of gorillas and tiles:
Now if I follow you, even though the tiles in the tilemap are all one composite sprite, you can have them "dispersed" and drawn as if they were individual sprites in the layer. So you can sort them in with the gorillas.
And if I follow you futher, if you have one texture (and blend mode) for a lot of sprites, you can batch them and render them all at once. (glBegin(QUADS)?)
However, can I assume the gorilla's animated texture and the tilemap texture are different texture maps, so wouldn't it "flush" every time you switch between drawing a patch of gorillas and draw a patch of tiles?
02/03/2013 (5:16 pm)
@Melv. Thanks for the blog!I have a question about using one draw call in the example of gorillas and tiles:
Now if I follow you, even though the tiles in the tilemap are all one composite sprite, you can have them "dispersed" and drawn as if they were individual sprites in the layer. So you can sort them in with the gorillas.
And if I follow you futher, if you have one texture (and blend mode) for a lot of sprites, you can batch them and render them all at once. (glBegin(QUADS)?)
However, can I assume the gorilla's animated texture and the tilemap texture are different texture maps, so wouldn't it "flush" every time you switch between drawing a patch of gorillas and draw a patch of tiles?
#5
My two cents is that I wish, while things were getting cleaned up, you could end the array kludge once and for all. In your example,
[pre]
<Sprite>
<Sprite.CollisionShapes>
<Circle Radius=â3â Sensor=âtrueâ />
<Polygon Friction=â0.5â Density=â1â Restitution=â1â
Point0 = â0 0â
Point1 = â1 0â
Point2 = â0.5 1"/>
<Edge
Point0 = â1 0â
Point1=â2 0â/>
</Sprite.CollisionShapes>
</Sprite>
[/pre]
There's that damnable Point0 Point1 stuff! Perhaps there's a way to create a "collection" of things without them being script objects? I realize in this example that the Points are "attributes" of the Polygon element, but I've missed a way to in/output an array for a while. TorqueScript supports them, kind of, after all.
02/03/2013 (5:23 pm)
Taml looks like a fine solution for an output format. (Although I admit I'll miss having a language-based one out of the box, because that's always cool.)My two cents is that I wish, while things were getting cleaned up, you could end the array kludge once and for all. In your example,
[pre]
<Sprite>
<Sprite.CollisionShapes>
<Circle Radius=â3â Sensor=âtrueâ />
<Polygon Friction=â0.5â Density=â1â Restitution=â1â
Point0 = â0 0â
Point1 = â1 0â
Point2 = â0.5 1"/>
<Edge
Point0 = â1 0â
Point1=â2 0â/>
</Sprite.CollisionShapes>
</Sprite>
[/pre]
There's that damnable Point0 Point1 stuff! Perhaps there's a way to create a "collection" of things without them being script objects? I realize in this example that the Points are "attributes" of the Polygon element, but I've missed a way to in/output an array for a while. TorqueScript supports them, kind of, after all.
#6
Writing TorqueScript is still there. If the objects state entirely consists of just static/dynamic fields then you can still do that if you wish.
So yeah, that was just an example, they are neither Torque fields nor ScriptObjects etc. They are just state inside an object not directly exposed as fields but via methods for the scripts. This is a custom persistence for the Collision-Shapes collection and is not limited by any array/field set-up.
The collection you mention is actually already there, at least partly, in the form of the collision-shapes themselves i.e. the "CollisionShapes" contains a collection of alias i.e. "Circle", "Polygon", "Chain", "Edge" etc. I do understand you were referring to the deeper structure there though but wanted to highlight this.
You could have (say):
<Point X="100" Y="200"/>
... but it was felt by those who were consuming it then (3SS Team) that an attribute for each point was nicer and less verbose. I put it out to a vote and that is what was chosen. It's actually one of the few times this appears (might be the only time, need to check that).
Certainly, nothing forces you down this route as a standard. I tend to be more verbose so a personal preference of mine would be to use elements per point as above.
Three are limits however (albeit not for this discussion here) and I've actually wanted to modify the Taml custom persistence stuff to make it more flexible in certain areas however time simply has not allowed me to do so. When it's open-source however, the sky's the limit!
02/04/2013 (12:10 am)
@Charlie:Writing TorqueScript is still there. If the objects state entirely consists of just static/dynamic fields then you can still do that if you wish.
So yeah, that was just an example, they are neither Torque fields nor ScriptObjects etc. They are just state inside an object not directly exposed as fields but via methods for the scripts. This is a custom persistence for the Collision-Shapes collection and is not limited by any array/field set-up.
The collection you mention is actually already there, at least partly, in the form of the collision-shapes themselves i.e. the "CollisionShapes" contains a collection of alias i.e. "Circle", "Polygon", "Chain", "Edge" etc. I do understand you were referring to the deeper structure there though but wanted to highlight this.
You could have (say):
<Point X="100" Y="200"/>
... but it was felt by those who were consuming it then (3SS Team) that an attribute for each point was nicer and less verbose. I put it out to a vote and that is what was chosen. It's actually one of the few times this appears (might be the only time, need to check that).
Certainly, nothing forces you down this route as a standard. I tend to be more verbose so a personal preference of mine would be to use elements per point as above.
Three are limits however (albeit not for this discussion here) and I've actually wanted to modify the Taml custom persistence stuff to make it more flexible in certain areas however time simply has not allowed me to do so. When it's open-source however, the sky's the limit!
#7
In answer to your previous post, yeah, that was a really old video where everything being rendered was on the same texture. It's not using "glBegin/glEnd" etc however.
At the time when I was writing the new rendering system I had a texture with a lot of crazy stuff in it just to ensure that the best case was always a single draw-call.
How many draw-calls you get depend obviously on not only this but other potential state-changes such as texture-blending and color etc. Whatever you have, I wanted to highlight that it can achieve the best-case if you tailor it to do so and can perform the "best possible" when things are less than optimal.
If the gorilla was in a separate texture and the ISO sprites were in (say) back-to-font depth-sort (Z) then continuous sets of tiles would be batched in z-order until a "gorilla" was encountered then that would cause a flush (draw-call) and it would continue.
How many draw-calls you ended-up with would obviously be down to the set-up but you can know that, should it be possible (given the sort you requested) to batch-up sprites together, it will do so automatically.
You have fine-grained control on this and it actually becomes part of the scene design. If all your projectiles are on the same layer (or even just on the same scene-layer-depth) then you are allowing the batching to perform its magic.
Hope this helps.
02/04/2013 (12:23 am)
@Charlie:In answer to your previous post, yeah, that was a really old video where everything being rendered was on the same texture. It's not using "glBegin/glEnd" etc however.
At the time when I was writing the new rendering system I had a texture with a lot of crazy stuff in it just to ensure that the best case was always a single draw-call.
How many draw-calls you get depend obviously on not only this but other potential state-changes such as texture-blending and color etc. Whatever you have, I wanted to highlight that it can achieve the best-case if you tailor it to do so and can perform the "best possible" when things are less than optimal.
If the gorilla was in a separate texture and the ISO sprites were in (say) back-to-font depth-sort (Z) then continuous sets of tiles would be batched in z-order until a "gorilla" was encountered then that would cause a flush (draw-call) and it would continue.
How many draw-calls you ended-up with would obviously be down to the set-up but you can know that, should it be possible (given the sort you requested) to batch-up sprites together, it will do so automatically.
You have fine-grained control on this and it actually becomes part of the scene design. If all your projectiles are on the same layer (or even just on the same scene-layer-depth) then you are allowing the batching to perform its magic.
Hope this helps.
#8
P.s. I don't find this blog when I hit the "blogs" button. I have to have an old link. Weird.
02/15/2013 (7:42 am)
Any chance for a small "prefab" write up? I understand that there are prefabs now. Yay!P.s. I don't find this blog when I hit the "blogs" button. I have to have an old link. Weird.

Torque 3D Owner Brian Szatkowski
The reorganization you've brought to T2D is much appreciated. The unification that Taml provides is awesome and the encapsulation that Modules brings just makes sense from an OOP perspective.
Also, the batched/sorted rendering opens up new possibilities with creating really nice eye candy with certain scenes.
I can now envision creating actual realtime-rendered-by-the-engine cutscenes for new apps (as opposed to being restricted to prerendered video).
Well done!
Thank you,
Brian