CfgWorlds: Clutter

Clutter is the randomly placed small vegetation - grass, etc. - that is not part of the map. Rather, it is defined by the underlying texture, which in turn is mapped to the island by the texture mask and Layers.cfg. To define clutter you first need to have your ground textures setup - if you don't, follow this tutorial.

The clutter section of the config starts with a few variables:

  clutterGrid = 1.0;
  clutterDist = 125;
  noDetailDist = 40;
  fullDetailDist = 15;
  midDetailTexture = "ca\chernarus\data\cr_trava1_mco.paa";
  minTreesInForestSquare = 3;
  minRocksInRockSquare = 3;

Fortunately, these variables are explained in the BISampleMap.

clutterGrid is likely the grid used for calculating the distribution of clutter, since it is 1.0 in Chernarus, a lush landscape, and 1.5 in Takistan, which is significantly more arid.

clutterDist is the maximum distance up to which clutter objects are visible, presumably in meters.

noDetailDist and fullDetailDist determine how far away from the camera the ground detail texture* fades in and out, with fullDetail being the lower value and noDetailDist being the higher value; that is, in the example above the full ground detail texture will be visible up to 15m away and fade out to 40m.

midDetailTexture is not explained anywhere, but I assume this texture is mixed with the ground detail texture over the fading distance, before fading into the satellite texture at longer distances.

minTreesInForestSquare and minRocksInRockSquare: my guess is that these define how many rocks or trees must be present in a given area for it to cause a forest or rock square overlay (green or gray) to show up on the ingame map.

This is followed by the "clutter" class (it is lowercase in the official maps, but I don't know if this makes any difference). This is a snippet from the BISampleMap config, but this class will typically be much longer.

    class clutter
    {
      class GrassGeneral: DefaultClutter
      {
        model = "ca\plants\clutter_grass_general.p3d";
        affectedByWind = 0.3;
        swLighting = 1;        //relativeColor[]={0.8,0.8,0.8,0};
        //colorByGround=0.9;
        scaleMin = 0.75;
        scaleMax = 1.0;
      };
      class GrassFlowers: GrassGeneral
      {
        model = "ca\plants\clutter_grass_flowers.p3d";
      };
      class GrassLong: GrassGeneral
      {
        model = "ca\plants\clutter_grass_long.p3d";
        affectedByWind = 0.6;
        scaleMin = 0.60;
        scaleMax = 1.10;
      };
   };

This defines each individual clutter model for use in surface definitions. In the official maps the usual technique is to define a general class and then inherit from it for the other clutter definitions.

model is obviously the path to the .p3d of the clutter model.

affectedByWind is likely how much this model will wave (i.e. be distorted) in the wind.

swLighting I'm not sure about, but it could possibly stand for software lighting; I'm not sure what effect this has.

relativeColor[] and colorByGround are likely legacy variables, as using them in ArmA 2 will cause an RPT error for colorByGround. I assume this was used to change the color of clutter depending on the underlying texture in OFP.

scaleMin and scaleMax work similarly to the random size settings for natural objects in Visitor 3, defining a minimum and maximum limit for clutter object scaling.

It is not necessary to guess at the appropriate values for each model when defining the clutter models for a custom island, as they are already defined in chernarus.pbo\ca\chernarus\config.bin, and in the configs of other islands.

The rest of the clutter configuration is actually not located inside CfgWorlds, but usually at the end of the file. The CfgSurfaces class defines a series of parameters for each ground texture, and CfgSurfaceCharacters associates these surfaces with clutter objects and probabilities. Thanks to the PMC Editing Wiki article for helping me figure this one out. Also see this thread.

The CfgSurfaces class is as follows (this is a snippet of the Chernarus config):

class CfgSurfaces
{
 class Default{};
 class Water{};
 class CRGrass1: Default
 {
  access = 2;
  files = "cr_trava1_*";
  rough = 0.11;
  dust = 0.1;
  soundEnviron = "grass";
  character = "CRGrassClutter";
  soundHit = "soft_ground";
 };
};

The Default and Water classes are stubbed. Each ground texture will then typically have an entry in the form of a class inheriting from Default.

access: I'm not clear on what this does here, but it is probably related to the constants defined in BISampleMap.

files is the all-important wildcard string. This defines which ground texture filenames this surface will apply to (usually only one). In this case CRGrass1 will apply to the cr_trava1 texture.

rough is the "bumpiness" of this surface, though this does not determine how bumpy it looks, only how much vehicles' wheels will bounce when traversing it.

dust is how much dirt will be kicked up by vehicles traversing this surface.

soundEnviron determines the sounds troops make when walking across this surface. It should be possible to add custom sounds by defining new entries under the SoundEnvironExt class, but you will likely be OK with the default ones. See this thread for a list of soundEnvirons. Default soundEnvirons for ArmA 2 are normalExt, normal, road, rock, water, gravel, sand, drygrass, grass, forest, mud, wood metal, snow, hallway, fallbody, laydown, standup, crawl.

character is the CfgSurfaceCharacters character which will be associated with this surface. This is where you choose which clutter object/probability pairs you want for this surface. If you don't want clutter for a surface, set this to "Empty".

soundHit is the sound bullets make when hitting this surface. I believe it is similar to the .bisurf surface setting; in the official islands the only values used for this are soft_ground, hard_ground and concrete.

Next up is CfgSurfaceCharacters, the class where the density of each clutter object is actually defined, per surface character. This is a snippet from the Chernarus config. The entry shown corresponds to the surface definition in the snippet above.

class CfgSurfaceCharacters
{
 class CRGrassClutter
 {
  probability[] = {0.79,0.1,0.1,0.01};
  names[] = {"GrassCrookedGreen","GrassCrooked","AutumnFlowers","WeedDead"};
 };
};

This class is relatively simple. A class is defined for each surface character. In it are defined probability[] and names[]. The first determines the density of that object, and the second determines which object it actually is. The name of the class under CfgSurfaceCharacters is used in CfgSurfaces for the "character" parameter. names[] is an array of strings containing the class names defined under the clutter class in CfgWorlds.

Unfortunately it is rather hard to test clutter distributions, as the island must be recompiled every time (Buldozer does not show clutter, as it runs a non-compiled island). Even if someone were to write a clutter visualizer, the particular algorithm into which these values are fed is probably known only to BI. For what it's worth, the highest probability in a BI surface character is 0.975 (for c_stubble.p3d in CRStubbleClutter), with typical values going up to 0.65 and the lowest value is 0.001 (for MushroomsHorcak in CRForestMixedClutter).

* - It's important to be aware that ground textures are actually only visible at short ranges, the ones defined by these values. Hence why these are called the "ground detail textures". At longer ranges the satellite texture is seen instead of the ground textures. Even then, the satellite texture is actually mixed with the ground detail texture to produce color variations right up to the player's feet.