The Machinery — January 2022 (version 2022.1)

Happy 2022, Year of the Water Tiger! Here at Our Machinery, we have lots of interesting news trickling out this year for you. To start you off, we have an absolutely jam packed January update. We decided to give everybody a nice holiday break last month, so this release includes features and fixes from both December and January. Enjoy!

If you are already running The Machinery, this new release should pop up in your Downloads tab. Otherwise, get it from our download page and have a look at this quick introduction video. We are also working on two books about The Machinery. One is an overview of the engine and the other one a collection of tutorials on how to do specific things. Note that both these books are still works in progress.

If you find bugs in this release or have requests for specific features, post them to our issue tracker. For more general discussions, hit us up on GitHub discussions or Discord.

Key highlights in this release are:

And as always, we also have a number of smaller updates.

NAT Punchthrough

Our collaboration mode now supports NAT punchthrough. This lets you collaborate over the Internet without explicit port forwarding. You can use it by just selecting Host NAT Server or Join NAT Server in the Collaboration tab:

Hosting a NAT Server in the Collaboration tab.

Hosting a NAT Server in the Collaboration tab.

Also, the Discord Collaboration mode now uses NAT punchthrough to connect the users.

Entity Thumbnails

The Asset Browser will now display thumbnails for entities and DCC assets. Thumbnails are generated from the Preview tab whenever you switch between entities. (The thumbnail will show the last view form the Preview tab.)

Entity thumbnails in the Asset Browser.

Entity thumbnails in the Asset Browser.

In addition, to address issues with assets becoming dirty because of thumbnails getting updated, we now only store the thumbnail in the asset if the asset is already dirty for other reasons. For non-dirty assets, they are temporarily stored outside of the asset until the asset becomes dirty.

Global Tabwell

The editor now features a “global tabwell” that is shared by all workspaces. The Global Tabwell can host things like the Asset Browser that you want to have access to in all workspaces. (Though you can also hide it, if you prefer the workspace to just focus on a specific view.)

Global tabwell at the bottom of the screen hosting the Console, the Asset Browser and the Preview.

Global tabwell at the bottom of the screen hosting the Console, the Asset Browser and the Preview.

Improved Statistics Graphs

The Statistics tab has received multiple improvements:

  • The graph view now supports per-curve ranges for the y-axis. This means that you can put curves that have very different scales in the same graph. For example, you could put the frame time and the renderer’s primitive count in the same graph to see if they’re covariant. The ranges can be set automatically or manually.

  • The list of predefined statistics views is now generated from an interface — tm_statistics_predefined_view_i. This means that plugins can add their own custom statistics views to the list.

Multiple y-axis ranges in the same graph

Multiple y-axis ranges in the same graph

Docgen Parser

Our documentation generator now uses a proper C parser instead of relying on ad-hoc heuristics. (Well to be honest, there’s still a bit of heuristics in there, because for documentation purposes you typically want to parse the code before it goes through the preprocessor which means you need special care to parse preprocessor directives.) This makes it possible to improve the quality of the documentation, since we now have more information to work from.

In the future we will use this parser to generate a machine readable JSON descriptions of our APIs. These descriptions could be used to generate documentation in other formats, implement autocomplete, or create automatic language bindings to other programming languages.

Shader Graph Loops

We’ve added support for basic loops in shaders built inside a creation graph:

An example of a simple shader graph loop.

An example of a simple shader graph loop.

The Loop Begin node sets up any variables you need access to inside the loop body. Max Iterations is a constant defining the maximum number of iterations the loop will do. For each variable declared in the settings, an input connector will appear with the variable’s name that can be used to initialize the variable. Initialization of the variables is mandatory, anything wired to these inputs will be executed exactly once.

The output from the Loop Begin node is a Loop identifier that should be wired to the Loop End node. In addition to the Loop identifier all variables will also be accessible as outputs from the Loop Begin node as well as inputs to Loop End. Any wires connected to the variable inputs of Loop End will be executed for each iteration of the loop and is referred to the Loop Body in the screenshot above.

To early-out of the loop the user can connect a wire to the Break Condition, this condition will be checked each loop iteration and break out of the loop if it evaluates to true. Once the loop is done executing the variables will be available as output from the Loop End node.

Community Contributions

  • Thanks to Tisten for multiple contributions:

    • Adding support for paths longer than MAX_PATH on Windows. [#778]
    • Fix for a save crash. [#809]
    • Various PhysX improvements. [#828]
    • HTTP support for tmbuild libraries. [#838]
    • Changing the task system to use a queue instead of a stack. [#852]
    • Optimizing collaboration buffer requests. [#853]
  • Thanks to lachsinc for a fix in locating the Visual Studio installation. [#857]

  • Thanks to endragor for multiple contributions:

    • Fix for stencil testing. [#840]
    • Fixing removal of rigid body shapes. [#847]
    • Adding atomic exchange for uint64_t. [#848]
    • Fixing the order of add and remove in the entity commands. [#856]
  • Thanks to ZeroErrors for multiple contributinos:

    • A fix for asset importing. [#836]
    • A fix for Float4 display names. [#835]
    • A fix to DCC asset multi-edit. [#834]
  • Thanks to RiderAlex for multiple contributions:

    • A connector tag fix. [#824]
    • Fix for the resolution of TM_SDK_DIR. [#825]
  • Thanks to photex for multiple contributions:

    • An --ubsan option for builds. [#832]
    • A fix for a segfault in the login tab. [#833]
  • Thanks to eigenbom for removing hard-coded include paths for vscode. [#827]


  • Buttons and other controls now react correctly to hovering when drawn in the overlay layer.
  • Alt+[1-9] can now be used to quickly jump between workspaces.
  • Improved the editing of rotation angles. [#851]
  • Supports opening child prototypes in a new workspace. [#967]
  • Fixed how <ENTER> and <ESC> works in numeric text fields (spinners).
  • Workspace icons now show tooltips when drawn in compact mode.
  • Fix for crash when right clicking in the workspace end area.
  • Improved the string pattern matching in the entity graph dropdown. [#891]


  • Revamp of tm_settings_api. This API can now be used to fetch application settings, per-project application settings and also project settings. The first two are stored in a separate Truth that is saved in the user’s home folder, while the project settings are stored in a hidden asset within the project. Many settings that were previously explicitly enumerated in the_machinery.h have been moved to use this API.


  • Properties that let you pick an entity can now pick that entity visually from the scene. You activate this from the picker using the new button to the right of it and then click on an entity in the scene tab. Click and hold to select any parent or child entity of the one that the picking hit.
  • It is now possible to remove components from within the properties tab.


  • Fix for printing strings longer than 1024 bytes using the %p{type} mechanism in the custom sprintf() implementation.
  • Fix for calling tm_temp_allocator_api->create(NULL).
  • tm_random_api now has array shuffle functionality.
  • TM_ERROR, TM_ASSERT and TM_FATAL_ASSERT now use tm_error_api->def by default. There are variations suffixed _CUSTOM that take a custom error interface.
  • The task system now has a concept of a task owner. You can query all tasks with a specific owner using tm_task_system_api->find_tasks(). The owner of a task can either be another task ID, or some arbitrary identifier. For tasks that depend on a specific The Truth instance being alive, a The Truth pointer is used as owner. The task manager tab uses the owner to group subtasks under their owning task.


  • Shader Compile tasks are now cancelable and any variation compile subtasks have the parent task as owner, grouping them properly in the Task Manager.
  • Performance improvements to Entity Spawner.
  • Support for multiple concurrently running truth objects in tm_shader_repository_o.

Graph Editor

  • Connections can now be reconnected by clicking and dragging their endpoint.


  • tmbuild now properly verifies the SSL trust chain of the library server.
  • tmbuild now can use custom fingerprints in libs.jsonvia the field fingerprint.
  • tmbuild now properly handles http repository entries in the libs.json file.


  • Fixed a bug that could cause NaNs when evaluating compressed animations.
  • Animation State Machine graph now has snapping.


  • Fix for errors when transmitting buffers > 2 GB.

Color Scopes Tab

  • Fix for crash when closing workspace containing color scopes tab.
  • Fix for crash when switching workspaces where one contained a color scopes tab.
  • Fix for crash when adding a color scopes tab with no viewer tabs present.

Asset Pipeline

  • Fix for materials and images stored within a DCC asset’s preview entity not being removed properly when the resources are extracted from the DCC asset.

Asset Browser

  • Added opportunistic thumbnail generation for entities and DCC assets. When the preview tab changes focus away from an entity or DCC asset, the image of the entity is used as thumbnail.


  • The Runner can now be run from within another application and draw into a subarea of that application’s window. There is a sample called wpf_hosted_runner that shows how one could do this from within a C# + WPF application.
  • There is a new tm_runner_api that lets you switch project, reset and pause.

Creation graph

  • dcc-material-opacity now respects the DCC asset’s opacity cutoff by default.
  • Thread-safety and bug fixes to creation graph consumer mechanism - i.e., dependency tracking for creation graph instances consuming the output of other creation graph instances.
  • Support for queuing named events between different creation graphs.
  • Added height-mask based implementation of “Procedural Stochastic Textures by Tiling and Blending” , useful for breaking up recognizable tiling patterns of stochastic textures.
  • Support for setting up a GPUSim system with shared storage.
  • Support for rotating normalized vectors using the math_transform node.
  • Input Normal node can now be read in the vertex shader stage.
  • GPUSim Reset node now correctly resets the dispatch indirect buffers.

Entity Graph

  • Added a Set Cursor Hidden node.
  • The Physx Raycast node will now raycast against all collision types if none is specified.

Scene Tab

  • Fixed a bug where gizmos committed to The Truth constantly, even though they should just commit the end position of the move. This was due to us wanting to propagate the move to other viewports continuously. This is now done using a transient transform change interface that the Simulation API implements.
  • Grid colors are now part of the theme.


  • Moved management of default cameras to the Simulation API. This removes lots of duplicated code in the Scene, Simulate and Preview Tab.
  • Introduced disable_all_camera_input and enable_camera_input on tm_simulation_api. These manage which camera gets input.
  • Fix for the Simulation State Tab scrolling when it was not in focus [#896]


  • Fixed a bug where the Crash Recovery data was not reset after the Save of an Asset Database project.
  • Windows without any tab won’t be saved/restored when exiting and reopening the project. [#911]
  • Fixed a bug where minimized windows sizes and positions were not saved correctly. [#962]

Entity Tree Tab

  • Fixed a bug where copy pasting objects wasn’t working properly. [#973]
  • Improved the default Copy paste behavior and aligned it to that of the Scene Tab [#972]


  • Fixed a bug where an incorrect IP address was used when simulating two separate instances on the same machine.


  • Fixed a crash when opening graphs as a collaboration client. [#981]
  • Fixed a crash when a camera entity is deleted from the entity context.
  • Fixed a bug where Project Application settings were not loaded correctly when opening a project.
  • Removed logging accidentally left in the code.
  • Fixed a bug where Collaboration did not work due to client actions not being received properly on server.
  • Fix for spam about Profiler Scopes when scrolling in asset browser.
  • Fix for Left and Right alignment being switched in the UI Text Component. [#987]
  • Fix for crash when renaming a variable to the empty string in a creation graph. [#988]
  • Fix for import of DCC assets failing on a collaboration client. [#983]
  • Fix for text being truncated in the login tab.
  • Removed unnecessary assert causing crashes with large crash recovery files.
by The Machinery Team