Home > notes > pcontent

Pcontent

Parameterized content (or pcontent for short) is the mechanism that allows Dungeon Siege to provide a huge range of armor and weapon types from a relatively small set of templates. Each basic item can have its attributes (damage, defense, magical enhancements, etc) determined by a random choice within ranges that the template or skrit specifies.

Where do I define pcontent?

Note: This is the DS2 answer, DS1 has some differences. Each item template contains two main sources. In the [common] block an item can be isolated from the pcontent system by setting is_pcontent_allowed = false, and if you don't do that, you can have a [pcontent] block that determines an item_level. This block can define variants of the item that may be selected to further alter the item level. In the example you can see the item_level being used to set the character requirements to equip the item.


[t:template,n:dg_1h_dg]
{
  specializes = base_dagger_template;
  doc = "dagger";
  [aspect]
  {
    . . .
  }
  [pcontent]
  {
    [base]
    {
      equip_requirements = uber:#item_level - 2.0,
	                 melee:#item_level - 2.0;
      item_level = 0.0;
    }
    [var1]
    {
      equip_requirements = uber:#item_level - 2.0,
	                 melee:#item_level - 4.0;
      item_level = 11.0;
    }
    . . .
  }
}

//Used in the Taar Secondary Quest
[t:template,n:dg_1h_dg_unq_haku_quest]
{
	specializes = base_dagger_template;
	doc = "dg_1h_dg_unq_haku_quest";
	[aspect]
	{
		model = m_w_dag_haku;
		tracer_texture = b_sfx_tra_generic-20;
	}
	[attack]
	{
		damage_min = 2;
		damage_max = 5;
	}
	[common]
	{
		allow_modifiers = false;
		is_pcontent_allowed = false;
		screen_name = "Hak'u Ceremonial Blade";
		base_screen_name = "Hak'u Ceremonial Blade";
		rarity = unique;
	}
	...
}

item_level is used in the _base templates to set such things as the defense value for armor, and the max/min damage for weapons.


  [attack]
  {
    attack_class = ac_sword;
    damage_min = 0.75 * (3.4 + 0.74 * #item_level);
    damage_max = 1.25 * (3.4 + 0.74 * #item_level);
    is_melee = true;
    reload_delay = 0.67;
    skill_class = melee;
  }

Pcontent actually goes one step further and allows the type of item to be randomly generated. This is typically used in drops from monsters and containers. Which brings us to...

How is pcontent used?

The easiest place to see pcontent use is in vendors' stores. If you look in the stores.gas file of any DS2 map, you will see examples of generating items for sale.


[act_1_weapon_store]
{
  [melee]
  {
    [all*]
    {
      il_main = #dg_1h_dg:base;
      count = 1;
      world_specific = mercenary;
    }
    [all*]
    {
      il_main = #hm_1h_hm:base;
      count = 1;
      world_specific = mercenary;
    }
    [all*]
    {
      il_main = #st_mg_rs:base;
      count = 1;
      world_specific = mercenary;
    }
  // other stuff
    [all*]
    {
      il_main = #melee;
      count = 16;
    }
    [all*]
    {
      il_main = #melee/3-8;
      count = 8;
      world_specific = mercenary;
    }
    . . .

If we analyze the individual entries, we can learn a lot about how pcontent can be used. There are useful comments in some stores, too!

First thing to note is that an entry in a store's inventory can be either the name of a specific template, or a generic (i.e. pcontent) request. The latter have an initial "#' character. This tells the engine to select from the content database, items that match the specification given.

The next part can be a template name, or a macro that includes multiple templates at once. These can be followed by modifers that control the selection.

An entry of the form #templatename:xxxx selects the "xxxx" variant from the [pcontent] block. In the example, the base variants are explicitly requested. This is the first weapon vendor you reach, and this ensures that you can buy at least some weapons you can actually use! The rest of the melee weapons page is filled with generic requests for any melee weapons, and some slots are also set aside for a range of item levels using the format #macro/range.

When the macros are used, a piece of skrit code comes in to play to choose the items, and their magical modifiers. Take a look at pcontent.skrit to see how the proportions of item types are determined. You may want to change the relative chances of swords versus axes or hammers, and this is the place to do that.

Another place that pcontent is used is in drops. Here the engine needs to be able to select unique and rare items that the stores don't carry. Take a look in the files in world/contentdb/pcontent/macros. Here you will find item specifications like #/-rare, which has no template or macro name specified at all, and so it means "any type of rare item", but there are additional lines of code that set limits such as pcontent_min_level or pcontent_max_modifier as well.


from a quest drop macro - item_level was calculated earlier: 
. . .
    [all*]	// 4% Chance to drop a rare item
    {
      chance = 0.04 * (1 + (#magic_find * .01));
      il_main = #/-rare;
      pcontent_min_level = #item_level - 5;
      pcontent_max_level = #item_level;
      pcontent_min_modifier = #item_level - 25;
      pcontent_max_modifier = #item_level + 5;
    }
. . .

[a1_pq3_dryad_outpost_celia]
{
  [all*]
  {
    player_drop_type = all;
    il_main = #amr_hlm_dryad;
    il_main = #amr_glv_dryad;
    il_main = #amr_bot_dryad;
    il_main = #st_mg_rs:base;    // restricted to base variant
    il_main = spell_jolt_1;      // explicit template - no pcontent
    il_main = scroll_resurrect;
    il_main = #potion_health_small; // pcontent!
    il_main = #potion_mana_small;
  }
}
[a1_sq_armorer_apprentice_correct_lowlevel]
{
  [all*]
  {
    player_drop_type = all;
    il_main = #amr_bdy_dryad/+ofsturdiness/+stable;
  }
}

The last example shows explicit modifiers being attached. I'm not certain why potions are defined with pcontent - maybe the intent was that the bottle would not always be full?

Testing pcontent

If you just made a new weapon and you want to check out the pcontent attached to it, you can run DS(2/LOA)MOD and give it to a character. Even if they can't use it, it will appear in their inventory for you to check the modifiers and damage levels. When you use pcontent this way, you can specify the modifiers and variants, but the levels don't seem to work.

Lara 3