This document describes the items.level.json file format used by BeamNG levels to store scene objects.
items.level.json files are used inside level object folders such as:
levels/<levelName>/main/items.level.json
They store serialized scene objects as line-delimited JSON, meaning each line is one complete JSON object.
This page describes the file format. For object behavior and class-specific fields, see Level Object Classes .
BeamNG levels store many scene objects as JSON objects. Instead of writing one large JSON array, the engine writes one object per line.
Example:
{"class":"SimGroup","name":"Environment"}
{"class":"TSStatic","name":"garage","shapeName":"/levels/example/art/shapes/garage.dae","position":[0,0,0],"rotationMatrix":[1,0,0,0,1,0,0,0,1],"scale":[1,1,1]}
{"class":"PointLight","name":"garage_light","position":[2,4,3],"rotationMatrix":[1,0,0,0,1,0,0,0,1],"scale":[1,1,1],"intensity":800}
This format is used because it is easy to stream, edit, diff, merge, and serialize incrementally.
The main level object file is usually:
levels/<levelName>/main/items.level.json
Additional object groups may be stored in subfolders:
levels/<levelName>/main/
├── items.level.json
├── Environment/
│ └── items.level.json
├── Buildings/
│ └── items.level.json
└── Gameplay/
└── items.level.json
Each folder can contain its own items.level.json.
items.level.json is not a normal JSON array.
Correct:
{"class":"SimGroup","name":"Buildings"}
{"class":"TSStatic","name":"building_01","shapeName":"/levels/example/art/shapes/building_01.dae"}
{"class":"TSStatic","name":"building_02","shapeName":"/levels/example/art/shapes/building_02.dae"}
Incorrect:
[
{"class":"SimGroup","name":"Buildings"},
{"class":"TSStatic","name":"building_01"},
{"class":"TSStatic","name":"building_02"}
]
items.level.json contents in [ ]. Each line must be a standalone JSON object.The engine loads items.level.json recursively.
When it finds a SimGroup object, it checks whether a folder with the same name exists. If it does, the engine loads that folder’s items.level.json as well.
Example root file:
{"class":"SimGroup","name":"Buildings"}
{"class":"SimGroup","name":"Gameplay"}
This causes the loader to look for:
main/Buildings/items.level.json
main/Gameplay/items.level.json
This allows large levels to organize objects into folders and groups.
Each line is a JSON object representing one serialized scene object.
Most objects contain at least:
| Field | Type | Description |
|---|---|---|
class |
string | Object class name, such as TSStatic, SimGroup, PointLight, TerrainBlock, etc. |
name |
string | Object name in the Scene Tree. |
position |
array[3] | Object position [x, y, z], when applicable. |
rotationMatrix |
array[9] | Object rotation as a 3×3 matrix, when applicable. |
scale |
array[3] | Object scale [x, y, z], when applicable. |
Different object classes can include many additional fields.
These examples show how different object classes appear in items.level.json. For full behavior details, use the matching class reference page.
A group object used for organization.
{"class":"SimGroup","name":"Buildings"}
If a folder named Buildings exists next to the current items.level.json, it can contain its own nested object file:
Buildings/items.level.json
A static mesh object.
{
"class": "TSStatic",
"name": "garage",
"shapeName": "/levels/example/art/shapes/garage.dae",
"position": [0, 0, 0],
"rotationMatrix": [1,0,0,0,1,0,0,0,1],
"scale": [1,1,1]
}
Important fields:
| Field | Description |
|---|---|
shapeName |
Path to the shape file. |
position |
Object position. |
rotationMatrix |
Object rotation. |
scale |
Object scale. |
A terrain object.
{
"class": "TerrainBlock",
"name": "theTerrain",
"terrainFile": "/levels/example/terrain/main.ter",
"position": [0,0,0],
"rotationMatrix": [1,0,0,0,1,0,0,0,1],
"maxHeight": 2048,
"squareSize": 1
}
Important fields:
| Field | Description |
|---|---|
terrainFile |
Path to the terrain data file. |
maxHeight |
Maximum terrain height. Defaults to 2048 if missing. |
squareSize |
Size of one terrain square. Defaults to 1 if missing. |
Terrain object scaling is disabled. Use squareSize for horizontal dimensions and maxHeight for vertical range. See Terrain Files
.
A spawn point.
{
"class": "SpawnSphere",
"name": "default_spawn",
"position": [10, 20, 1],
"rotationMatrix": [1,0,0,0,1,0,0,0,1]
}
Spawn points are collected by name and position. The engine also adds a fallback spawn point named Zero at the origin.
A water plane object.
{
"class": "WaterPlane",
"name": "lake",
"position": [0,0,0],
"rotationMatrix": [1,0,0,0,1,0,0,0,1],
"scale": [100,100,1]
}
Many scene objects use these transform fields:
"position": [0, 0, 0]
A 3-value array:
[x, y, z]
"rotationMatrix": [
1,0,0,
0,1,0,
0,0,1
]
A 9-value 3×3 rotation matrix.
"scale": [1, 1, 1]
A 3-value scale vector:
[x, y, z]
If invalid transform values are found, the loader may default them to safe values such as:
position = [0, 0, 0]
rotation = identity matrix
scale = [1, 1, 1]
When writing line-object files, the engine can sort objects before saving.
There are two sorting modes:
If enabled, objects with a string serializeOrder field are sorted numerically.
{"class":"TSStatic","name":"a","serializeOrder":"10"}
{"class":"TSStatic","name":"b","serializeOrder":"20"}
The serializeOrder field is removed before writing the final object line.
If serializeOrder sorting is not used, objects are sorted by:
classnameThis gives stable output and makes files easier to diff.
The engine can save objects into namespace folders.
For example, an object namespace list may be saved as:
main/
├── Environment/
│ └── items.level.json
├── Gameplay/
│ └── items.level.json
└── Buildings/
└── items.level.json
Each namespace becomes a folder, and the entries inside it are written to that folder’s items.level.json.
During level loading, the engine starts from:
levels/<levelName>/main/
It then recursively loads:
items.level.json
from the main folder and any discovered SimGroup subfolders.
The resulting object list is then used to create scene objects.
Each line should:
class fieldInvalid lines are skipped and logged.
Manual editing is possible, but use care.
Recommended workflow:
Example levels/example/main/items.level.json:
{"class":"SimGroup","name":"Environment"}
{"class":"SpawnSphere","name":"default_spawn","position":[0,0,1],"rotationMatrix":[1,0,0,0,1,0,0,0,1]}
{"class":"TSStatic","name":"test_cube","shapeName":"/levels/example/art/shapes/test_cube.dae","position":[5,0,0],"rotationMatrix":[1,0,0,0,1,0,0,0,1],"scale":[1,1,1]}
Optional nested file:
levels/example/main/Environment/items.level.json
{"class":"PointLight","name":"env_light","position":[0,0,5],"rotationMatrix":[1,0,0,0,1,0,0,0,1],"scale":[1,1,1],"intensity":1000}
Possible causes:
classSimGroup nameCheck that the parent items.level.json contains:
{"class":"SimGroup","name":"GroupName"}
and that the folder exists:
GroupName/items.level.json
Possible causes:
position arrayCheck that rotationMatrix has exactly 9 numeric values.
Check that scale has exactly 3 numeric values.
items.level.json files store level objects as line-delimited JSON.
Key points:
SimGroup folders.position, rotationMatrix, and scale.serializeOrder, or by class and name.This format is compact, tool-friendly, and suitable for large levels with many scene objects.
See also: SimGroup , TSStatic , TerrainBlock , Prefab , Level Object Classes .
Was this article helpful?