Objective placement

How ATG Scenario decides where an objective goes, and how to author zones for your own map.

Zones are authored, positions are derived

The engine can tell you a position is flat, dry, clear of geometry and near some buildings. It cannot tell you the spot is worth fighting over — good sightlines, a compound with a reason to exist, somewhere players will recognise. So the mod does not try to invent locations.

Instead you author zones: named stretches of your map where objectives belong. The mod picks a zone, then picks a specific position inside it that survives every hard constraint. Geography comes from someone who knows the terrain; usability is decided mechanically.

The exact position varies each time, so the same zone does not replay identically. A 250m-radius zone holds a lot of different fights.

Two ways to author zones

Survey them in-game. A Game Master places a marker, drags it where the fight should be, sizes its ring, and writes the file from chat. Needs no Workbench and no mod of your own — this is the route for a server owner. Covered next.

Ship a zone config in your map mod. Authored in Workbench, versioned with the map, and carried along by a map update. This is the route for whoever owns the map. Covered further down.

If both exist the surveyed file wins outright, and the mod says so at startup. It is a whole-file replacement, not a merge — you get one set of zones or the other, never half of each.

Surveying zones in-game

You need a Game Master role, ATG Commands loaded ahead of ATG Scenario, and nothing else.

  1. Open the Game Master content browser and place Zone surveyor (under Systems). A translucent ring appears, draped over the terrain.
  2. Drag it to where a fight should happen — a village, a compound, an industrial site.
  3. Select it and open Edit Attributes. Under Zone surveyor you get Radius, Weight and Exclusion. Change the radius and the ring resizes immediately.
  4. Repeat for as many zones as you want.
  5. Mark your base: place one more surveyor at it and tick Exclusion. Objectives will not be placed inside it, and the distance-from-home limits measure from it.
  6. /atg zone save.

The attributes

AttributeControlMeaning
RadiusSlider, 50–1000m in 25m stepsHow far from the marker an objective may be placed.
WeightSlider, 0–5 in steps of 0.5How often this zone is chosen against the others. Two means twice as often; zero retires it without deleting the marker.
ExclusionCheckboxMarks somewhere nothing may be placed, rather than somewhere objectives belong.

Weight is hidden on an exclusion, because nothing is ever drawn from one — an editable field that silently did nothing would be worse than none.

Doing it from chat instead

The same three values are reachable as chat commands, which act on whichever surveyor you are standing nearest:

/atg zone                    list every marker with coordinates and radii
/atg zone radius <metres>    resize the nearest
/atg zone exclusion          make the nearest an exclusion
/atg zone area               make it a zone again
/atg zone save               write the file

The attributes panel is usually the better tool — it edits what is selected rather than what you are standing beside, and it shows you the current values. The commands are still the quickest way to see every marker at once.

radius accepts 50–1000 from chat, exactly matching the slider, so the two routes cannot disagree about what is allowed. The zones file itself accepts up to 5000 if you hand-edit it, but a zone that large is better split into several.

Who can do what

Placing a surveyor, dragging it and changing all three attributes needs a Game Master role — the attributes panel has no privilege of its own, so anyone who can select the entity can edit it. The chat verbs match that.

/atg zone save requires a full administrator. It is the one thing here that writes a file on the server, so it sits a rung above the rest — a session administrator is refused by name. Run /atg whoami to see what you hold.

The file lands at <profile>/ATG/atg-scenario-zones.json. It is read at startup only, so restart the server for it to take effect.

If that file already exists it is never overwritten — you get atg-scenario-zones.new.json alongside it instead, and the command tells you which one it wrote. Surveying can’t destroy zones you have since hand-edited.

After saving

Surveyors are named Zone 1, Zone 2 and so on, because the chat router lowercases every argument it is given and there is no way to recover the capitals in a name you typed. Open the file and rename them to something you will recognise in a log — the name is never shown to players.

The first exclusion you mark is named MOB, which is what m_sBaseExclusionName already defaults to. Mark your base first and the distance-from-home limits work with no further setting.

The file is also where you add anything the surveyor does not cover — task-type restrictions, or a different weight per zone. Both are described below.

The surveyors themselves are ordinary Game Master entities. Delete them once the file is written; they take no part in placement and a surveyor left in the world does nothing at all.

Shipping a zone config in your map mod

Zones are map data, so they can equally live in whichever mod owns your map. That keeps the mod portable and means a map update carries its own geography with it.

In Workbench, create a new config in your map’s mod with ATG_Scenario_ZoneConfig as its root class — somewhere like Configs/Scenario/ObjectiveZones.conf. Your mod needs ATG Scenario as a dependency for that class to be available.

Then point the mod at it by setting m_sZoneConfig to your new config. Because that setting is a single value, it can also be set per-server through the JSON layer, so several servers can run the same map mod with different zone sets.

Until either m_sZoneConfig or a surveyed file exists, nothing can be placed and the mod says so at startup.

Finding coordinates in World Editor

Zone centres are world coordinates, which you read out of World Editor:

  1. Open your world in Workbench’s World Editor.
  2. Navigate the camera to the place you want.
  3. Select any object near the centre of it. A building, a bush, anything static will do; you only need a position, not a specific entity.
  4. Read its coords from the entity properties panel. Three numbers: X, height, Z.
  5. Copy them into m_vCenter.

The middle value is height and is ignored — positions are resolved onto the terrain surface at placement time, so it does not matter if the object you picked was on a rooftop or below ground.

Pick a radius that keeps a fight recognisably in one place. 200–400m works well; larger zones give more variety but risk drifting somewhere that does not suit the objective.

The zones file

Both routes produce the same two lists. Written out as JSON:

{
  "m_aZones": [
    {
      "m_sName": "Naudeh outskirts",
      "m_vCenter": "3120.45 0 5188.12",
      "m_fRadiusM": 250,
      "m_fWeight": 1
    }
  ],
  "m_aExclusionZones": [
    {
      "m_sName": "MOB",
      "m_vCenter": "1024.00 0 2048.00",
      "m_fRadiusM": 400
    }
  ]
}

Keep the keys exactly as written — a mistyped key is not an error, it is a field that silently keeps its default. A file that parses but yields no zones at all is reported at startup and falls back to the map mod’s config.

To restrict a zone to certain objective types, add m_aTaskTypes to it; the values are the same task types listed under objective templates on Configuration. Leaving it out allows any.

Zone fields

FieldMeaning
m_sNameName for logs, and the place name players are shown when a civilian is killed.
m_vCenterWorld position. The height component is ignored.
m_fRadiusMHow far from the centre an objective may be placed.
m_fWeightRelative likelihood. 0 retires the zone without deleting it.
m_aTaskTypesWhich objective types suit this zone. Empty allows any.
m_bAllowObjectivesWhether objectives may be placed here at all. Default true.
m_bAllowCiviliansWhether people live here. Default true.
m_iCivilianCountHow many live here. -1 derives it from the radius.

The last three are independent of each other, so a zone can host objectives with nobody around, people with no objectives, or both — see Civilians. Because a zone name can now reach players, give them the names the place actually has rather than internal shorthand.

Restricting task types is worth doing where a place only makes sense for one kind of job — a fuel depot might only ever host Destroy, while a village suits most things.

Exclusion fields

FieldMeaning
m_sNameName for logs, and what m_sBaseExclusionName matches against.
m_sEntityNameWorld entity to follow. Wins over the coordinate below.
m_vCenterCoordinate, used when no entity is named.
m_fRadiusMNothing may be placed within this distance.

Prefer m_sEntityName wherever the thing being avoided is an entity — a coordinate silently goes stale the moment somebody moves the base in World Editor, and nothing will tell you.

You will want at least one exclusion around your main base, and m_sBaseExclusionName should match its name, since that is what the distance-from-home limits measure against.

What exclusions are and are not for

Exclusions are for permanent features — a main base, a fixed spawn point.

They constrain placed objectives, the ones whose position has to be chosen. They say nothing about anchored objectives, whose location is inherent to what they are: an attack on the main base happens at the main base by definition, so it never asks for a position. Listing somewhere as an exclusion does not make it immune from being attacked — it makes it ineligible as a dartboard for routine objectives.

Avoid listing places that are only sometimes occupied. A static exclusion sterilises that ground permanently, even when nothing is there — and those are often the most interesting parts of a map, which is exactly why something was placed there in the first place.

The constraint pipeline

Vanilla’s terrain search does the first pass: a hexagonal-grid sweep across the zone looking for a clear cylinder, tracing against entities and ocean. Positions come back resolved onto the terrain surface, so “below terrain” cannot happen by construction, and anything intersecting a wall is already rejected.

Candidates then pass through the mod’s own rules, cheapest first so most rejects cost only a distance comparison:

  1. Separation from other live objectives
  2. Outside every exclusion
  3. Within the min–max ring from home
  4. Clear of connected players
  5. Ground variation across the footprint
  6. Open sky overhead

The survivors are pooled and one is chosen at random.

Why the overhead check exists

The clear-cylinder test will happily hand back the inside of a sealed room, because the interior genuinely is empty ground sitting on terrain — exactly what it was asked to find. Tracing upward is what tells a courtyard from a locked room.

What the checks do not cover

Two things the solver cannot judge, worth knowing when you author zones:

Pathability. The checks confirm ground is clear, not that AI can move around it sensibly. A position hemmed in by terrain can be perfectly valid and still make for poor defenders. If a zone consistently produces awkward fights, tighten its radius onto ground you know plays well.

Very tall interiors. A hangar or warehouse with a ceiling above m_fOverheadClearanceM clears the overhead trace. Lowering that setting rejects such interiors, at the cost of also rejecting legitimate spots beside tall buildings — worth adjusting only if you see objectives appearing indoors.