ABOUT

In this folder are levels, the structure of levels looks like this:

level_folder:    <- name of the folder, is level ID.
    /
    level.json            <- level.json is the main data file of the level.
    custom_mesh.obj
    custom_mesh2.obj
    ...

LEVEL.JSON <- the main data file of the level, it contains objects, light and other information of level.

{

"weather_color": "0a0a0a", // HEX color of sky background

"daylight": false, // turn on/off daylight state of the level

"fog": true, // volumetric fog, works only when daylight:false

"light": [], // array with light sources

"level_data": [] // array with level objects (static and usable)

}

LIGHT : [ ] <- array with light sources

{ "color": [ 238, 157, 49 ], <- array of the colors R G B "distance": 7.0, <- float number for the light size (light sphere diameter) "energy": 1, <- float number for the light source brightness "name": "point_light", <- by that name you can find this light by scripts "position": [ 11.36, 1.91, -2.91 ], <- array of floats for Vector3( ) of position "shadows": false, <- turns on/off shadows on level (works only when daylight:false) "type": "point" <- type of light }

LEVEL_DATA : [ ] <- array with level data. There are few types of objects.

Let's start with simple one, static object. It hasn't "id": "id_type", so it's static. Like terrain model, boxes, walls, etc.

{

"model": "assets/...", <- path to *.obj model, starts from assets/

"texture": "pbandit.png", <- texture name in assets/textures/

"position": [ 0, 0, 0 ], <- position, float numbers

"rotation": [ 0, 180, 0 ], <- rotation, float numbers

"collider": null, <- generate colliders, can be null, "box", "mesh", "sphere"

"scale": 1, <- scale times, or can be array [1, 1, 1] of floats

"lit": false, <- lit/unlit material can be fake emission with no light

"name": "object_name", <- name for using in scripts through get_node()

"alpha": false, <- transparent texture if it has alpha

"billboard": false, <- billboard or not

"double_sided": false, <- on/off material back culling

}

Second type of level objects its usable or "dynamic" or whatever. The contains special key -> "id": "id_type"

List of all available id types:

ID KEY
WHAT THEY DO

"id" : "sprite3d"

Sprite object in 3D that can be billboard, best example - light sparkles under lamps in underground

"id" : "spawn_point"

Invisible object that spawn player at self coordinates and rotate it. Can be only one on level!

"id" : "animated3dsprite"

Sprite object but with animation, only used for fire.

"id" : "radiation"

3D area that has shape of cube and if player come inside - it start hurt the player

"id" : "hostile_eyezone"

3D area that allow enemies attack player inside.

"id" : "npc"

Friendly NPC

"id" : "npc_hostile"

Hostile AI Bot

"id" : "loot_money"

3D usable area in shape of cube that gives player only money on use

"id" : "loot"

3D usable area in shape of cube that allow player to open loot window and take items from it

"id" : "usable_area"

3D usable area in shape of cube that gives player event key after use

"id" : "transition_to_level"

3D usable area in shape of cube that change level on use

"id" : "transition"

3D usable area in shape of cube that allow player to move by waypoints and teleport to specific position in current level

"id" : "block"

3D invisible wall, that block player raycast so player can't use triggers behind this block

And now what kind of keys can be added to object of specific ID.

ID
MUST HAVE KEYS
WHAT THEY DO

"id" : "sprite3d"

"texture": "filename.png"

Filename of texture in textures/

"3d_sound": { "volume_db": 0, "audio": "assets/...",

"max_distance": 5.0 }

<- 0 is 100% volume, -88 is 0% <- path from assets/ <- max distance float

"id" : "spawn_point"

Keep only id, position, rotation and name.

"id" : "animated3dsprite"

"sequence": "fire"

Main sequence of fire animation.

"id" : "radiation"

"size": [1.0, 1.0, 1.0]

Size of area in float

"id" : "hostile_eyezone"

"hostile_id": "any_string"

ID of eyezone for AI Bots

"size": [1.0, 1.0, 1.0]

Size of area in float

"id" : "npc"

"profile": "npc_profile_id"

ID of profile from creatures/characters.json

"id" : "npc_hostile"

"animations": [ "anim1", "anim2"... ]

Attack animation for AI. All anims list search in scripts/p_game.gd

"profile": "ai_profile_id"

ID from creatures/enemy.json

"zone_id": "eyezone_id"

ID of eyezone where they will be

"id" : "loot_money"

"value": 100

Money amount. Use Int value.

"model": "cube"

You need add it!

"invisible": true

Always keep it invisible

"id" : "loot"

"loot_id": "loot_id"

ID from gameplay/loot_containers.json

"model": "cube"

You need add it!

"invisible": true

Always keep it invisible

"id" : "usable_area"

"event_key": "key.id"

Add event key, then you can add logic for key in scripts/p_game.gd

"model": "cube"

You need add it!

"invisible": true

Always keep it invisible

"id" : "transition_to_level"

"condition": "key.id"

*optional* door will have lock icon and can't be used until player will have event key with this id

"level": "level_folder_id"

level ID for loading

"model": "cube"

You need add it!

"invisible": true

Always keep it invisible

"id" : "transition"

"target_position": [ 1.0, 1.0, 1.0 ]

Position of player destination when door will be used

"target_rotation": [ 0.0, 0.0, 0.0 ]

Rotation of player destination when door will be used

"invisible": true

Always keep it invisible

"waypoints": "waypoint_id"

ID from gameplay/waypoints.json

"id" : "block"

"collider": "box"

Always put box collider

"invisible": true

Always keep it invisible

Here's list of this additional words:

WAYPOINT WORD
WHAT IT DOES

$to_this_door

Move camera from it's position forward to the trigger position. This word must replace waypoint id.

<waypoint_id>_last_points

Go backward by waypoints and start first point from middle of path

<waypoint_id>_return

Go backward by waypoints from end of points and finish at transition object position

<waypoint_id>_back_only_waypoints

Go backward by waypoints from end of points and finish only at last point

So this is how level.json is works! Here's as example - intro level of the game:

levels/intro/level.json
{
	"weather_color": "4a739f",
	"daylight": true,
	"fog": false,
	"light": [],
	"level_data": [
		{
			"uid": "skybox",
			"model": "assets/levels/intro/l_0_0_skybox",
			"texture": "texsky1.png",
			"position": [
				0,
				-13.77,
				0
			],
			"rotation": [
				0,
				0,
				0
			],
			"lit": true,
			"collider": null,
			"scale": 1,
			"name": "skybox",
			"alpha": false,
			"billboard": false
		},
		{
			"id": "spawn_point",
			"position": [
				6.318,
				1.564,
				-5.53
			],
			"rotation": [
				0,
				158.14,
				0
			],
			"name": "SpawnPoint"
		},
		{
			"id": "loot_money",
			"value": 75,
			"model": "cube",
			"position": [
				5.975,
				0,
				0.626
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": "box",
			"invisible": true,
			"scale": 1,
			"color": [
				10,
				10,
				10,
				128
			],
			"name": "loot_money_0",
			"alpha": false,
			"lit": false,
			"billboard": false
		},
		{
			"id": "loot_money",
			"value": 125,
			"model": "cube",
			"position": [
				2.528,
				0,
				-2.036
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": "box",
			"invisible": true,
			"scale": 1,
			"color": [
				10,
				10,
				10,
				128
			],
			"name": "loot_money_1",
			"alpha": false,
			"lit": false,
			"billboard": false
		},
		{
			"id": "loot",
			"loot_id": "level_0_0_corpse_0",
			"model": "cube",
			"position": [
				-1.023,
				0,
				-2.953
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": "box",
			"invisible": true,
			"scale": 1,
			"color": [
				10,
				10,
				10,
				128
			],
			"name": "items_loot",
			"alpha": false,
			"lit": false,
			"billboard": false
		},
		{
			"id": "loot_money",
			"value": 50,
			"model": "cube",
			"position": [
				0.341,
				0,
				1.524
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": "box",
			"invisible": true,
			"scale": 1,
			"color": [
				10,
				10,
				10,
				128
			],
			"name": "loot_money_2",
			"alpha": false,
			"lit": false,
			"billboard": false
		},
		{
			"id": "transition_to_level",
			"level": "intro_battle",
			"waypoints": "intro_wp_0",
			"model": "cube",
			"position": [
				0.32,
				2.41,
				9.17
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": "box",
			"invisible": true,
			"scale": [
				5.66,
				4.54,
				1
			],
			"name": "transition",
			"alpha": false,
			"lit": false,
			"billboard": false
		},
		{
			"model": "assets/levels/intro/terrain_intro",
			"texture": "objects/terrain_type2.png",
			"position": [
				0,
				0,
				0
			],
			"rotation": [
				0,
				180,
				0
			],
			"collider": null,
			"lit": true,
			"scale": 1,
			"name": "terrain_intro",
			"alpha": false,
			"billboard": false
		},
		{
			"model": "assets/levels/intro/l_0_0_rocks",
			"texture": "texobj2.png",
			"position": [
				0,
				0,
				0
			],
			"rotation": [
				0,
				180,
				0
			],
			"collider": null,
			"lit": true,
			"scale": 1,
			"name": "rocks",
			"alpha": false,
			"billboard": false
		},
		{
			"model": "assets/levels/intro/l_0_0_forest",
			"texture": "texforest1.png",
			"position": [
				0,
				0,
				0
			],
			"rotation": [
				0,
				180,
				0
			],
			"collider": null,
			"alpha": true,
			"lit": true,
			"scale": 1,
			"name": "forest",
			"billboard": false
		},
		{
			"model": "assets/levels/intro/l_0_0_dead_stalkers",
			"texture": "pstalker.png",
			"position": [
				0,
				0,
				0
			],
			"rotation": [
				0,
				180,
				0
			],
			"collider": null,
			"lit": true,
			"scale": 1,
			"name": "corpses",
			"alpha": false,
			"billboard": false
		},
		{
			"model": "assets/levels/intro/l_0_0_dead_bandit",
			"texture": "pbandit.png",
			"position": [
				0,
				0,
				0
			],
			"rotation": [
				0,
				180,
				0
			],
			"collider": null,
			"scale": 1,
			"lit": true,
			"name": "dead_bandit",
			"alpha": false,
			"billboard": false
		},
		{
			"model": "assets/levels/intro/l_0_0_dead_stalkers_weapons",
			"texture": "texobj2.png",
			"position": [
				0,
				0,
				0
			],
			"rotation": [
				0,
				180,
				0
			],
			"lit": true,
			"collider": null,
			"scale": 1,
			"name": "weapons",
			"alpha": false,
			"billboard": false
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				-6,
				0,
				8
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"scale": [
				1.52,
				1.52,
				1.52
			],
			"double_sided": true,
			"alpha": true,
			"lit": true,
			"name": "tree1",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				13.83,
				-0.42,
				-3.91
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"scale": [
				1.86,
				1.86,
				1.86
			],
			"double_sided": true,
			"alpha": true,
			"lit": true,
			"name": "tree5",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				16.52,
				-0.42,
				8.84
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"scale": [
				1.86,
				1.86,
				1.86
			],
			"double_sided": true,
			"alpha": true,
			"lit": true,
			"name": "tree18",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				21.4,
				-1.35,
				-20.41
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"scale": [
				1.86,
				2.05,
				1.86
			],
			"double_sided": true,
			"alpha": true,
			"lit": true,
			"name": "tree19",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				5,
				0,
				17
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"scale": [
				1.55,
				1.55,
				1.55
			],
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree2",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				1,
				0,
				32
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"scale": 1,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree3",
			"billboard": false
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				16.33,
				0,
				25
			],
			"rotation": [
				0,
				-28,
				0
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree4",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				-30.2,
				0,
				11.11
			],
			"rotation": [
				0,
				-84.9,
				0
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree14",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				-30.2,
				0,
				-26.06
			],
			"rotation": [
				0,
				-84.9,
				0
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree15",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				-10.09,
				0,
				-31.5
			],
			"rotation": [
				0,
				-84.9,
				0
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree16",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				-27.83,
				0,
				-6.51
			],
			"rotation": [
				0,
				-84.9,
				0
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree17",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				-6.09,
				-0.51,
				-14.72
			],
			"rotation": [
				65.61,
				-38.38,
				50.47
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree20",
			"billboard": false
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				-5.98,
				-0.11,
				-14.64
			],
			"rotation": [
				32.91,
				-171.29,
				-71.75
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree21",
			"billboard": false
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				21.82,
				-0.48,
				7.37
			],
			"rotation": [
				0,
				-28,
				0
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree6",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				30,
				0,
				-17
			],
			"rotation": [
				0,
				-28,
				0
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree7",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				14,
				0,
				32
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"scale": 1,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree8",
			"billboard": false
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				4,
				0,
				-46
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"scale": 1,
			"alpha": true,
			"lit": true,
			"name": "tree9",
			"billboard": false
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				-21,
				0,
				-6
			],
			"rotation": [
				0,
				90,
				0
			],
			"collider": null,
			"scale": [
				1.31,
				1.31,
				1.31
			],
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree10",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				-8.6,
				0,
				-22.1
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"alpha": true,
			"lit": true,
			"scale": [
				1.75,
				1.75,
				1.75
			],
			"double_sided": true,
			"name": "tree11",
			"billboard": true
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree1.png",
			"position": [
				-7,
				0,
				-39
			],
			"rotation": [
				0,
				0,
				0
			],
			"collider": null,
			"scale": [
				1.61,
				1.61,
				1.61
			],
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree12",
			"billboard": false
		},
		{
			"model": "assets/models/tree_faced",
			"texture": "textree3.png",
			"position": [
				14,
				0,
				-43
			],
			"rotation": [
				0,
				-28,
				0
			],
			"collider": null,
			"scale": 3,
			"alpha": true,
			"lit": true,
			"double_sided": true,
			"name": "tree13",
			"billboard": true
		},
		{
			"collider": "box",
			"id": "block",
			"invisible": true,
			"model": "cube",
			"name": "raycast_block_zone",
			"position": [
				0,
				-0.94,
				0
			],
			"rotation": [
				0,
				0,
				0
			],
			"scale": [
				81.13,
				1,
				66.38
			],
			"alpha": false,
			"lit": false,
			"billboard": false
		},
		{
			"collider": null,
			"lit": true,
			"model": "assets/models/mi24",
			"name": "mi24",
			"position": [
				-2.61,
				-0.95,
				-14.91
			],
			"rotation": [
				0,
				121.41,
				-9.62
			],
			"scale": 1,
			"texture": "mi24.png",
			"double_sided": true,
			"billboard": false
		},
		{
			"collider": "box",
			"lit": true,
			"model": "assets/models/garbage",
			"name": "garbage",
			"position": [
				-6.24,
				0,
				-13.01
			],
			"rotation": [
				0,
				0,
				0
			],
			"scale": [
				1.8,
				1.8,
				1.8
			],
			"texture": "texobj2.png",
			"billboard": false
		},
		{
			"collider": "box",
			"lit": true,
			"model": "assets/models/garbage",
			"name": "garbage2",
			"position": [
				2.54,
				0,
				-20.5
			],
			"rotation": [
				0,
				0,
				0
			],
			"scale": [
				3.42,
				3.42,
				3.42
			],
			"texture": "texobj2.png",
			"billboard": false
		},
		{
			"collider": "box",
			"lit": true,
			"model": "assets/models/old_tree",
			"name": "old_tree",
			"position": [
				7.96,
				0.06,
				-23.64
			],
			"rotation": [
				-0.24,
				-56.65,
				-76.05
			],
			"scale": [
				1.6,
				1.6,
				1.6
			],
			"texture": "texobj1.png",
			"billboard": false
		},
		{
			"billboard": true,
			"id": "animated3dsprite",
			"name": "fire",
			"position": [
				-2.39,
				1.64,
				-13.27
			],
			"rotation": [
				0,
				30,
				0
			],
			"scale": 2.80000000000291,
			"sequence": "fire",
			"3d_sound": {
				"volume_db": 0,
				"audio": "assets/sounds/ambient_sfx/campfire.mp3",
				"max_distance": 12
			}
		},
		{
			"billboard": true,
			"id": "animated3dsprite",
			"name": "fire2",
			"position": [
				-7.44,
				1.64,
				-13.34
			],
			"rotation": [
				0,
				30,
				0
			],
			"scale": 2.80000000000291,
			"sequence": "fire"
		},
		{
			"billboard": true,
			"id": "animated3dsprite",
			"name": "fire3",
			"position": [
				3.36,
				3.34,
				-19.74
			],
			"rotation": [
				0,
				30,
				0
			],
			"scale": 2.80000000000291,
			"sequence": "fire"
		}
	]
}

Last updated