TSStatic is the main object class for individually placed static meshes in BeamNG levels. It is commonly used for buildings, signs, bridges, and other manually placed environment meshes.
For very large amounts of repeated static objects, such as trees, rocks, bushes, or small vegetation and props, clutter, barriers, the Forest system is usually more efficient. Forest items are the preferred lightweight solution for repeated assets, while TSStatic is best suited for individually placed objects.
A simple TSStatic entry in items.level.json:
{
"class": "TSStatic",
"name": "garage_building",
"shapeName": "/levels/example/art/shapes/garage.dae",
"position": [100, 200, 0],
"rotationMatrix": [1, 0, 0, 0, 1, 0, 0, 0, 1],
"scale": [1, 1, 1],
"collisionType": "Collision Mesh",
"decalType": "Collision Mesh",
"isRenderEnabled": true
}
| Field | Type | Description |
|---|---|---|
class |
string | Must be "TSStatic". |
name |
string | Scene object name. Should be unique within the level. |
shapeName |
string | Path to the model file used by this object. |
position |
array[3] | World position. |
rotationMatrix |
array[9] | Object rotation as a 3x3 matrix. |
scale |
array[3] | Object scale. |
collisionType |
enum/string | Mesh data used for physics/collision queries. |
decalType |
enum/string | Mesh data used for decal projection/clipping. |
dynamic |
bool | Disables some static-object render optimizations. |
playAmbient |
bool | Plays an animation sequence named ambient, if present. |
meshCulling |
bool | Enables per-submesh culling for large complex shapes. |
originSort |
bool | Sorts translucent rendering by object origin instead of bounds. |
useInstanceRenderData |
bool | Enables per-instance render data such as instance colors. |
instanceColor |
color | Per-instance base color multiplier. |
instanceColor1 |
color | First palette color for instance color palette materials. |
instanceColor2 |
color | Second palette color for instance color palette materials. |
skin |
string | Optional material target remapping / skin name. |
prebuildCollisionData |
bool | Prebuilds collision data at load time. |
renderNormals |
number | Debug normal rendering scale. |
forceDetail |
integer | Forces a specific shape detail/LOD level. -1 means automatic. |
The most important field is:
"shapeName": "/levels/example/art/shapes/garage.dae"
This points to the model used by the object.
Supported shape paths usually point to:
.dae
.cdae
.dts
The engine may use cached shape data internally, such as .cdae, but level files usually reference the source/imported shape path.
Most TSStatic objects use standard transform fields.
"position": [100, 200, 0]
World position in meters.
"rotationMatrix": [
1, 0, 0,
0, 1, 0,
0, 0, 1
]
3x3 rotation matrix.
"scale": [1, 1, 1]
Object scale.
collisionType controls what mesh data is used for physics collision and raycasts.
Supported values:
| Value | Description |
|---|---|
None |
No collision. |
Bounds |
Uses the object bounding box. Limited support. |
Collision Mesh |
Uses dedicated collision meshes from the shape. Recommended. |
Visible Mesh |
Uses rendered mesh polygons for collision. Expensive. |
Visible Mesh Final |
Uses rendered mesh polygons intentionally. Use only when required. |
Example:
"collisionType": "Collision Mesh"
Recommended default:
"collisionType": "Collision Mesh"
Use None for purely decorative objects that should not collide:
"collisionType": "None"
For best performance, models should include dedicated collision geometry.
A dedicated collision mesh should be much simpler than the visible mesh.
Good collision meshes are:
Avoid using visible mesh collision unless necessary.
Visible Mesh Final; otherwise prefer proper collision meshes.decalType controls which mesh data decals are clipped/projected against.
Example:
"decalType": "Collision Mesh"
Common values are the same as collisionType.
For objects that should receive projected decals, use a mesh type that matches the surface reasonably well.
For objects that should not receive decals:
"decalType": "None"
By default, TSStatic objects without animation can be rendered through the static shape manager. This allows the engine to batch and optimize repeated static shapes.
This is important for performance, especially when a level contains many placed meshes.
The object can use static manager rendering when:
dynamic is falseambient animation is activeIf an object is dynamic or animated, it uses its own TSShapeInstance.
"dynamic": true
dynamic disables some render optimizations for static objects.
Use it only when needed, such as for objects that need per-object dynamic behavior or cannot be managed as a static instance.
For normal level props and buildings, leave it false or omit it.
TSStatic can automatically play an animation sequence named:
ambient
if the shape contains it and playAmbient is enabled.
"playAmbient": true
This is useful for simple repeating animations such as:
If an ambient animation exists, the object becomes process-enabled and will not use the most static optimized path.
"meshCulling": true
meshCulling enables more detailed per-submesh culling inside the object.
This is a legacy feature that only works if dynamic is enabled, howver it’s not recommend to use as it creates performance issues.
"originSort": true
originSort changes translucent sorting behavior by using the object origin instead of bounds.
This can help with some transparent objects, but it can also create sorting issues if the origin is poorly placed.
Use only when needed for translucent materials.
useInstanceRenderData enables per-instance render properties.
"useInstanceRenderData": true
This is used by materials that support instance color or palette data.
Important fields:
"instanceColor": [1, 1, 1, 1],
"instanceColor1": [1, 0, 0, 1],
"instanceColor2": [0, 0, 1, 1]
These can drive material features such as:
The material must be authored to use these features.
{
"class": "TSStatic",
"name": "colored_barrier",
"shapeName": "/levels/example/art/shapes/barrier.dae",
"position": [0, 0, 0],
"rotationMatrix": [1, 0, 0, 0, 1, 0, 0, 0, 1],
"scale": [1, 1, 1],
"useInstanceRenderData": true,
"instanceColor": [1, 0.2, 0.1, 1],
"collisionType": "Collision Mesh"
}
The skin field remaps material targets on the shape.
"skin": "blue"
Basic behavior:
base.Example:
base_body → blue_body
Advanced syntax:
"skin": "base=blue;glass=darkglass"
This replaces multiple material target prefixes.
TSStatic material targets come from the shape’s material list. These targets are matched to BeamNG Material definitions through mapTo.
For example, if the model has a material target:
garage_wall
then the material definition should use:
"mapTo": "garage_wall"
Use the Material Editor or tooling to inspect material targets.
Useful runtime methods for tools include:
getTargetCount()
getTargetName(index)
TSStatic uses the shape’s detail levels for LOD.
The engine selects a detail level based on the object’s estimated screen-space size. In simple terms, it checks how large the object appears on screen and chooses an appropriate LOD.
Several factors affect this:
$pref::TS::detailAdjust scales the calculated pixel size, allowing higher or lower LOD bias.The result is a calculated pixelSize value. This is compared against the detail levels stored in the shape. Higher pixelSize means the object appears larger on screen and should use a higher-detail mesh; lower pixelSize means the object appears smaller and can use a lower-detail mesh.
For example, a small prop and a large building at the same distance will not necessarily use the same LOD. The building has a larger bounding radius, so it occupies more screen space and may keep a higher detail level farther away.
Relevant settings include:
$pref::TS::detailAdjust
$pref::TS::skipRenderDLs
"forceDetail": -1
-1 means automatic detail selection.
A non-negative value forces a specific detail level:
"forceDetail": 0
Use this only for debugging or special cases. For normal content, let the engine select LOD automatically.
Shapes can contain billboard/imposter detail levels. The engine can use these for far-away rendering if the shape is set up correctly.
This is handled by the shape data and is not configured directly in TSStatic.
"renderNormals": 1
If greater than zero, renders debug normals for the current detail level.
Useful for checking:
Forces a detail level, useful for checking LODs.
TSStatic supports raycasts and poly list generation.
Depending on context, it may use:
This affects:
TSStatic listens for shape resource changes.
If the referenced shape file changes, the object can recreate its shape and refresh collision/material data.
This is useful when iterating on level art.
{
"class": "TSStatic",
"name": "warehouse_01",
"shapeName": "/levels/example/art/shapes/buildings/warehouse_01.dae",
"position": [250, 120, 0],
"rotationMatrix": [0, -1, 0, 1, 0, 0, 0, 0, 1],
"scale": [1, 1, 1],
"collisionType": "Collision Mesh",
"decalType": "Collision Mesh",
"dynamic": false,
"playAmbient": true,
"meshCulling": true,
"originSort": false,
"useInstanceRenderData": false,
"isRenderEnabled": true,
"canSaveDynamicFields": true
}
Use TSStatic for individually placed objects:
Use the Forest system for large quantities of repeated objects:
Forest items are generally more lightweight for high object counts.
TSStatic for manually placed static level meshes.collisionType: None for decorative non-collidable objects.dynamic disabled unless required.forceDetail except for debugging.mapTo..dae/.cdae assets with proper LODs and collision detail.Possible causes:
shapeNamePossible causes:
mapTo mismatchCheck:
"collisionType": "Collision Mesh"
Also verify the shape actually contains collision mesh/detail data.
Possible causes:
TSStatic objectsCheck:
"decalType": "Collision Mesh"
or use a mesh type better suited for decal clipping.
Check that:
playAmbient is trueambientCheck that:
useInstanceRenderData is trueTry originSort, but also check:
TSStatic is the main object class for individually placed static 3D meshes in levels.
For large numbers of repeated natural or scatter assets, use the Forest system instead. BeamNG level geometry should normally be placed either as TSStatic objects or as Forest items.
TSStatic directly references a shape file and supports rendering, collision, decals, LODs, material remapping, optional ambient animation, and per-instance render data.
Was this article helpful?