Modding:Encounters and Population: Difference between revisions

Add new info about population table merging
(add dynamic table example)
(Add new info about population table merging)
Line 1: Line 1:
{{stub}}[[Category:Modding]]{{Modding Info}}
[[Category:Modding]]{{Modding Info}}
There are two primary population systems in Caves of Qud, the legacy <code>EncounterTables.xml</code> system, and the <code>ZoneTemplates.xml</code>+<code>PopulationTables.xml</code> system. Encounter tables are an older system and we prefer to use zone templates + population tables these days, but much of the game is still populated via <code>EncounterTables.xml</code>.
There are two primary population systems in Caves of Qud, the legacy <code>EncounterTables.xml</code> system, and the <code>ZoneTemplates.xml</code>+<code>PopulationTables.xml</code> system. Encounter tables are an older system and we prefer to use zone templates + population tables these days, but much of the game is still populated via <code>EncounterTables.xml</code>.


Like ObjectTables, <code>EncounterTables.xml</code> supports <code>Load="Merge"</code> in the object root tag. This will append entries to that particular table instead of overwriting.
Like <code>ObjectBlueprints.xml</code>, both the <code>EncounterTables.xml</code> and the <code>PopulationTables.xml</code> support use of the <code>Load="Merge"</code> attribute to merge content into existing tables defined by the base game files. This will append entries to the specified table instead of overwriting it.


Population tables currently do not support XML modding, but many zone template encounters draw objects from dynamically created population tables. Check out the following tags in <code>ObjectBlueprints.xml</code> to see them in use: <code>DynamicObjectsTable</code>, <code>ExcludeFromDynamicEncounters</code>. Some dynamic population tables are created based on the base type of the object, so new objects will begin appearing immediately in areas generated with dynamic population tables unless they are tagged with <code>ExcludeFromDynamicEncounters</code>.
Many zone template encounters draw objects from dynamically created population tables. Check out the following tags in <code>ObjectBlueprints.xml</code> to see them in use: <code>DynamicObjectsTable</code>, <code>ExcludeFromDynamicEncounters</code>. Some dynamic population tables are created based on the base type of the object, so new objects will begin appearing immediately in areas generated with dynamic population tables unless they are tagged with <code>ExcludeFromDynamicEncounters</code>. Refer to the section below for more information about Dynamic population tables.


The unaffiliated cave systems are the only areas currently heavily populated with the template+population system.
The unaffiliated cave systems are one area that is heavily populated with the zone template+population system.


== Extending Encounter Tables ==
== Extending Encounter Tables ==
Line 22: Line 22:
</syntaxhighlight>
</syntaxhighlight>


== Additional Info ==
==Extending Population Tables==
{{Cleanup |The information from the Steam thread needs to be integrated into this article.}}
To modify existing populations, you can take a similar approach. For example, the following could be used in a mod's <code>PopulationTables.xml</code> file to add a new type of Wristblade Legendary merchant lair:
Here's a thread on Steam where Brian discusses using encounter and population tables: http://steamcommunity.com/app/333640/discussions/3/358415738194955181/
 
<syntaxhighlight lang="xml">
  <population Name="GenericLairOwner" Load="Merge">
    <group Name="Options" Load="Merge">  <!-- Add the Load="Merge" attribute to each nested group, mimicking the base game's PopulationTables.xml structure -->
      <object Blueprint="WristbladeMerchant" Weight="20" /> <!-- Insert your new item! -->
    </group>
  </population>
</syntaxhighlight>
 
Of course, this would also need to be supplemented with an ObjectBlueprints.xml that defines the new "WristbladeMerchant". It would likely inherit from "BaseMerchant" and have the appropriate parts defined, similar to other legendary merchants.


==Modifying Existing Populations==
=== Full Example Usage ===
To modify existing populations, use <code>PopulationManager.cs</code> to load the changes on game boot up.
Here is some example XML from a mod that creates a fully functional Six Day Stilt vendor using a combination of <code>Load="Merge"</code> tables and new tables defined by the mod. This is everything that's needed in the mod's PopulationTables.xml file, though this won't work by itself. It would also require an ObjectBlueprints.xml to define the various Blueprint objects that are not included here.
<syntaxhighlight lang="c#">
// Helper method to fudge into the most common/simple pop tables.
public static bool AddToPopTable(string table, params PopulationItem[] items) {
    PopulationInfo info;
    if (!PopulationManager.Populations.TryGetValue(table, out info))
        return false;
       
    // If this is a single group population, add to that group.
    if (info.Items.Count == 1 && info.Items[0] is PopulationGroup) {
        var group = info.Items[0] as PopulationGroup;
        group.Items.AddRange(items);
        return true;
    }


     info.Items.AddRange(items);
<syntaxhighlight lang="xml">
     return true;
  <!-- Merge new YoyoWinderTent into the game's StiltTents population table -->
}
  <population Name="StiltTents" Load="Merge">
     <group Name="Types" Load="Merge">
      <table Name="YoyoWinderTent" Weight="4" />
     </group>
  </population>


// Usage in IPart constructor slapped on dummy XML object
  <!-- Define the YoyoWinderTent -->
public class SomeInitialiser : IPart
  <population Name="YoyoWinderTent">
{
    <group Name="Contents" Style="pickeach">
     public SomeInitialiser() {
      <object Blueprint="YoyoWinder" Number="1" Hint="Interior" />
        AddToPopTable("RandomLiquid", new PopulationObject { Blueprint = "SomeLiquid" });
      <table Name="YoyoWinderTentContents" />
        AddToPopTable("RandomFaction", new PopulationObject { Blueprint = "SomeFaction" });
    </group>
        AddToPopTable("LairOwners_Saltdunes", new PopulationTable { Name = "DynamicObjectsTable:SomeCreature", Weight = 5 });
  </population>
     }
  <population Name="YoyoSigns">
}
    <group Name="Items" Style="pickone">
      <object Blueprint="YoyoSign1" Number="1" Hint="OutsideDoor:1" />
      <object Blueprint="YoyoSign2" Number="1" Hint="OutsideDoor:1" />
      <object Blueprint="YoyoSign3" Number="1" Hint="OutsideDoor:1" />
     </group>
  </population>
  <population Name="YoyoWinderTentContents">
    <group Name="Contents" Style="pickeach">
      <object Blueprint="Torchpost" Number="1" Hint="InsideCorner" />
      <table Name="YoyoSigns" />
      <object Blueprint="Torchpost" Number="1-2" Hint="OutsideDoor:2" />
      <object Blueprint="YoyoWinder Workbench" Number="1-2" Hint="AlongInsideWall" />
      <object Blueprint="Woven Basket" Number="1" />
      <object Blueprint="YoyoWinder Workbench" Number="1" />
      <object Blueprint="Yoyo Oil Pitcher" Number="1-2" Hint="AlongInsideWall" />
      <object Blueprint="Yoyo String Plastifer 3" Number="1" Chance="15" />
      <object Blueprint="Yoyo String Elastyne 3" Number="1" Chance="35" />
      <object Blueprint="Yoyo String Elastyne 5" Number="1" Chance="20" />
      <object Blueprint="Chest" Number="1-2" Hint="AlongInsideWall" />
     </group>
  </population>
</syntaxhighlight>
</syntaxhighlight>


Line 125: Line 145:
| 1000
| 1000
|}
|}
== Additional Info ==
{{Cleanup |The information from the Steam thread needs to be integrated into this article.}}
Here's a thread on Steam where Brian discusses using encounter and population tables: http://steamcommunity.com/app/333640/discussions/3/358415738194955181/


{{Modding Navbox}}
{{Modding Navbox}}