Skip to content

EDT Map script format

Alienmario edited this page Jan 25, 2022 · 27 revisions

EDT format

Our edt file format takes some inspiration from Synergy, however, has been built from the ground up specifically for the needs of this project. It allows to configure a map with co-op related settings as well as do some significant modifications to it. It uses Valve's keyvalues syntax which can inherit properties from parent configs.

Features

  • Checkpoint system
  • Equipment system
  • Advanced entity editing system
  • Conditions (if-then-else)
  • Regex matching
  • Delayed mapchange and delayed map start support
  • Support for various map intros
  • Setup convars, plugin features and more

Adding coop support

To enable coop mode on desired map, an edt file for it needs to be created first. EDTs are searched at locations in this order:

  1. sourcemod/data/srccoop/mapname.edt
  2. maps/mapname.edt (This location can also be loaded from inside the bsp, therefore enabling embedded configs)

If you're adding a new edt, it's recommended to start with the included samples.

Dumping map entities

The entity list for current map can be dumped to a file with sc_dump.

Full documentation

General information

Structure

#base "..."

"config"
{
	"param1" "value"
	"param2" "another value"
	// ..etc.. (this is a comment)
	
	"features"
	{}
	"define"
	{}	
	"console"
	{}
	"equipment"
	{}
	"entity"
	{}
	"checkpoint"
	{}
}
  • #base optionally specifies the parent config to inherit values from. The path is relative to the current file. Think of it as copying elements from the parent to this file, with this file taking precedence if property names clash. Multiple levels of nesting are allowed.
  • config is the root element and is required. It can contain properties and other sub-elements.
  • elements inside config are optional
  • base configs may use entity_base_* instead of entity in order to not collide with other edt's entity modifications when merging the files.

Regex

By putting a value between forward slashes, you can create a regex match. This uses sourcemod's internal regex extension, that is PCRE. Regex is supported in most properties that match some value.

Examples:

Regex Description
"/^(suit|weapons|ammo)$/" Matches the values "suit", "weapon" or "ammo"
"/^snds_conveyors/" Matches all values starting with "snds_conveyors"
"/.*/" Matches all possible values

Go to regex101.com to test and build your regexes.

Conditions

Conditions allow to selectively parse sub-elements by testing the given condition against known states. The #else block is optional.

Basic - all conditions must be true:

#if
{
	"condition1" "tested value"
	"condition2" "tested value"
	...
	
	#then
	{
		...
	}
	#else
	{
		...
	}
}

At least 1 condition must be true:

#if
{
	#any
	{
		"condition1" "value"
		"condition2" "value"
	}
	#then
	{
		...
	}
	#else
	{
		...
	}
}

Mixing and nesting is possible - either condition 1 or both 2 and 3 must be true:

#if
{
	#any
	{
		"condition1" "value"
		#all
		{
			"condition2" "value"
			"condition3" "value"
		}
	}
	#then
	{
		...
	}
	#else
	{
		...
	}
}

Conditions:

Condition Description
globalstate Tests whether the given engine global state is currently active
prevmap Tests for the name of previous map
os Tests the server operating system - linux or windows

To negate the condition, add ! in front of it.

When a condition is not found, the "define" list is searched. If the condition is not even found in defines, the result will be false.

Sections

Config

Property Plugin Type Description Repeatable Regex Default
campaign voting string The campaing, used as first category for map voting.
chapter voting string The chapter, used as second category for map voting.
nextmap core string Tells the mod which trigger_changelevel entities are allowed by comparing their map name with this value. Depending on the transitions in the map, can be specified to prevent players from backtracking. ✔️ ✔️
intro_type core string Used together with delayed entity outputs. "freeze" freezes players in place until everyone connects or the startup timer runs out, "none" - players walk around freely and "fade" - same as freeze but fades from black. none
voting_skip_to voting string If this is an intro map, set the map a successful skip vote will change to.
voting_skip_autostart voting bool If this is an intro map, whether to start a skip vote automatically. 0
allow_server_download workshop manager bool 1 to use direct server download for workshop maps. Not recommended - see "Authoring maps for SourceCoop". 0

Config➡️Features

Sets up enabled plugin features for the map. Usually defaulted in base configs.

Example - disable first person death camera:

"features"
{
	"FIRSTPERSON_DEATHCAM" "0"
}

Config➡️Define

Sets up defines, which consist of a name and value (like convars). Usually setup in base configs and overridden in map config to simplify the configuration between the two. For example, the base config can do a specific action, only if the define is set to 1. The map config can override the define to 0 to prevent the action.

Example - base/pizza_base.edt:

"define"
{
	"all_is_pizza" "1"
}
"entity_base_pizza"
{
	#if
	{
		"all_is_pizza" "1"
	}
	#then
	{
		"modify"
		{
			"model" "/.*/"
			"set"
			{
				"model" "models/props_junk/interdimensional_pizza.mdl"
			}
		}
	}
}

melon_map.edt:

"define"
{
	"all_is_pizza" "0"
}

Config➡️Console

Lets you setup server console variables (convars) for the map. They are loaded before any server configs and will be reverted to their default value after the map ends.

Example - enable item spawn effects:

"console"
{
	"sv_mp_spawneffect_item" "1"
}

Config➡️Equipment

Sets up the state and items players spawn with.

Example - Spawn with crowbar, mp5, 70 hp and 15 suit:

"equipment"
{
	"item" "item_weapon_crowbar"
	"item" "item_weapon_mp5"
	"item" "item_suit"
	"health" "70"
	"armor" "15"
}

Example - Import equipment from the map:

"equipment"
{
	"lookup"
	{
		"targetname" "items_at_start"
	}
}

Note: Spawning with default MP equipment is controlled by enabled features.

Config➡️Entity

This section allows modifying map's entities before the level starts.

Small number of entities are precompiled into the map and cannot be modified - for example static lights and props.

Brush entities have a "model" property which starts with * followed by number. The matching geometric model representation is saved separately in a different "lump" of the map and cannot be altered. SourceCoop can however create basic "box" brushes that can be used for invisible entities like triggers.

Config➡️Entity➡️Add

Alt: create

Adds an entity.

Example - add an ambient_generic:

"add"
{
	"classname" "ambient_generic"
	"targetname" "gman_offer_fix"
	"spawnflags" "49"
	"message" "endgame.gman.wiselydone01"
}

Config➡️Entity➡️Remove

Alt: delete

Deletes entities with matching properties. Additional properties narrow down the filter. Supports regex in key and value.

Example - delete entity with name trigger_slamdoor:

"delete"
{
	"targetname" "trigger_slamdoor"
}

Config➡️Entity➡️Modify

Alt: edit

Modifies entities with matching properties. Additional properties narrow down the filter. Supports regex in key and value.

Config➡️Entity➡️Modify➡️add

Alt: create, replace, set

Adds properties to the entity. Replaces existing.

Config➡️Entity➡️Modify➡️remove

Alt: delete

Removes properties from the entity. Only the key is matched, the value can be left empty.

Example - make a changelevel entity stay enabled:

"modify"
{
	"targetname" "c1a4a_c1a4b_transition"
	"add"
	{
		"StartDisabled" "0"
	}
	"remove"
	{
		"targetname" ""
	}
}

Config➡️Entity➡️*

* = Modify or Add

When modifying or adding an entity, there are additional helpers, used as subsections, which make precise editing easier.

Config➡️Entity➡️*➡️Functions
Config➡️Entity➡️*➡️Outputs
Config➡️Entity➡️*➡️Flags

Config➡️Checkpoint

Property Plugin Type Description Repeatable Regex Default
use_map_spawnpoint core bool Add spawn point from map as the first checkpoint (currently just info_player_start). 0
use_map_autosave core bool Add autosave from map as checkpoints (currently just trigger_autosave). 0
strict_order core bool Whether checkpoints must activate in the same order as defined. Not applicable if using use_map_autosave. 1

Config➡️Checkpoint➡️Checkpoint name

Property Plugin Type Description Repeatable Regex Default
origin core vector Destination location 0 0 0
angles core vector Destination orientation 0 0 0
triggerid core string Entity which activates this checkpoint with an output. Accepts targetname or hammerid.
output core string Output from the trigger entity which activates this checkpoint.
delay core float Delays the checkpoint activation, in seconds. 0
followid core string Set to move the checkpoint with an entity. If set, origin and angles become relative to the entity. Accepts targetname or hammerid.
touchid core string Entity which activates this checkpoint when touched by a player. Accepts targetname or hammerid.
portal core vector Location of the portal teleporter to spawn when this checkpoint becomes active.
bringall core bool Teleport all players here upon activation. 0
bringall_radius core float Maximum range from the destination a player is allowed to be in order to not be teleported by bringall. 0

Example:

"checkpoint"
{
	"use_map_autosave" "1"
	
	"spawn"
	{
		"origin"	"-13200 -2544 9878"
		"angles"	"0 0 0"
	}
	"doubledoor"
	{
		"origin"	"-10747 -1900 9573"
		"angles"	"0 30 0"
		"triggerid"	"bd_door"
		"output"	"OnOpen"
	}
}

Checkpoints without a way to activate are assumed to be initial spawn points and will activate on start.

Checkpoint names can be anything descriptive, they are unused at the moment.

Clone this wiki locally