This guide assumes that you are already familiar with Enforce Script Syntax.
Many functions documented in this guide take vector
instances as parameters
to describe X, Y, and Z coordinates on the map. These instances can be expressed as either
vector literals, which look a lot like strings, or as explicit instantiation, which look more
like traditional C++ or C# syntax. Both are valid. Literals require less typing, but explicit
instantiation might provide better syntax highlighting in your editor.
// vector literal vector pos1 = "1234.56 7.890 4433.22"; // explicit vector instantiation vector pos2 = Vector(1234.56, 7.890, 4433.22);
Note: For brevity, vector
instances will be expressed as literals for the remainder
of this guide.
The deathmatch mod provides mission hooks for executing code when rounds start and end. See the
init.c
files in the mission folders.
class CustomMission : MissionServer { override void OnRoundStart(DMArena arena) { // Put your custom round start stuff here } override void OnRoundEnd(DMArena arena) { // Put your custom round end stuff here } };
The following describes the public interface of the DMArena
class that is usable
after the CustomMission
has been constructed.
class DMArena { // Return the arena name string GetName(); // Return the distance from the arena center to a position float DistanceFromCenter(vector position); // Return the playable radius of the arena int GetRadius(); // Return the radius at which players are insta-killed for being too far away int GetKillRadius(); // Find objects that need to be cleaned up at the end of the round void FindObjectsToClean(array<Object> objects); // Return true if the arena is dark and requires Night Vision Goggles bool IsDark(); // Return possible player spawn points TVectorArray GetPlayerSpawnPositions(); // Return a randomly selected player spawn point vector GetRandomPlayerSpawnPosition(); // Set a player's location to a random spawn point void SpawnPlayer(PlayerBase player); // Return possible spawn locations for crates TVectorArray GetCratePositions(); // Return true if at least one possible infected spawn location exists bool HaveInfectedPositions(); // Return the number of possible infected spawn locations int GetInfectedPositionCount(); // Return possible infected spawn locations TVectorArray GetInfectedPositions(); // Return a random infected spawn location vector GetRandomInfectedPosition(); // Return spawn locations for Christmas trees TVectorArray GetChristmasTreePositions(); // Return true if playerCount is between the minimum and maximum player settings bool SupportsPlayers(int playerCount); }
See the Arena Customization Guide if you would prefer to customize arenas using JSON instead of Enforce script.
Arenas for each map are defined in the server mission init.c
script. By convention,
each arena is defined inside its own function and a CreateArenas
function calls
each of the individual arena creation functions before the server finishes loading the mission.
Creating arenas after CustomMission
has been constructed and modifying arenas after
they have been added to the DMArenaRegistry
may result in undefined behavior.
All arenas must have names and center positions. Names should be strings that uniquely identify
the arena location. Center positions should be vector
instances. Construct a new
instance of DMArena
with these two parameters to start creating a new arena. For
example:
DMArena arena = new DMArena("Mordor", "1234.56 7.890 5556.32");
After creating a new DMArena
, it needs to be added to the
DMArenaRegistry
so that it can be used by the server. Call AddArena
to
add the arena to the registry. For example:
DMArena arena = new DMArena("Mordor", "1234.56 7.890 5556.32"); // ... DMArenaRegistry.AddArena(arena);
By default, arenas have a playable radius of 500 meters. If players travel more than 500 meters from the center point, they will begin taking damage. If they travel too far, they will eventually be insta-killed.
To change the playable radius of an arena, pass the desired radius as the optional third
parameter to the DMArena
constructor. For example, the following sets the playable
radius of the Mordor arena to 250 meters:
DMArena arena = new DMArena("Mordor", "1234.56 7.890 5556.32", 250);
Note that as the radius increases, end-of-round object cleanup will take longer. Arenas larger than 500 meters are possible but generally not recommended as they may introduce stuttering when rounds end.
By default, arenas are defined as a circle with a given radius. Rectangular arenas may be created with a specified width and breadth. The boundaries of rectangular arenas are aligned with the map's X and Z axes.
To make an arena rectangular, pass the desired width and breadth to the
SetRectangle
method. For example:
arena.SetRectangle(400, 200);
Although optional, a sufficient number of player spawn positions should be set to ensure that
players do not spawn on top of each other at the start of rounds. To set the possible player
spawn positions for an arena, call the SetPlayerSpawnPositions
method and pass a
TVectorArray
instance. For example:
arena.SetPlayerSpawnPositions({ "4567.89 1.234 9876.54", "4433.24 2.872 9798.44", "4599.16 1.598 9811.59", // ... });
If no player spawn positions are set, all players will spawn at the center of the arena.
To prevent an arena from being randomly chosen when there are too few players connected, call
the SetMinimumPlayers
method and pass the minimum number of players required to
randomly choose the arena. For example:
arena.SetMinimumPlayers(5);
By default, the minimum player count of areas is 0
.
To prevent an arena from being randomly chosen when there are too many players connected, call
the SetMaximumPlayers
method and pass the maximum number of players required to
randomly choose the arena. For example:
arena.SetMaximumPlayers(20);
By default, arenas have no limit to the number of players.
Configuring an arena to be "dark" instructs the server to spawn players with Night Vision Goggles, even if the world time is set to daylight hours. This can be useful for creating arenas in underground locations on modded maps that make underground locations dark. For example:
arena.SetDark();
Walls enclosing arenas can be disabled on a per-arena basis. For example:
arena.DisableWalls();
See CrimsonZamboniDeathmatch Setup Guide: Disable Walls for a way to globally disable walls on all arenas.
Crates containing high-tier items can be configured to spawn at random locations by calling the
SetCratePositions
method and passing a TVectorArray
instance. For
example:
arena.SetCratePositions({ "4567.89 1.234 9876.54", "4433.24 2.872 9798.44", "4599.16 1.598 9811.59", // ... });
Note: No crates will spawn if there are no spawn locations set.
Infected can be configured to spawn at random locations by calling the
SetInfectedPositions
method and passing a TVectorArray
instance. For
example:
arena.SetInfectedPositions({ "4567.89 1.234 9876.54", "4433.24 2.872 9798.44", "4599.16 1.598 9811.59", // ... });
Note: No infected will spawn if there are no spawn locations set.
When Christmas is enabled, Christmas trees can be configured
to spawn by calling the SetChristmasTreePositions
method and passing a
TVectorArray
instance. For example:
arena.SetChristmasTreePositions({"7878.65 432.12 10519.46"});
Unlike the other methods that take TStringArray
instances, described above, Christmas
tree positions are not randomized. Instead, a tree will spawn at every vector in the array. Very
large arenas might benefit from having multiple trees, but I prefer to only have one tree per
arena.
Note: No Christmas trees will spawn if there are no spawn locations set.
To spawn a static object inside the arena when rounds start, call the AddProp
method with the object type name, position, and orientation. For example:
arena.AddProp("Land_Wreck_C130J", "7878.65 432.12 10519.46", "-161.993 0.5 6.5");