This guide outlines how to place forests using the Procedural Placement tool. Follow these steps carefully to ensure success. Note that it can be a bit tricky to figure out and setup, make sure to use a test map first, and you have a decent knowledge of the Editor.
Step 1: Verify Map.i3d Setup/Coding
Ensure your map.i3d file contains the following section. This will ensure you have the *basic* scripts needed:
Below Scenes:
<ProceduralPlacement> <Types> <Type name="defaultFoliage"> <Distance to="defaultFoliage" min="0" /> <Distance to="defaultReference" min="0" /> <Distance to="parentTrees" min="0" /> </Type> <Type name="defaultReference"> <Distance to="defaultFoliage" min="0" /> <Distance to="defaultReference" min="4" /> <Distance to="mediumTree" min="5" /> <Distance to="parentTrees" min="6" /> <Distance to="smallTrees" min="3" /> </Type> <Type name="defaultTexture"> <Distance to="defaultTexture" min="0" /> </Type> <Type name="mediumTree"> <Distance to="defaultReference" min="5" /> <Distance to="mediumTree" min="6" /> <Distance to="parentTrees" min="7" /> <Distance to="smallTrees" min="4" /> </Type> <Type name="parentTrees"> <Distance to="defaultFoliage" min="0" /> <Distance to="defaultReference" min="6" /> <Distance to="mediumTree" min="7" /> <Distance to="parentTrees" min="20" /> <Distance to="smallTrees" min="4" /> </Type> <Type name="smallTrees"> <Distance to="defaultReference" min="3" /> <Distance to="mediumTree" min="4" /> <Distance to="parentTrees" min="4" /> <Distance to="smallTrees" min="2" /> </Type> </Types> <Objects> <Object type="terrainFoliage" name="F_AcreDetail" foliageTypeName="terrainDetail" channels="2" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_GrassSmall" foliageTypeName="decoFoliage" channels="289" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_GrassMedium" foliageTypeName="decoFoliage" channels="321" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_Meadow" foliageTypeName="meadow" channels="131" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_DecoFSmall" foliageTypeName="decoFoliage" channels="33" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_DecoFSmallRumex" foliageTypeName="decoFoliage" channels="65" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_DecoChaero" foliageTypeName="decoFoliage" channels="129" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_DecoCheno" foliageTypeName="decoFoliage" channels="161" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_DecoCirsium" foliageTypeName="decoFoliage" channels="193" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_DecoRumex" foliageTypeName="decoFoliage" channels="257" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="F_BushSmall" foliageTypeName="decoBush" channels="1" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="ForestDryBranch" foliageTypeName="forestPlants" channels="36" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="ForestClover" foliageTypeName="forestPlants" channels="68" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="ForestStarFlower" foliageTypeName="forestPlants" channels="100" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="ForestBunchBerry" foliageTypeName="forestPlants" channels="132" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="ForestSalmonBerry" foliageTypeName="forestPlants" channels="164" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="ForestStarryFalse" foliageTypeName="forestPlants" channels="196" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="ForestSwordFern" foliageTypeName="forestPlants" channels="228" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="ForestDeerFern" foliageTypeName="forestPlants" channels="260" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="ForestGrass" foliageTypeName="forestPlants" channels="292" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushCommon01" foliageTypeName="decoBushUS" channels="34" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushCommon02" foliageTypeName="decoBushUS" channels="66" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushCommon03" foliageTypeName="decoBushUS" channels="98" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushDynamite01" foliageTypeName="decoBushUS" channels="130" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushDynamite02" foliageTypeName="decoBushUS" channels="162" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushDynamite03" foliageTypeName="decoBushUS" channels="194" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushPaw01" foliageTypeName="decoBushUS" channels="226" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushPaw02" foliageTypeName="decoBushUS" channels="258" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushPaw03" foliageTypeName="decoBushUS" channels="290" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushWaterElm01" foliageTypeName="decoBushUS" channels="322" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushWaterElm02" foliageTypeName="decoBushUS" channels="354" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushWaterElm03" foliageTypeName="decoBushUS" channels="386" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushSumac" foliageTypeName="decoBushUS" channels="418" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushHazel01" foliageTypeName="decoBushUS" channels="450" ppType="defaultFoliage" /> <Object type="terrainFoliage" name="BushHazel02" foliageTypeName="decoBushUS" channels="482" ppType="defaultFoliage" /> </Objects> <Rules> <Rule name="GEN_Roads" isMainRule="true" objectMinDistance="0" slopeStart="0" slopeEnd="90" > <Script name="createRoadMaskUS.lua" > <Arg name="includeChildren" type="boolean" value="false" /> <Arg name="excludeChildren" type="boolean" value="false" /> <Arg name="nodesInclude" type="nodes" value="@184486>0{{!}};" /> <Arg name="nodesExclude" type="nodes" value="5857;" /> </Script> </Rule> <Rule name="T_Asphalt" isMainRule="true" objectMinDistance="0" slopeStart="0" slopeEnd="90" > <Script name="scatterInMask.lua" > <Arg name="mask" type="mask" value="GEN_Roads" /> </Script> <Object id="1" childRule="" objectName="ASPHALT" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> </Rule> <Rule name="T_Forest01" isMainRule="true" objectMinDistance="0" slopeStart="0" slopeEnd="90" > <Script name="scatterInMask.lua" > <Arg name="mask" type="mask" value="PG_Forest" /> </Script> <Object id="1" childRule="" objectName="FOREST_GROUND" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> <Object id="2" childRule="" objectName="FOREST_GRASS" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="3" /> <Object id="3" childRule="" objectName="FOREST_ROOTS" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> </Rule> <Rule name="T_Forest02" isMainRule="true" objectMinDistance="0" slopeStart="0" slopeEnd="90" > <Script name="scatterInPerlinNoise.lua" > <Arg name="seed" type="int" value="44" /> <Arg name="clampThreshold" type="int" value="127" /> <Arg name="frequency" type="float" value="0.154000" /> <Arg name="clamped" type="boolean" value="true" /> <Arg name="mask" type="mask" value="PG_Forest" /> </Script> <Object id="1" childRule="" objectName="FOREST_LEAVES" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> <Object id="2" childRule="" objectName="FOREST_NEEDELS" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> </Rule> <Rule name="F_ForestGrass" isMainRule="true" objectMinDistance="0" slopeStart="0" slopeEnd="90" > <Script name="scatterInPerlinNoise.lua" > <Arg name="seed" type="int" value="2377" /> <Arg name="clampThreshold" type="int" value="128" /> <Arg name="frequency" type="float" value="0.400000" /> <Arg name="clamped" type="boolean" value="true" /> <Arg name="mask" type="mask" value="PG_Forest" /> </Script> <Object id="1" childRule="" objectName="ForestGrass" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="4" /> <Object id="2" childRule="" objectName="F_GrassSmall" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> <Object id="3" childRule="" objectName="F_GrassMedium" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> <Object id="4" childRule="" objectName="F_DecoFSmall" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="3" /> </Rule> <Rule name="F_ForestPatches" isMainRule="true" objectMinDistance="0" slopeStart="0" slopeEnd="90" > <Script name="scatterInPerlinNoise.lua" > <Arg name="seed" type="int" value="1549" /> <Arg name="clampThreshold" type="int" value="100" /> <Arg name="frequency" type="float" value="0.500000" /> <Arg name="clamped" type="boolean" value="true" /> <Arg name="mask" type="mask" value="PG_Forest" /> </Script> <Object id="6" childRule="" objectName="ForestClover" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> </Rule> <Rule name="F_ForestClutter" isMainRule="true" objectMinDistance="0" slopeStart="0" slopeEnd="90" > <Script name="scatterInPerlinNoise.lua" > <Arg name="seed" type="int" value="478" /> <Arg name="clampThreshold" type="int" value="121" /> <Arg name="frequency" type="float" value="0.180000" /> <Arg name="clamped" type="boolean" value="true" /> <Arg name="mask" type="mask" value="PG_Forest" /> </Script> <Object id="6" childRule="" objectName="ForestBunchBerry" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="4" /> <Object id="7" childRule="" objectName="ForestStarFlower" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> <Object id="8" childRule="" objectName="ForestSalmonBerry" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> <Object id="9" childRule="" objectName="ForestStarryFalse" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> <Object id="10" childRule="" objectName="ForestSwordFern" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> <Object id="11" childRule="" objectName="ForestDeerFern" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> </Rule> <Rule name="F_ForestBushes" isMainRule="true" objectMinDistance="0" slopeStart="0" slopeEnd="90" > <Script name="scatterInPerlinNoise.lua" > <Arg name="seed" type="int" value="9784" /> <Arg name="clampThreshold" type="int" value="100" /> <Arg name="frequency" type="float" value="0.540000" /> <Arg name="clamped" type="boolean" value="true" /> <Arg name="mask" type="mask" value="PG_Forest" /> </Script> <Object id="1" childRule="" objectName="BushCommon01" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> <Object id="2" childRule="" objectName="BushCommon02" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> <Object id="3" childRule="" objectName="BushCommon03" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> <Object id="7" childRule="" objectName="BushPaw01" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> <Object id="8" childRule="" objectName="BushPaw02" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> <Object id="9" childRule="" objectName="BushPaw03" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> <Object id="10" childRule="" objectName="BushWaterElm01" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> <Object id="11" childRule="" objectName="BushWaterElm02" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> <Object id="12" childRule="" objectName="BushWaterElm03" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="1" /> <Object id="13" childRule="" objectName="BushHazel01" childMinCount="1" childMaxCount="10" childMinRadius="0" childMaxRadius="20" probability="2" /> </Rule> </Rules> </ProceduralPlacement>
Go to your map folder and ensure you have a folder within data named masks.
Step 2: Overview of the Procedural Placement Window
- Open the Procedural Placement window (Windows > Procedural Placement).
- If it asks you to select a file for a BLOCKMASK, go to the previously mentioned masks folder and name it BLOCKMASK. This will create a BLOCKMASK.png.
- Masks Tab (1st tab):
- Create masks for placement later.
- Select Add Mask and double-click the empty field under Filename. Name it (e.g., Forest1).
- To the left, name it again (e.g., Forest1) for the Layers applied on the map.
- Apply changes and save the map to retain these settings.
- Ensure the resolution matches your map (e.g., 2048x2048 for base maps).
- Scripts Tab (2nd tab):
- Displays the scripts included in your map.i3d.
- Advanced users can modify scripts, but they are not required initially.
- Distance Matrix (3rd tab):
- Avoid modifying this tab.
- Objects Tab (4th tab):
- Add foliage and objects for Procedural Placement.
- For objects:
- Click Add i3d reference.
- Select the desired i3d file (e.g., pinusSylvestris\_stage05.i3d).
- Name the tree (e.g., pinusSylvestris\_stage05) and choose the appropriate type (e.g., ParentTree). This is to help PP use the correct distances setup in the Distance Matrix.
- Save after every addition.
- Rules Tab (5th tab):
- Configure and manage Procedural Placement rules.
- Rules are read top-down:
- Add textures first, followed by foliage and objects.
- Use the ScatterInMask script for the FIRST rule you use.
- Use scatterInPerlinNoise for subsequent rules.
- Select the appropriate mask for each rule (e.g., Forest1).
- Add textures, foliage, and objects with adjustable probabilities and scales.
- Place Objects runs the script, do *not* use now, only when all steps are completed.
Step 3: Set Up Your Objects and Rules
- Verify i3d paths for all objects.
- Name rules using a consistent format (e.g., T_whatever for textures, F_ whatever for foliage and objects).
- Keep textures, foliages and objects on separate rules!
- Arrange rules in the following order:
- Textures (placed first).
- Foliage and objects (placed below textures).
- Use at least three textures to avoid default placement issues.
- Save your map after every modification.
Step 4: Place Down Your Forest
- Select the Procedural Placement terrain tool (next to the Foliage tool).
- Choose the correct layer (e.g., Forest1) in the Procedural Placement Area menu.
- Paint the desired area for the forest. (Save your map to keep the mask in case of a crash during PP).
- In the Procedural Placement window:
- Go to the Rules tab.
- Verify rule order and scripts.
- Ensure textures are placed first, followed by foliage and objects.
- You can have many rules running on the same mask to create a more diverse Forest.
- Click Place Objects.
Note: If the editor crashes, review your setup and try again.
Step 5: Finalize the Placement
- Rename the Procedural Group in the Scenegraph (e.g., Forest1). This prevents PP from using it again for future generations.
- Save your map.
- Restart the editor before placing additional forests to prevent issues; this resets PP memory.
Additional Notes
- Re-run placements immediately if unsatisfied, perhaps changing textures in rules, or foliage, etc.
- Test new setups on a separate map to avoid corruption. (Make a copy of current map to keep all settings!)
- Create multiple masks for different forests. Forest1, Forest2, Forest3, etc.
- Avoid reusing masks unless rules are identical. This will affect previously placed things within that mask.
Thanks to Gamerdesigns and StrauntMaunt for testing and findings!