Civilians

Keeping your towns inhabited, and what it costs a player to shoot the people in them.

What this is

Towns on your map can be populated. People live in the zones you have already authored for objective placement, walk around during the day, go home at night, and are billed against the faction score if a player shoots them.

The point is that crossing the map costs something again. A town somebody drives past is a town with people in it, and a driver who does not slow down finds out what that is worth.

Civilians only exist inside zones. They are never placed on an open road in the middle of nowhere — a lone figure walking a country road reads as a bug rather than as a country with people in it.

What you have to supply

Zones, and nothing else. The mod ships four vanilla CIV character prefabs — a generic civilian, a businessman, a dockworker and a construction worker — so a town inside a zone is inhabited on a stock setup with no further setup.

Replace that list if your setting wants different people. One prefab is drawn per person, so several entries give a varied street. They are character prefabs, not group prefabs: each civilian gets a group of their own built around them and takes their faction from the character prefab, so who the locals are is decided by the prefab and never configured twice.

Zones are the part that is yours. They are the same zone list objectives are placed from, which you author on Objective placement. Each zone carries its own tick for whether people live there, so a military camp or an airfield can be excluded while the towns around it stay inhabited.

The two ticks are independent, which is how somewhere becomes populated but never fought over: a friendly town beside your main base with m_bAllowObjectives off and m_bAllowCivilians on is lived-in and never generated into.

Only while somebody is near

Nobody is simulated in a town nobody is looking at. A zone fills when a player comes within m_fCivilianSpawnDistanceM of its edge, and empties again once every player is past m_fCivilianDespawnDistanceM from it.

Measuring to the edge rather than the centre is what makes a large zone fill as somebody reaches the outskirts, instead of when they are already halfway across it. The gap between the two distances is what stops a player sitting on the boundary making a town flicker.

A Game Master camera does not count — the check measures player-controlled characters. Inspecting a town means taking your character there.

Their day

Everybody gets a house. When a zone fills, its buildings are surveyed and handed out one per person, and only repeat once a town has more people than usable interiors. A civilian is placed near their own front door, and wanders a circuit drawn around it at walking pace — so where somebody is at a given hour follows from which house they were given, and each of them keeps to their own street rather than crossing the whole town.

After sunset, m_fCivilianNightIndoorsFraction of them stop wandering and go inside their own house. The rest carry on as they were. It is decided by position in the list rather than by a roll, so the same people are in and the same people are out each night — a street that empties and refills differently every evening reads as a fault rather than as a curfew.

Somebody in a zone with no building they can get inside holds their doorstep instead. Nothing about this needs authoring: no building is tagged, and no navmesh work is involved.

Name tags

Set m_sCivilianFactionKey to the faction your civilian prefabs actually carry, and name tags are kept off them. A street of neutral characters otherwise wears a wall of white names that hides anything moving behind it.

It must match the prefabs to have any effect, and it changes nothing about how they behave. Leave it empty to keep their name tags.

Killing one costs the faction

Shooting a civilian charges the faction score and names the player who did it.

The tariff starts at m_fCivilianPenalty and climbs by m_fCivilianPenaltyStep for each further kill inside m_iCivilianPenaltyWindowSec, up to m_fCivilianPenaltyMax. The window is measured from the last kill, so somebody who keeps going keeps climbing, and somebody who stops for the window drops back to the base rate next time.

Only a player is billed. A civilian caught in a firefight between the AI is a casualty of the war, and charging the faction for a stray AI round would make the ledger lie about who did what. Those deaths are logged and cost nothing.

Civilian kills share one record with damage to protected areas, so somebody who does both does not get a fresh allowance for each. Warnings and removal escalate across both together.

Those four settings live with the rest of the enforcement settings on Configuration.

During a narrative op

By default civilians carry on through a narrative op exactly as they do the rest of the time, so a town stays as lived-in for an authored scene as it is for a rolling objective.

Turn m_bCiviliansInNarrative off and every zone empties when the op begins and fills again when combat ops resumes, which leaves the map to the characters your Game Masters placed. It takes a few seconds either way rather than happening on the instant of the switch.

On a server not running the mode switch at all, this setting does nothing.

Settings

SettingDefaultMeaning
m_bCiviliansEnabledtrueMaster switch. Off leaves every zone empty and costs nothing.
m_aCivilianPrefabs4 CIVCharacter prefabs to draw from. Emptying it places nobody.
m_sCivilianFactionKeyCIVFaction whose name tags are suppressed. Must match what the prefabs carry. Empty keeps their tags.
m_fCiviliansPer100M4People per 100 m of a zone’s radius. The main cost dial — it multiplies across every populated zone at once.
m_iCiviliansMin2Fewest a zone allowing civilians will hold. Below about two, nowhere reads as inhabited.
m_iCiviliansMax16Most one zone may hold, whatever the scaling works out to. 0 means no ceiling.
m_fCivilianSpawnDistanceM600How close a player must come to a zone’s edge before its people are placed.
m_fCivilianDespawnDistanceM900How far every player must be from the edge before they are taken away.
m_fCivilianWanderRadiusM60How far somebody wanders from their own house.
m_bCivilianDayNighttrueWhether a share of them go in for the night. Off, everybody wanders around the clock.
m_fCivilianNightIndoorsFraction0.6Share who stay in after dark. The rest keep wandering.
m_bCiviliansInNarrativetrueWhether the zones stay inhabited during a narrative op. Off, they empty for the op and fill again afterwards.

Population works out as the rate multiplied by the zone’s radius, then held between the floor and the ceiling — so the ceiling is what bounds one very large zone, and the rate is what bounds your server.

Per-zone overrides

Two fields on each zone, alongside its name, centre and radius on Objective placement:

FieldDefaultMeaning
m_bAllowCivilianstrueWhether people live here at all. Turn it off for a camp, airfield or depot.
m_iCivilianCount-1How many live here. -1 derives it from the radius, which is usually right.

Set m_iCivilianCount to make one place busier or quieter than its size suggests.

Overriding these on your server

If ATG Core is loaded ahead of this mod, all of the above can be set per server from $profile:ATG/atg-scenario.json without touching any mod files. Booleans are written true and false — a 1 is ignored and the setting silently keeps the value it already had.

{
  "m_bCiviliansEnabled": true,
  "m_aCivilianPrefabs": [
    "{22E43956740A6794}Prefabs/Characters/Factions/CIV/GenericCivilians/Character_CIV_Randomized.et",
    "{B3AB6D12D247DDB5}Prefabs/Characters/Factions/CIV/Businessman/Character_CIV_Businessman_Randomized.et",
    "{5882AE7A4543AFB4}Prefabs/Characters/Factions/CIV/Dockworker/Character_CIV_Dockworker_Randomized.et",
    "{D97EAE64721478F3}Prefabs/Characters/Factions/CIV/ConstructionWorker/Character_CIV_ConstructionWorker_Randomized.et"
  ],
  "m_sCivilianFactionKey": "CIV",
  "m_fCiviliansPer100M": 4,
  "m_iCiviliansMin": 2,
  "m_iCiviliansMax": 16,
  "m_fCivilianSpawnDistanceM": 600,
  "m_fCivilianDespawnDistanceM": 900,
  "m_fCivilianWanderRadiusM": 60,
  "m_bCivilianDayNight": true,
  "m_fCivilianNightIndoorsFraction": 0.6,
  "m_bCiviliansInNarrative": true,

  "m_fCivilianPenalty": 50,
  "m_fCivilianPenaltyStep": 10,
  "m_fCivilianPenaltyMax": 100,
  "m_iCivilianPenaltyWindowSec": 600
}

Delete the lines you do not want to change — a key you leave out keeps its shipped value. m_aCivilianPrefabs needs care: it is a list, so naming it replaces the whole thing rather than merging, and naming it with an empty array places nobody at all. Leave it out unless you are changing who the locals are, and write resource strings out in full, braces included, taken from the Workbench picker rather than typed.

If nobody appears

The server log says which of the reasons applies, at startup:

[ATG_Scenario] Civilians: m_bCiviliansEnabled is off, no civilians will be placed
[ATG_Scenario] Civilians enabled but no civilian prefabs configured - none will be placed
[ATG_Scenario] Civilians enabled but no zone allows them - none will be placed

A healthy start names how many zones took part, and each town then reports itself as it fills and stands down:

[ATG_Scenario] Civilians active - 6 zone(s), 4 per 100m of radius (min 2, max 16), spawning within 600m, day/night 1
[ATG_Scenario] 10 civilian(s) went about their business in "Naudeh", between 9 house(s)
[ATG_Scenario] Civilians in "Naudeh" stood down - nobody within 1240m

If people appear but every one of them is on the outskirts, the town’s buildings are not being recognised as somewhere anyone could live — the house count in that line is what to look at.