The Machinery — November 2021 (version 2021.11)

As 2021 is drawing to a close, don’t miss your chance to get in on our Early Adopters license at half the regular price! We have a number of new features and bug fixes for you in this release.

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.

Animation Curves

This version of The Machinery adds support for Animation Curves.

Animation Curves are animations that are edited directly in The Machinery by manipulating curve keys. (Note that this is in contrast to character animations which are typically imported from an animation package.)

Editing Animation Curves.

Editing Animation Curves.

Animation Curves are based on the Entity Property system that was introduced in the October release and can be used to animate any property exposed to that system (positions, rotations, light colors, shader variables, etc).

The tree view of the Animation Curve asset first lists the entities that the asset has animations for. Each entity is identified by its path from the root asset that the Animation Curve is played on. If you expand an entity, you can see the individual property curves for that entity, identified by their property paths.

To play an Animation Curve asset you can use the Animation Play Curve node in the entity graph. Here’s an example with a more complex animation:

Using Animation Curves.

The plan is to use the Animation Curve system as the foundation for a bigger Cutscene tool. Stay tuned!

Properties Tab Overhaul

The new look of the property panel, with the alternating background colors of nested groups and right-aligned labels.

The new look of the property panel, with the alternating background colors of nested groups and right-aligned labels.

The Properties tab and the tm_properties_view_api have gotten an overhaul. This version introduces many changes to both the look of the Properties tab as well as the code behind it:

  • Expandable UI groups now have a background color to make them more distinct from each other. Nested groups — for example, components within a child entity — use an alternating background color. To facilitate this we have made the UI groups scoped in the code.

  • The property labels are now right-aligned. This improves readability since the group labels are still left-aligned.

  • Labels of properties now use a fractional width, making the width resize of the properties panel more useful.

  • Inherited and disabled subobjects / UI groups can now be expanded and inspected without having to override them. There is a new Override Tree context menu option for deeply nested items. This overrides all the objects from the first inherited point to where the context menu is activated.

  • Checkboxes are completely right-aligned.

  • The rectangle of nested UI groups is indented, i.e. it becomes slightly smaller in width for each indentation level.

More in-depth points about properties code changes:

  • The UI grouping functions of tm_properties_view_api have been renamed since we made them scoped like so:

  • For drawing general tree items: ui_tree_item()ui_begin_tree_item() and ui_end_tree_item()

  • For drawing general tree items, but have the key automatically calculated using an object ID: ui_group()ui_begin_object_tree_item() and ui_end_object_tree_item()

  • For drawing subobject set items: ui_subobject_set_item_header()ui_begin_subobject_set_item() and ui_end_subobject_set_item()

  • The parameters of the UI group functions have been revised and made more consistent, the differences between the different functions thus become clearer.

  • The previously introduced “inline groups” have been removed since the UI groups are now clear enough on their own.

  • The indent parameter that was passed to many functions of tm_properties_view_api has been incorporated into the item rect. Calling functions on API that draw subobjects, or using UI groups, automatically indents the passed rect. The indent parameter has been completely removed from all functions in properties.h. The current indent level can still be checked within tm_properties_ui_args_t but it is not meant to be changed.

Simulation State Tab

The State of the Simulation can now be inspected via the newly introduced Simulation State tab. It allows you to find, inspect and edit all the defined properties of the Entities that there are in the Simulation.

It’s also possible to write the property values from the simulation back to the Scene and make them permanent. As an example use case for this — you can create natural-looking “piles” of entities, by simulating them using the physics system and then save those piles back out to the Scene state.

Selected Entities in the Simulation State are Highlighted in yellow

Selected Entities in the Simulation State are Highlighted in yellow

Community Contributions

  • Thanks to IachSinc for fixing a crash when restarting the Simulation. [#783]
  • Thanks to IachSinc for providing a Shortcut to open the Simulation Tab. [#802]
  • Thanks to geekrelief for adding support for saving your workspace settings. [#781]
  • Thanks to jamesmintram for fixing the handling of custom scaling factors. [#798]
  • Thanks to Tisten for adding verbose flags to unit tests and for unifying the test execution for the foundation project. [#772] [#773]
  • Thanks to Tisten for fixing a crash when saving projects. [#809]
  • Thanks to geekrelief for adding support for enabling/disabling throttling in the interface settings. [#780]
  • Thanks to jamesmintram for fixing a crash when references do not exist in the collision lookup hash. [#799]

Project Management

  • Fixed a bug where maximized windows weren’t restored correctly when opening a project. [#864].
  • Added tm_settings_api. Plugins can now define their own persistent global or project-specific settings.


  • Fixed a bug where it wasn’t possible to remove a Tag from an entity with an overridden Tag component. [#879]
  • Spotlights now use sliders for inner and outer angles.
  • Added the aspect TM_TT_PROP_ASPECT__PROPERTIES__UNIT which can be set on float properties. The implementation of the aspect is a callback that returns a string representing the unit of the property. If set, the callback will be run when the property is drawn and the unit displayed next to the property.
  • Components are now only auto-expanded on the first indentation level.
  • Fixed issues where tabbing between controls that had pickers didn’t work properly.


  • PhysX shapes are now correctly updated when a child entity is deleted or a rigid body component added to it. [#881]
  • Fixed a bug where Physx heightfield shapes weren’t correctly positioned.
  • Added flags to lock linear and angular axis in Physics Body Component.
  • Fixed an issue that could cause the Character Mover to float above the ground.

Asset Pipeline

  • Fix for DCC asset extraction not keeping track of extracted materials properly in the case of multi-editing being used to do multi-asset-extraction.


  • Fixed a bug where the default camera wasn’t restored when switching scenes.
  • It’s now possible to cap the frame rate of the Simulate Tab to some common values.
  • Fixed a memory leak when a Simulation Entry didn’t have a shutdown() method.

Scene Tab

  • The snapping for the scaling gizmo now works more like the snapping for the move gizmo.
  • Fixed Duplicate being broken in the Scene Tab.


  • Added a watermark to better distinguish Graph Instances.
  • Fixed a bug where the Properties panel had to be open for subgraph nodes to be initialized correctly.
  • Fixed a bug where multiple levels of graph inheritance led to the graph not being able to figure out if connections were in conflict with each other or not. The new approach also comes with the benefit that the graph code became simpler since the conflict checks are now more functional and thus involve less state tracking.
  • Fixed a one-pixel glitch in node headers seen under certain zoom levels.
  • While making a new connection, you now just need to hover the label of the connector for the connection to snap to the connector.

Entity Graph

  • The Entity Debugger has been polished.
  • Fixed a bug where the add tag and has tag nodes weren’t compiled correctly.
  • Auto-complete of render component properties now works.

Creation Graph

  • The Lit node now has support for a Clear Coat layer by connecting Clear Coat Properties constructed using the Construct Clear Coat Properties node.
  • Fixed a bug where the dependency tracking did not discover deleted assets in some cases leading to undefined behavior.
  • Removed the reference counting mechanism for GPU resources created by DCC Asset-nodes as it sometimes didn’t behave as expected leading to undefined behavior.


  • Updated the dcc-mesh and dcc-material creation graph prototypes to have decent default names for constant variables and draw calls.
  • Fixed a deadlock when opening a project in need of a core update while hosting a collaboration session.


  • Added tm_ui_api->theme_is_high_contrast() which can be used to check if the current theme is a high contrast theme, or based on a high contrast theme. This can be used to do additional things on top of just color customization, such as adding extra borders to UI elements.

Console Tab

  • Added Filters for the console tab for Debug, Info, and Error Messages as well as a toolbar.


  • Introducing Indirection Index Buffers. These can be used to draw things behind other things without forcing the user to do any index buffer copying tricks. It works by tm_ui_api->create_indirection_ibuffer() creating tm_draw2d_ibuffer_t objects that actually have a special index buffer as their backing buffer. So the user can use the return value as a normal index buffer. You can feed the function the index in the index buffer where you want your UI elements to be injected, it will be sorted out automatically at the end of the frame.
  • Added TM_UI_BUFFER_USER as a buffer assignable to the buffer of tm_ui_style_t. It can be used like this in combination with Indirection Index Buffers:
tm_draw2d_ibuffer_t *ibuf = tm_ui_api->create_indirection_ibuffer(ui, TM_UI_BUFFER_MAIN, index_buffer_injection_idx);
uistyle->buffer = TM_UI_BUFFER_USER;
uib.ibuffers[TM_UI_BUFFER_USER] = ibuf;
  • The background color of the padding around scrollbars has been changed to something that differs from the default tab background color so that they do not blend together.
  • Buttons and push buttons in the dark theme now have clearer background color while active.
  • Fixed a crash that would occur if no icon font was loaded.

Entity Tree

  • Fixed a bug in the Entity Tree where the entity wasn’t deselected correctly when locked.
  • The Override and Remove Override behavior in the Entity Tree is now the same as in the properties panel. Ctrl + Double Click overrides, Ctrl + Shift + Double Click removes overrides. This is hinted at in the context menu.


  • Added a new physical camera mode that is specified in focal length and sensor size.
  • The color spaces plugin has been promoted to the Foundation.
  • tm_hash_get() is now thread-safe as long as the hash is not being modified by another thread.


  • Added support for Visual Studio 2022.


  • Added -c flag which does a dry run and outputs any error in your documentation.


  • Render-graph-toolbox debug visualization resources can now be pre-exposed.
  • tmsl now supports the maxvertexcount hlsl attribute.
  • Fixed a GPU memory corruption bug when many big blocks were allocated.
  • Added full support for Adobe RGB and Display-P3 color spaces.
  • Vulkan: Fixed an issue in the TLSF allocator when the remainder block becomes smaller than 32 bytes.
  • Vulkan: Fixed an issue with memory budget calculations overflowing 32 bits.
  • Vulkan: Fix for incorrectly returning VK_ERROR_OUT_OF_HOST_MEMORY instead of VK_ERROR_OUT_OF_DEVICE_MEMORY in Vulkan device memory allocators.
  • Vulkan: Executing ray tracing work on AMD RDNA2/RX6000-series GPUs now works as expected.
  • Removed unnecessary dependencies on the tm_default_render_pipe_api.
  • Fix for hit/closes/miss/any/intersection shaders not correctly using NonUniformResourceIndex() when indexing resources.
  • We now store two copies of main depth stencil- and gbuffer1-targets (storing normal and roughness) as persistent resources and ping-pong cycle between them to have access to last frames data for disocclusion queries.
  • Fixed Vulkan validation warning in thumbnail rendering.
  • Exposed last frames inverse view-projection matrix to the viewer system.
  • Shader blobs now also store human-readable names of constants and resources.
  • The Render Graph no longer allocates memory for persistent resources unless they are referenced by an active pass.
  • Fixed a bug in the SSR shaders sometimes resulting in Inf/NaN being written to the HDR accumulation buffer.
  • The TAA settings are now persistent settings stored in the project.
  • Made it possible to change the default viewport background color.


  • The Project is now reloaded when turning Safe Mode on and off so that project-specific plugins can be loaded/unloaded.
  • Better error messages are now printed as to why a specific plugin is loaded or not.
  • Settings for “Always Run” and “Always Deny” DLLs can now be edited in the editor.

The Truth

  • Settings for Truth properties (such as .tooltip, etc) are now reloaded on hot reload. Note that it is still not possible to add or remove properties during hot reload since that would break existing loaded Truths.


  • Fix for a race condition in animation state machine triggers.
  • Added support for triggers on animation states that are blending out.
by The Machinery Team