This document describes the modern BeamNG forest placement format used by levels:
forest/*.forest4.json - forest item placement filesart/forest/managedItemData.json - forest item type definitionsThese files work together. managedItemData.json defines what can be placed, while .forest4.json files define where each item is placed in the level.
The Forest system is used for large numbers of repeated static objects, such as:
Forest items are optimized for rendering and collision. They are generally not meant to be individually moved or animated during gameplay, but they can support wind animation through their asset setup and forest item parameters.
A typical level uses:
levels/example_level/
├── art/
│ └── forest/
│ └── managedItemData.json
└── forest/
├── trees.forest4.json
├── rocks.forest4.json
└── bushes.forest4.json
| File | Purpose |
|---|---|
art/forest/managedItemData.json |
Defines forest item types, such as tree or rock definitions. |
forest/*.forest4.json |
Stores placed instances of those item types. |
art/forest/managedItemData.cs |
Legacy TorqueScript format, still supported as fallback. |
*.forest / *.forest.json |
Older forest placement formats, deprecated. |
managedItemData.json if it exists. If it does not exist, it falls back to managedItemData.cs.managedItemData.json defines reusable forest item types. Each item type references a shape file and optional physical/wind parameters.
levels/<levelName>/art/forest/managedItemData.json
The file is a JSON object. Each top-level entry contains a forest item data block.
{
"oak_large": {
"class": "ForestItemData",
"internalName": "oak_large",
"shapeFile": "/levels/example/art/shapes/trees/oak_large.dae",
"mass": 100,
"rigidity": 10,
"tightnessCoefficient": 0.5,
"dampingCoefficient": 0.2,
"windScale": 1,
"trunkBendScale": 0.5,
"branchAmp": 1,
"detailAmp": 0.25,
"detailFreq": 1
}
}
The supported class names are:
ForestItemData
TSForestItemData
Both are accepted by the loader.
| Field | Type | Description |
|---|---|---|
class |
string | Must be ForestItemData or TSForestItemData. |
internalName |
string | Unique item type name used by .forest4.json placement files. |
shapeFile |
string | Path to the shape used for this forest item. |
mass |
number | Physics mass used by the item. |
rigidity |
number | Controls stiffness for wind/interaction behavior. |
tightnessCoefficient |
number | Controls how tightly the item returns to its rest state. |
dampingCoefficient |
number | Controls damping of motion. |
windScale |
number | Scales how strongly wind affects the item. |
trunkBendScale |
number | Controls trunk bending amount. |
branchAmp |
number | Controls branch wind animation amplitude. |
detailAmp |
number | Controls detail wind animation amplitude. |
detailFreq |
number | Controls detail wind animation frequency. |
Not all fields are required, but internalName and shapeFile are essential.
The internalName is the link between item definitions and placed instances.
Example item definition:
"pine_small": {
"class": "ForestItemData",
"internalName": "pine_small",
"shapeFile": "/levels/example/art/shapes/trees/pine_small.dae"
}
Example placement referencing it:
{"type":"pine_small","pos":[10,20,0],"rotationMatrix":[1,0,0,0,1,0,0,0,1],"scale":1}
If a placement references a type that does not exist in managedItemData.json, that instance cannot be resolved.
.forest4.json files store placed forest item instances.
levels/<levelName>/forest/*.forest4.json
Example:
levels/example/forest/trees.forest4.json
.forest4.json files are line-delimited JSON.
This means each line is a separate JSON object. The file is not a single JSON array.
Example:
{"type":"pine_small","pos":[10,20,0],"rotationMatrix":[1,0,0,0,1,0,0,0,1],"scale":1}
{"type":"pine_small","pos":[15,25,0],"rotationMatrix":[0,-1,0,1,0,0,0,0,1],"scale":0.85}
{"type":"rock_large","pos":[30,12,0],"rotationMatrix":[1,0,0,0,1,0,0,0,1],"scale":1.4}
.forest4.json contents in [ ]. Each line must be a standalone JSON object.| Field | Type | Description |
|---|---|---|
type |
string | Forest item type. Must match an internalName from managedItemData.json. |
pos |
array[3] | World position [x, y, z]. |
rotationMatrix |
array[9] | 3×3 rotation matrix stored as 9 numbers. |
scale |
number | Uniform scale for the item. |
{
"type": "oak_large",
"pos": [100.5, 42.0, 12.3],
"rotationMatrix": [
1, 0, 0,
0, 1, 0,
0, 0, 1
],
"scale": 1.0
}
When a level is loaded, the engine roughly follows this process:
Look for forest item data:
art/forest/managedItemData.jsonart/forest/managedItemData.csParse all valid forest item definitions.
Search the level forest folder for:
forest/*.forest4.json
Read each .forest4.json file line by line.
For each placement:
typeinternalName in item datashapeFileThe engine can still detect older forest files:
*.forest
*.forest.json
These are deprecated. If old files are present, the engine may print warnings similar to:
Old forest file format detected. Please resave the forest and delete the old files.
Modern levels should use:
*.forest4.json
If managedItemData.json is missing, the engine can fall back to:
art/forest/managedItemData.cs
This is the older TorqueScript-style format.
Example:
datablock ForestItemData(oak_large)
{
internalName = "oak_large";
shapeFile = "/levels/example/art/shapes/trees/oak_large.dae";
mass = "100";
rigidity = "10";
windScale = "1";
};
For new content, prefer managedItemData.json.
Forest items can react to wind if the asset and material support it. The item data values control how strongly the object responds.
Common wind-related fields:
| Field | Description |
|---|---|
windScale |
Overall wind influence. Use 0 for static objects such as rocks. |
trunkBendScale |
Amount of large-scale trunk bending. |
branchAmp |
Branch movement amplitude. |
detailAmp |
Fine detail movement amplitude. |
detailFreq |
Frequency of fine wind motion. |
Example for a tree:
{
"class": "ForestItemData",
"internalName": "pine_large",
"shapeFile": "/levels/example/art/shapes/trees/pine_large.dae",
"windScale": 1,
"trunkBendScale": 0.6,
"branchAmp": 1,
"detailAmp": 0.25,
"detailFreq": 1.5
}
Example for a rock:
{
"class": "ForestItemData",
"internalName": "rock_large",
"shapeFile": "/levels/example/art/shapes/rocks/rock_large.dae",
"windScale": 0
}
Forest items can contribute collision depending on their shape and item setup. The engine builds collision data per forest cell and can reuse collision data for repeated shapes.
This is important for performance: many instances using the same shapeFile can share cached collision information.
For best results:
The forest system is designed for large numbers of repeated static objects, but performance still depends on asset quality.
Important factors:
shapeFile assetsUse the Forest Editor and debug tools to validate placement density and performance.
managedItemData.json for new levels..forest4.json placement files..forest4.json as line-delimited JSON.type matches an internalName.windScale to 0 for objects that should not move..forest and .forest.json files after upgrading.Possible causes:
managedItemData.jsontype does not match any internalNameshapeFile path.forest4.jsonCheck console/log output for invalid lines or missing item types. A single bad line may fail while other lines still load.
Check that rotationMatrix contains 9 valid numeric values.
Check the scale field. .forest4.json uses a single uniform scale value.
Possible causes:
windScale is 0If the level contains both old and new forest files, remove deprecated files after verifying the upgraded .forest4.json data.
art/forest/managedItemData.json
{
"pine_small": {
"class": "ForestItemData",
"internalName": "pine_small",
"shapeFile": "/levels/example/art/shapes/trees/pine_small.dae",
"windScale": 1,
"trunkBendScale": 0.4,
"branchAmp": 1,
"detailAmp": 0.25,
"detailFreq": 1
},
"rock_large": {
"class": "ForestItemData",
"internalName": "rock_large",
"shapeFile": "/levels/example/art/shapes/rocks/rock_large.dae",
"windScale": 0
}
}
forest/forest.forest4.json
{"type":"pine_small","pos":[0,0,0],"rotationMatrix":[1,0,0,0,1,0,0,0,1],"scale":1}
{"type":"pine_small","pos":[5,2,0],"rotationMatrix":[0,-1,0,1,0,0,0,0,1],"scale":0.9}
{"type":"rock_large","pos":[10,4,0],"rotationMatrix":[1,0,0,0,1,0,0,0,1],"scale":1.5}
The modern forest format uses two parts:
managedItemData.json defines reusable forest item types..forest4.json files store placed instances as line-delimited JSON.This structure allows the engine to efficiently render, batch, collide, and manage large numbers of repeated static objects in a level.
Was this article helpful?