<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.trainzsimulator.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Microlem</id>
	<title>TrainzOnline - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.trainzsimulator.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Microlem"/>
	<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/wiki/Special:Contributions/Microlem"/>
	<updated>2026-11-05T05:58:20Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Material_Types&amp;diff=40009</id>
		<title>Material Types</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Material_Types&amp;diff=40009"/>
		<updated>2024-02-13T08:52:10Z</updated>

		<summary type="html">&lt;p&gt;Microlem: Add m.foliage&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Material]]s describe how a modelled surface will appear in the game. They specify a range of configurations and resources including classic material properties, textures and shaders. Each Material is an instance of a particular preset Material Type, from the selection described on this page.&lt;br /&gt;
&lt;br /&gt;
This page describes [[&amp;quot;Trainz-build&amp;quot; number|content format v4.6]] and assumes that the [[FBX file format]] is used as a data source for any meshes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Material Naming=&lt;br /&gt;
&lt;br /&gt;
A material name consists of a creator-supplied given name and a material type suffix. The material type is one of a set of supported types defined below, eg. &#039;m.onetex&#039;. The material type is manually appended to the name of the material within the creation program eg. [[Autodesk 3ds Max]], it is not implied by the configuration of the material. Material type names in Trainz are not case sensitive. In creation programs which do not support the period (&amp;quot;.&amp;quot;) character within a user-supplied material name, the underscore character (&amp;quot;_&amp;quot;) may be used instead. (Note: in modern Trainz, the &amp;quot;m&amp;quot; may be omitted to leave &amp;quot;name.type&amp;quot; rather than the unsightly &amp;quot;namem.type&amp;quot;.)&lt;br /&gt;
&lt;br /&gt;
For more info about configuring materials see [[Exporting with 3D Studio Max]].&lt;br /&gt;
&lt;br /&gt;
=PBR Material Types=&lt;br /&gt;
Trainz uses a Metallic/Roughness style [[Physically Based Rendering|PBR workflow]]. All materials are expressed in these terms, or (in the case of legacy materials) are converted into these terms using a best-effort approximation. PBR and the Metallic/Roughness workflow are discussed in great detail online, with a number of freely available presentations and demonstrations ranging from beginner material to advanced math. It is recommended that content creators read up on the subject before attempting to configure Trainz materials.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==m.pbrmetal==&lt;br /&gt;
[[m.pbrmetal]] is a generic opaque PBR material. This should be considered the starting point for any Trainz content creation which has no special needs.&lt;br /&gt;
&lt;br /&gt;
* Albedo (RGB)&lt;br /&gt;
* Normal (XYZ)&lt;br /&gt;
* Height&lt;br /&gt;
* Emissive&lt;br /&gt;
* Roughness&lt;br /&gt;
* Ambient Occlusion&lt;br /&gt;
* Metallicity&lt;br /&gt;
&lt;br /&gt;
For .CDP example files visit the [[m.pbrmetal]] page and look under the example section.&lt;br /&gt;
&lt;br /&gt;
==m.pbrmetalmasked==&lt;br /&gt;
[[m.pbrmetalmasked]] gives identical results to m.pbrmetal but adds masked opacity support.&lt;br /&gt;
&lt;br /&gt;
* Albedo (RGB)&lt;br /&gt;
* Masked Opacity (A)&lt;br /&gt;
* Normal (XYZ)&lt;br /&gt;
* Height&lt;br /&gt;
* Emissive&lt;br /&gt;
* Roughness&lt;br /&gt;
* Ambient Occlusion&lt;br /&gt;
* Metallicity&lt;br /&gt;
&lt;br /&gt;
For .CDP example files visit the [[m.pbrmetalmasked]] page and look under the example section.&lt;br /&gt;
&lt;br /&gt;
==m.pbrmetaldetail==&lt;br /&gt;
[[m.pbrmetaldetail]] gives identical results to m.pbrmetal but adds support for a detail map.&lt;br /&gt;
&lt;br /&gt;
* Albedo (RGB)&lt;br /&gt;
* Opacity (A)&lt;br /&gt;
* Detail (RGB)&lt;br /&gt;
* Normal (XYZ)&lt;br /&gt;
* Height (A)&lt;br /&gt;
* Detail Normal (RGB)&lt;br /&gt;
* Emissive (R)&lt;br /&gt;
* Roughness (G)&lt;br /&gt;
* Ambient Occlusion (B)&lt;br /&gt;
* Metallicity (A)&lt;br /&gt;
&lt;br /&gt;
For .CDP example files visit the [[m.pbrmetaldetail]] page and look under the example section.&lt;br /&gt;
&lt;br /&gt;
==m.glass==&lt;br /&gt;
[[m.glass]] is a transparent PBR material. This enables glass-like substances to be rendered but has a number of peculiarities that make it inappropriate for other purposes.&lt;br /&gt;
&lt;br /&gt;
* Albedo (RGB)&lt;br /&gt;
* Opacity (A)&lt;br /&gt;
* Normal (XYZ)&lt;br /&gt;
* Height&lt;br /&gt;
* Emissive&lt;br /&gt;
* Roughness&lt;br /&gt;
* Ambient Occlusion&lt;br /&gt;
* Metallicity&lt;br /&gt;
&lt;br /&gt;
For .CDP example files visit the [[m.glass]] page and look under the example section.&lt;br /&gt;
&lt;br /&gt;
==m.clutter==&lt;br /&gt;
[[m.clutter]] gives similar results to m.pbrmetalmasked but adds support for cross-faded LOD transitions and does not include support for parallax mapping. This is intended for use with [[Clutter Effect Layer]]s. &lt;br /&gt;
&lt;br /&gt;
* Albedo (RGB)&lt;br /&gt;
* Masked Opacity (A)&lt;br /&gt;
* Normal (XYZ)&lt;br /&gt;
* Emissive&lt;br /&gt;
* Roughness&lt;br /&gt;
* Ambient Occlusion&lt;br /&gt;
* Metallicity&lt;br /&gt;
&lt;br /&gt;
==m.foliage==&lt;br /&gt;
[[m.foliage]] gives similar results to m.clutter but adds support for per-vertex procedural wind animation and ground alignment. This material is intended for use with [[Clutter Effect Layer]]s and is supported in [[&amp;quot;Trainz-build&amp;quot; number|content format v5.4]] and later. &lt;br /&gt;
&lt;br /&gt;
* Albedo (RGB)&lt;br /&gt;
* Opacity (A)&lt;br /&gt;
* Normal (XYZ)&lt;br /&gt;
* Emissive&lt;br /&gt;
* Roughness&lt;br /&gt;
* Ambient Occlusion&lt;br /&gt;
* Metallicity&lt;br /&gt;
&lt;br /&gt;
For .CDP example files visit the [[m.foliage]] page and look under the example section.&lt;br /&gt;
&lt;br /&gt;
==Ground Texture Material==&lt;br /&gt;
[[KIND Groundtexture]] assets make use of a custom material which offers features equivalent to [[m.pbrmetal]]. It is not possible to override the ground texture material.&lt;br /&gt;
&lt;br /&gt;
[[Surveyor]] allows the user to paint multiple layers of ground texture with automated blending. Historically, this capability was used extensively to help hide the fact that ground textures were low resolution and tiled heavily. Overuse of this approach may induce substantial blurriness and reduce performance. Current-generation ground materials are high resolution and should not tile noticeably. For best performance and visuals, blending should be reserved for actual changes in surface material (eg. grass vs rocks vs mud) rather than to simulate texture detail.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Legacy Material Types=&lt;br /&gt;
The material types here are intended for backwards-compatibility with older versions of Trainz. They are not PBR materials and offer the content creator less control over the end result. It is recommended that the PBR materials are used instead.&lt;br /&gt;
&lt;br /&gt;
==m.notex==&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;This is a legacy material, and should only be used where compatibility with older versions of Trainz is required.&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[m.notex]] is a non-textured material.&lt;br /&gt;
&lt;br /&gt;
Opacity = Uniform opacity can be controlled in the material settings.&lt;br /&gt;
&lt;br /&gt;
Full details here: [[m.notex]]&lt;br /&gt;
&lt;br /&gt;
[[Image:mat_notex.jpg]]&lt;br /&gt;
==m.onetex==&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;This is a legacy material, and should only be used where compatibility with older versions of Trainz is required.&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[m.onetex]] is a diffuse texture mapped material.&lt;br /&gt;
&lt;br /&gt;
Opacity = Per-texel opacity can be controlled via the diffuse texture&#039;s alpha channel.&lt;br /&gt;
&lt;br /&gt;
Full details here: [[m.onetex]]&lt;br /&gt;
&lt;br /&gt;
[[Image:mat_onetex.jpg]]&lt;br /&gt;
==m.reflect==&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;This is a legacy material, and should only be used where compatibility with older versions of Trainz is required.&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[m.reflect]] is a reflective material. &lt;br /&gt;
&lt;br /&gt;
Full details here: [[m.reflect]]&lt;br /&gt;
&lt;br /&gt;
[[Image:mat_reflect.jpg]]&lt;br /&gt;
&lt;br /&gt;
==m.gloss==&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;This is a legacy material, and should only be used where compatibility with older versions of Trainz is required.&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[m.gloss]] is a glossy reflective material.&lt;br /&gt;
&lt;br /&gt;
Opacity = Uniform opacity can be controlled in the material settings.&lt;br /&gt;
&lt;br /&gt;
Full details here: [[m.gloss]]&lt;br /&gt;
&lt;br /&gt;
[[Image:mat_gloss.jpg]]&lt;br /&gt;
==m.tbumptex==&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;This is a legacy material, and should only be used where compatibility with older versions of Trainz is required.&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[m.tbumptex]] is a bump mapped material.&lt;br /&gt;
&lt;br /&gt;
Opacity  = Per-texel opacity can be controlled via the diffuse texture&#039;s alpha channel.&lt;br /&gt;
&lt;br /&gt;
Specular = Per-texel specular strength can be controlled via the normal texture&#039;s alpha channel.&lt;br /&gt;
&lt;br /&gt;
Full details here: [[m.tbumptex]]&lt;br /&gt;
&lt;br /&gt;
[[Image:mat_tbumptex.jpg]]&lt;br /&gt;
==m.tbumpgloss==&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;This is a legacy material, and should only be used where compatibility with older versions of Trainz is required.&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[m.tbumpgloss]] is a bump mapped reflective material.&lt;br /&gt;
&lt;br /&gt;
View the tutorial video on tbumpgloss [https://youtu.be/ymfWeaPLIEk HERE] and download an example asset [http://download.trainzportal.com/tutorials/16_1_trainz_material_rust.zip HERE] to drop into Trainz to see what effect can be created using this material. The example asset is a &amp;quot;rust&amp;quot; type material.&lt;br /&gt;
&lt;br /&gt;
Opacity    = Uniform opacity can be controlled in the material settings.&lt;br /&gt;
&lt;br /&gt;
Specular   = Per-texel specular strength can be controlled via the normal texture&#039;s alpha channel.&lt;br /&gt;
&lt;br /&gt;
Reflection = Per-texel blend strength of the reflection can be controlled via the diffuse texture&#039;s alpha channel.&lt;br /&gt;
&lt;br /&gt;
Full details here: [[m.tbumpgloss]]&lt;br /&gt;
&lt;br /&gt;
[[Image:mat_tbumpgloss.jpg]]&lt;br /&gt;
&lt;br /&gt;
==m.tbumpenv==&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;This is a legacy material, and should only be used where compatibility with older versions of Trainz is required.&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[[m.tbumpenv]] is a bump mapped environment reflective material. In current versions of Trainz this is the preferred material for most models lit by world lighting, unless a particular effect is desired. Exceptions include tunnels and interiors.&lt;br /&gt;
&lt;br /&gt;
View the tutorial video on tbumpenv [https://youtu.be/YGGkb6nvg5I HERE] and download an example asset [http://download.trainzportal.com/tutorials/16_2_trainz_material_paint.zip HERE] to drop into Trainz to see what effect can be created using this material. The example asset is a &amp;quot;paint&amp;quot; type material.&lt;br /&gt;
&lt;br /&gt;
Opacity    = Uniform opacity can be controlled in the material settings.&lt;br /&gt;
&lt;br /&gt;
Specular   = Per-texel specular strength can be controlled via the normal texture&#039;s alpha channel.&lt;br /&gt;
&lt;br /&gt;
Reflection = Per-texel blend strength of the environment map can be controlled via the diffuse texture&#039;s alpha channel.&lt;br /&gt;
&lt;br /&gt;
Full details here: [[m.tbumpenv]]&lt;br /&gt;
&lt;br /&gt;
[[Image:mat_tbumpenv.jpg]]&lt;br /&gt;
&lt;br /&gt;
=Material Examples=&lt;br /&gt;
Download example assets below and drop them into Trainz to see what effect can be created using the Materials listed below:&lt;br /&gt;
&lt;br /&gt;
These examples don&#039;t use the new PBR shaders:&lt;br /&gt;
 - Rust - [http://download.trainzportal.com/tutorials/16_1_trainz_material_rust.zip Download Asset]. View the tutorial video for this asset [https://youtu.be/ymfWeaPLIEk HERE]&lt;br /&gt;
 - Paint - [http://download.trainzportal.com/tutorials/16_2_trainz_material_paint.zip Download Asset]. View the tutorial video for this asset [https://youtu.be/YGGkb6nvg5I HERE]&lt;br /&gt;
 - Creating Specular Maps - [http://download.trainzportal.com/tutorials/16_3_trainz_material_specular.zip Download Asset]. View the tutorial video for this asset [https://youtu.be/bR3l1LgHSAk HERE]&lt;br /&gt;
&lt;br /&gt;
[[Category:Material types| ]]&lt;br /&gt;
[[Category:Modeling]]&lt;br /&gt;
[[Category:Content creation]]&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Mesh_metadata_file&amp;diff=40008</id>
		<title>Mesh metadata file</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Mesh_metadata_file&amp;diff=40008"/>
		<updated>2024-02-13T08:46:05Z</updated>

		<summary type="html">&lt;p&gt;Microlem: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Various attributes which users may wish to control are frequently not available in standard modelling packages, or are not exported to the [[FBX file format]]. An optional &amp;quot;&amp;lt;mesh-file-name&amp;gt;.txt&amp;quot; file may be included alongside the &amp;quot;&amp;lt;mesh-file-name&amp;gt;.fbx&amp;quot; file to convey these attributes. Where attributes are specified in this metadata file, they override any entries read from the FBX file itself. If an attribute is not specified, it is calculated from the FBX file.&lt;br /&gt;
&lt;br /&gt;
Mesh metadata files are in a simple text format similar to the [[config.txt]] format. They are not currently validated in any fashion beyond basic readability; if you mis-type a tag it will simply be ignored by the reader. Do not rely on this behaviour- we may add validation in the future and it may apply retroactively.&lt;br /&gt;
&lt;br /&gt;
At the current time, the only use for a mesh metadata file is to specify additional material parameters. A &amp;quot;materials&amp;quot; block is added to the file, and within this you may name any of the materials present within your FBX file. Within each of those, you may specify one of the following parameters:&lt;br /&gt;
&lt;br /&gt;
* &#039;two-sided&#039; - A boolean (0 / 1) value which indicates whether chunks which use this material should be rendered as two-sided (no backface culling) or one-sided (regular backface culling).&lt;br /&gt;
* &#039;blend-mode&#039; - A string with one of the following values:&lt;br /&gt;
** &#039;alpha-blend&#039; - Chunks which use this material are rendered using a true alpha blend.&lt;br /&gt;
** &#039;alpha-to-coverage&#039; - Chunks which use this material are rendered using alpha-to-coverage. This technique is a fast approximation of alpha which sacrifices some visual detail in favour of performance and depth-independance.&lt;br /&gt;
** &#039;alpha-masked&#039; - Chunks which use this material are rendered using alpha masking. This technique discards pixels with low diffuse alpha values, resulting in holes in the geometry.&lt;br /&gt;
** &#039;opaque&#039; - Chunks which use this material are rendered fully opaque.&lt;br /&gt;
* &#039;material-type&#039; - A string which specifies the [[Material_Types|material type]] to use. This causes the game to ignore any material type suffix on the material name. Be careful when overriding material types in this manner, as other requirements (such as texture slot bindings) may vary between material types. The material type string does not include a leading &amp;quot;m.&amp;quot; - so &amp;quot;notex&amp;quot; is a valid entry here, but &amp;quot;m.notex&amp;quot; is not.&lt;br /&gt;
* &#039;textures&#039; - A subcontainer list with zero or more texture containers. Each texture container is named for the material texture slot to which the texture is to be assigned (&amp;quot;albedo&amp;quot;, &amp;quot;normal&amp;quot;, &amp;quot;parameter&amp;quot;, &amp;quot;detail-albedo&amp;quot; or &amp;quot;detail-normal&amp;quot;). If this list is present at all, it overrides ALL automatic texture assignment from the FBX file; a partial override is not supported. The following subtags are accepted within each texture container:&lt;br /&gt;
** &#039;texture-resource&#039; - A string within the provides the texture resource name (eg. &amp;quot;foo.texture&amp;quot;). As always, texture resource names are equivalent to texture.txt file names without the trailing &amp;quot;.txt&amp;quot;. The resource name may include sub-folder or parent-folder path prefixes, which are resolved relative to the folder containing the metadata file.&lt;br /&gt;
* &#039;bend-normals-upward-ratio&#039; - The default value (0.0) will not modify the mesh normals imported from FBX. The maximal value (1.0) will force the normals to point directly upward. Mid-range values may be used, although care should be taken with normals which are pointing straight downward to start with. This is supported from v4.7 and will be ignored in any prior version. As Trainz is Z-up, &amp;quot;directly upward&amp;quot; means (0.0, 0.0, 1.0).&lt;br /&gt;
* &#039;clutter-wind-type&#039; - Supported in [[&amp;quot;Trainz-build&amp;quot; number|content format v5.4]] and later. This tag only applies to materials of type [[m.foliage]]. The details of this attribute can be found [[m.foliage|here]].&lt;br /&gt;
* &#039;clutter-sample-method&#039; - Supported in [[&amp;quot;Trainz-build&amp;quot; number|content format v5.4]] and later. This only applies pertains to materials of type [[m.foliage]]. The details of this attribute can be found [[m.foliage|here]].&lt;br /&gt;
* &#039;clutter-geometry-root&#039; - Supported in [[&amp;quot;Trainz-build&amp;quot; number|content format v5.4]] and later. This only applies pertains to materials of type [[m.foliage]]. The details of this attribute can be found [[m.foliage|here]].&lt;br /&gt;
= Mesh Metadata File Example =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;materials&lt;br /&gt;
{&lt;br /&gt;
  example0&lt;br /&gt;
  {&lt;br /&gt;
    two-sided 1&lt;br /&gt;
    material-type &amp;quot;pbrmetal&amp;quot;&lt;br /&gt;
    bend-normals-upward-ratio 0.0&lt;br /&gt;
    textures&lt;br /&gt;
    {&lt;br /&gt;
      albedo&lt;br /&gt;
      {&lt;br /&gt;
        texture-resource &amp;quot;albedo.texture&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
      normal&lt;br /&gt;
      {&lt;br /&gt;
        texture-resource &amp;quot;normal.texture&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
      parameter&lt;br /&gt;
      {&lt;br /&gt;
        texture-resource &amp;quot;parameter.texture&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  example1.m.onetex&lt;br /&gt;
  {&lt;br /&gt;
    two-sided 1&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=M.foliage&amp;diff=40007</id>
		<title>M.foliage</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=M.foliage&amp;diff=40007"/>
		<updated>2024-02-13T08:43:20Z</updated>

		<summary type="html">&lt;p&gt;Microlem: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[m.foliage]] is a variation on the [[m.pbrmetal]] material, supported in assets using trainz-build 5.4 and up.&lt;br /&gt;
&lt;br /&gt;
This material is intended for use with the [[Clutter Effect Layer]], and is tuned to suit that purpose to the detriment of any other possible use-case. While it is permissible to use the material with non-clutter asset types (scenery, traincars, etc.), it may result in visual artifacts or errors if configured improperly. We reserve the right to make changes to the behaviour of the material in ways that do not impact negatively on the clutter effect layer usage, even where those changes negatively impact other uses. For this reason, and because performance of an m.foliage asset is likely to be lower than an equivalent m.pbrmetal asset, it is recommended that m.foliage is used for a non-clutter asset only where substantial performance and visual gains are possible which cannot be achieved using other techniques.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
m.foliage introduces support for per-vertex procedural wind animation and ground alignment, to be used with clutter effect layers.&lt;br /&gt;
&lt;br /&gt;
NOTE: This material pertains to meshes which require advanced wind animation or ground alignment. If your clutter mesh is intended to be a static object without ground shearing, the [[m.clutter]] material should be used instead.&lt;br /&gt;
&lt;br /&gt;
[[File:Foliage_animation_1.gif|border|middle|x500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All PBR materials are defined using a multitude of texture channels (not just a simple RGB image) which define various aspects of the material on a per-texel basis. One major advantage of this approach is that a single in-game [[material]] can be used to display various different real-world materials, rather than requiring multiple separate in-game materials with different parameters. Trainz uses a Metallic/Roughness style [[Physically Based Rendering|PBR workflow]].&lt;br /&gt;
&lt;br /&gt;
This page describes [[&amp;quot;Trainz-build&amp;quot; number|content format v5.4]] and assumes that the [[FBX file format]] is used as a data source for any meshes.&lt;br /&gt;
&lt;br /&gt;
= Mesh Metadata Config =&lt;br /&gt;
&lt;br /&gt;
m.foliage supports several attributes which must be configured through the use of a [[mesh metadata file]].&lt;br /&gt;
&lt;br /&gt;
Listed below are the mesh metadata tags associated with m.foliage, and their meaning.&lt;br /&gt;
&lt;br /&gt;
==clutter-wind-type==&lt;br /&gt;
&lt;br /&gt;
m.foliage supports three wind animation modes, specified by the &#039;&#039;clutter-wind-type&#039;&#039; tag:&lt;br /&gt;
&lt;br /&gt;
===none===&lt;br /&gt;
Default behavior. Wind will not affect this material.&lt;br /&gt;
&lt;br /&gt;
===vertex-color===&lt;br /&gt;
In this wind mode, the mesh vertex color represents the wind strength multiplier on a per-vertex basis (i.e. how far each vertex is allowed deviate from its initial position in windy conditions).&lt;br /&gt;
This is useful for assets such as trees or shrubs, which may need explicit control over how the individual vertices of leaves or branches are permitted to sway in the wind.&lt;br /&gt;
&lt;br /&gt;
The vertex color channels control the following values:&lt;br /&gt;
&lt;br /&gt;
R:&lt;br /&gt;
Wind strength factor [0-1].&lt;br /&gt;
&lt;br /&gt;
GBA:&lt;br /&gt;
Currently unused. Care should be taken to ensure the green and blue channels remain 0, as they may become used by this material in future.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Authoring vertex color data: TBA&lt;br /&gt;
&lt;br /&gt;
===position-z===&lt;br /&gt;
In this wind mode, the vertex Z position is used as the wind strength factor (Higher Z = sways more intensely in the wind).&lt;br /&gt;
This is useful for dense meshes, such as grass blades, where the root of each blade should remain fixed in place on the ground while the tips sway fully in the wind.&lt;br /&gt;
&lt;br /&gt;
==clutter-sample-method==&lt;br /&gt;
&lt;br /&gt;
m.foliage supports three ground alignment/shear modes, specified by the &#039;&#039;clutter-sample-method&#039;&#039; tag:&lt;br /&gt;
&lt;br /&gt;
===origin===&lt;br /&gt;
Default behavior. No change is made to the vertex position depending on the ground height. This matches existing clutter behavior.&lt;br /&gt;
&lt;br /&gt;
===per-vertex===&lt;br /&gt;
In this mode, each vertex will be offset based on the ground height directly below it. For instance, on meshes where all vertices are Z=0, this results in the mesh being projected directly onto the ground geometry.&lt;br /&gt;
This mode is useful for large dense ground cover meshes, or &#039;fake&#039; grass meshes that use a simple billboard card rather than individually modeled blades. These meshes have no discernable &#039;roots&#039; and thus must deform smoothly and continuously onto the ground rather than discretely.&lt;br /&gt;
This mode is NOT recommended for use on meshes featuring individually modeled grass blades. Those meshes should use the &#039;&#039;contiguous-geometry&#039;&#039; mode, documented below.&lt;br /&gt;
&lt;br /&gt;
===contiguous-geometry===&lt;br /&gt;
In this mode, vertices will align to the ground intelligently as a group, determined by Trainz based on loose/unconnected geometry within the mesh.&lt;br /&gt;
This mode is most useful for grass meshes featuring individually modeled blades. It allows each connected blade in a mesh to snap to the ground as a single unit, preventing distortion effects that would otherwise be caused by rough or noisy ground height.&lt;br /&gt;
&lt;br /&gt;
The contiguous-geometry sample point is determined according to the value of the clutter-geometry-root tag.&lt;br /&gt;
clutter-geometry-root can be one of three values:&lt;br /&gt;
&lt;br /&gt;
* bottom - The vertex with the lowest Z position in each sample group is used as the sample location. This is the default behavior, and is the most typical for meshes featuring grass blades.&lt;br /&gt;
&lt;br /&gt;
* top - The vertex with the highest Z position in each sample group is used as the sample location.&lt;br /&gt;
&lt;br /&gt;
* center - The bounding box center of each sample group is used as the sample location.&lt;br /&gt;
&lt;br /&gt;
== Mesh Metadata File Example ==&lt;br /&gt;
&lt;br /&gt;
It is recommended to use the bend-normals-upward-ratio tag with grass meshes using m.foliage, as this allows the grass blades to be more convincingly lit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;materials&lt;br /&gt;
{&lt;br /&gt;
    grass.m.foliage&lt;br /&gt;
    {&lt;br /&gt;
        clutter-sample-method       per-vertex&lt;br /&gt;
        clutter-wind-type           position-z&lt;br /&gt;
        two-sided                   0&lt;br /&gt;
        bend-normals-upward-ratio   1.0			&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Texture Slots=&lt;br /&gt;
The following texture slots are used for this material. All textures should typically have the same dimensions unless they represent a uniform color, however this is not strictly enforced.&lt;br /&gt;
&lt;br /&gt;
==Albedo==&lt;br /&gt;
RGB: The [[albedo map]] defines the base color of each texel. The sRGB color space is used.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Albedo Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Grass_12_albedo.png|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
A: The alpha channel provides a greyscale [[blended alpha]] channel. Black indicates full transparency. White indicates full opacity. Mid levels offer partial transparency. If the alpha channel is omitted, this material becomes fully opaque but still suffers from a number of drawbacks, unlike the truly opaque [[m.pbrmetal]]. Note that unlike legacy Trainz materials, PBR materials do not autodetect opacity mode based on the texture in use. The content creator must select the appropriate material for their desired outcome.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Alpha Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Grass_12_alpha.png|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
The full texture is available here: [[File:Grass_12_albedo.tga]]&lt;br /&gt;
&lt;br /&gt;
==Normal==&lt;br /&gt;
RGB: Surface [[normal map]]. This defines which way the surface is facing, relative to the interpolated vertex normals. Since this is an XYZ format rather than color data, it should never be modified in Photoshop. Using Photoshop to add a fourth channel or copy/paste smaller textures into a [[texture atlas]] is acceptable. Per-pixel manipulation or use of filters on the &amp;quot;RGB&amp;quot; channels is not acceptable.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Normal Texture Example&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrnormalmap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
==Parameter==&lt;br /&gt;
This texture is comprised of four separate channels which each form a separate data element. Linear color space (not sRGB) is used for these channels.&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersall.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
R: Emissive. This causes the texture to have an internal glow, even when no external light is present. Used for phosphors, permanently-lit markings, etc. The glow color is based on the albedo. Note that this glow does not cast light upon surrounding surfaces except via the Bloom post-processing effect.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parameters (Emissive - Red Channel) Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersemissivemap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
G: Roughness. Defines whether the surface reflections are shiny (0.0) or matte (1.0). See the [[Physically Based Rendering|PBR metal workflow]] for details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parameters (Roughness - Green Channel) Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersroughnessmap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
B: Ambient Occlusion. Defines whether the surface is exposed to ambient lighting conditions (1.0) or affected only by direct lighting (0.0).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parameters (Ambient Occlusion - Blue Channel) Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersambientocclusionmap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
A: Metallicity. Defines whether the surface is metallic (1.0) with the albedo used to colorize reflected light, or dielectric (0.0) with the albedo used to colorize the surface. While intermediate values are not physically accurate, they may be used to emulate subsurfaces which are partially metallic. See the [[Physically Based Rendering|PBR metal workflow]] for details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parameters (Metallic - Alpha Channel) Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersmetallicmap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Examples=&lt;br /&gt;
&lt;br /&gt;
[[File:Foliage_blender_crop.png|border|middle|x300px]]&lt;br /&gt;
[[File:Foliage_animation_2.gif|border|middle|x300px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example asset (blend + CDP) download:&lt;br /&gt;
&lt;br /&gt;
[https://dl1.n3vgames.com/downloads/content/foliage/m.foliage-grass-12-sample-source.zip Sample asset and source files]&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=M.foliage&amp;diff=40006</id>
		<title>M.foliage</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=M.foliage&amp;diff=40006"/>
		<updated>2024-02-13T08:38:30Z</updated>

		<summary type="html">&lt;p&gt;Microlem: Created page with &amp;quot;m.foliage is a variation on the m.pbrmetal material, supported in assets using trainz-build 5.4 and up.  This material is intended for use with the [[Clutter Effect La...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[m.foliage]] is a variation on the [[m.pbrmetal]] material, supported in assets using trainz-build 5.4 and up.&lt;br /&gt;
&lt;br /&gt;
This material is intended for use with the [[Clutter Effect Layer]], and is tuned to suit that purpose to the detriment of any other possible use-case. While it is permissible to use the material with non-clutter asset types (scenery, traincars, etc.), it may result in visual artifacts or errors if configured improperly. We reserve the right to make changes to the behaviour of the material in ways that do not impact negatively on the clutter effect layer usage, even where those changes negatively impact other uses. For this reason, and because performance of an m.foliage asset is likely to be lower than an equivalent m.pbrmetal asset, it is recommended that m.foliage is used for a non-clutter asset only where substantial performance and visual gains are possible which cannot be achieved using other techniques.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
m.foliage introduces support for per-vertex procedural wind animation and ground alignment, to be used with clutter effect layers.&lt;br /&gt;
&lt;br /&gt;
NOTE: This material pertains to meshes which require advanced wind animation or ground alignment. If your clutter mesh is intended to be a static object without ground shearing, the [[m.clutter]] material should be used instead.&lt;br /&gt;
&lt;br /&gt;
[[File:Foliage_animation_1.gif|border|middle|x500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All PBR materials are defined using a multitude of texture channels (not just a simple RGB image) which define various aspects of the material on a per-texel basis. One major advantage of this approach is that a single in-game [[material]] can be used to display various different real-world materials, rather than requiring multiple separate in-game materials with different parameters. Trainz uses a Metallic/Roughness style [[Physically Based Rendering|PBR workflow]].&lt;br /&gt;
&lt;br /&gt;
This page describes [[&amp;quot;Trainz-build&amp;quot; number|content format v5.4]] and assumes that the [[FBX file format]] is used as a data source for any meshes.&lt;br /&gt;
&lt;br /&gt;
= Mesh Metadata Config =&lt;br /&gt;
&lt;br /&gt;
m.foliage supports several attributes which must be configured through the use of a [[mesh metadata file]].&lt;br /&gt;
&lt;br /&gt;
Listed below are the mesh metadata tags associated with m.foliage, and their meaning.&lt;br /&gt;
&lt;br /&gt;
==clutter-wind-type==&lt;br /&gt;
&lt;br /&gt;
m.foliage supports three wind animation modes, specified by the &#039;&#039;clutter-wind-type&#039;&#039; tag:&lt;br /&gt;
&lt;br /&gt;
===none===&lt;br /&gt;
Default behavior. Wind will not affect this material.&lt;br /&gt;
&lt;br /&gt;
===vertex-color===&lt;br /&gt;
In this wind mode, the mesh vertex color represents the wind strength multiplier on a per-vertex basis (i.e. how far each vertex is allowed deviate from its initial position in windy conditions).&lt;br /&gt;
This is useful for assets such as trees or shrubs, which may need explicit control over how the individual vertices of leaves or branches are permitted to sway in the wind.&lt;br /&gt;
&lt;br /&gt;
The vertex color channels control the following values:&lt;br /&gt;
&lt;br /&gt;
R:&lt;br /&gt;
Wind strength factor [0-1].&lt;br /&gt;
&lt;br /&gt;
GBA:&lt;br /&gt;
Currently unused. Care should be taken to ensure the green and blue channels remain 0, as they may become used by this material in future.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Authoring vertex color data: TBA&lt;br /&gt;
&lt;br /&gt;
===position-z===&lt;br /&gt;
In this wind mode, the vertex Z position is used as the wind strength factor (Higher Z = sways more intensely in the wind).&lt;br /&gt;
This is useful for dense meshes, such as grass blades, where the root of each blade should remain fixed in place on the ground while the tips sway fully in the wind.&lt;br /&gt;
&lt;br /&gt;
==clutter-sample-method==&lt;br /&gt;
&lt;br /&gt;
m.foliage supports three ground alignment/shear modes, specified by the &#039;&#039;clutter-sample-method&#039;&#039; tag:&lt;br /&gt;
&lt;br /&gt;
===origin===&lt;br /&gt;
Default behavior. No change is made to the vertex position depending on the ground height. This matches existing clutter behavior.&lt;br /&gt;
&lt;br /&gt;
===per-vertex===&lt;br /&gt;
In this mode, each vertex will be offset based on the ground height directly below it. For instance, on meshes where all vertices are Z=0, this results in the mesh being projected directly onto the ground geometry.&lt;br /&gt;
This mode is useful for large dense ground cover meshes, or &#039;fake&#039; grass meshes that use a simple billboard card rather than individually modeled blades. These meshes have no discernable &#039;roots&#039; and thus must deform smoothly and continuously onto the ground rather than discretely.&lt;br /&gt;
This mode is NOT recommended for use on meshes featuring individually modeled grass blades. Those meshes should use the &#039;&#039;contiguous-geometry&#039;&#039; mode, documented below.&lt;br /&gt;
&lt;br /&gt;
===contiguous-geometry===&lt;br /&gt;
In this mode, vertices will align to the ground intelligently as a group, determined by Trainz based on loose/unconnected geometry within the mesh.&lt;br /&gt;
This mode is most useful for grass meshes featuring individually modeled blades. It allows each connected blade in a mesh to snap to the ground as a single unit, preventing distortion effects that would otherwise be caused by rough or noisy ground height.&lt;br /&gt;
&lt;br /&gt;
The contiguous-geometry sample point is determined according to the value of the clutter-geometry-root tag.&lt;br /&gt;
clutter-geometry-root can be one of three values:&lt;br /&gt;
&lt;br /&gt;
=====bottom=====&lt;br /&gt;
The vertex with the lowest Z position in each sample group is used as the sample location. This is the default behavior, and is the most typical for meshes featuring grass blades.&lt;br /&gt;
&lt;br /&gt;
=====top=====&lt;br /&gt;
The vertex with the highest Z position in each sample group is used as the sample location.&lt;br /&gt;
&lt;br /&gt;
=====center=====&lt;br /&gt;
The bounding box center of each sample group is used as the sample location.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mesh Metadata File Example ==&lt;br /&gt;
&lt;br /&gt;
It is recommended to use the bend-normals-upward-ratio tag with grass meshes using m.foliage, as this allows the grass blades to be more convincingly lit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;materials&lt;br /&gt;
{&lt;br /&gt;
    grass.m.foliage&lt;br /&gt;
    {&lt;br /&gt;
        clutter-sample-method       per-vertex&lt;br /&gt;
        clutter-wind-type           position-z&lt;br /&gt;
        two-sided                   0&lt;br /&gt;
        bend-normals-upward-ratio   1.0			&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Texture Slots=&lt;br /&gt;
The following texture slots are used for this material. All textures should typically have the same dimensions unless they represent a uniform color, however this is not strictly enforced.&lt;br /&gt;
&lt;br /&gt;
==Albedo==&lt;br /&gt;
RGB: The [[albedo map]] defines the base color of each texel. The sRGB color space is used.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Albedo Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Grass_12_albedo.png|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
A: The alpha channel provides a greyscale [[blended alpha]] channel. Black indicates full transparency. White indicates full opacity. Mid levels offer partial transparency. If the alpha channel is omitted, this material becomes fully opaque but still suffers from a number of drawbacks, unlike the truly opaque [[m.pbrmetal]]. Note that unlike legacy Trainz materials, PBR materials do not autodetect opacity mode based on the texture in use. The content creator must select the appropriate material for their desired outcome.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Alpha Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Grass_12_alpha.png|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
The full texture is available here: [[File:Grass_12_albedo.tga]]&lt;br /&gt;
&lt;br /&gt;
==Normal==&lt;br /&gt;
RGB: Surface [[normal map]]. This defines which way the surface is facing, relative to the interpolated vertex normals. Since this is an XYZ format rather than color data, it should never be modified in Photoshop. Using Photoshop to add a fourth channel or copy/paste smaller textures into a [[texture atlas]] is acceptable. Per-pixel manipulation or use of filters on the &amp;quot;RGB&amp;quot; channels is not acceptable.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Normal Texture Example&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrnormalmap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
==Parameter==&lt;br /&gt;
This texture is comprised of four separate channels which each form a separate data element. Linear color space (not sRGB) is used for these channels.&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersall.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
R: Emissive. This causes the texture to have an internal glow, even when no external light is present. Used for phosphors, permanently-lit markings, etc. The glow color is based on the albedo. Note that this glow does not cast light upon surrounding surfaces except via the Bloom post-processing effect.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parameters (Emissive - Red Channel) Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersemissivemap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
G: Roughness. Defines whether the surface reflections are shiny (0.0) or matte (1.0). See the [[Physically Based Rendering|PBR metal workflow]] for details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parameters (Roughness - Green Channel) Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersroughnessmap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
B: Ambient Occlusion. Defines whether the surface is exposed to ambient lighting conditions (1.0) or affected only by direct lighting (0.0).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parameters (Ambient Occlusion - Blue Channel) Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersambientocclusionmap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
A: Metallicity. Defines whether the surface is metallic (1.0) with the albedo used to colorize reflected light, or dielectric (0.0) with the albedo used to colorize the surface. While intermediate values are not physically accurate, they may be used to emulate subsurfaces which are partially metallic. See the [[Physically Based Rendering|PBR metal workflow]] for details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parameters (Metallic - Alpha Channel) Texture Example&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pbrparametersmetallicmap1.jpg|border|middle|x200px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Examples=&lt;br /&gt;
&lt;br /&gt;
[[File:Foliage_blender_crop.png|border|middle|x300px]]&lt;br /&gt;
[[File:Foliage_animation_2.gif|border|middle|x300px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example asset (blend + CDP) download:&lt;br /&gt;
&lt;br /&gt;
[https://dl1.n3vgames.com/downloads/content/foliage/m.foliage-grass-12-sample-source.zip Sample asset and source files]&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=File:Grass_12_alpha.png&amp;diff=40005</id>
		<title>File:Grass 12 alpha.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=File:Grass_12_alpha.png&amp;diff=40005"/>
		<updated>2024-02-13T07:46:34Z</updated>

		<summary type="html">&lt;p&gt;Microlem: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=File:Grass_12_albedo.png&amp;diff=40004</id>
		<title>File:Grass 12 albedo.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=File:Grass_12_albedo.png&amp;diff=40004"/>
		<updated>2024-02-13T07:44:16Z</updated>

		<summary type="html">&lt;p&gt;Microlem: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=File:Grass_12_albedo.tga&amp;diff=40003</id>
		<title>File:Grass 12 albedo.tga</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=File:Grass_12_albedo.tga&amp;diff=40003"/>
		<updated>2024-02-13T07:43:21Z</updated>

		<summary type="html">&lt;p&gt;Microlem: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=File:Foliage_animation_2.gif&amp;diff=40002</id>
		<title>File:Foliage animation 2.gif</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=File:Foliage_animation_2.gif&amp;diff=40002"/>
		<updated>2024-02-13T07:37:34Z</updated>

		<summary type="html">&lt;p&gt;Microlem: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=File:Foliage_blender_crop.png&amp;diff=40001</id>
		<title>File:Foliage blender crop.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=File:Foliage_blender_crop.png&amp;diff=40001"/>
		<updated>2024-02-13T07:35:11Z</updated>

		<summary type="html">&lt;p&gt;Microlem: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=File:Foliage_blender_example.jpg&amp;diff=40000</id>
		<title>File:Foliage blender example.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=File:Foliage_blender_example.jpg&amp;diff=40000"/>
		<updated>2024-02-13T07:30:32Z</updated>

		<summary type="html">&lt;p&gt;Microlem: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=File:Foliage_animation_1.gif&amp;diff=39998</id>
		<title>File:Foliage animation 1.gif</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=File:Foliage_animation_1.gif&amp;diff=39998"/>
		<updated>2024-02-13T07:28:18Z</updated>

		<summary type="html">&lt;p&gt;Microlem: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=KIND_tni-physics-plugin&amp;diff=27913</id>
		<title>KIND tni-physics-plugin</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=KIND_tni-physics-plugin&amp;diff=27913"/>
		<updated>2021-02-15T03:22:23Z</updated>

		<summary type="html">&lt;p&gt;Microlem: Created page with &amp;quot;KIND tni-physics-plugin is an asset type which provides control of the internal train physics for any traincar, via TrainzNativeInterface. This asset type requires nat...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[KIND tni-physics-plugin]] is an asset type which provides control of the internal train physics for any traincar, via [[TrainzNativeInterface]]. This asset type requires native code support and its use is restricted to authorised TNI content creators only.&lt;br /&gt;
&lt;br /&gt;
==KIND Hierarchy==&lt;br /&gt;
===Parent Classes===&lt;br /&gt;
* [[KIND Library]]&lt;br /&gt;
===Child Classes===&lt;br /&gt;
* &#039;&#039;none&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Supported Tags==&lt;br /&gt;
Each tni-physics-plugin asset supports the following tags:&lt;br /&gt;
&lt;br /&gt;
  kind                                    &amp;quot;tni-physics-plugin&amp;quot;&lt;br /&gt;
  tni-library-name                        &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
====tni-library-name====&lt;br /&gt;
:Type: string&lt;br /&gt;
:Desc: Specifies the filename of the [[TNI_Core_Interface|plugin DLL]] to load (minus the platform-specific file extension). This plugin is expected to return a processing priority and handle a relevant locomotive&#039;s physics requests through [[TNI_Physics_Interface|TNIPhysics]].&lt;br /&gt;
&lt;br /&gt;
==Example Config.txt==&lt;br /&gt;
Sample [[config.txt file]] for a tni-physics-plugin asset, with some standard tags excluded for brevity:&lt;br /&gt;
&lt;br /&gt;
  kuid                                    &amp;lt;kuid:401543:1085&amp;gt;&lt;br /&gt;
  kind                                    &amp;quot;tni-physics-plugin&amp;quot;&lt;br /&gt;
  trainz-build                            4.7&lt;br /&gt;
  username                                &amp;quot;Core Train Physics Plugin&amp;quot;&lt;br /&gt;
  tni-library-name                        &amp;quot;TNIPhysicsCore&amp;quot;&lt;br /&gt;
  category-class                          &amp;quot;YL&amp;quot;&lt;br /&gt;
  description                             &amp;quot;TNI plugin for default train physics&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Categories==&lt;br /&gt;
[[Category:Asset KIND|T]]&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=TrainzNativeInterface&amp;diff=27912</id>
		<title>TrainzNativeInterface</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=TrainzNativeInterface&amp;diff=27912"/>
		<updated>2021-02-15T03:04:44Z</updated>

		<summary type="html">&lt;p&gt;Microlem: Add TNIPhysics link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[TrainzNativeInterface]] is a plugin system which allows native-code developers to create extensions which perform tasks normally inaccessible from within the Trainz environment, such as communicating with custom hardware or external software. This allows third-party developers to extend Trainz into areas where the [[N3V Games]] development team do not presently have the resources to undertake core development.&lt;br /&gt;
&lt;br /&gt;
Some sample ideas which might be viable candidates for TNI plugins:&lt;br /&gt;
* Connecting the controls in a real Train cab to a computer running Trainz.&lt;br /&gt;
* Controlling a model train layout from within Trainz Driver.&lt;br /&gt;
* Importing from third-party data sources into Surveyor.&lt;br /&gt;
* Implementing a custom train physics and/or train sound system for a specific series of locomotives.&lt;br /&gt;
* Interfacing with third-party train scheduling software.&lt;br /&gt;
&lt;br /&gt;
Please note that this page is a &amp;quot;beginner&#039;s summary&amp;quot; of the TNI development process, and is not in itself a legal agreement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=TNI Developer Requirements=&lt;br /&gt;
Creating a TNI plugin imposes a number of requirements on the developer:&lt;br /&gt;
* The developer program resources are in English, and the developer is required to provide a representative who can communicate technical concepts effectively in English. N3V Games is unfortunately unable to provide translation resources.&lt;br /&gt;
* The developer is required to agree to a development license. The license is intended to protect the developer, N3V Games, and the Trainz end users by defining a number of expectations and responsibilities. The license is not negotiable.&lt;br /&gt;
* The developer is expected to provide a short project proposal, which allows N3V Games to confirm that a TNI plugin is an appropriate solution for the project.&lt;br /&gt;
* The developer is expected to provide a development schedule detailing the proposed project, estimated delivery timeframe, business model, etc. Freeware and Open Source developers are welcome to apply.&lt;br /&gt;
* The developer is required to have an existing understanding of native C/C++ coding practices including the development of DLLs. N3V Games cannot assist with learning native code development.&lt;br /&gt;
* The developer must be willing to provide N3V Games with source-level access to the TNI plugin and all linked libraries for review and code-signing. If the plugin communicates with a third-party application, the source code of the application is not required.&lt;br /&gt;
* The developer must be prepared to address technical concerns raised by N3V Games, including bugs, stability concerns, and resource usage (memory, cpu, etc.) concerns.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=TNI Proposal Review=&lt;br /&gt;
Acceptance of a TNI development proposal is a complex process, but the following quick guide will help you determine if your idea is likely to be approved:&lt;br /&gt;
&lt;br /&gt;
* Can your proposal be implemented effectively in TrainzScript? If yes, we are unlikely to approve a native solution.&lt;br /&gt;
* Does your proposal function as a reusable component? We are much more likely to approve projects which can be reused by many Trainz developers than a project which can only be deployed by the author. Individual components which work together via a documented API are preferred over monolithic systems which don&#039;t allow individual replacement of the various components.&lt;br /&gt;
* Does your proposal duplicate built-in functionality? We are unlikely to approve anything which duplicates core functionality. Exceptions to this guideline will be explicitly noted.&lt;br /&gt;
* Do you have the necessary resources to develop your proposal? Supporting TNI developers costs us time and money, which we will prefer to spend on developers who have the technical know-how or other necessary resources to complete their project.&lt;br /&gt;
* Does your proposal introduce unnecessary dependencies on third-party software or hardware? If there are two practical ways to do something, one which introduces dependencies and one which does not, we will favor the approach which does not.&lt;br /&gt;
* Does your proposed DLL require access to functionality outside that provided by the TrainzNativeInterface DLL? Direct usage of external functionality (including OS-provided functions) is not recommended and will only be approved if strictly necessary.&lt;br /&gt;
* Is your proposal mindful of user privacy, collecting only the minimum amount of data required to undertake its stated goal? Data collection that is not strictly required for a plugin&#039;s primary purpose will not be approved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=TNI Codesigning=&lt;br /&gt;
As with any native software, TNI plugins are capable of performing any action authorised to the user account under which the Trainz application is running, typically including reading and writing user documents, changing security settings, and accessing the internet. As a security precaution, and to ensure ongoing compatibility, N3V Games does not allow ad hoc distribution of TNI plugin DLLs.&lt;br /&gt;
&lt;br /&gt;
Access to the TNI development environment requires that the developer agrees to and abides by the TNI developer license agreement. Failure to abide by the terms of the agreement will make the developer subject to permanent ejection from the TNI developer program, meaning that they will no longer be able to develop TNI plugins or run development versions of plugins.&lt;br /&gt;
&lt;br /&gt;
Outside of the TNI development environment, TNI plugins require code-signing before they can be deployed. Final build and code-sign of a TNI DLL is performed by N3V Games using source code provided by the developer. The (code-signed) distribution version of the TNI plugin may then be distributed according to the terms of the TNI developer license agreement.&lt;br /&gt;
&lt;br /&gt;
Users require an active internet connection in order to authorise TNI plugins. Users who have no internet connection, or who choose to run Trainz in &amp;quot;offline mode&amp;quot; (where applicable) will not be able to utilise TNI plugins. The internet connection is not required to be permanently active while the TNI plugin is in use.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Interfacing with Trainz=&lt;br /&gt;
TNI is not a magic wand to do anything within the Trainz environment. In order to access or replace any Trainz functionality, a relevant interface must be exposed by Trainz. Additional interfaces will be introduced over time as development resources allow. Please read and understand the capabilities of the interfaces to ensure that your project idea is actually feasible within the capabilities of TNI.&lt;br /&gt;
&lt;br /&gt;
The following interfaces are implemented or planned. No release schedule is available for interfaces which are not yet implemented.&lt;br /&gt;
&lt;br /&gt;
* [[TNI Core Interface]]&lt;br /&gt;
* [[TNI TrainzScript Interface]]&lt;br /&gt;
* [[TNI Controls Interface]]&lt;br /&gt;
* [[TNI Socket Interface]]&lt;br /&gt;
* [[TNI Physics Interface]]&lt;br /&gt;
* TNI Sound Interface - Not yet implemented.&lt;br /&gt;
* TNI Graphics Interface - Not yet implemented.&lt;br /&gt;
* TNI User Interface - Not yet implemented.&lt;br /&gt;
* TNI Asset Database Interface - Not yet implemented.&lt;br /&gt;
* TNI Surveyor Interface - Not yet implemented.&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=TNI_Physics_Interface&amp;diff=27911</id>
		<title>TNI Physics Interface</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=TNI_Physics_Interface&amp;diff=27911"/>
		<updated>2021-02-15T03:03:01Z</updated>

		<summary type="html">&lt;p&gt;Microlem: Created page with &amp;quot;TNIPhysics is a builtin TNILibrary within Trainz which allows physics plugin assets to control all the internal train physics for any traincar. Thi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TNIPhysics is a builtin TNILibrary within Trainz which allows [[KIND tni-physics-plugin|physics plugin]] assets to control all the internal train physics for any traincar. This includes engine physics, braking systems and shared systems such as track/air resistance. It doesn&#039;t currently include systems such as random motion, coupling interactions, collisions or derailments.&lt;br /&gt;
&lt;br /&gt;
Before continuing, it is recommended you first familiarise yourself with the following pages:&lt;br /&gt;
* [[TrainzNativeInterface]] - For an overview of TNI and the associated licensing requirements&lt;br /&gt;
* [[TNI Core Interface]] - For details of the core TNI functionality, object types, etc.&lt;br /&gt;
* [[KIND tni-physics-plugin]] - For the specification of the physics plugin asset kind.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;NOTE: This page is a work in progress, and reflects technologies which are not yet present in retail versions of Trainz.&#039;&#039;&lt;br /&gt;
&#039;&#039;As of publication, TNI Physics is currently in beta release. Information may change.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
TNIPhysics is initialised at game startup, and will automatically locate and load any installed TNI physics plugin assets at world/map load time. All TNIPhysics plugins must have a QueryProcessingPriority function, which will allow Trainz to determine which of the user&#039;s installed plugins is best suited to handle a request. TNIPhysics will make all physics update calls through a plugin&#039;s LibraryCall interface.&lt;br /&gt;
&lt;br /&gt;
The specific function calls supported by TNIPhysics are detailed in the next section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TNIPhysics Library Calls==&lt;br /&gt;
&lt;br /&gt;
====Init====&lt;br /&gt;
TNIPhysics will call the plugin library DLL with the function name &amp;quot;Init&amp;quot; on initialization. This call can safely be ignored if no initialisation is necessary. This function expects no return object, and takes no parameters.&lt;br /&gt;
&lt;br /&gt;
====QueryProcessingPriority====&lt;br /&gt;
This function is called from Trainz code to query the processing priority of a plugin for a given traincar. The function will be called across every plugin for every vehicle at load/creation time and when switching control modes (DCC vs cab). Whichever plugin returns the highest priority result will process the vehicle&#039;s physics. It has a single TNIPhysicsVehicle as the param, and expects a TNIInteger return result. The TNIPhysics_Priority enum defines a list of example return values, but the programmer is not constrained to using these defines.&lt;br /&gt;
*TNIPhysics_PriorityInvalid - Never use this plugin (-127)&lt;br /&gt;
*TNIPhysics_PriorityLowest - Only use this plugin if there&#039;s no other option (-20)&lt;br /&gt;
*TNIPhysics_PriorityLow - Prefer not using this plugin, but it might work ok (-10)&lt;br /&gt;
*TNIPhysics_PriorityDefault - This plugin can handle the request adequately (0). The builtin core plugin asset always returns this value.&lt;br /&gt;
*TNIPhysics_PriorityHigh - This plugin is somewhat specialised to handle the request (10)&lt;br /&gt;
*TNIPhysics_PriorityHighest - This plugin was built exactly for this request (20)&lt;br /&gt;
&lt;br /&gt;
====RegisterVehicle====&lt;br /&gt;
This function is called from Trainz code on the plugin which returns the highest valid result from a call to &amp;quot;QueryProcessingPriority&amp;quot;. It notifies a physics plugin that it has been selected to manage the vehicle, and should perform any appropriate internal initialisation. This function takes a single TNIPhysicsVehicle param (being the vehicle to register) and expects no return object.&lt;br /&gt;
&lt;br /&gt;
====UnregisterVehicle====&lt;br /&gt;
This function is the counter to RegisterVehicle, and instructs a plugin that it is no longer managing the physics for a particular vehicle. This will occur when the vehicle is deleted, or Trainz hands it over to a more appropriate plugin (based on the result of a call to the &amp;quot;QueryProcessingPriority&amp;quot; function). This function takes a single TNIPhysicsVehicle param (being the vehicle to unregister) and expects no return object. &lt;br /&gt;
&lt;br /&gt;
When called, the plugin should discard any internal data is has for the specified vehicle. If Trainz required anything to be saved, then a call to SaveVehicleState() will have already made.&lt;br /&gt;
&lt;br /&gt;
====ProcessPhysicsCommands====&lt;br /&gt;
The main vehicle update function. This function is called from Trainz code to process a physics command stream for a specific vehicle. The function takes a TNIArray object which contains the TNIPhysicsVehicle (element 0) and a TNIStream (element 1) containing the commands to run (see enum TNIPhysicsPluginCommand for a list of physics commands and their params). Trainz expects a TNIStream return result, containing a list of physics update commands to Trainz from the plugin (see enum TNIPhysicsGameCommand).&lt;br /&gt;
&lt;br /&gt;
==Physics Commands==&lt;br /&gt;
The ProcessPhysicsCommands LibraryCall employs incoming and outgoing command buffers to communicate physics information with Trainz.&lt;br /&gt;
The command buffer data is sequential - each command ID is written as a 16 bit integer, and will be followed followed by any relevant command parameters (see enum TNIPhysicsPluginCommand for specific command details).&lt;br /&gt;
&lt;br /&gt;
As this is a raw command stream it is critical that the programmer carefully reads the documentation on each specific command, and correctly reads off each parameter value, even if they are not being used by the plugin. Failure to correctly read all command parameters will result in corruption of the stream, and undefinied application behaviour.&lt;br /&gt;
&lt;br /&gt;
The stream has no terminating value, but stream end may be detected using the TNIStreamTell and TNIStreamGetSize functions, or simply by reading commands until failure is detected (e.g. &amp;lt;code&amp;gt;while (TNIStreamReadInt16(commandStream, 0))&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
The programmer must employ similar practices when writing the reply command stream. I.e. Each command is written as a 16 bit integer (TNIStreamWriteInt16), and must be followed by the parameters detailed in enum TNIPhysicsGameCommand. Failure to write data in the correct format will result in undefined behaviour within the application. &lt;br /&gt;
&lt;br /&gt;
==Incoming Commands (TNIPhysicsPluginCommand)==&lt;br /&gt;
Enumeration listing the possible physics commands the game may issue to a plugin. Commands and parameters will be written, in sequence, to the TNIStream param passed to the ProcessPhysicsCommands library call.&lt;br /&gt;
&lt;br /&gt;
====TNIP_UpdatePhysicsForVehicle====&lt;br /&gt;
The main physics update function. This is regularly called by Trainz code to update the traincar physics for a particular time period. This function takes two extra params for the front and rear coupled vehicles, but keep in mind these may be using different TNI plugins.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*float - The time interval to update for.&lt;br /&gt;
*TNIPhysicsVehicle - The front coupled vehicle.&lt;br /&gt;
*TNIPhysicsVehicle - The rear coupled vehicle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_AdjustMomentum====&lt;br /&gt;
Called from Trainz to notify of an adjustment to a vehicles momentum. This is typically used to apply the results of coupler physics interactions. Vehicles for which the plugin does not internally track momentum can safely ignore this call.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new vehicle momentum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_FinaliseFramePhysics====&lt;br /&gt;
Called by Trainz to notify that all updates relating to this vehicle for the current frame are complete. This includes all plugin updates and all coupler interactions. Plugins may use this as an appropriate location to synchronise plugin state to that of the game, or apply visible state changes only. At the time this call is made it is &amp;quot;too late&amp;quot; to perform or apply physics calculations for a given frame.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*float - The time interval that&#039;s been updated.&lt;br /&gt;
*double - The final momentum for this frame.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_NormalisePhysicsData====&lt;br /&gt;
Called following an external physics state update in order to perform any physics-mode-specific follow up validation/correction. Examples include after physics/control state replication in multiplayer.&lt;br /&gt;
&lt;br /&gt;
This command takes no parameters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SaveVehicleState====&lt;br /&gt;
Called by Trainz code to request save data for a specific vehicle. If the plugin maintains any internal state for the specified vehicle then this function should save that state, so that players are able to save and reload with seamless physics behaviour. The save state should be returned to the game by adding a TNIP_ReturnSaveState command to the library call result stream (see TNIPhysicsGameCommand for more). If the plugin tracks no state for the vehicle passed, then this call can be safely ignored.&lt;br /&gt;
&lt;br /&gt;
This command takes no parameters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_LoadVehicleState====&lt;br /&gt;
Called by Trainz code to load previously saved vehicle state. Note that this is always called, even if the plugin does not produce any save state when TNIP_SaveVehicleState is called. Also note that the the passed soup param may have been produced by a different plugin.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*TNISoup - A saved soup generated by a previous TNIP_SaveVehicleState call on this or another plugin. The soup will contain an AssetID param for the plugin that produced it, using the tag name &amp;quot;plugin-kuid&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SteamEngine_AddCoalToFire====&lt;br /&gt;
Called by Trainz code to add coal to a steam engine. For example, when the player uses the manual &amp;quot;Shovel coal&amp;quot; command.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The volume (not mass) of coal to add.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Outgoing Commands (TNIPhysicsGameCommand)==&lt;br /&gt;
Enumeration listing the possible physics commands a plugin may issue to the game. A TNIPhysics plugin may write these commands (and their params) to the TNIStream returned by a ProcessPhysicsCommands library call.&lt;br /&gt;
&lt;br /&gt;
====TNIP_UpdateVehicleBegin====&lt;br /&gt;
Specifies which vehicle a sequence of update commands refers to. Use of this command is not necessary, and by default any written commands will update the vehicle which ProcessPhysicsCommands() was called for. If, however, the plugin wishes to run commands for connection data on one of the coupled vehicles (such as brake pipes, etc) then this is used to specify that vehicle.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*TNIPhysicsVehicle - The vehicle to start updating.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_UpdateVehicleEnd====&lt;br /&gt;
Used to mark the end of a vehicle update stream. This will set the update vehicle to null. Following this, a new TNIP_UpdateVehicleBegin command *must* be written before any further update commands.&lt;br /&gt;
&lt;br /&gt;
This command takes no parameters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_ReturnSaveState====&lt;br /&gt;
Used to return the generated save state for a TNIP_SaveVehicleState command (documented above, in TNIPhysicsPluginCommand).&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*TNISoup - A soup containing the saved plugin state. The plugin should write enough state to adequately restore its current internal state for the given vehicle on reload. It is also courtesy to return known/common save data which this plugin itself may not use/require, but which may be useful/expected by other plugins (this aids in seemless plugin switchover during gameplay).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Engine Commands===&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetResistanceForce====&lt;br /&gt;
Sets the current resistant force for train movement. This includes all track resistance, slope resistance, and internal engine resistances.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The current resistance force, in Newtons.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetBrakingForce====&lt;br /&gt;
Sets the current braking force for the train. This is the force from any/all applied brakes.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The current braking force, in Newtons.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetEngineForce====&lt;br /&gt;
Sets the force currently being output by the engine.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The current engine force, in Newtons.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetAppliedEngineForce====&lt;br /&gt;
Sets the force currently being applied to the wheels by the engine. In other words, this is the engine force minus any wheelslip.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The current applied engine force, in Newtons.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetWheelslipForce====&lt;br /&gt;
Sets the amount of force currently being lost to wheelslip.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The current wheelslip force, in Newtons.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetCurrentDrawn====&lt;br /&gt;
Updates the current drawn stat.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The current being drawn, in Amps.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetPFXEnergyUseAmount====&lt;br /&gt;
Updates the &amp;quot;energy use&amp;quot; stat, which is used to generate the PFX &amp;quot;load&amp;quot; variable. This currently has no effect on traincar physics, just particle effects (smoke).&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The energy use for the current time interval.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetWheelMomentum====&lt;br /&gt;
Sets the current forward momentum for a traincar (i.e. this value will be negative if the traincar is not moving forwards).&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new forward momentum for the updated traincar, in Newton seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_AddWheelMomentum====&lt;br /&gt;
Adds momentum to the updated traincar. A negative (or positive, for backward travelling traincars) value may be used to remove momentum.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The momentum to add onto the traincar, in Newton seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetExtraEngineMass====&lt;br /&gt;
Sets the amount of &#039;extra&#039; engine mass a vehicle currently has. This is typically the fuel mass (water and coal) for steam locos.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The current extra engine mass, in kg.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetEngineParam====&lt;br /&gt;
Sets the value of a named engine param, as returned by the script &amp;lt;code&amp;gt;GetEngineParam()&amp;lt;/code&amp;gt; function on Vehicle. This is used to add support for custom named parameters, attempting to override the natively supported params may not work.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*TNILabel - The name of the engine parameter to add/update.&lt;br /&gt;
*double - The new value of the parameter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetEngineThrottle====&lt;br /&gt;
Sets the current engine throttle. This should gradually move toward the throttle setting, with some amount of latency.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new engine throttle amount (0 to 1).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetCompressorActive====&lt;br /&gt;
Sets whether the brake system compressor is active.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*int8_t - The new compressor state (0- off, 1-on).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetEqualiserPressure====&lt;br /&gt;
Sets the pressure of the brake system equaliser.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new equaliser pressure, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetMainReservoirPressure====&lt;br /&gt;
Sets the pressure of the brake system main reservoir.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new main reservoir pressure, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetAuxReservoirPressure====&lt;br /&gt;
Sets the pressure of the brake system auxiliary reservoir.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new auxiliary reservoir pressure, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetAutoBrakeCylinderPressure====&lt;br /&gt;
Sets the pressure of the brake cylinder.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new brake cylinder pressure, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetIndependentBrakeCylinderPressure====&lt;br /&gt;
Sets the pressure of the independent/loco brake cylinder.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new independent/loco brake cylinder pressure, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetTrainBrakePipePressure====&lt;br /&gt;
Sets the pressure of the main train brake pipe.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new train brake pipe pressure, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetEpReservoirPipePressure====&lt;br /&gt;
Sets the pressure of the electro-pneumatic brake pipe.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new electro-pneumatic brake pipe pressure, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetNo3PipePressure====&lt;br /&gt;
Sets the pressure of the no3 brake pipe.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new no3 brake pipe pressure, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetNo4PipePressure====&lt;br /&gt;
Sets the pressure of the no4 brake pipe.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new no4 brake pipe pressure, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetBrakePressureFlowRate====&lt;br /&gt;
Notifies of the brake pressure flow rate.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new brake pressure flow rate, in g/m^3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Steam Engine Commands===&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetCoalLevel====&lt;br /&gt;
Sets the coal level in a steam locomotive. This is the current ratio between the minimum (0) and maximum (1) coal levels for the firebox. i.e., a reading of 0 indicates the fire is at minimum coal, not that it&#039;s necessarily &amp;quot;empty&amp;quot;, and a value over 1 indicates the fire is over-filled with coal.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The current coal level in the firebox.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetWaterLevel====&lt;br /&gt;
Sets the water level in a steam locomotive. This is the current ratio between the minimum (0) and maximum (1) water levels for the boiler, as would be shown on the cab gauge(s). i.e., a reading of 0 indicates the boiler is at or below minimum, not that it&#039;s necessarily &amp;quot;empty&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The current water level in the boiler.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetBoilerPressure====&lt;br /&gt;
Sets the current pressure within the boiler, in pascals.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new boiler pressure, in pascals.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetSteamChestPressure====&lt;br /&gt;
Sets the current pressure within the steam chest, in pascals.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The new steam chest pressure, in pascals.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetThrashing====&lt;br /&gt;
Sets the amount the engine is being &#039;thrashed&#039;, as returned to script by a call to &amp;lt;code&amp;gt;Locomotive.GetEngineParam(&amp;quot;thrashing&amp;quot;);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*double - The amount the engine is being &#039;thrashed&#039;, 0 to 1 for normal engine operation, &amp;gt;1 for thrashing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_ConsumeCoal====&lt;br /&gt;
Informs Trainz to consume an amount of coal product, for use as steam engine fuel. The caller should first verify that there is sufficient fuel to meet the request, using TNIPhysicsGetVehicleCoalAvailable().&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*int32_t - The amount of product to consume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_ConsumeWater====&lt;br /&gt;
Informs Trainz to consume an amount of water product, for use as steam engine fuel. The caller should first verify that there is sufficient fuel to meet the request, using TNIPhysicsGetVehicleWaterAvailable().&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*int32_t - The amount of product to consume.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Effect Commands===&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetWheelAngularVelocity====&lt;br /&gt;
Sets the angular velocity of the wheels on a steam locomotive. This affects the value of the &amp;quot;cyclespeed2&amp;quot; PFX variable.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*float - The angular velocity of the driving wheels, in m/s.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetWheelAnimationData====&lt;br /&gt;
Sets the animation data for the wheels of a traincar. Two values are always written here, but which is used will depend on the type of wheel animation which being used by the traincar.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*float - The current wheel rotation, from 0 to 2PI.&lt;br /&gt;
*float - The wheel velocity, in m/s.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetBrakeReleaseSoundFade====&lt;br /&gt;
Sets the volume of the brake release sound on this traincar.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*float - The new brake release sound volume, 0 to 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====TNIP_SetPFXVariableValue====&lt;br /&gt;
Sets the value of a named PFX variable. See validation/steam-mode.txt for a list of valid variable names.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
*TNILabel - The name of the variable to update.&lt;br /&gt;
*float - The new value of the variable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Accessor Commands (TNIPhysics.h)==&lt;br /&gt;
Basic accessors for TNIPhysicsVehicle member variables, including those on the frame data, engine spec or steam engine spec.&lt;br /&gt;
&lt;br /&gt;
===AssetID/Config Accessors===&lt;br /&gt;
{{MethodHeader|const TNIAssetID* TNIPhysicsGetVehicleAssetID(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|const TNISoup* TNIPhysicsGetVehicleAssetConfig(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|const TNIAssetID* TNIPhysicsGetVehicleEngineAssetID(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|const TNISoup* TNIPhysicsGetVehicleEngineAssetConfig(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|const TNIAssetID* TNIPhysicsGetVehicleTrackAssetID(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|const TNISoup* TNIPhysicsGetVehicleTrackAssetConfig(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Train Control Settings===&lt;br /&gt;
{{MethodHeader|int8_t TNIPhysicsGetVehiclePhysicsModelSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|int8_t TNIPhysicsGetVehicleTractionSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleThrottleSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleSteamRegulatorSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleSteamCutoffSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleTrainBrakeSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|int8_t TNIPhysicsGetVehicleDynamicBrakeSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleLocoBrakeSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|int8_t TNIPhysicsGetVehicleEpBrakeSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleBailTimeSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleHandBrakeSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleSandingSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleCoalRateSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleInjector1Setting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleInjector2Setting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleBlowerSetting(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Vehicle State Accessors===&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleMass(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleVelocity(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|bool TNIPhysicsGetVehicleIsStopped(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleWheelMomentum(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleWheelslip(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleWheelslipTractionMultiplier(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleWheelslipMomentumMultiplier(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleEngineForce(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleEngineThrottle(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleThrottleGraphOutput(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleDynamicBrakeGraphOutput(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
{{MethodHeader|bool TNIPhysicsGetVehicleIsDerailed(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|bool TNIPhysicsGetVehicleAllowsUserControl(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|bool TNIPhysicsGetVehicleIsAutomaticFireman(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|uint32_t TNIPhysicsGetVehicleCoalAvailable(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|uint32_t TNIPhysicsGetVehicleWaterAvailable(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleSandingTractionMultiplier(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleScriptTractionMultiplier(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Vehicle Brake Pressure State Accessors===&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleEqualiserPressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleMainReservoirPressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleNo3PipePressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleTrainBrakePipePressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleEpReservoirPipePressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleNo4PipePressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleAuxReservoirPressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleAutoBrakeCylinderPressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleIndependentBrakeCylinderPressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleScriptBrakePressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleBrakePipeEfficiency(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleCompressorEfficiency(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|int8_t TNIPhysicsGetVehicleCompressorActive(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleBrakeReleaseSoundFade(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Vehicle Track State Accessors===&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleTrackGradient(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleTrackCurveAngle(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Vehicle Spec Accessors===&lt;br /&gt;
{{MethodHeader|int8_t TNIPhysicsGetVehicleEngineType(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleMaximumTractiveEffort(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleWheelDiameter(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Engine Spec Accessors===&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleMaxSpeed(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleMaxDCCAcceleration(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleMaxDCCDeceleration(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleMaxVoltage(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetEngineBrakeRatio(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleThrottleAdjustmentRate(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleAxleCount(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleSurfaceArea(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleMovingFrictionCoefficient(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleAirDragCoefficient(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|double TNIPhysicsGetVehicleDrivingWheelWeightRatio(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Engine Spec Flowsize Accessors===&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_TrainBrakePipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_EpReservoirPipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_No3Pipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_No4Pipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_AuxReservoirVent(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_AuxReservoirToNo3Pipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_AuxReservoirToTrainBrakePipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_AutoBrakeCylinderVent(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_AuxReservoirToAutoBrakeCylinder(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_EqualiserMainReservoir(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_EqualiserVentHandleOff(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_EqualiserVentEmergency(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_EqualiserVent(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_No3PipeVent(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_No3PipeMainReservoir(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_Compressor(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_TrainBrakePipeReservoir(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_TrainBrakePipeVent(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_No3PipeToAutoBrakeCylinder(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_EpReservoirPipeToAutoBrakeCylinder(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleFlowsize_MainReservoirEP(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Engine Spec Volume Accessors===&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleVolume_Equaliser(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleVolume_MainReservoir(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleVolume_No3Pipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleVolume_TrainBrakePipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleVolume_EpReservoirPipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleVolume_No4Pipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleVolume_AuxReservoir(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleVolume_AutoBrakeCylinder(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehicleVolume_IndependentBrakeCylinder(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Engine Spec Pressure Accessors===&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehiclePressure_BrakePipe(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehiclePressure_BrakeInitial(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehiclePressure_BrakeFull(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehiclePressure_IndBrakeFull(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetVehiclePressure_Compressor(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Steam Engine Spec Accessors===&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEnginePistonVolumeMin(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEnginePistonVolumeMax(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEnginePistonArea(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEnginePistonLength(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|int TNIPhysicsGetSteamEnginePistonAngularOffsetsCount(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEnginePistonAngularOffset(const TNIPhysicsVehicle* vehicle, int i)}}&lt;br /&gt;
&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineTractiveEffortConstant(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineHandBrakeMaxForce(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineTestSpeed(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineTestCutoff(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBurnRate(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBurnRateIdle(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineMinFireTemperature(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineMaxFireTemperature(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineFireboxEfficiency(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineFireboxHeatingSurfaceArea(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineFireboxPlateThickness(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineFireboxThermalConductivity(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBlowerEffect(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBlowerMaxFlow(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineStartingCoal(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineIdealCoalMass(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineMaxFireCoalMass(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineFuelEnergy(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineFuelSpecificHeatCapacity(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBoilerVolume(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBoilerVolumeMin(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBoilerVolumeMax(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBoilerFusiblePlugVolume(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineSteamChestVolume(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineSteamChestMaxFlow(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineValveLapPercent(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBoilerEfficency(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBoilerEfficencyIdle(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBoilerEfficencyMin(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineBoilerHeatLoss(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineInitialBoilerTemperature(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineSuperheatingConstant(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineStartingWater(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineStartingBoilerSteam(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineSafetyValveLowPressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineSafetyValveLowFlow(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineSafetyValveHighPressure(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineSafetyValveHighFlow(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineCoalShovelMass(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineWaterInjectorRate(const TNIPhysicsVehicle* vehicle)}}&lt;br /&gt;
{{MethodHeader|float TNIPhysicsGetSteamEngineWaterInjectorRate2(const TNIPhysicsVehicle* vehicle)}}&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
	<entry>
		<id>https://wiki.trainzsimulator.com/index.php?title=Script_Feature_Requests&amp;diff=17406</id>
		<title>Script Feature Requests</title>
		<link rel="alternate" type="text/html" href="https://wiki.trainzsimulator.com/index.php?title=Script_Feature_Requests&amp;diff=17406"/>
		<updated>2019-01-27T17:53:39Z</updated>

		<summary type="html">&lt;p&gt;Microlem: /* Requests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is where the [[scripting]] community gets to post all their API feature requests. Request any additions that you think will enhance the game. Things to keep in mind:&lt;br /&gt;
* We are unlikely to add a feature which breaks any existing content.&lt;br /&gt;
* Script is for control purposes, and is not intended to enable significant modifications to the underlying game engine. We are very unlikely to introduce a feature where the obvious uses are going to result in significant performance penalties.&lt;br /&gt;
* We are far more likely to add features which are directly blocking something that the community is working on. If you have something cool, and need just a few minor additions then please detail what you&#039;re working on (ideally, on another wiki page linked from both here and your [[Content Creation Groups]] page) and why you need the additions.&lt;br /&gt;
* [[MiniBrowser]] requests should go on the separate [[MiniBrowser Feature Requests]] page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Requests==&lt;br /&gt;
Requests are placed in this section by the community, for discussion and possible inclusion.&lt;br /&gt;
&lt;br /&gt;
* Str.Tokens(&amp;quot;Foo&amp;quot;, &amp;quot;&amp;quot;) should return [&amp;quot;F&amp;quot;, &amp;quot;o&amp;quot;, &amp;quot;o&amp;quot;] when called without separator in 2nd argument analogous to other languages (String.split()).  --[[User:Sachsenbahner|Sachsenbahner]] 19:53, 10 December 2018 (AEST)&lt;br /&gt;
&lt;br /&gt;
* Add a method that will let you identify the industry at which a vehicle is located. If an industry track section can also carry the industry identifier, it would be most helpful.&lt;br /&gt;
&lt;br /&gt;
* Add a handle to allow a custom bell animation to be played when the bell is played on a locomotive (Vehicle.StartBell() and Vehicle.StopBell(), perhaps?).  Justification: Script can currently listen for the bell message, but since the message is a toggle, it is easy to get out of synch with the true state of the bell. For example, when coupling a locomotive whose bell is ringing to a locomotive whose bell is not ringing, the end result depends on which locomotive is currently in focus. - Curtis&lt;br /&gt;
&lt;br /&gt;
* Scale the visible bulk load animation on a traincar such that it takes Vehicle.GetLoadTime() to complete.  For example, if Vehicle.GetLoadTime() returns 5 seconds, the bulk animation would take 5 seconds to transition from the full state to the empty state.  This would be useful for industries that take more than one second to load / unload a car, as the visible load animation could be synced more closely with the industry animation. -Curtis&lt;br /&gt;
&lt;br /&gt;
* Extension to the function World.GetAssetList(string kind, bool OnlyIfUsedInCurrentMap) -Andi06&lt;br /&gt;
&lt;br /&gt;
* Ability to play an avi and wait for it to finsh (no user interaction allowed) ~Jenolan&lt;br /&gt;
&lt;br /&gt;
* The ability to modify scenery trigger radii on the fly in script. This is really aimed at crossings so that train detection can be varied in line with track speed limits.  -Andi06&lt;br /&gt;
&lt;br /&gt;
* A method of refreshing the Property Browser to take account of any change in the target object&#039;s name during a property editing session. (Objects which have &#039;autoname 1&#039; in config will often be renamed by the user.  In some circumstances I am using the object name to set other properties. Typically an object might be created as &#039;Double Slip 1&#039; and might refer to its constituent nodes as &#039;Double Slip 1,Track 1&#039;.  This is to enable other objects to refer to it in a user friendly way.  On a name change the Property Browser continues to use the old name until the browser has been closed and reopened.  This is counter intuitive) -Andi&lt;br /&gt;
&lt;br /&gt;
* Ability for a script to be able to read/change loco/rolling stock parameters (ie to simulate one loco losing air etc etc etc) ~Jenolan&lt;br /&gt;
&lt;br /&gt;
* SetFXCoronaTexture() A means of resetting to config.txt defaults.&lt;br /&gt;
&lt;br /&gt;
* Be able to play mp3 as well as wav. ~Jenolan&lt;br /&gt;
: &#039;&#039;I&#039;ve been able to do this where the asset doing the playing is a script library, I had Acker Bilk coming over a station tannoy at one point.  Not sure why it doesn&#039;t seem to work elsewhere. -Andi&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interface.MessageBox(Caption,Text), calling up a small browser with a close button would be helpful, especially for novices. Interface.Print() is a monumental PITA because it prints out upside down, doesn&#039;t hold enough lines, and only works in Driver. For sure its possible to write your own version of this but browsers aren&#039;t all that easy to get your head around and its a very basic facility that should be built in. -Andi&lt;br /&gt;
&lt;br /&gt;
* A standard config.txt tag &#039;junction-type normal/singleslip/doubleslip&#039; etc together with a spec for construction and behaviour might be helpful. I already have a complete schema for this. -Andi&lt;br /&gt;
: &#039;&#039;Uncertain what you&#039;re expecting to achieve here? -chris&#039;&#039;&lt;br /&gt;
: &#039;&#039;see Animated Fixed Junctions Thread&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Is it possible to make a mesh available which matches the existing graphic direction indicators, it appears to be some sort of directional corona or variant. If not could a new marker mesh be developed that could be used with both types? The existing one has nasty alpha effects in any case. -Andi&lt;br /&gt;
&lt;br /&gt;
* Ability to dynamically change the length of a piece of rolling stock as part of the load / unload process; to support logging disconnects (see http://www.trainzone.co.nz/logging.htm for examples)- Curtis&lt;br /&gt;
: &#039;&#039;This is an interesting concept, but sounds difficult to implement. I can&#039;t think of any way of adjusting the length unless it was the end item of a consist, since adjustment at any other time would require displacing the remainder of the consist. Could you expand on your ideas please.&#039;&#039; -chris&lt;br /&gt;
: &#039;&#039;The entire car, including lmfront &amp;amp; lmback, would be part of the loading / unloading animation. When loading, it would probably be necessary to displace the consist by moving one of the ends - perhaps the end with the locomotive? Potential issue: if when loading, the increase in consist length causes the end of the consist to run off the end of the track or collide with another train.  When unloading, you could break the consist at either or both lmfront / lmback - whichever move as part of the unloading animation.&#039;&#039; - Curtis&lt;br /&gt;
: &#039;&#039;May be simpler to just break the consist at both lmfront and lmback; centering the car in-between the two halves. -Curtis&lt;br /&gt;
&lt;br /&gt;
*Allow SetFXNameText(effect,text) to accept an empty string in the second parameter - Reason: It&#039;s really irritating having to write workarounds for this. ~Andi&lt;br /&gt;
&lt;br /&gt;
*SetMeshScale(X,Y,Z) and corresponding config tags. Positive or negative values would implement mesh mirroring at the same time. As an example of potential a placement option for trees might allow random scale factors (within reasonable limits) and random rotation.  Each tree placed would then vary in size, shape and rotation getting much more variation from the same mesh asset. ~Andi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Update to product loading / unloading functionality to allow incremental loads and unloads.&lt;br /&gt;
:Potential usages:  &lt;br /&gt;
:- Animation that plays once per item being loaded; such as a forklift carrying a crate to a boxcar, or a crane lifting a log to a flatcar.&lt;br /&gt;
:- Allow dynamic load times of bulk loads (small cars load faster than large cars), with the animated load rising / lowering synchronously.&lt;br /&gt;
&lt;br /&gt;
:Potential implementation:&lt;br /&gt;
:Extend vehicle.LoadProduct(report,units) where units = integer number of queue to be loaded each increment.  0 would be everything, defaulting to current LoadProduct() behavior, and add additional calls BeginIncrementalLoad(), EndIncrementalLoad(), BeginIncrementalUnload(), and EndIncrementalUnload().&lt;br /&gt;
&lt;br /&gt;
:During a load operation that loads 3 increments (units=1, target queue on the car = 3), the flow would look like:&lt;br /&gt;
 BeginLoad() // open car doors; station doors&lt;br /&gt;
 &lt;br /&gt;
 BeginIncrementalLoad() //  start loading animation, start sounds; pfx; add any delays&lt;br /&gt;
 TransferProductFrom() // maximumToTransfer = units&lt;br /&gt;
 EndIncrementalLoad() // animate forklift returning to station / end sounds / pfx / other cleanup&lt;br /&gt;
 &lt;br /&gt;
 BeginIncrementalLoad()&lt;br /&gt;
 TransferProductFrom()&lt;br /&gt;
 EndIncrementalLoad()&lt;br /&gt;
 &lt;br /&gt;
 BeginIncrementalLoad()&lt;br /&gt;
 TransferProductFrom()&lt;br /&gt;
 EndIncrementalLoad()&lt;br /&gt;
 &lt;br /&gt;
 EndLoad() // close car &amp;amp; station doors&lt;br /&gt;
&lt;br /&gt;
* Ability to add a vehicle to an existing consist like Vehicle.Reposition( Train, MyCouple, OtherCouple ) this would save needing a work track mark to add vehicles which would be very helpful ~Jenolan&lt;br /&gt;
&lt;br /&gt;
* Extension to AddHandler to allow this syntax: AddHandler(target,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;MessageHandler&amp;quot;), passing all messages to the specified handler, for justification see discussion page. -Andi&lt;br /&gt;
&lt;br /&gt;
* Ability to store any information along with the layout and not the session (i.e. &#039;&#039;PropertyObject.SetLayoutProperties&#039;&#039; and &#039;&#039;PropertyObject.GetLayoutProperties&#039;&#039;, taking/returning &#039;&#039;Soup&#039;&#039; objects respectively). Rationale: the non-existence is a major drawback with configurable signals - [[User:Klausm|Klausm]]&lt;br /&gt;
&lt;br /&gt;
* Access to asset location, height, rotation in script.  This came up twice - once when I wanted to keep traffic lights upright when the containing asset is rolled, and once when I wanted to add simple real time ground shadows to assets. -Andi06&lt;br /&gt;
&lt;br /&gt;
* Ability to arbitrarily add an attachment point to an item. To allow things like FRED/BOG sundry animations and so on ~Jenolan&lt;br /&gt;
&lt;br /&gt;
* Not really script. A generic clickable mesh object, its an easy hack using a fixedtrack junction but it would nice to have an official version - click on the engine shed to open the doors, click on the signal box to open a track browser etc etc. Mappable click regions too if its not too much to ask :-) -Andi&lt;br /&gt;
&lt;br /&gt;
* Extension/Alternative to World.GetJunctionList to return fixed track junction objects or nodes, I can script this easily for objects using my library but this would not be the case for all junctions. -Andi&lt;br /&gt;
&lt;br /&gt;
* World.Play2DSound(Asset,filename) allows sound files to be saved in a &#039;sound library&#039; asset and avoids duplication.  Can we have a similar facility for images to be used in html assets.  A lot of the dependencies that I use are images and icons.  I&#039;m consciously trying to avoid this now - its the source of much pain - but to do this for the Junction Kit for instance I would have to have copies of all necessary images in all of the placeable assets (there are more than 50) If I could simply keep one copy in the script library it would save much bandwidth, diskspace and support. -Andi06&lt;br /&gt;
&lt;br /&gt;
* genesteal : cab features.&lt;br /&gt;
- methods for light controls in cabin : Control.SetFlash (float frequency).Make the control visible/invisible on the intervall frequency. may be Meshobjects.gs for more general purpose. The same for texture swapping in texture replacement.&lt;br /&gt;
- New conrol cab &amp;quot;button&amp;quot; with vertical translation limit : method set and get value as usual, method for &amp;quot;while depressed&amp;quot; behavior: Setdepressed ( method to run).&lt;br /&gt;
&lt;br /&gt;
- Speedlimiter method : Set a speedlimit replacing the max speed possible on cab mode.(engine)&lt;br /&gt;
&lt;br /&gt;
- Set engine methods : &lt;br /&gt;
Locomotive.SwapEngine(kuid); replace engine by another for a locomotive. feature existing on actual loco to set a traction service if the loco have to drive freight or passengers consists. This method can replace speedlimit above and may be more accurate : speedlimit and power will be set together as prototypical setting before a journey. &lt;br /&gt;
- Locomotive.EngineStop(): stops the enginesound  and play a stop.wav, located in enginesound folder.&lt;br /&gt;
- Locomotive.EngineStart() : starts enginesound like this : play  a start.wav located in enginesound folder, then idle 0.wav.&lt;br /&gt;
&lt;br /&gt;
* Allow function Vehicle.SetTractionMultiplier(float) to set multiplier to 0. ~Mike&lt;br /&gt;
: UPD: sorry, misunderstood functionality of this function. But could there be a method to disable traction on locos?&lt;br /&gt;
&lt;br /&gt;
* Ability to change (or only to reduce) the presure in auxilary reservoir of a vehicle. This provides a way to create different types of tripte valves for long-length trains (~70  vehicles), where using Train.SetVelocity() is unrealistic&lt;br /&gt;
&lt;br /&gt;
* Make in addition to Vehice.GetTrackGradient() also float Vehice.GetTrackCurveRadius() which return 0 for straight sections of track (instead of infinity). ~tram&lt;br /&gt;
* Make a function for smooth control of &amp;quot;soundscript&amp;quot;&#039;s sound volume. For example like void MapObject.SetSoundScriptVolume(string soundTrigger, float NewVolume, float Duration).  ~tram&lt;br /&gt;
&lt;br /&gt;
* Ability to set the camera view within an interior by a script to one of the defined cameras in the cameralist container.  It would also be handy if the camera orientation be configurable via a method call. --[[User:Pcas1986|pcas1986]] ([[User talk:Pcas1986|talk]]) 18:14, 20 February 2014 (EST)&lt;br /&gt;
&lt;br /&gt;
* Ability to place a bogey in an interior via the interiors config file.  This would allow for me to make a realistic gangway for my Amlfeets ~ Ashton&lt;br /&gt;
&lt;br /&gt;
* Locomotive.SetEngineSetting(string setting, float value) - Ability to mute/activate engine sound for a locomotive adding setting &amp;quot;enginesound&amp;quot; to the list of settings, value 0 to mute, 1 to activate engine sound ~manweb&lt;br /&gt;
 - setting = The name of the setting to save (enginesound).&lt;br /&gt;
 - value = The value of the named setting. (0 - 1)&lt;br /&gt;
&lt;br /&gt;
* Math.sin,cos,tan,arcsin,arccos,arctan - Trigonometric functions to get the sine, cosine, and tangent of a float, and inverses of these&lt;br /&gt;
&lt;br /&gt;
==Complete==&lt;br /&gt;
* Simple destructor routine, or some other method of receiving notification of the deletion of scripted objects during a Surveyor session. (In the absence of World.GetJunctionBaseList() my new junction objects are maintaining a list of fixedtrack junctions via library calls in the Init() method of each object.  Apart from using the list myself, it is intended to be returned on demand to any script making the appropriate LibraryCall.  Since I have no way of telling that an object has been deleted, I need to rescan the entire list before returning it to ensure that each object still exists, this seems a touch inefficient when it could be easily kept up to date without a complete parse) -Andi&lt;br /&gt;
:&#039;&#039;Now a function of the [[TrackSearch]] system.&#039;&#039; -chris&lt;br /&gt;
&lt;br /&gt;
* The ability for [[TrackSearch]] to return the trigger or track reference found for SceneryWithTrack descendants, including turntables and the ability to initiate a search from a specified trigger or track in SceneryWithTrack descendants.  A million reasons for this including trains being able to detect which track of an industry they can see in a proposed &#039;Call-At All Stations&#039; rule. -Andi06&lt;br /&gt;
:&#039;&#039;Now a function of the [[TrackSearch]] system.&#039;&#039; -chris&lt;br /&gt;
&lt;br /&gt;
* Compatibility of the [[TrackSearch]] with the animated fixed junctions. When I first got TRS2006 in my hands, I tried out my TrackView rule, but quickly discovered that it was impossible to find out the track topology (forgot the exact details, though) - [[User:Klausm|Klausm]]&lt;br /&gt;
:&#039;&#039;[[TrackSearch]] system is now considerably more robust.&#039;&#039; -chris&lt;br /&gt;
&lt;br /&gt;
* Extensions to TrackSearch()/GSTrackSearch() covered elsewhere to be sufficient to allow the topography of multi node junctions to be fully discovered. -Andi&lt;br /&gt;
:&#039;&#039;[[TrackSearch]] system is now considerably more robust.&#039;&#039; -chris&lt;br /&gt;
&lt;br /&gt;
*If we are going to use radians now (SetMeshOrientation()) could we please have PI?&lt;br /&gt;
:&#039;&#039;Math.PI&#039;&#039; -chris&lt;br /&gt;
&lt;br /&gt;
* Ability to configure permit structure to allow multi node junctions to coexist with the AI, whilst denying conflicting paths, as discussed above. -Andi&lt;br /&gt;
:&#039;&#039;Added named mutex support for attached junctions. See [[KIND SceneryWithTrack]].&#039;&#039; ~chris&lt;br /&gt;
&lt;br /&gt;
* Fix World.GetAssetList(&amp;quot;texture-group&amp;quot;), this has been broken since TRS2004. -Andi06&lt;br /&gt;
:&#039;&#039;Now returns all assets with category-class &#039;JO&#039;. This seems to contain all &#039;texture-group&#039; type assets - though there maybe some unexpected extras.&#039;&#039; -James&lt;br /&gt;
&lt;br /&gt;
* Ability to detect the use of &#039;Pause&#039; easily (a message would do) to stop cheating in shunting puzzles ~Jenolan&lt;br /&gt;
:&#039;&#039;New messages &amp;quot;World&amp;quot;, &amp;quot;Paused&amp;quot; and &amp;quot;World&amp;quot;, &amp;quot;Unpaused&amp;quot; now exist and should be broadcast at the appropriate times.&#039;&#039; -James&lt;br /&gt;
&lt;br /&gt;
* World.GetCurrentTrain() Not essential obviously but it would save a lot of work. -Andi06&lt;br /&gt;
:&#039;&#039;Now exists.&#039;&#039; -James&lt;br /&gt;
&lt;br /&gt;
* Ability to optionally detect mouseclick/ Keys [J] &amp;amp; [^J] without switching the junction. This can be hacked by making node 0 an invisible junction, but this will result in other objects querying the junction structure not getting the answer they expect (or not one they can understand). This is needed to allow objects with more than one junction node to cycle through their options in response to the user. -Andi&lt;br /&gt;
:&#039;&#039;I believe this is now possible via script overrides on the map object in question.&#039;&#039; ~chris&lt;br /&gt;
&lt;br /&gt;
* A method of subclassing or outright using a script from another asset (ie. a script which is written once and reused heavily, allowing any fixes to be released as a single asset update.) - chris&lt;br /&gt;
:&#039;&#039;TS2009 now has the ability to cross-include scripts from another asset.&#039;&#039; ~chris&lt;br /&gt;
&lt;br /&gt;
* Dreamland, a new message: &#039;&#039;Junction,AboutToToggle&#039;&#039; -Andi&lt;br /&gt;
: &#039;&#039;How do you expect to act on this? -chris&#039;&#039;&lt;br /&gt;
: &#039;&#039;see Animated Fixed Junctions Thread&#039;&#039;&lt;br /&gt;
::&#039;I believe this concept has been fulfilled via the UserRequestToggle overrides.&#039;&#039; ~chris&lt;br /&gt;
&lt;br /&gt;
* On a similar note is there any chance you might amend the Exception dialogue to specify the object, (or even the Asset) which is causing the exception :-) -Andi&lt;br /&gt;
:: I think we did this one a while back. ~chris&lt;br /&gt;
&lt;br /&gt;
* SetMeshPosition(&amp;quot;meshname&amp;quot;, x,y,z) absolute positioning of a Mesh or Object. -Caby&lt;br /&gt;
: &amp;lt;font color=red&amp;gt;This exists ~Andi&amp;lt;/font&amp;gt;&lt;br /&gt;
:: &#039;&#039;Not necessarily - we support relative positioning, not absolute. This may or may not achieve what he wants.&#039;&#039; ~chris&lt;br /&gt;
:: This has been added. ~chris&lt;br /&gt;
&lt;br /&gt;
* GetMeshPosition(&amp;quot;meshname&amp;quot;, &amp;quot;x&amp;quot;)[&amp;quot;Y&amp;quot;][&amp;quot;Z&amp;quot;] receive the absolute position of a Mesh or Object. -Caby&lt;br /&gt;
: &amp;lt;font color=red&amp;gt;Since you have used SetMeshPosition() to move the mesh, this is unneccessary&amp;lt;/font&amp;gt;&lt;br /&gt;
:: &#039;&#039;Absolute position can be set in Surveyor. Relative position can be set in the [[config.txt file]]. I wouldn&#039;t say that this is completely unnecessary.&#039;&#039; ~chris&lt;br /&gt;
::: Thanks a lot for MapObject.GetMapObjectPosition() and MapObject.GetMapObjectOrientation() ~tram&lt;br /&gt;
:: This has been added. ~chris&lt;br /&gt;
&lt;br /&gt;
* Ability to load a menu asset directly from the command line ~Jenolan&lt;br /&gt;
:: This exists with &amp;quot;-scriptedmenu=&amp;lt;KUID&amp;gt;&amp;quot; ~chris&lt;br /&gt;
&lt;br /&gt;
==Rejected==&lt;br /&gt;
If there&#039;s a request that we&#039;re clearly not going to entertain at the current time, we&#039;ll move it to here. This includes both flat rejections and also requests which sound good but won&#039;t be done for the next version of Trainz.&lt;br /&gt;
&lt;br /&gt;
[[Rejected Script Feature Requests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature Request]]&lt;/div&gt;</summary>
		<author><name>Microlem</name></author>
	</entry>
</feed>